1 martin 1.121 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.122 //
|
3 martin 1.121 // 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.122 //
|
10 martin 1.121 // 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.122 //
|
17 martin 1.121 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.122 //
|
20 martin 1.121 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.122 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.121 // 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.122 //
|
28 martin 1.121 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include <Pegasus/Common/Config.h>
|
33 kumpf 1.28 #include <Pegasus/Common/Constants.h>
|
34 mike 1.2 #include <cctype>
35 #include <cstdio>
36 #include <Pegasus/Common/XmlParser.h>
37 #include <Pegasus/Common/XmlReader.h>
38 #include <Pegasus/Common/XmlWriter.h>
39 #include <Pegasus/Common/XmlConstants.h>
|
40 kumpf 1.51 #include <Pegasus/Common/System.h>
|
41 mike 1.2 #include <Pegasus/Common/Logger.h>
42 #include <Pegasus/Common/Tracer.h>
|
43 sage 1.41 #include <Pegasus/Common/StatisticalData.h>
|
44 mike 1.2 #include "CIMOperationRequestDecoder.h"
|
45 david 1.60 #include <Pegasus/Common/CommonUTF.h>
|
46 humberto 1.59 #include <Pegasus/Common/MessageLoader.h>
|
47 mike 1.120 #include <Pegasus/Common/BinaryCodec.h>
|
48 marek 1.138 #include <Pegasus/Common/OperationContextInternal.h>
|
49 marek 1.139 #include <Pegasus/General/CIMError.h>
50
51 #ifdef PEGASUS_PAM_SESSION_SECURITY
52 #include <Pegasus/Security/Authentication/PAMSessionBasicAuthenticator.h>
53 #include <Pegasus/Security/Authentication/AuthenticationStatus.h>
54 #endif
55
|
56 humberto 1.59
|
57 mike 1.2 PEGASUS_USING_STD;
58
59 PEGASUS_NAMESPACE_BEGIN
60
|
61 karl 1.137 // throw CIM_ERR_NOT_SUPPORTED with no additional text
62 void _throwCIMExceptionCIMErrNotSupported(const String& param = String::EMPTY)
63 {
64 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, param);
65 }
66
67 // Throw CIM_ERR_INVALID_PARAMETER with optional parameter name(s)
68 void _throwCIMExceptionInvalidParameter(const String& param = String::EMPTY)
69 {
70 throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, param);
71 }
72
73 // Common call for all cases where duplicate IparameterValues recieved
74 // in a single operation. Throw InvalidParameter exception with optional
75 // additional data.
76 void _throwCIMExceptionDuplicateParameter(const String& name = String::EMPTY)
77 {
78 _throwCIMExceptionInvalidParameter(name);
79 }
80
81 // Common call for cases where Invalid IParameterValue names recived
82 karl 1.137 void _throwCIMExceptionInvalidIParamName(const String& param = String::EMPTY)
83 {
84 _throwCIMExceptionCIMErrNotSupported(param);
85 }
86
|
87 marek 1.139 #ifdef PEGASUS_PAM_SESSION_SECURITY
88 void CIMOperationRequestDecoder::_updateExpiredPassword(
89 Uint32 queueId,
90 HttpMethod httpMethod,
91 const String& messageId,
92 Boolean closeConnect,
93 const ContentLanguageList& httpContentLanguages,
94 CIMMessage * request,
95 const String& userName,
96 const String& oldPass)
97 {
98 static CIMName meth = CIMName("UpdateExpiredPassword");
99 static CIMName clName = CIMName("PG_Account");
100
101
102 // this has to be an invokeMethod and
103 if (CIM_INVOKE_METHOD_REQUEST_MESSAGE != request->getType())
104 {
105 sendHttpError(
106 queueId,
107 HTTP_STATUS_BADREQUEST,
108 marek 1.139 "invalid header",
109 "Header \'Pragma: UpdateExpiredPassword\' not valid for this "
110 "CIMMethod.",
111 closeConnect);
112
113 return;
114 }
115
116 CIMInvokeMethodRequestMessage* msg =
117 dynamic_cast<CIMInvokeMethodRequestMessage*>(request);
118
119 // class PG_Account
120 // method UpdateExpiredPassword
121 // InterOp namespace
122 if ((!clName.equal(msg->className)) ||
123 (!(meth.equal(msg->methodName))) ||
124 (!msg->nameSpace.equal(PEGASUS_NAMESPACENAME_INTEROP.getString())))
125 {
126 // not of interest for us, chicken out
127 sendHttpError(
128 queueId,
129 marek 1.139 HTTP_STATUS_BADREQUEST,
130 "invalid header",
131 "Header \'Pragma: UpdateExpiredPassword\' not valid for this "
132 "class, method or namespace.",
133 closeConnect);
134 return;
135 }
136
137 String newPass;
138 Boolean found = false;
139
140 try
141 {
142 // Get new password from request - String-type Parameter UserPassword
143 Array<CIMParamValue> inParm = msg->inParameters;
144 for (Uint32 i=0; i < inParm.size(); i++)
145 {
146 CIMParamValue x = inParm[i];
147 if (String::equalNoCase(x.getParameterName(),"UserPassword"))
148 {
149 CIMValue passValue = x.getValue();
150 marek 1.139 passValue.get(newPass);
151 found = true;
152 break;
153 }
154 }
155 } catch(Exception &e)
156 {
157 // already know it is an invokeMethod, see checks above
158 sendMethodError(
159 queueId,
160 httpMethod,
161 messageId,
162 meth.getString(),
163 PEGASUS_CIM_EXCEPTION(
164 CIM_ERR_INVALID_PARAMETER, e.getMessage()),
165 closeConnect);
166 return;
167 }
168 if (!found)
169 {
170 sendMethodError(
171 marek 1.139 queueId,
172 httpMethod,
173 messageId,
174 meth.getString(),
175 PEGASUS_CIM_EXCEPTION(
176 CIM_ERR_INVALID_PARAMETER, "Missing Parameter UserPassword"),
177 closeConnect);
178 return;
179 }
180 // Call password update function from PAMSession.h
181 AuthenticationStatus authStat =
182 PAMSessionBasicAuthenticator::updateExpiredPassword(
183 userName,
184 oldPass,
185 newPass);
186
187 if (authStat.isSuccess())
188 {
189 // Send success message
190 Buffer message;
191 Buffer emptyBody;
192 marek 1.139
193 message = XmlWriter::formatSimpleMethodRspMessage(
194 meth,
195 messageId,
196 httpMethod,
197 httpContentLanguages,
198 emptyBody,
199 0,
200 true,
201 true);
202
203 sendResponse(queueId, message,closeConnect);
204 }
205 else
206 {
207 sendHttpError(
208 queueId,
209 authStat.getHttpStatus(),
210 String::EMPTY,
211 authStat.getErrorDetail(),
212 closeConnect);
213 marek 1.139 }
214 }
215 #endif
216
217
218
219
|
220 mike 1.2 CIMOperationRequestDecoder::CIMOperationRequestDecoder(
|
221 sahana.prabhakar 1.126 MessageQueue* outputQueue,
|
222 kumpf 1.104 Uint32 returnQueueId)
223 : Base(PEGASUS_QUEUENAME_OPREQDECODER),
|
224 mday 1.16 _outputQueue(outputQueue),
225 _returnQueueId(returnQueueId),
226 _serverTerminating(false)
|
227 mike 1.2 {
228 }
229
230 CIMOperationRequestDecoder::~CIMOperationRequestDecoder()
231 {
232 }
233
234 void CIMOperationRequestDecoder::sendResponse(
|
235 kumpf 1.104 Uint32 queueId,
236 Buffer& message,
237 Boolean closeConnect)
238 {
239 MessageQueue* queue = MessageQueue::lookup(queueId);
240
241 if (queue)
242 {
243 AutoPtr<HTTPMessage> httpMessage(new HTTPMessage(message));
244 httpMessage->setCloseConnect(closeConnect);
245 queue->enqueue(httpMessage.release());
246 }
|
247 mike 1.2 }
248
|
249 kumpf 1.18 void CIMOperationRequestDecoder::sendIMethodError(
|
250 kumpf 1.104 Uint32 queueId,
251 HttpMethod httpMethod,
252 const String& messageId,
253 const String& iMethodName,
254 const CIMException& cimException,
255 Boolean closeConnect)
|
256 mday 1.16 {
|
257 mike 1.96 Buffer message;
|
258 kumpf 1.19 message = XmlWriter::formatSimpleIMethodErrorRspMessage(
259 iMethodName,
260 messageId,
|
261 kumpf 1.53 httpMethod,
|
262 kumpf 1.35 cimException);
|
263 kumpf 1.18
|
264 j.alex 1.95 sendResponse(queueId, message,closeConnect);
|
265 kumpf 1.18 }
|
266 mday 1.16
|
267 kumpf 1.18 void CIMOperationRequestDecoder::sendMethodError(
|
268 kumpf 1.104 Uint32 queueId,
269 HttpMethod httpMethod,
270 const String& messageId,
271 const String& methodName,
272 const CIMException& cimException,
273 Boolean closeConnect)
|
274 kumpf 1.18 {
|
275 mike 1.96 Buffer message;
|
276 kumpf 1.19 message = XmlWriter::formatSimpleMethodErrorRspMessage(
277 methodName,
278 messageId,
|
279 kumpf 1.53 httpMethod,
|
280 kumpf 1.35 cimException);
|
281 chip 1.92
|
282 j.alex 1.95 sendResponse(queueId, message,closeConnect);
|
283 mike 1.2 }
284
|
285 marek 1.139 void CIMOperationRequestDecoder::sendUserAccountExpired(
286 Uint32 queueId,
287 HttpMethod httpMethod,
288 const String& messageId,
289 const String& methodName,
290 Boolean closeConnect,
291 Boolean isIMethod)
292 {
293 Buffer message;
294
295 CIMError errorInst;
296 errorInst.setErrorType(CIMError::ERROR_TYPE_OTHER);
297 errorInst.setOtherErrorType("Expired Password");
298 errorInst.setProbableCause(CIMError::PROBABLE_CAUSE_AUTHENTICATION_FAILURE);
299
300 CIMException myExc(
301 CIM_ERR_ACCESS_DENIED,
302 "User Account Expired",
303 errorInst.getInstance());
304
305 if (isIMethod)
306 marek 1.139 {
307 message = XmlWriter::formatSimpleIMethodErrorRspMessage(
308 methodName,
309 messageId,
310 httpMethod,
311 myExc);
312 }
313 else
314 {
315 message = XmlWriter::formatSimpleMethodErrorRspMessage(
316 methodName,
317 messageId,
318 httpMethod,
319 myExc);
320 }
321
322 sendResponse(queueId, message,closeConnect);
323 }
324
|
325 kumpf 1.33 void CIMOperationRequestDecoder::sendHttpError(
|
326 kumpf 1.104 Uint32 queueId,
327 const String& status,
328 const String& cimError,
329 const String& pegasusError,
330 Boolean closeConnect)
|
331 kumpf 1.21 {
|
332 mike 1.96 Buffer message;
|
333 kumpf 1.33 message = XmlWriter::formatHttpErrorRspMessage(
334 status,
335 cimError,
|
336 kumpf 1.37 pegasusError);
|
337 chip 1.92
|
338 j.alex 1.95 sendResponse(queueId, message,closeConnect);
|
339 kumpf 1.26 }
340
|
341 kumpf 1.104 void CIMOperationRequestDecoder::handleEnqueue(Message* message)
|
342 mike 1.2 {
|
343 kumpf 1.104 if (!message)
344 return;
|
345 mike 1.2
|
346 kumpf 1.104 switch (message->getType())
347 {
348 case HTTP_MESSAGE:
349 handleHTTPMessage((HTTPMessage*)message);
350 break;
|
351 kumpf 1.112
352 default:
353 // Unexpected message type
|
354 dl.meetei 1.136 PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);)
|
355 kumpf 1.112 break;
|
356 kumpf 1.104 }
|
357 mday 1.16
|
358 kumpf 1.104 delete message;
|
359 mday 1.16 }
|
360 mike 1.2
361
|
362 mday 1.16 void CIMOperationRequestDecoder::handleEnqueue()
363 {
|
364 kumpf 1.104 Message* message = dequeue();
365 if (message)
366 handleEnqueue(message);
|
367 mike 1.2 }
368
369 //------------------------------------------------------------------------------
370 //
371 // From the HTTP/1.1 Specification (RFC 2626):
372 //
|
373 chip 1.92 // Both types of message consist of a start-line, zero or more header fields
374 // (also known as "headers"), an empty line (i.e., a line with nothing
375 // preceding the CRLF) indicating the end of the header fields, and possibly
|
376 mike 1.2 // a message-body.
377 //
378 // Example CIM request:
379 //
|
380 chip 1.92 // M-POST /cimom HTTP/1.1
381 // HOST: www.erewhon.com
|
382 marek 1.132 // Content-Type: application/xml; charset=utf-8
|
383 chip 1.92 // Content-Length: xxxx
384 // Man: http://www.dmtf.org/cim/operation ; ns=73
385 // 73-CIMOperation: MethodCall
386 // 73-CIMMethod: EnumerateInstances
387 // 73-CIMObject: root/cimv2
388 //
|
389 mike 1.2 //------------------------------------------------------------------------------
390
391 void CIMOperationRequestDecoder::handleHTTPMessage(HTTPMessage* httpMessage)
392 {
|
393 kumpf 1.104 PEG_METHOD_ENTER(TRC_DISPATCHER,
394 "CIMOperationRequestDecoder::handleHTTPMessage()");
|
395 kumpf 1.20
|
396 kumpf 1.104 // Set the Accept-Language into the thread for this service.
397 // This will allow all code in this thread to get
398 // the languages for the messages returned to the client.
|
399 kumpf 1.114 Thread::setLanguages(httpMessage->acceptLanguages);
|
400 kumpf 1.104
401 // Save queueId:
402
403 Uint32 queueId = httpMessage->queueId;
404
|
405 marek 1.139 // Save userName, userRole, userPass and authType:
|
406 kumpf 1.104
407 String userName;
|
408 marek 1.138 String userRole;
|
409 marek 1.139 String userPass;
410 Boolean isExpiredPassword = false;
411 Boolean updateExpiredPassword;
|
412 kumpf 1.104 String authType;
413 Boolean closeConnect = httpMessage->getCloseConnect();
414
415 PEG_TRACE((
416 TRC_HTTP,
|
417 marek 1.118 Tracer::LEVEL4,
|
418 kumpf 1.104 "CIMOperationRequestDecoder::handleHTTPMessage()- "
419 "httpMessage->getCloseConnect() returned %d",
420 closeConnect));
421
|
422 sushma.fernandes 1.109 userName = httpMessage->authInfo->getAuthenticatedUser();
423 authType = httpMessage->authInfo->getAuthType();
|
424 marek 1.138 userRole = httpMessage->authInfo->getUserRole();
|
425 marek 1.139 userPass = httpMessage->authInfo->getAuthenticatedPassword();
426
427 #ifdef PEGASUS_PAM_SESSION_SECURITY
428 isExpiredPassword = httpMessage->authInfo->isExpiredPassword();
429 #endif
|
430 kumpf 1.104
431 // Parse the HTTP message:
432
433 String startLine;
434 Array<HTTPHeader> headers;
435 char* content;
436 Uint32 contentLength;
437
438 httpMessage->parse(startLine, headers, contentLength);
439
440 // Parse the request line:
441
442 String methodName;
443 String requestUri;
444 String httpVersion;
445 HttpMethod httpMethod = HTTP_METHOD__POST;
446
447 HTTPMessage::parseRequestLine(
448 startLine, methodName, requestUri, httpVersion);
449
450 //
451 kumpf 1.104 // Set HTTP method for the request
452 //
453 if (methodName == "M-POST")
454 {
455 httpMethod = HTTP_METHOD_M_POST;
456 }
457
458 // Unsupported methods are caught in the HTTPAuthenticatorDelegator
459 PEGASUS_ASSERT(methodName == "M-POST" || methodName == "POST");
460
461 //
462 // Mismatch of method and version is caught in HTTPAuthenticatorDelegator
463 //
464 PEGASUS_ASSERT(!((httpMethod == HTTP_METHOD_M_POST) &&
465 (httpVersion == "HTTP/1.0")));
|
466 humberto 1.80
|
467 kumpf 1.104 // Process M-POST and POST messages:
|
468 humberto 1.80
|
469 kumpf 1.104 if (httpVersion == "HTTP/1.1")
470 {
471 // Validate the presence of a "Host" header. The HTTP/1.1 specification
472 // says this in section 14.23 regarding the Host header field:
473 //
474 // All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad
475 // Request) status code to any HTTP/1.1 request message which lacks
476 // a Host header field.
477 //
478 // Note: The Host header value is not validated.
479
|
480 kumpf 1.124 const char* hostHeader;
|
481 kumpf 1.104 Boolean hostHeaderFound = HTTPMessage::lookupHeader(
482 headers, "Host", hostHeader, false);
|
483 mike 1.2
|
484 kumpf 1.104 if (!hostHeaderFound)
485 {
486 MessageLoaderParms parms(
487 "Server.CIMOperationRequestDecoder.MISSING_HOST_HEADER",
488 "HTTP request message lacks a Host header field.");
489 sendHttpError(
490 queueId,
491 HTTP_STATUS_BADREQUEST,
492 "",
493 MessageLoader::getMessage(parms),
494 closeConnect);
495 PEG_METHOD_EXIT();
496 return;
497 }
498 }
|
499 mike 1.2
|
500 kumpf 1.104 // Validate the "CIMOperation" header:
|
501 mike 1.2
|
502 kumpf 1.124 const char* cimOperation;
|
503 karl 1.135
|
504 kumpf 1.104 // If the CIMOperation header was missing, the HTTPAuthenticatorDelegator
505 // would not have passed the message to us.
|
506 marek 1.134 PEGASUS_FCT_EXECUTE_AND_ASSERT(
507 true,
508 HTTPMessage::lookupHeader(headers, "CIMOperation", cimOperation, true));
|
509 kumpf 1.104
|
510 kumpf 1.124 if (System::strcasecmp(cimOperation, "MethodCall") != 0)
|
511 kumpf 1.104 {
512 // The Specification for CIM Operations over HTTP reads:
513 // 3.3.4. CIMOperation
514 // If a CIM Server receives CIM Operation request with this
515 // [CIMOperation] header, but with a missing value or a value
516 // that is not "MethodCall", then it MUST fail the request with
517 // status "400 Bad Request". The CIM Server MUST include a
518 // CIMError header in the response with a value of
519 // unsupported-operation.
520 MessageLoaderParms parms(
521 "Server.CIMOperationRequestDecoder."
522 "CIMOPERATION_VALUE_NOT_SUPPORTED",
523 "CIMOperation value \"$0\" is not supported.",cimOperation);
524 sendHttpError(
525 queueId,
526 HTTP_STATUS_BADREQUEST,
527 "unsupported-operation",
528 MessageLoader::getMessage(parms),
529 closeConnect);
530 PEG_METHOD_EXIT();
531 return;
532 kumpf 1.104 }
533
534 // Validate the "CIMBatch" header:
535
|
536 kumpf 1.124 const char* cimBatch;
537 if (HTTPMessage::lookupHeader(headers, "CIMBatch", cimBatch, true))
|
538 kumpf 1.104 {
539 // The Specification for CIM Operations over HTTP reads:
540 // 3.3.9. CIMBatch
541 // If a CIM Server receives CIM Operation Request for which the
542 // CIMBatch header is present, but the Server does not support
543 // Multiple Operations, then it MUST fail the request and
544 // return a status of "501 Not Implemented".
545 sendHttpError(
546 queueId,
547 HTTP_STATUS_NOTIMPLEMENTED,
548 "multiple-requests-unsupported",
549 String::EMPTY,
550 closeConnect);
551 PEG_METHOD_EXIT();
552 return;
553 }
554
555 // Save these headers for later checking
556
|
557 kumpf 1.124 const char* cimProtocolVersion;
|
558 kumpf 1.104 if (!HTTPMessage::lookupHeader(
559 headers, "CIMProtocolVersion", cimProtocolVersion, true))
560 {
561 // Mandated by the Specification for CIM Operations over HTTP
|
562 kumpf 1.124 cimProtocolVersion = "1.0";
|
563 kumpf 1.104 }
564
|
565 marek 1.139 // Validate if Pragma: UpdateExpiredPassword is set
566 updateExpiredPassword = false;
567
568 String pragmaValue;
569 if(HTTPMessage::lookupHeader(headers,"Pragma",pragmaValue))
570 {
571 updateExpiredPassword =
572 (PEG_NOT_FOUND != pragmaValue.find("UpdateExpiredPassword"));
573 }
574
|
575 kumpf 1.124 String cimMethod;
|
576 kumpf 1.104 if (HTTPMessage::lookupHeader(headers, "CIMMethod", cimMethod, true))
577 {
578 if (cimMethod == String::EMPTY)
579 {
580 // This is not a valid value, and we use EMPTY to mean "absent"
581 MessageLoaderParms parms(
582 "Server.CIMOperationRequestDecoder.EMPTY_CIMMETHOD_VALUE",
583 "Empty CIMMethod value.");
584 sendHttpError(
585 queueId,
586 HTTP_STATUS_BADREQUEST,
587 "header-mismatch",
588 MessageLoader::getMessage(parms),
589 closeConnect);
590 PEG_METHOD_EXIT();
591 return;
592 }
|
593 mike 1.98
|
594 kumpf 1.104 try
595 {
596 cimMethod = XmlReader::decodeURICharacters(cimMethod);
597 }
598 catch (const ParseError&)
599 {
600 // The CIMMethod header value could not be decoded
601 MessageLoaderParms parms(
602 "Server.CIMOperationRequestDecoder."
603 "CIMMETHOD_VALUE_SYNTAX_ERROR",
604 "CIMMethod value syntax error.");
605 sendHttpError(
606 queueId,
607 HTTP_STATUS_BADREQUEST,
608 "header-mismatch",
609 MessageLoader::getMessage(parms),
610 closeConnect);
611 PEG_METHOD_EXIT();
612 return;
613 }
614 }
|
615 mike 1.2
|
616 kumpf 1.124 String cimObject;
|
617 kumpf 1.104 if (HTTPMessage::lookupHeader(headers, "CIMObject", cimObject, true))
618 {
619 if (cimObject == String::EMPTY)
620 {
621 // This is not a valid value, and we use EMPTY to mean "absent"
622 MessageLoaderParms parms(
623 "Server.CIMOperationRequestDecoder.EMPTY_CIMOBJECT_VALUE",
624 "Empty CIMObject value.");
625 sendHttpError(
626 queueId,
627 HTTP_STATUS_BADREQUEST,
628 "header-mismatch",
629 MessageLoader::getMessage(parms),
630 closeConnect);
631 PEG_METHOD_EXIT();
632 return;
633 }
|
634 mike 1.2
|
635 kumpf 1.104 try
636 {
637 cimObject = XmlReader::decodeURICharacters(cimObject);
638 }
639 catch (const ParseError&)
640 {
641 // The CIMObject header value could not be decoded
642 MessageLoaderParms parms(
643 "Server.CIMOperationRequestDecoder."
644 "CIMOBJECT_VALUE_SYNTAX_ERROR",
645 "CIMObject value syntax error.");
646 sendHttpError(
647 queueId,
648 HTTP_STATUS_BADREQUEST,
649 "header-mismatch",
650 MessageLoader::getMessage(parms),
651 closeConnect);
652 PEG_METHOD_EXIT();
653 return;
654 }
655 }
|
656 mike 1.2
|
657 kumpf 1.104 // Validate the "Content-Type" header:
|
658 mike 1.2
|
659 kumpf 1.124 const char* cimContentType;
|
660 kumpf 1.104 Boolean contentTypeHeaderFound = HTTPMessage::lookupHeader(
661 headers, "Content-Type", cimContentType, true);
|
662 kumpf 1.115 String type;
663 String charset;
|
664 mike 1.120 Boolean binaryRequest = false;
|
665 kumpf 1.115
|
666 kumpf 1.123 if (!contentTypeHeaderFound ||
|
667 kumpf 1.115 !HTTPMessage::parseContentTypeHeader(cimContentType, type, charset) ||
|
668 marek 1.127 (((!String::equalNoCase(type, "application/xml") &&
|
669 kumpf 1.115 !String::equalNoCase(type, "text/xml")) ||
|
670 kumpf 1.123 !String::equalNoCase(charset, "utf-8"))
671 && !(binaryRequest = String::equalNoCase(type,
|
672 mike 1.120 "application/x-openpegasus"))
|
673 marek 1.127 ))
|
674 kumpf 1.104 {
|
675 j.alex 1.95 MessageLoaderParms parms(
|
676 kumpf 1.104 "Server.CIMOperationRequestDecoder.CIMCONTENTTYPE_SYNTAX_ERROR",
|
677 kumpf 1.105 "HTTP Content-Type header error.");
|
678 j.alex 1.95 sendHttpError(
679 queueId,
680 HTTP_STATUS_BADREQUEST,
|
681 kumpf 1.105 "",
|
682 j.alex 1.95 MessageLoader::getMessage(parms),
683 closeConnect);
|
684 kumpf 1.104 PEG_METHOD_EXIT();
685 return;
686 }
|
687 marek 1.130 // Calculate the beginning of the content from the message size and
688 // the content length.
689 if (binaryRequest)
690 {
691 // binary the "Content" also contains a few padding '\0' to align
692 // data structures to 8byte boundary
693 // the padding '\0' are also part of the counted contentLength
694 Uint32 headerEnd = httpMessage->message.size() - contentLength;
695 Uint32 binContentStart = CIMBuffer::round(headerEnd);
696
697 contentLength = contentLength - (binContentStart - headerEnd);
698 content = (char*) httpMessage->message.getData() + binContentStart;
699 }
700 else
701 {
702 content = (char*) httpMessage->message.getData() +
703 httpMessage->message.size() - contentLength;
704 }
705
|
706 kumpf 1.104 // Validating content falls within UTF8
707 // (required to be complaint with section C12 of Unicode 4.0 spec,
708 // chapter 3.)
|
709 marek 1.130 if (!binaryRequest)
|
710 kumpf 1.104 {
711 Uint32 count = 0;
712 while(count<contentLength)
713 {
714 if (!(isUTF8((char*)&content[count])))
715 {
716 MessageLoaderParms parms(
717 "Server.CIMOperationRequestDecoder.INVALID_UTF8_CHARACTER",
718 "Invalid UTF-8 character detected.");
719 sendHttpError(
720 queueId,
721 HTTP_STATUS_BADREQUEST,
722 "request-not-valid",
723 MessageLoader::getMessage(parms),
724 closeConnect);
725
726 PEG_METHOD_EXIT();
|
727 mike 1.120 return;
|
728 kumpf 1.104 }
729 UTF8_NEXT(content,count);
730 }
731 }
732
|
733 kumpf 1.123 // Check for "Accept: application/x-openpegasus" HTTP header to see if
|
734 mike 1.120 // client can accept binary responses.
735
736 bool binaryResponse;
737
738 if (HTTPMessage::lookupHeader(headers, "Accept", type, true) &&
739 String::equalNoCase(type, "application/x-openpegasus"))
740 {
741 binaryResponse = true;
742 }
743 else
744 {
745 binaryResponse = false;
746 }
|
747 marek 1.129 httpMessage->binaryResponse=binaryResponse;
|
748 mike 1.120
|
749 kumpf 1.104 // If it is a method call, then dispatch it to be handled:
750
751 handleMethodCall(
752 queueId,
753 httpMethod,
754 content,
755 contentLength,
756 cimProtocolVersion,
757 cimMethod,
758 cimObject,
759 authType,
760 userName,
|
761 marek 1.138 userRole,
|
762 marek 1.139 userPass,
763 isExpiredPassword,
764 updateExpiredPassword,
|
765 kumpf 1.104 httpMessage->ipAddress,
766 httpMessage->acceptLanguages,
767 httpMessage->contentLanguages,
|
768 mike 1.120 closeConnect,
769 binaryRequest,
770 binaryResponse);
|
771 kumpf 1.104
772 PEG_METHOD_EXIT();
773 }
774
775 void CIMOperationRequestDecoder::handleMethodCall(
776 Uint32 queueId,
777 HttpMethod httpMethod,
778 char* content,
779 Uint32 contentLength, // used for statistics only
|
780 kumpf 1.124 const char* cimProtocolVersionInHeader,
|
781 kumpf 1.104 const String& cimMethodInHeader,
782 const String& cimObjectInHeader,
783 const String& authType,
784 const String& userName,
|
785 marek 1.138 const String& userRole,
|
786 marek 1.139 const String& userPass,
787 Boolean isExpiredPassword,
788 Boolean updateExpiredPassword,
|
789 kumpf 1.104 const String& ipAddress,
790 const AcceptLanguageList& httpAcceptLanguages,
791 const ContentLanguageList& httpContentLanguages,
|
792 mike 1.120 Boolean closeConnect,
793 Boolean binaryRequest,
794 Boolean binaryResponse)
|
795 kumpf 1.104 {
796 PEG_METHOD_ENTER(TRC_DISPATCHER,
797 "CIMOperationRequestDecoder::handleMethodCall()");
798
799 //
800 // If CIMOM is shutting down, return "Service Unavailable" response
801 //
802 if (_serverTerminating)
803 {
|
804 j.alex 1.95 MessageLoaderParms parms(
|
805 kumpf 1.104 "Server.CIMOperationRequestDecoder.CIMSERVER_SHUTTING_DOWN",
806 "CIM Server is shutting down.");
|
807 j.alex 1.95 sendHttpError(
808 queueId,
|
809 kumpf 1.104 HTTP_STATUS_SERVICEUNAVAILABLE,
810 String::EMPTY,
|
811 j.alex 1.95 MessageLoader::getMessage(parms),
812 closeConnect);
|
813 kumpf 1.104 PEG_METHOD_EXIT();
814 return;
815 }
816
|
817 thilo.boehm 1.119 PEG_TRACE((TRC_XML,Tracer::LEVEL4,
|
818 marek 1.116 "CIMOperationRequestdecoder - XML content: %s",
819 content));
|
820 kumpf 1.104
|
821 mike 1.120 //
822 // Handle binary messages:
823 //
|
824 kumpf 1.104
825 AutoPtr<CIMOperationRequestMessage> request;
|
826 marek 1.139 String messageId;
827 Boolean isIMethodCall = true;
|
828 kumpf 1.104
|
829 mike 1.120 if (binaryRequest)
|
830 kumpf 1.104 {
|
831 marek 1.130 CIMBuffer buf(content, contentLength);
832 CIMBufferReleaser buf_(buf);
|
833 mike 1.120
834 request.reset(BinaryCodec::decodeRequest(buf, queueId, _returnQueueId));
835
836 if (!request.get())
837 {
838 sendHttpError(
839 queueId,
840 HTTP_STATUS_BADREQUEST,
841 "Corrupt binary request message",
842 String::EMPTY,
843 closeConnect);
844 PEG_METHOD_EXIT();
845 return;
846 }
847 }
848 else try
849 {
850 XmlParser parser(content);
851 XmlEntry entry;
852 const char* cimMethodName = "";
853
|
854 kumpf 1.104 //
855 // Process <?xml ... >
856 //
857
858 // These values are currently unused
859 const char* xmlVersion = 0;
860 const char* xmlEncoding = 0;
|
861 mike 1.2
|
862 kumpf 1.104 XmlReader::getXmlDeclaration(parser, xmlVersion, xmlEncoding);
|
863 mike 1.2
|
864 kumpf 1.104 // Expect <CIM ...>
|
865 chip 1.92
|
866 kumpf 1.104 const char* cimVersion = 0;
867 const char* dtdVersion = 0;
|
868 mike 1.2
|
869 kumpf 1.104 XmlReader::getCimStartTag(parser, cimVersion, dtdVersion);
|
870 mike 1.2
|
871 karl 1.108 if (!XmlReader::isSupportedCIMVersion(cimVersion))
|
872 kumpf 1.104 {
873 MessageLoaderParms parms(
874 "Server.CIMOperationRequestDecoder.CIM_VERSION_NOT_SUPPORTED",
875 "CIM version \"$0\" is not supported.",
876 cimVersion);
877 sendHttpError(
878 queueId,
879 HTTP_STATUS_NOTIMPLEMENTED,
880 "unsupported-cim-version",
881 MessageLoader::getMessage(parms),
882 closeConnect);
|
883 kumpf 1.23 PEG_METHOD_EXIT();
884 return;
|
885 kumpf 1.104 }
|
886 kumpf 1.23
|
887 karl 1.108 if (!XmlReader::isSupportedDTDVersion(dtdVersion))
|
888 kumpf 1.104 {
889 MessageLoaderParms parms(
890 "Server.CIMOperationRequestDecoder.DTD_VERSION_NOT_SUPPORTED",
891 "DTD version \"$0\" is not supported.",
892 dtdVersion);
893 sendHttpError(
|
894 j.alex 1.95 queueId,
|
895 kumpf 1.104 HTTP_STATUS_NOTIMPLEMENTED,
896 "unsupported-dtd-version",
897 MessageLoader::getMessage(parms),
|
898 j.alex 1.95 closeConnect);
|
899 kumpf 1.20 PEG_METHOD_EXIT();
|
900 kumpf 1.34 return;
|
901 kumpf 1.104 }
902
903 // Expect <MESSAGE ...>
904
905 String protocolVersion;
|
906 kumpf 1.73
|
907 kumpf 1.104 if (!XmlReader::getMessageStartTag(
908 parser, messageId, protocolVersion))
909 {
910 MessageLoaderParms mlParms(
911 "Server.CIMOperationRequestDecoder.EXPECTED_MESSAGE_ELEMENT",
912 "expected MESSAGE element");
|
913 mday 1.16
|
914 kumpf 1.104 throw XmlValidationError(parser.getLine(), mlParms);
915 }
|
916 mday 1.16
|
917 kumpf 1.104 // Validate that the protocol version in the header matches the XML
918 if (!String::equalNoCase(protocolVersion, cimProtocolVersionInHeader))
919 {
|
920 j.alex 1.95 MessageLoaderParms parms(
|
921 kumpf 1.104 "Server.CIMOperationRequestDecoder."
922 "CIMPROTOCOL_VERSION_MISMATCH",
923 "CIMProtocolVersion value \"$0\" does not match CIM request "
924 "protocol version \"$1\".",
925 cimProtocolVersionInHeader,
926 protocolVersion);
|
927 j.alex 1.95 sendHttpError(
928 queueId,
929 HTTP_STATUS_BADREQUEST,
930 "header-mismatch",
931 MessageLoader::getMessage(parms),
932 closeConnect);
|
933 kumpf 1.39 PEG_METHOD_EXIT();
934 return;
|
935 kumpf 1.104 }
|
936 kumpf 1.39
|
937 karl 1.108 // Accept protocol version 1.x (see Bugzilla 1556)
938 if (!XmlReader::isSupportedProtocolVersion(protocolVersion))
|
939 kumpf 1.104 {
940 // See Specification for CIM Operations over HTTP section 4.3
|
941 j.alex 1.95 MessageLoaderParms parms(
|
942 kumpf 1.104 "Server.CIMOperationRequestDecoder."
943 "CIMPROTOCOL_VERSION_NOT_SUPPORTED",
944 "CIMProtocolVersion \"$0\" is not supported.",
945 protocolVersion);
|
946 j.alex 1.95 sendHttpError(
947 queueId,
|
948 kumpf 1.104 HTTP_STATUS_NOTIMPLEMENTED,
949 "unsupported-protocol-version",
|
950 j.alex 1.95 MessageLoader::getMessage(parms),
951 closeConnect);
|
952 kumpf 1.23 PEG_METHOD_EXIT();
953 return;
|
954 kumpf 1.104 }
|
955 kumpf 1.23
|
956 kumpf 1.104 if (XmlReader::testStartTag(parser, entry, "MULTIREQ"))
957 {
958 // We wouldn't have gotten here if CIMBatch header was specified,
959 // so this must be indicative of a header mismatch
|
960 j.alex 1.95 MessageLoaderParms parms(
|
961 kumpf 1.104 "Server.CIMOperationRequestDecoder."
962 "MULTI_REQUEST_MISSING_CIMBATCH_HTTP_HEADER",
963 "Multi-request is missing CIMBatch HTTP header");
|
964 j.alex 1.95 sendHttpError(
965 queueId,
966 HTTP_STATUS_BADREQUEST,
967 "header-mismatch",
968 MessageLoader::getMessage(parms),
969 closeConnect);
|
970 kumpf 1.23 PEG_METHOD_EXIT();
971 return;
|
972 kumpf 1.104 // Future: When MULTIREQ is supported, must ensure CIMMethod and
973 // CIMObject headers are absent, and CIMBatch header is present.
974 }
975
976 // Expect <SIMPLEREQ ...>
977
978 XmlReader::expectStartTag(parser, entry, "SIMPLEREQ");
979
980 // Check for <IMETHODCALL ...>
981
982 if (XmlReader::getIMethodCallStartTag(parser, cimMethodName))
983 {
|
984 marek 1.139 isIMethodCall = true;
|
985 kumpf 1.104 // The Specification for CIM Operations over HTTP reads:
986 // 3.3.6. CIMMethod
987 //
988 // This header MUST be present in any CIM Operation Request
989 // message that contains a Simple Operation Request.
990 //
991 // It MUST NOT be present in any CIM Operation Response message,
992 // nor in any CIM Operation Request message that is not a
993 // Simple Operation Request.
994 //
995 // The name of the CIM method within a Simple Operation Request
996 // is defined to be the value of the NAME attribute of the
997 // <METHODCALL> or <IMETHODCALL> element.
998 //
999 // If a CIM Server receives a CIM Operation Request for which
1000 // either:
1001 //
1002 // - The CIMMethod header is present but has an invalid value,
1003 // or;
1004 // - The CIMMethod header is not present but the Operation
1005 // Request Message is a Simple Operation Request, or;
1006 kumpf 1.104 // - The CIMMethod header is present but the Operation Request
1007 // Message is not a Simple Operation Request, or;
1008 // - The CIMMethod header is present, the Operation Request
1009 // Message is a Simple Operation Request, but the
1010 // CIMIdentifier value (when unencoded) does not match the
1011 // unique method name within the Simple Operation Request,
1012 //
1013 // then it MUST fail the request and return a status of
1014 // "400 Bad Request" (and MUST include a CIMError header in the
1015 // response with a value of header-mismatch), subject to the
1016 // considerations specified in Errors.
1017 if (!String::equalNoCase(cimMethodName, cimMethodInHeader))
1018 {
1019 // ATTN-RK-P3-20020304: How to decode cimMethodInHeader?
1020 if (cimMethodInHeader == String::EMPTY)
1021 {
1022 MessageLoaderParms parms(
1023 "Server.CIMOperationRequestDecoder."
1024 "MISSING_CIMMETHOD_HTTP_HEADER",
1025 "Missing CIMMethod HTTP header.");
1026 sendHttpError(
1027 kumpf 1.104 queueId,
1028 HTTP_STATUS_BADREQUEST,
1029 "header-mismatch",
1030 MessageLoader::getMessage(parms),
1031 closeConnect);
1032 }
1033 else
1034 {
1035 MessageLoaderParms parms(
1036 "Server.CIMOperationRequestDecoder."
1037 "CIMMETHOD_VALUE_DOES_NOT_MATCH_REQUEST_METHOD",
1038 "CIMMethod value \"$0\" does not match CIM request "
1039 "method \"$1\".",
1040 cimMethodInHeader,
1041 cimMethodName);
1042 sendHttpError(
1043 queueId,
1044 HTTP_STATUS_BADREQUEST,
1045 "header-mismatch",
1046 MessageLoader::getMessage(parms),
1047 closeConnect);
1048 kumpf 1.104 }
1049 PEG_METHOD_EXIT();
1050 return;
1051 }
|
1052 kumpf 1.23
|
1053 kumpf 1.104 // Expect <LOCALNAMESPACEPATH ...>
1054
1055 String nameSpace;
1056
1057 if (!XmlReader::getLocalNameSpacePathElement(parser, nameSpace))
1058 {
1059 MessageLoaderParms mlParms(
1060 "Server.CIMOperationRequestDecoder."
1061 "EXPECTED_LOCALNAMESPACEPATH_ELEMENT",
1062 "expected LOCALNAMESPACEPATH element");
1063 throw XmlValidationError(parser.getLine(), mlParms);
1064 }
1065
1066 // The Specification for CIM Operations over HTTP reads:
1067 // 3.3.7. CIMObject
1068 //
1069 // This header MUST be present in any CIM Operation Request
1070 // message that contains a Simple Operation Request.
1071 //
1072 // It MUST NOT be present in any CIM Operation Response message,
1073 // nor in any CIM Operation Request message that is not a
1074 kumpf 1.104 // Simple Operation Request.
1075 //
1076 // The header identifies the CIM object (which MUST be a Class
1077 // or Instance for an extrinsic method, or a Namespace for an
1078 // intrinsic method) on which the method is to be invoked, using
1079 // a CIM object path encoded in an HTTP-safe representation.
1080 //
1081 // If a CIM Server receives a CIM Operation Request for which
1082 // either:
1083 //
1084 // - The CIMObject header is present but has an invalid value,
1085 // or;
1086 // - The CIMObject header is not present but the Operation
1087 // Request Message is a Simple Operation Request, or;
1088 // - The CIMObject header is present but the Operation Request
1089 // Message is not a Simple Operation Request, or;
1090 // - The CIMObject header is present, the Operation Request
1091 // Message is a Simple Operation Request, but the ObjectPath
1092 // value does not match (where match is defined in the section
1093 // section on Encoding CIM Object Paths) the Operation Request
1094 // Message,
1095 kumpf 1.104 //
1096 // then it MUST fail the request and return a status of
1097 // "400 Bad Request" (and MUST include a CIMError header in the
1098 // response with a value of header-mismatch), subject to the
1099 // considerations specified in Errors.
1100 if (!String::equalNoCase(nameSpace, cimObjectInHeader))
1101 {
1102 if (cimObjectInHeader == String::EMPTY)
1103 {
1104 MessageLoaderParms parms(
1105 "Server.CIMOperationRequestDecoder."
1106 "MISSING_CIMOBJECT_HTTP_HEADER",
1107 "Missing CIMObject HTTP header.");
1108 sendHttpError(
1109 queueId,
1110 HTTP_STATUS_BADREQUEST,
1111 "header-mismatch",
1112 MessageLoader::getMessage(parms),
1113 closeConnect);
1114 }
1115 else
1116 kumpf 1.104 {
1117 MessageLoaderParms parms(
1118 "Server.CIMOperationRequestDecoder."
|
1119 kumpf 1.113 "CIMOBJECT_VALUE_DOES_NOT_MATCH_REQUEST_OBJECT",
|
1120 kumpf 1.104 "CIMObject value \"$0\" does not match CIM request "
1121 "object \"$1\".",
1122 cimObjectInHeader,
1123 nameSpace);
1124 sendHttpError(
1125 queueId,
1126 HTTP_STATUS_BADREQUEST,
1127 "header-mismatch",
1128 MessageLoader::getMessage(parms),
1129 closeConnect);
1130 }
1131 PEG_METHOD_EXIT();
1132 return;
1133 }
1134
1135 // This try block only catches CIMExceptions, because they must be
1136 // responded to with a proper IMETHODRESPONSE. Other exceptions are
1137 // caught in the outer try block.
1138 try
1139 {
1140 // Delegate to appropriate method to handle:
1141 kumpf 1.104
1142 if (System::strcasecmp(cimMethodName, "GetClass") == 0)
1143 request.reset(decodeGetClassRequest(
1144 queueId, parser, messageId, nameSpace));
1145 else if (System::strcasecmp(cimMethodName, "GetInstance") == 0)
1146 request.reset(decodeGetInstanceRequest(
1147 queueId, parser, messageId, nameSpace));
1148 else if (System::strcasecmp(
1149 cimMethodName, "EnumerateClassNames") == 0)
1150 request.reset(decodeEnumerateClassNamesRequest(
1151 queueId, parser, messageId, nameSpace));
1152 else if (System::strcasecmp(cimMethodName, "References") == 0)
1153 request.reset(decodeReferencesRequest(
1154 queueId, parser, messageId, nameSpace));
1155 else if (System::strcasecmp(
1156 cimMethodName, "ReferenceNames") == 0)
1157 request.reset(decodeReferenceNamesRequest(
1158 queueId, parser, messageId, nameSpace));
1159 else if (System::strcasecmp(
1160 cimMethodName, "AssociatorNames") == 0)
1161 request.reset(decodeAssociatorNamesRequest(
1162 kumpf 1.104 queueId, parser, messageId, nameSpace));
1163 else if (System::strcasecmp(cimMethodName, "Associators") == 0)
1164 request.reset(decodeAssociatorsRequest(
1165 queueId, parser, messageId, nameSpace));
1166 else if (System::strcasecmp(
1167 cimMethodName, "CreateInstance") == 0)
1168 request.reset(decodeCreateInstanceRequest(
1169 queueId, parser, messageId, nameSpace));
1170 else if (System::strcasecmp(
1171 cimMethodName, "EnumerateInstanceNames")==0)
1172 request.reset(decodeEnumerateInstanceNamesRequest(
1173 queueId, parser, messageId, nameSpace));
1174 else if (System::strcasecmp(
1175 cimMethodName, "DeleteQualifier") == 0)
1176 request.reset(decodeDeleteQualifierRequest(
1177 queueId, parser, messageId, nameSpace));
1178 else if (System::strcasecmp(cimMethodName, "GetQualifier") == 0)
1179 request.reset(decodeGetQualifierRequest(
1180 queueId, parser, messageId, nameSpace));
1181 else if (System::strcasecmp(cimMethodName, "SetQualifier") == 0)
1182 request.reset(decodeSetQualifierRequest(
1183 kumpf 1.104 queueId, parser, messageId, nameSpace));
1184 else if (System::strcasecmp(
1185 cimMethodName, "EnumerateQualifiers") == 0)
1186 request.reset(decodeEnumerateQualifiersRequest(
1187 queueId, parser, messageId, nameSpace));
1188 else if (System::strcasecmp(
1189 cimMethodName, "EnumerateClasses") == 0)
1190 request.reset(decodeEnumerateClassesRequest(
1191 queueId, parser, messageId, nameSpace));
1192 else if (System::strcasecmp(
1193 cimMethodName, "EnumerateInstances") == 0)
1194 request.reset(decodeEnumerateInstancesRequest(
1195 queueId, parser, messageId, nameSpace));
1196 else if (System::strcasecmp(cimMethodName, "CreateClass") == 0)
1197 request.reset(decodeCreateClassRequest(
1198 queueId, parser, messageId, nameSpace));
1199 else if (System::strcasecmp(cimMethodName, "ModifyClass") == 0)
1200 request.reset(decodeModifyClassRequest(
1201 queueId, parser, messageId, nameSpace));
1202 else if (System::strcasecmp(
1203 cimMethodName, "ModifyInstance") == 0)
1204 kumpf 1.104 request.reset(decodeModifyInstanceRequest(
1205 queueId, parser, messageId, nameSpace));
1206 else if (System::strcasecmp(cimMethodName, "DeleteClass") == 0)
1207 request.reset(decodeDeleteClassRequest(
1208 queueId, parser, messageId, nameSpace));
1209 else if (System::strcasecmp(
1210 cimMethodName, "DeleteInstance") == 0)
1211 request.reset(decodeDeleteInstanceRequest(
1212 queueId, parser, messageId, nameSpace));
1213 else if (System::strcasecmp(cimMethodName, "GetProperty") == 0)
1214 request.reset(decodeGetPropertyRequest(
1215 queueId, parser, messageId, nameSpace));
1216 else if (System::strcasecmp(cimMethodName, "SetProperty") == 0)
1217 request.reset(decodeSetPropertyRequest(
1218 queueId, parser, messageId, nameSpace));
1219 else if (System::strcasecmp(cimMethodName, "ExecQuery") == 0)
1220 request.reset(decodeExecQueryRequest(
1221 queueId, parser, messageId, nameSpace));
1222 else
1223 {
1224 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
1225 kumpf 1.104 MessageLoaderParms(
1226 "Server.CIMOperationRequestDecoder."
1227 "UNRECOGNIZED_INTRINSIC_METHOD",
1228 "Unrecognized intrinsic method: $0",
1229 cimMethodName));
1230 }
1231 }
1232 catch (CIMException& e)
1233 {
1234 sendIMethodError(
1235 queueId,
1236 httpMethod,
1237 messageId,
1238 cimMethodName,
1239 e,
1240 closeConnect);
1241
1242 PEG_METHOD_EXIT();
1243 return;
1244 }
1245 catch (XmlException&)
1246 kumpf 1.104 {
1247 // XmlExceptions are handled below
1248 throw;
1249 }
1250 catch (Exception& e)
1251 {
1252 // Caught an unexpected exception from decoding. Since we must
1253 // have had a problem reconstructing a CIM object, we'll treat
1254 // it as an invalid parameter
1255 sendIMethodError(
1256 queueId,
1257 httpMethod,
1258 messageId,
1259 cimMethodName,
1260 PEGASUS_CIM_EXCEPTION(
1261 CIM_ERR_INVALID_PARAMETER, e.getMessage()),
1262 closeConnect);
1263
1264 PEG_METHOD_EXIT();
1265 return;
1266 }
1267 kumpf 1.104
1268 // Expect </IMETHODCALL>
1269
1270 XmlReader::expectEndTag(parser, "IMETHODCALL");
1271 }
1272 // Expect <METHODCALL ...>
1273 else if (XmlReader::getMethodCallStartTag(parser, cimMethodName))
1274 {
1275 CIMObjectPath reference;
|
1276 marek 1.139 isIMethodCall = false;
|
1277 kumpf 1.104
1278 // The Specification for CIM Operations over HTTP reads:
1279 // 3.3.6. CIMMethod
1280 //
1281 // This header MUST be present in any CIM Operation Request
1282 // message that contains a Simple Operation Request.
1283 //
1284 // It MUST NOT be present in any CIM Operation Response message,
1285 // nor in any CIM Operation Request message that is not a
1286 // Simple Operation Request.
1287 //
1288 // The name of the CIM method within a Simple Operation Request
1289 // is defined to be the value of the NAME attribute of the
1290 // <METHODCALL> or <IMETHODCALL> element.
1291 //
1292 // If a CIM Server receives a CIM Operation Request for which
1293 // either:
1294 //
1295 // - The CIMMethod header is present but has an invalid value,
1296 // or;
1297 // - The CIMMethod header is not present but the Operation
1298 kumpf 1.104 // Request Message is a Simple Operation Request, or;
1299 // - The CIMMethod header is present but the Operation Request
1300 // Message is not a Simple Operation Request, or;
1301 // - The CIMMethod header is present, the Operation Request
1302 // Message is a Simple Operation Request, but the
1303 // CIMIdentifier value (when unencoded) does not match the
1304 // unique method name within the Simple Operation Request,
1305 //
1306 // then it MUST fail the request and return a status of
1307 // "400 Bad Request" (and MUST include a CIMError header in the
1308 // response with a value of header-mismatch), subject to the
1309 // considerations specified in Errors.
1310
1311 // Extrinic methods can have UTF-8!
1312 String cimMethodNameUTF16(cimMethodName);
1313 if (cimMethodNameUTF16 != cimMethodInHeader)
1314 {
1315 // ATTN-RK-P3-20020304: How to decode cimMethodInHeader?
1316 if (cimMethodInHeader == String::EMPTY)
1317 {
1318 MessageLoaderParms parms(
1319 kumpf 1.104 "Server.CIMOperationRequestDecoder."
1320 "MISSING_CIMMETHOD_HTTP_HEADER",
1321 "Missing CIMMethod HTTP header.");
1322 sendHttpError(
1323 queueId,
1324 HTTP_STATUS_BADREQUEST,
1325 "header-mismatch",
1326 MessageLoader::getMessage(parms),
1327 closeConnect);
1328 }
1329 else
1330 {
1331 MessageLoaderParms parms(
1332 "Server.CIMOperationRequestDecoder."
1333 "CIMMETHOD_VALUE_DOES_NOT_MATCH_REQUEST_METHOD",
1334 "CIMMethod value \"$0\" does not match CIM request "
1335 "method \"$1\".",
1336 (const char*)cimMethodInHeader.getCString(),
1337 cimMethodName);
1338 sendHttpError(
1339 queueId,
1340 kumpf 1.104 HTTP_STATUS_BADREQUEST,
1341 "header-mismatch",
1342 MessageLoader::getMessage(parms),
1343 closeConnect);
1344 }
1345 PEG_METHOD_EXIT();
1346 return;
1347 }
1348
1349 //
1350 // Check for <LOCALINSTANCEPATHELEMENT> or <LOCALCLASSPATHELEMENT>
1351 //
1352 if (!(XmlReader::getLocalInstancePathElement(parser, reference) ||
1353 XmlReader::getLocalClassPathElement(parser, reference)))
1354 {
1355 MessageLoaderParms parms(
1356 "Common.XmlConstants.MISSING_ELEMENT_LOCALPATH",
1357 MISSING_ELEMENT_LOCALPATH);
1358 // this throw is not updated with MLP because
1359 // MISSING_ELEMENT_LOCALPATH is a hardcoded variable,
1360 // not a message
1361 kumpf 1.104 throw XmlValidationError(parser.getLine(), parms);
1362 }
1363
1364 // The Specification for CIM Operations over HTTP reads:
1365 // 3.3.7. CIMObject
1366 //
1367 // This header MUST be present in any CIM Operation Request
1368 // message that contains a Simple Operation Request.
1369 //
1370 // It MUST NOT be present in any CIM Operation Response message,
1371 // nor in any CIM Operation Request message that is not a
1372 // Simple Operation Request.
1373 //
1374 // The header identifies the CIM object (which MUST be a Class
1375 // or Instance for an extrinsic method, or a Namespace for an
1376 // intrinsic method) on which the method is to be invoked, using
1377 // a CIM object path encoded in an HTTP-safe representation.
1378 //
1379 // If a CIM Server receives a CIM Operation Request for which
1380 // either:
1381 //
1382 kumpf 1.104 // - The CIMObject header is present but has an invalid value,
1383 // or;
1384 // - The CIMObject header is not present but the Operation
1385 // Request Message is a Simple Operation Request, or;
1386 // - The CIMObject header is present but the Operation Request
1387 // Message is not a Simple Operation Request, or;
1388 // - The CIMObject header is present, the Operation Request
1389 // Message is a Simple Operation Request, but the ObjectPath
1390 // value does not match (where match is defined in the section
1391 // section on Encoding CIM Object Paths) the Operation Request
1392 // Message,
1393 //
1394 // then it MUST fail the request and return a status of
1395 // "400 Bad Request" (and MUST include a CIMError header in the
1396 // response with a value of header-mismatch), subject to the
1397 // considerations specified in Errors.
1398 if (cimObjectInHeader == String::EMPTY)
1399 {
1400 MessageLoaderParms parms(
1401 "Server.CIMOperationRequestDecoder."
1402 "MISSING_CIMOBJECT_HTTP_HEADER",
1403 kumpf 1.104 "Missing CIMObject HTTP header.");
1404 sendHttpError(
1405 queueId,
1406 HTTP_STATUS_BADREQUEST,
1407 "header-mismatch",
1408 MessageLoader::getMessage(parms),
1409 closeConnect);
1410 PEG_METHOD_EXIT();
1411 return;
1412 }
1413
1414 CIMObjectPath headerObjectReference;
1415 try
1416 {
1417 headerObjectReference.set(cimObjectInHeader);
1418 }
1419 catch (Exception&)
1420 {
1421 MessageLoaderParms parms(
1422 "Server.CIMOperationRequestDecoder."
1423 "COULD_NOT_PARSE_CIMOBJECT_VALUE",
1424 kumpf 1.104 "Could not parse CIMObject value \"$0\".",
1425 cimObjectInHeader);
1426 sendHttpError(
1427 queueId,
1428 HTTP_STATUS_BADREQUEST,
1429 "header-mismatch",
1430 MessageLoader::getMessage(parms),
1431 closeConnect);
1432 PEG_METHOD_EXIT();
1433 return;
1434 }
1435
1436 if (!reference.identical(headerObjectReference))
1437 {
1438 MessageLoaderParms parms(
1439 "Server.CIMOperationRequestDecoder."
|
1440 kumpf 1.113 "CIMOBJECT_VALUE_DOES_NOT_MATCH_REQUEST_OBJECT",
|
1441 kumpf 1.104 "CIMObject value \"$0\" does not match CIM request "
1442 "object \"$1\".",
1443 cimObjectInHeader,
|
1444 kumpf 1.113 reference.toString());
|
1445 kumpf 1.104 sendHttpError(
1446 queueId,
1447 HTTP_STATUS_BADREQUEST,
1448 "header-mismatch",
1449 MessageLoader::getMessage(parms),
1450 closeConnect);
1451 PEG_METHOD_EXIT();
1452 return;
1453 }
1454
1455 // This try block only catches CIMExceptions, because they must be
1456 // responded to with a proper METHODRESPONSE. Other exceptions are
1457 // caught in the outer try block.
1458 try
1459 {
1460 // Delegate to appropriate method to handle:
1461
1462 request.reset(decodeInvokeMethodRequest(
1463 queueId,
1464 parser,
1465 messageId,
1466 kumpf 1.104 reference,
1467 cimMethodNameUTF16)); // contains UTF-16 converted from UTF-8
1468 }
1469 catch (CIMException& e)
1470 {
1471 sendMethodError(
1472 queueId,
1473 httpMethod,
1474 messageId,
1475 cimMethodNameUTF16, // contains UTF-16 converted from UTF-8
1476 e,
1477 closeConnect);
1478
1479 PEG_METHOD_EXIT();
1480 return;
1481 }
1482 catch (XmlException&)
1483 {
1484 // XmlExceptions are handled below
1485 throw;
1486 }
1487 kumpf 1.104 catch (Exception& e)
1488 {
1489 // Caught an unexpected exception from decoding. Since we must
1490 // have had a problem reconstructing a CIM object, we'll treata
1491 // it as an invalid parameter
1492 sendMethodError(
1493 queueId,
1494 httpMethod,
1495 messageId,
1496 cimMethodNameUTF16, // contains UTF-16 converted from UTF-8
1497 PEGASUS_CIM_EXCEPTION(
1498 CIM_ERR_INVALID_PARAMETER, e.getMessage()),
1499 closeConnect);
1500
1501 PEG_METHOD_EXIT();
1502 return;
1503 }
|
1504 kumpf 1.73
|
1505 kumpf 1.104 // Expect </METHODCALL>
|
1506 mday 1.16
|
1507 kumpf 1.104 XmlReader::expectEndTag(parser, "METHODCALL");
1508 }
1509 else
1510 {
1511 MessageLoaderParms mlParms(
1512 "Server.CIMOperationRequestDecoder.EXPECTED_IMETHODCALL_ELEMENT",
1513 "expected IMETHODCALL or METHODCALL element");
1514 throw XmlValidationError(parser.getLine(),mlParms);
1515 }
1516
1517 // Expect </SIMPLEREQ>
1518
1519 XmlReader::expectEndTag(parser, "SIMPLEREQ");
1520
1521 // Expect </MESSAGE>
1522
1523 XmlReader::expectEndTag(parser, "MESSAGE");
1524
1525 // Expect </CIM>
1526
1527 XmlReader::expectEndTag(parser, "CIM");
1528 kumpf 1.104 }
1529 catch (XmlValidationError& e)
1530 {
|
1531 thilo.boehm 1.119 PEG_TRACE((TRC_XML,Tracer::LEVEL1,
|
1532 kumpf 1.104 "CIMOperationRequestDecoder::handleMethodCall - "
|
1533 marek 1.116 "XmlValidationError exception has occurred. Message: %s",
1534 (const char*) e.getMessage().getCString()));
|
1535 kumpf 1.24
|
1536 kumpf 1.104 sendHttpError(
1537 queueId,
1538 HTTP_STATUS_BADREQUEST,
1539 "request-not-valid",
1540 e.getMessage(),
1541 closeConnect);
1542 PEG_METHOD_EXIT();
1543 return;
1544 }
1545 catch (XmlSemanticError& e)
1546 {
|
1547 thilo.boehm 1.119 PEG_TRACE((TRC_XML,Tracer::LEVEL1,
|
1548 kumpf 1.104 "CIMOperationRequestDecoder::handleMethodCall - "
|
1549 marek 1.116 "XmlSemanticError exception has occurred. Message: %s",
1550 (const char*) e.getMessage().getCString()));
|
1551 mday 1.16
|
1552 kumpf 1.104 // ATTN-RK-P2-20020404: Is this the correct response for these errors?
1553 sendHttpError(
1554 queueId,
1555 HTTP_STATUS_BADREQUEST,
1556 "request-not-valid",
1557 e.getMessage(),
1558 closeConnect);
1559 PEG_METHOD_EXIT();
1560 return;
1561 }
1562 catch (XmlException& e)
1563 {
|
1564 thilo.boehm 1.119 PEG_TRACE((TRC_XML,Tracer::LEVEL1,
|
1565 kumpf 1.104 "CIMOperationRequestDecoder::handleMethodCall - "
|
1566 marek 1.116 "XmlException has occurred. Message: %s",
1567 (const char*) e.getMessage().getCString()));
|
1568 kumpf 1.104
1569 sendHttpError(
1570 queueId,
1571 HTTP_STATUS_BADREQUEST,
1572 "request-not-well-formed",
1573 e.getMessage(),
1574 closeConnect);
1575 PEG_METHOD_EXIT();
1576 return;
1577 }
|
1578 marek 1.133 catch (TooManyElementsException& e)
1579 {
1580 PEG_TRACE((TRC_XML,Tracer::LEVEL1,
1581 "CIMOperationRequestDecoder::handleMethodCall - "
1582 "TooManyElementsException has occurred. Message: %s",
1583 (const char*) e.getMessage().getCString()));
1584
1585 sendHttpError(
1586 queueId,
1587 HTTP_STATUS_BADREQUEST,
1588 "request-with-too-many-elements",
1589 e.getMessage(),
1590 closeConnect);
1591 PEG_METHOD_EXIT();
1592 return;
1593 }
|
1594 kumpf 1.104 catch (Exception& e)
1595 {
1596 // Don't know why I got this exception. Seems like a bad thing.
1597 // Any exceptions we're expecting should be caught separately and
1598 // dealt with appropriately. This is a last resort.
1599 sendHttpError(
1600 queueId,
1601 HTTP_STATUS_INTERNALSERVERERROR,
1602 String::EMPTY,
1603 e.getMessage(),
1604 closeConnect);
1605 PEG_METHOD_EXIT();
1606 return;
1607 }
1608 catch (...)
1609 {
1610 // Don't know why I got whatever this is. Seems like a bad thing.
1611 // Any exceptions we're expecting should be caught separately and
1612 // dealt with appropriately. This is a last resort.
1613 sendHttpError(
1614 queueId,
1615 kumpf 1.104 HTTP_STATUS_INTERNALSERVERERROR,
1616 String::EMPTY,
1617 String::EMPTY,
1618 closeConnect);
1619 PEG_METHOD_EXIT();
1620 return;
1621 }
1622
1623 STAT_BYTESREAD
1624
1625 request->authType = authType;
1626 request->userName = userName;
1627 request->ipAddress = ipAddress;
1628 request->setHttpMethod (httpMethod);
|
1629 mike 1.120 request->binaryResponse = binaryResponse;
|
1630 sage 1.41
|
1631 chuck 1.58 //l10n start
1632 // l10n TODO - might want to move A-L and C-L to Message
1633 // to make this more maintainable
|
1634 kumpf 1.104 // Add the language headers to the request
1635 CIMMessage* cimmsg = dynamic_cast<CIMMessage*>(request.get());
1636 if (cimmsg != NULL)
1637 {
1638 cimmsg->operationContext.insert(IdentityContainer(userName));
|
1639 marek 1.138 cimmsg->operationContext.insert(UserRoleContainer(userRole));
|
1640 kumpf 1.104 cimmsg->operationContext.set(
1641 AcceptLanguageListContainer(httpAcceptLanguages));
1642 cimmsg->operationContext.set(
1643 ContentLanguageListContainer(httpContentLanguages));
1644 }
1645 else
1646 {
1647 ; // l10n TODO - error back to client here
1648 }
|
1649 chip 1.92 // l10n end
|
1650 chuck 1.58
|
1651 marek 1.139 #ifdef PEGASUS_PAM_SESSION_SECURITY
1652
1653 // Whatever happens on the authentication, we need to check for
1654 // a change of an expired password
1655 // Since the definition for password updates is not completely
1656 // defined in DMTF yet, keep this feature PAM_SESSION only
1657 // This also only works with CIM-XML right now.
1658 if (isExpiredPassword)
1659 {
1660 // only try password update if req. Pragma is set
1661 if (updateExpiredPassword)
1662 {
1663 // update expired password
1664 // fct. _updateExpiredPassword returns false
1665 // if the request was NOT for PG_Account etc.
1666 _updateExpiredPassword(
1667 queueId,
1668 httpMethod,
1669 messageId,
1670 closeConnect,
1671 httpContentLanguages,
1672 marek 1.139 cimmsg,
1673 userName,
1674 userPass);
1675 }
1676 else
1677 {
1678 sendUserAccountExpired(
1679 queueId,
1680 httpMethod,
1681 messageId,
1682 cimMethodInHeader,
1683 closeConnect,
1684 isIMethodCall);
1685 }
1686 PEG_METHOD_EXIT();
1687 return;
1688 }
1689 #endif
1690
|
1691 kumpf 1.104 request->setCloseConnect(closeConnect);
1692 _outputQueue->enqueue(request.release());
|
1693 chip 1.92
|
1694 kumpf 1.104 PEG_METHOD_EXIT();
|
1695 mike 1.2 }
|
1696 karl 1.137 /**************************************************************************
1697 **
1698 ** Decode CIM Operation Type Common IParameter types.
1699 ** Each class defines processing for a particular IPARAM type
1700 ** (ex. boolean)or parameter name (i.e. propertyListIParam)
1701 ** Each struct defines:
1702 ** got - Boolean defines whether this parameter has been found
1703 ** value - The value container for this type
1704 ** iParamFound(...) - function sets the duplicate flag and the got flag
1705 ** get - Function to get the defined parameter from the
1706 ** parser
1707 ** NOTE: at least one has multiple get.. functions.
1708 ** NOTE: Some of these are defined for a particular attribute (ex.
1709 ** propertyListIparam) so the attribute name is integrated into the
1710 ** methods and others for a whole class of attributes (Boolean,
1711 ** String,ClassName etc.) so the attribute name is defined as part
1712 ** of the constructor.
1713 ***************************************************************************/
1714 // Common xml attribute accessor for all boolean attributes. The
1715 // attribute name is defined in the constructor.
1716 // The usage pattern is:
1717 karl 1.137 // Boolean duplicate; // Flag to indicate multiple calls
1718 //
1719 // booleanIParam xyz("xyz"); default is false for attribute xyz
1720 //
1721 // if(xyz.get(parser, name, emptyTag) // parses to test if name == xyz
1722 // iParamFound(duplicate); // set flag to indicate exists etc.
1723 class booleanIParam
1724 {
1725 public:
1726 Boolean got;
1727 Boolean value;
1728
1729 // constructor with default value = false
1730 booleanIParam(const char* name): got(false),value(false),iParamName(name){}
1731
1732 // constructor with initial value specifically set from the input
1733 booleanIParam(const char* name, Boolean _value):
1734 got(false),value(_value),iParamName(name){}
1735
1736 ~booleanIParam(){}
1737
1738 karl 1.137 void iParamFound(Boolean& duplicate)
1739 {
1740 duplicate = got;
1741 got = true;
1742 }
1743
1744 // get the value of the parameter if the parameter if it exists.
1745 // Note that the attribute name is defined in the constructor
1746 // Value is required.
1747 // @param parser
1748 // @param testName attribute name from parse.
1749 // @emptyTag returns true if emptyTag returned true from parser
1750 Boolean get(XmlParser& parser, const char * testName, Boolean& emptyTag)
1751 {
1752 if (System::strcasecmp(iParamName.getCString(), testName) == 0)
1753 {
1754 XmlReader::rejectNullIParamValue(parser, emptyTag,
1755 iParamName.getCString());
1756 XmlReader::getBooleanValueElement(parser, value, true);
1757 return true;
1758 }
1759 karl 1.137 return false;
1760 }
1761 private:
1762 String iParamName;
1763 // hide unused default constructor and assign, copy constructors
1764 booleanIParam();
1765 booleanIParam(const booleanIParam&);
1766 booleanIParam& operator = (const booleanIParam&);
1767 };
1768
1769 // decode Iparam to CIMName representing class names. This struct
1770 // has two get functions:
1771 // get - parse where the parameter value is required
1772 // getOptional - parse where the parameter value is optional
1773
1774 class classNameIParam
1775 {
1776 public:
1777 Boolean got;
1778 CIMName value;
1779
1780 karl 1.137 // Set the flag to inidcate that this IParam has been gotten and also
1781 // set the flag defined by the duplicate parameter
1782 // @param duplicate Boolean that is set to previous value of the got
1783 // variable indicating whether this is second call to this IParam
1784 void iParamFound(Boolean& duplicate)
1785 {
1786 duplicate = got;
1787 got = true;
1788 }
1789
1790 // construct an IParam definition with name.
1791 // @param name const char* defining name of IParam to match
1792 // @return true if IParam found with _attrName
1793 classNameIParam(const char* name): got(false), iParamName(name){}
1794
1795 ~classNameIParam(){}
1796
1797 // Get Required value element.Test for name parameter as IParam with
1798 // name and if found, if value not NULL, parse the className and
1799 // set into value
1800 Boolean get(XmlParser& parser, const char* name, Boolean& emptyTag)
1801 karl 1.137 {
1802 if (System::strcasecmp(name,iParamName.getCString()) == 0)
1803 {
1804 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
1805 XmlReader::getClassNameElement(parser, value, true);
1806 return true;
1807 }
1808 return false;
1809 }
1810 // Get Iparam with optional value.
1811 Boolean getOptional(XmlParser& parser, const char* name,
1812 Boolean& emptyTag)
1813 {
1814 if (System::strcasecmp(name, iParamName.getCString()) == 0)
1815 {
1816 // value may be NULL
1817 if (!emptyTag)
1818 {
1819 XmlReader::getClassNameElement(parser, value, false);
1820 }
1821 return true;
1822 karl 1.137 }
1823 return false;
1824 }
1825 private:
1826 String iParamName;
1827 // hide unused default constructor and assign, copy constructors
1828 classNameIParam();
1829 classNameIParam(const classNameIParam&);
1830 classNameIParam& operator = (const classNameIParam&);
1831 };
1832
1833 // test for "InstanceName" iParam and if found, return CIMObjectPath
1834 // in value
1835 class instanceNameIParam
1836 {
1837 public:
1838 Boolean got;
1839 CIMObjectPath value;
1840
1841 void iParamFound(Boolean& duplicate)
1842 {
1843 karl 1.137 duplicate = got;
1844 got = true;
1845 }
1846 instanceNameIParam(): got(false){}
1847
1848 ~instanceNameIParam(){}
1849
1850 Boolean get(XmlParser& parser, const char * name, Boolean& emptyTag)
1851 {
1852 if (System::strcasecmp(name, "InstanceName") == 0)
1853 {
1854 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
1855 XmlReader::getInstanceNameElement(parser, value);
1856 return true;
1857 }
1858 return false;
1859 }
1860 private:
1861 // hide unused assign, copy constructors
1862 instanceNameIParam(const instanceNameIParam&);
1863 instanceNameIParam& operator = (const instanceNameIParam&);
1864 karl 1.137 };
1865
1866 // test for "ObjectName" attribute and if found, return CIMObjectPath
1867 // This struct has an extra attribute, the flag isClassNameElement which
1868 // returns true if the objectName was a classPath and not an instance
1869 // path.
1870 // If Xmlreader returns true, this is class only element, no
1871 // key bindings. That state must be set into the request
1872 // message (ex. objectName.isClassElement)
1873 class objectNameIParam
1874 {
1875 public:
1876 Boolean got;
1877 CIMObjectPath value;
1878 Boolean isClassNameElement;
1879
1880 void iParamFound(Boolean& duplicate)
1881 {
1882 duplicate = got;
1883 got = true;
1884 }
1885 karl 1.137
1886 objectNameIParam(): got(false), isClassNameElement(false){}
1887
1888 ~objectNameIParam(){}
1889
1890 Boolean get(XmlParser& parser, const char * name, Boolean& emptyTag)
1891 {
1892 if (System::strcasecmp(name, "ObjectName") == 0)
1893 {
1894 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
1895 isClassNameElement =
1896 XmlReader::getObjectNameElement(parser, value);
1897 return true;
1898 }
1899 return false;
1900 }
1901 private:
1902 // hide unused assign, copy constructors
1903 objectNameIParam(const objectNameIParam&);
1904 objectNameIParam& operator = (const objectNameIParam&);
1905 };
1906 karl 1.137
1907 // test for "PropertyList" attribute and, if found, return property list
1908 // in the value element.
1909 class propertyListIParam
1910 {
1911 public:
1912 Boolean got;
1913 CIMPropertyList value;
1914
1915 void iParamFound(Boolean& duplicate)
1916 {
1917 duplicate = got;
1918 got = true;
1919 }
1920
1921 // construct a propertyListIParam object
1922 propertyListIParam(): got(false){}
1923
1924 ~propertyListIParam(){}
1925
1926 Boolean get(XmlParser& parser, const char* name, Boolean& emptyTag)
1927 karl 1.137 {
1928 if (System::strcasecmp(name, "PropertyList") == 0)
1929 {
1930 if (!emptyTag)
1931 {
1932 CIMValue pl;
1933 if (XmlReader::getValueArrayElement(parser, CIMTYPE_STRING, pl))
1934 {
1935 Array<String> propertyListArray;
1936 pl.get(propertyListArray);
1937 // NOTE: Cannot use the propertyList.set(...) method
1938 // here because set does not create propertyList tags
1939 value.append(propertyListArray);
1940 }
1941 }
1942 return true;
1943 }
1944 return false;
1945 }
1946
1947 // This version of the get function usees the propertyList set function
1948 karl 1.137 // to set the property list array into the propertyList object. It
1949 // can only be used for those Operations where the propertylist is NOT
1950 // used by the Server in the response (i.e. getClass and modifyInstance).
1951 //
1952 Boolean getSpecial(XmlParser& parser, const char* name, Boolean& emptyTag)
1953 {
1954 if (System::strcasecmp(name, "PropertyList") == 0)
1955 {
1956 if (!emptyTag)
1957 {
1958 CIMValue pl;
1959 if (XmlReader::getValueArrayElement(parser, CIMTYPE_STRING, pl))
1960 {
1961 Array<String> propertyListArray;
1962 pl.get(propertyListArray);
1963 Array<CIMName> cimNameArray;
1964 // Map the strings to CIMNames.
1965 for (Uint32 i = 0; i < propertyListArray.size(); i++)
1966 {
1967 cimNameArray.append(propertyListArray[i]);
1968 }
1969 karl 1.137 // use set to put list into property list without
1970 // setting propertyList tags.
1971 value.set(cimNameArray);
1972 }
1973 }
1974 return true;
1975 }
1976 return false;
1977 }
1978 private:
1979 // hide unused default assign, copy constructors
1980 propertyListIParam(const propertyListIParam&);
1981 propertyListIParam& operator = (const propertyListIParam&);
1982 };
1983
1984 // Attribute decoder for String Parameters
1985 // The constructor MUST include the attribute name.
1986 // The second defines whether a value is required.
1987 // If true and there is no value, the XmlReader does an exception.
1988 class stringIParam
1989 {
1990 karl 1.137 public:
1991 Boolean got;
1992 String value;
1993
1994 // constructor with definition of iParam name and default for the
1995 // required flag.
1996 // @param name const char* with name of IParam to match
1997 //// stringIParam(const char* name):
1998 //// got(false), iParamName(name), valueRequired(false){}
1999
2000 // constructor with definition of attribute and default for the
2001 // required flag.
2002 // @param name const char* with name of IParam to match
2003 // @param valueRequired Boolean that defines whether value is required
2004 stringIParam(const char* name, Boolean _valueRequired):
2005 got(false), iParamName(name), valueRequired(_valueRequired){}
2006
2007 ~stringIParam(){}
2008
2009 void iParamFound(Boolean& duplicate)
2010 {
2011 karl 1.137 duplicate = got;
2012 got = true;
2013 }
2014
2015 // get the attribute if it exists. The attribute name is defined in
2016 // the constructor
2017 // @param parser
2018 // @param testName attribute name from parse.
2019 // @emptyTag returns true if emptyTag returned true from parser
2020 // @return Returns true if testName matches the IParam defined by current
2021 // position in the parser
2022 Boolean get(XmlParser& parser, const char * testName, Boolean& emptyTag)
2023 {
2024 if (System::strcasecmp(iParamName.getCString(), testName) == 0)
2025 {
2026 if (!emptyTag)
2027 {
2028 XmlReader::getStringValueElement(parser, value, valueRequired);
2029 }
2030 return true;
2031 }
2032 karl 1.137 return false;
2033 }
2034 private:
2035 String iParamName;
2036 Boolean valueRequired;
2037 stringIParam();
2038 stringIParam(const stringIParam&);
2039 stringIParam& operator = (const stringIParam&);
2040 };
2041
2042
2043 /************************************************************************
2044 **
2045 ** Common functions used by the decoders to avoid duplicate code.
2046 **
2047 **************************************************************************/
2048 // test for valid end of XML and duplicate parameters on input
2049 // This function returns if OK or executes appropriate exceptions if there
2050 // is either a duplicate (duplicateParameter == true) or the
2051 // end tag IPARAMVALUE is not found.
2052 void _checkMissingEndTagOrDuplicateParamValue(
2053 karl 1.137 XmlParser& parser, Boolean duplicateParameter, Boolean emptyTag)
2054 {
2055 if (!emptyTag)
2056 {
2057 XmlReader::expectEndTag(parser, "IPARAMVALUE");
2058 }
2059
2060 if (duplicateParameter)
2061 {
2062 _throwCIMExceptionDuplicateParameter();
2063 }
2064 }
2065
2066 // test if Required paramters exist (i.e. the got variable is
2067 // true. Generates exception if exist == false
2068 void _testRequiredParametersExist(Boolean exist)
2069 {
2070 if (!exist)
2071 {
2072 _throwCIMExceptionInvalidParameter();
2073 }
2074 karl 1.137 }
2075 /**************************************************************************
2076 **
2077 ** Decode each CIMOperation type, processing the parameters for that type
2078 ** and producing either a CIMMessage of the appropriate type or
2079 ** an exception.
2080 **
2081 ***************************************************************************/
|
2082 mike 1.2
|
2083 kumpf 1.104 CIMCreateClassRequestMessage*
2084 CIMOperationRequestDecoder::decodeCreateClassRequest(
2085 Uint32 queueId,
2086 XmlParser& parser,
2087 const String& messageId,
2088 const CIMNamespaceName& nameSpace)
2089 {
2090 STAT_GETSTARTTIME
2091
2092 CIMClass newClass;
|
2093 karl 1.137 Boolean gotNewClass = false;
2094
2095 Boolean emptyTag;
|
2096 kumpf 1.104 Boolean duplicateParameter = false;
2097
2098 for (const char* name;
2099 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2100 {
2101 if (System::strcasecmp(name, "NewClass") == 0)
2102 {
2103 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
|
2104 kumpf 1.106 if (!XmlReader::getClassElement(parser, newClass))
2105 {
|
2106 karl 1.137 _throwCIMExceptionInvalidParameter("NewClass");
|
2107 kumpf 1.106 }
|
2108 karl 1.137 duplicateParameter = gotNewClass;
2109 gotNewClass = true;
|
2110 kumpf 1.104 }
2111 else
2112 {
|
2113 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2114 kumpf 1.104 }
|
2115 sage 1.41
|
2116 karl 1.137 // generate exception if endtag error or duplicate attributes
2117 _checkMissingEndTagOrDuplicateParamValue(
2118 parser, duplicateParameter, emptyTag);
|
2119 kumpf 1.104 }
2120
|
2121 karl 1.137 _testRequiredParametersExist(gotNewClass);
|
2122 kumpf 1.104
2123 AutoPtr<CIMCreateClassRequestMessage> request(
2124 new CIMCreateClassRequestMessage(
2125 messageId,
2126 nameSpace,
2127 newClass,
2128 QueueIdStack(queueId, _returnQueueId)));
2129
2130 STAT_SERVERSTART
2131
2132 return request.release();
|
2133 mike 1.2 }
2134
2135 CIMGetClassRequestMessage* CIMOperationRequestDecoder::decodeGetClassRequest(
|
2136 kumpf 1.104 Uint32 queueId,
2137 XmlParser& parser,
2138 const String& messageId,
2139 const CIMNamespaceName& nameSpace)
2140 {
|
2141 karl 1.137 STAT_GETSTARTTIME
|
2142 kumpf 1.104
|
2143 karl 1.137 // GetClass Parameters
2144 classNameIParam className("ClassName");
2145 booleanIParam localOnly("localOnly",true);
2146 booleanIParam includeQualifiers("IncludeQualifiers", true);
2147 booleanIParam includeClassOrigin("IncludeClassOrigin");
2148 propertyListIParam propertyList;
|
2149 kumpf 1.104
2150 Boolean duplicateParameter = false;
2151 Boolean emptyTag;
2152
2153 for (const char* name;
2154 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2155 {
|
2156 karl 1.137 if(className.get(parser, name, emptyTag))
|
2157 kumpf 1.104 {
|
2158 karl 1.137 className.iParamFound(duplicateParameter);
|
2159 kumpf 1.104 }
|
2160 karl 1.137 else if(localOnly.get(parser, name, emptyTag))
|
2161 kumpf 1.104 {
|
2162 karl 1.137 localOnly.iParamFound(duplicateParameter);
|
2163 kumpf 1.104 }
|
2164 karl 1.137 else if(includeQualifiers.get(parser, name, emptyTag))
|
2165 kumpf 1.104 {
|
2166 karl 1.137 includeQualifiers.iParamFound(duplicateParameter);
|
2167 kumpf 1.104 }
|
2168 karl 1.137 else if(includeClassOrigin.get(parser, name, emptyTag))
|
2169 kumpf 1.104 {
|
2170 karl 1.137 includeClassOrigin.iParamFound(duplicateParameter);
|
2171 kumpf 1.104 }
|
2172 karl 1.137 else if(propertyList.getSpecial(parser, name, emptyTag))
|
2173 kumpf 1.104 {
|
2174 karl 1.137 propertyList.iParamFound(duplicateParameter);
|
2175 kumpf 1.104 }
2176 else
2177 {
|
2178 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2179 kumpf 1.104 }
|
2180 karl 1.137 // generate exception if endtag error or duplicate attributes
2181 _checkMissingEndTagOrDuplicateParamValue(
2182 parser, duplicateParameter, emptyTag);
|
2183 kumpf 1.104 }
2184
|
2185 karl 1.137 // test for required parameters
2186 _testRequiredParametersExist(className.got);
|
2187 kumpf 1.104
|
2188 karl 1.137 // Build message
|
2189 kumpf 1.104 AutoPtr<CIMGetClassRequestMessage> request(new CIMGetClassRequestMessage(
2190 messageId,
2191 nameSpace,
|
2192 karl 1.137 className.value,
2193 localOnly.value,
2194 includeQualifiers.value,
2195 includeClassOrigin.value,
2196 propertyList.value,
|
2197 kumpf 1.104 QueueIdStack(queueId, _returnQueueId)));
2198
2199 STAT_SERVERSTART
2200
2201 return request.release();
2202 }
2203
2204 CIMModifyClassRequestMessage*
2205 CIMOperationRequestDecoder::decodeModifyClassRequest(
2206 Uint32 queueId,
2207 XmlParser& parser,
2208 const String& messageId,
2209 const CIMNamespaceName& nameSpace)
2210 {
2211 STAT_GETSTARTTIME
2212
2213 CIMClass modifiedClass;
2214 Boolean gotClass = false;
|
2215 karl 1.137
|
2216 kumpf 1.104 Boolean emptyTag;
|
2217 karl 1.137 Boolean duplicateParameter = false;
|
2218 kumpf 1.104
2219 for (const char* name;
2220 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2221 {
2222 if (System::strcasecmp(name, "ModifiedClass") == 0)
2223 {
2224 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
|
2225 kumpf 1.106 if (!XmlReader::getClassElement(parser, modifiedClass))
2226 {
|
2227 karl 1.137 _throwCIMExceptionInvalidParameter("ModifiedClass");
|
2228 kumpf 1.106 }
|
2229 kumpf 1.104 duplicateParameter = gotClass;
2230 gotClass = true;
2231 }
2232 else
2233 {
|
2234 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2235 kumpf 1.104 }
2236
|
2237 karl 1.137 // generate exception if endtag error or duplicate attributes
2238 _checkMissingEndTagOrDuplicateParamValue(
2239 parser, duplicateParameter, emptyTag);
|
2240 kumpf 1.104 }
2241
|
2242 karl 1.137 _testRequiredParametersExist(gotClass);
|
2243 kumpf 1.104
2244 AutoPtr<CIMModifyClassRequestMessage> request(
2245 new CIMModifyClassRequestMessage(
2246 messageId,
2247 nameSpace,
2248 modifiedClass,
2249 QueueIdStack(queueId, _returnQueueId)));
2250
2251 STAT_SERVERSTART
2252
2253 return request.release();
2254 }
2255
2256 CIMEnumerateClassNamesRequestMessage*
2257 CIMOperationRequestDecoder::decodeEnumerateClassNamesRequest(
2258 Uint32 queueId,
2259 XmlParser& parser,
2260 const String& messageId,
2261 const CIMNamespaceName& nameSpace)
2262 {
2263 STAT_GETSTARTTIME
2264 kumpf 1.104
|
2265 karl 1.137 classNameIParam className("ClassName");
2266 booleanIParam deepInheritance("DeepInheritance");
2267
|
2268 kumpf 1.104 Boolean duplicateParameter = false;
2269 Boolean emptyTag;
2270
2271 for (const char* name;
2272 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2273 {
|
2274 karl 1.137 if(className.getOptional(parser, name, emptyTag))
|
2275 kumpf 1.104 {
|
2276 karl 1.137 className.iParamFound(duplicateParameter);
|
2277 kumpf 1.104 }
|
2278 karl 1.137 else if(deepInheritance.get(parser, name, emptyTag))
|
2279 kumpf 1.104 {
|
2280 karl 1.137 deepInheritance.iParamFound(duplicateParameter);
|
2281 kumpf 1.104 }
2282 else
2283 {
|
2284 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2285 kumpf 1.104 }
2286
|
2287 karl 1.137 // generate exception if endtag error or duplicate attributes
2288 _checkMissingEndTagOrDuplicateParamValue(
2289 parser, duplicateParameter, emptyTag);
2290 }
|
2291 kumpf 1.104
|
2292 karl 1.137 // NOTE: className not required for this operation
|
2293 kumpf 1.104
2294 AutoPtr<CIMEnumerateClassNamesRequestMessage> request(
2295 new CIMEnumerateClassNamesRequestMessage(
2296 messageId,
2297 nameSpace,
|
2298 karl 1.137 className.value,
2299 deepInheritance.value,
|
2300 kumpf 1.104 QueueIdStack(queueId, _returnQueueId)));
2301
2302 STAT_SERVERSTART
2303
2304 return request.release();
2305 }
2306
2307 CIMEnumerateClassesRequestMessage*
2308 CIMOperationRequestDecoder::decodeEnumerateClassesRequest(
2309 Uint32 queueId,
2310 XmlParser& parser,
2311 const String& messageId,
2312 const CIMNamespaceName& nameSpace)
2313 {
2314 STAT_GETSTARTTIME
2315
|
2316 karl 1.137 // EnumerateClasses Parameters
2317 classNameIParam className("ClassName");
2318 booleanIParam deepInheritance("deepInheritance");
2319 booleanIParam localOnly("localOnly",true);
2320 booleanIParam includeQualifiers("IncludeQualifiers", true);
2321 booleanIParam includeClassOrigin("IncludeClassOrigin");
2322
|
2323 kumpf 1.104 Boolean duplicateParameter = false;
2324 Boolean emptyTag;
2325
2326 for (const char* name;
2327 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2328 {
|
2329 karl 1.137 if(className.getOptional(parser, name, emptyTag))
|
2330 kumpf 1.104 {
|
2331 karl 1.137 className.iParamFound(duplicateParameter);
|
2332 kumpf 1.104 }
|
2333 karl 1.137 else if(deepInheritance.get(parser, name, emptyTag))
|
2334 kumpf 1.104 {
|
2335 karl 1.137 deepInheritance.iParamFound(duplicateParameter);
|
2336 kumpf 1.104 }
|
2337 karl 1.137 else if(localOnly.get(parser, name, emptyTag))
|
2338 kumpf 1.104 {
|
2339 karl 1.137 localOnly.iParamFound(duplicateParameter);
|
2340 kumpf 1.104 }
|
2341 karl 1.137 else if(includeQualifiers.get(parser, name, emptyTag))
|
2342 kumpf 1.104 {
|
2343 karl 1.137 includeQualifiers.iParamFound(duplicateParameter);
|
2344 kumpf 1.104 }
|
2345 karl 1.137 else if(includeClassOrigin.get(parser, name, emptyTag))
|
2346 kumpf 1.104 {
|
2347 karl 1.137 includeClassOrigin.iParamFound(duplicateParameter);
|
2348 kumpf 1.104 }
2349 else
2350 {
|
2351 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2352 kumpf 1.104 }
2353
|
2354 karl 1.137 // generate exception if endtag error or duplicate attributes
2355 _checkMissingEndTagOrDuplicateParamValue(
2356 parser, duplicateParameter, emptyTag);
2357 }
|
2358 kumpf 1.104
|
2359 karl 1.137 // NOTE: Class name not required for this enumerate.
|
2360 kumpf 1.104
2361 AutoPtr<CIMEnumerateClassesRequestMessage> request(
2362 new CIMEnumerateClassesRequestMessage(
2363 messageId,
2364 nameSpace,
|
2365 karl 1.137 className.value,
2366 deepInheritance.value,
2367 localOnly.value,
2368 includeQualifiers.value,
2369 includeClassOrigin.value,
|
2370 kumpf 1.104 QueueIdStack(queueId, _returnQueueId)));
2371
2372 STAT_SERVERSTART
2373
2374 return request.release();
2375 }
2376
2377 CIMDeleteClassRequestMessage*
2378 CIMOperationRequestDecoder::decodeDeleteClassRequest(
2379 Uint32 queueId,
2380 XmlParser& parser,
2381 const String& messageId,
2382 const CIMNamespaceName& nameSpace)
2383 {
2384 STAT_GETSTARTTIME
2385
|
2386 karl 1.137 classNameIParam className("ClassName");
2387
|
2388 kumpf 1.104 Boolean duplicateParameter = false;
2389 Boolean emptyTag;
2390
2391 for (const char* name;
2392 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2393 {
|
2394 karl 1.137 if(className.get(parser, name, emptyTag))
|
2395 kumpf 1.104 {
|
2396 karl 1.137 className.iParamFound(duplicateParameter);
|
2397 kumpf 1.104 }
2398 else
2399 {
|
2400 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2401 kumpf 1.104 }
2402
|
2403 karl 1.137 // generate exception if endtag error or duplicate attributes
2404 _checkMissingEndTagOrDuplicateParamValue(
2405 parser, duplicateParameter, emptyTag);
|
2406 kumpf 1.104 }
2407
|
2408 karl 1.137 _testRequiredParametersExist(className.got);
|
2409 kumpf 1.104
2410 AutoPtr<CIMDeleteClassRequestMessage> request(
2411 new CIMDeleteClassRequestMessage(
2412 messageId,
2413 nameSpace,
|
2414 karl 1.137 className.value,
|
2415 kumpf 1.104 QueueIdStack(queueId, _returnQueueId)));
2416
2417 STAT_SERVERSTART
2418
2419 return request.release();
2420 }
2421
2422 CIMCreateInstanceRequestMessage*
2423 CIMOperationRequestDecoder::decodeCreateInstanceRequest(
2424 Uint32 queueId,
2425 XmlParser& parser,
2426 const String& messageId,
2427 const CIMNamespaceName& nameSpace)
2428 {
2429 STAT_GETSTARTTIME
2430
2431 CIMInstance newInstance;
2432 Boolean gotInstance = false;
|
2433 karl 1.137
|
2434 kumpf 1.104 Boolean emptyTag;
|
2435 karl 1.137 Boolean duplicateParameter = false;
|
2436 kumpf 1.104
2437 for (const char* name;
2438 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2439 {
2440 if (System::strcasecmp(name, "NewInstance") == 0)
2441 {
2442 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2443 XmlReader::getInstanceElement(parser, newInstance);
2444 duplicateParameter = gotInstance;
2445 gotInstance = true;
2446 }
2447 else
2448 {
|
2449 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2450 kumpf 1.104 }
2451
|
2452 karl 1.137 // generate exception if endtag error or duplicate attributes
2453 _checkMissingEndTagOrDuplicateParamValue(
2454 parser, duplicateParameter, emptyTag);
2455 }
|
2456 kumpf 1.104
2457
|
2458 karl 1.137 _testRequiredParametersExist(gotInstance);
|
2459 kumpf 1.104
2460 AutoPtr<CIMCreateInstanceRequestMessage> request(
2461 new CIMCreateInstanceRequestMessage(
2462 messageId,
2463 nameSpace,
2464 newInstance,
2465 QueueIdStack(queueId, _returnQueueId)));
2466
2467 STAT_SERVERSTART
2468
2469 return request.release();
2470 }
2471
2472 CIMGetInstanceRequestMessage*
2473 CIMOperationRequestDecoder::decodeGetInstanceRequest(
2474 Uint32 queueId,
2475 XmlParser& parser,
2476 const String& messageId,
2477 const CIMNamespaceName& nameSpace)
2478 {
2479 STAT_GETSTARTTIME
2480 kumpf 1.104
|
2481 karl 1.137 instanceNameIParam instanceName;
2482 // This attribute is accepted for compatibility reasons, but is
2483 // not honored because it is deprecated.
2484 booleanIParam localOnly("localOnly",true);
2485 booleanIParam includeQualifiers("IncludeQualifiers");
2486 booleanIParam includeClassOrigin("IncludeClassOrigin");
2487 propertyListIParam propertyList;
2488
|
2489 kumpf 1.104 Boolean duplicateParameter = false;
2490 Boolean emptyTag;
2491
2492 for (const char* name;
2493 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2494 {
|
2495 karl 1.137 if(instanceName.get(parser, name, emptyTag))
|
2496 kumpf 1.104 {
|
2497 karl 1.137 instanceName.iParamFound(duplicateParameter);
|
2498 kumpf 1.104 }
|
2499 karl 1.137 // localOnly is accepted for compatibility reasons, but is
2500 // not honored because it is deprecated.
2501 else if(localOnly.get(parser, name, emptyTag))
|
2502 kumpf 1.104 {
|
2503 karl 1.137 localOnly.iParamFound(duplicateParameter);
|
2504 kumpf 1.104 }
|
2505 karl 1.137 else if(includeQualifiers.get(parser, name, emptyTag))
|
2506 kumpf 1.104 {
|
2507 karl 1.137 includeQualifiers.iParamFound(duplicateParameter);
|
2508 kumpf 1.104 }
|
2509 karl 1.137 else if(includeClassOrigin.get(parser, name, emptyTag))
|
2510 kumpf 1.104 {
|
2511 karl 1.137 includeClassOrigin.iParamFound(duplicateParameter);
|
2512 kumpf 1.104 }
|
2513 karl 1.137 else if(propertyList.get(parser, name, emptyTag))
|
2514 kumpf 1.104 {
|
2515 karl 1.137 propertyList.iParamFound(duplicateParameter);
|
2516 kumpf 1.104 }
2517 else
2518 {
|
2519 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2520 kumpf 1.104 }
2521
|
2522 karl 1.137 // generate exception if endtag error or duplicate attributes
2523 _checkMissingEndTagOrDuplicateParamValue(
2524 parser, duplicateParameter, emptyTag);
|
2525 kumpf 1.104 }
2526
|
2527 karl 1.137 _testRequiredParametersExist(instanceName.got);
|
2528 kumpf 1.104
2529 AutoPtr<CIMGetInstanceRequestMessage> request(
2530 new CIMGetInstanceRequestMessage(
2531 messageId,
2532 nameSpace,
|
2533 karl 1.137 instanceName.value,
|
2534 h.sterling 1.97 #ifdef PEGASUS_DISABLE_INSTANCE_QUALIFIERS
|
2535 kumpf 1.104 false,
|
2536 h.sterling 1.97 #else
|
2537 karl 1.137 includeQualifiers.value,
|
2538 h.sterling 1.97 #endif
|
2539 karl 1.137 includeClassOrigin.value,
2540 propertyList.value,
|
2541 kumpf 1.104 QueueIdStack(queueId, _returnQueueId)));
2542
2543 STAT_SERVERSTART
2544
2545 return request.release();
2546 }
2547
|
2548 karl 1.137
|
2549 kumpf 1.104 CIMModifyInstanceRequestMessage*
2550 CIMOperationRequestDecoder::decodeModifyInstanceRequest(
2551 Uint32 queueId,
2552 XmlParser& parser,
2553 const String& messageId,
2554 const CIMNamespaceName& nameSpace)
2555 {
2556 STAT_GETSTARTTIME
2557
2558 CIMInstance modifiedInstance;
2559 Boolean gotInstance = false;
|
2560 karl 1.137
2561 booleanIParam includeQualifiers("IncludeQualifiers", true);
2562 propertyListIParam propertyList;
2563
|
2564 kumpf 1.104 Boolean emptyTag;
|
2565 karl 1.137 Boolean duplicateParameter = false;
|
2566 kumpf 1.104
2567 for (const char* name;
2568 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2569 {
2570 if (System::strcasecmp(name, "ModifiedInstance") == 0)
2571 {
2572 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2573 XmlReader::getNamedInstanceElement(parser, modifiedInstance);
2574 duplicateParameter = gotInstance;
2575 gotInstance = true;
2576 }
|
2577 karl 1.137 else if(includeQualifiers.get(parser, name, emptyTag))
|
2578 kumpf 1.104 {
|
2579 karl 1.137 includeQualifiers.iParamFound(duplicateParameter);
|
2580 kumpf 1.104 }
|
2581 karl 1.137 else if(propertyList.getSpecial(parser, name, emptyTag))
|
2582 kumpf 1.104 {
|
2583 karl 1.137 propertyList.iParamFound(duplicateParameter);
|
2584 kumpf 1.104 }
2585 else
2586 {
|
2587 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2588 kumpf 1.104 }
2589
|
2590 karl 1.137 _checkMissingEndTagOrDuplicateParamValue(
2591 parser, duplicateParameter, emptyTag);
|
2592 kumpf 1.104 }
2593
|
2594 karl 1.137 _testRequiredParametersExist(gotInstance);
|
2595 kumpf 1.104
2596 AutoPtr<CIMModifyInstanceRequestMessage> request(
2597 new CIMModifyInstanceRequestMessage(
2598 messageId,
2599 nameSpace,
2600 modifiedInstance,
|
2601 karl 1.137 includeQualifiers.value,
2602 propertyList.value,
|
2603 kumpf 1.104 QueueIdStack(queueId, _returnQueueId)));
2604
2605 STAT_SERVERSTART
2606
2607 return request.release();
2608 }
2609
2610 CIMEnumerateInstancesRequestMessage*
2611 CIMOperationRequestDecoder::decodeEnumerateInstancesRequest(
2612 Uint32 queueId,
2613 XmlParser& parser,
2614 const String& messageId,
2615 const CIMNamespaceName& nameSpace)
2616 {
2617 STAT_GETSTARTTIME
2618
|
2619 karl 1.137 // EnumerateInstance Parameters
2620 classNameIParam className("ClassName");
2621 booleanIParam deepInheritance("DeepInheritance", true);
2622 // localOnly is accepted for compatibility reasons, but is
2623 // not honored because it is deprecated.
2624 booleanIParam localOnly("localOnly", true);
2625 booleanIParam includeQualifiers("IncludeQualifiers");
2626 booleanIParam includeClassOrigin("IncludeClassOrigin");
2627 propertyListIParam propertyList;
2628
|
2629 kumpf 1.104 Boolean duplicateParameter = false;
2630 Boolean emptyTag;
2631
2632 for (const char* name;
2633 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2634 {
|
2635 karl 1.137 if(className.get(parser, name, emptyTag))
|
2636 kumpf 1.104 {
|
2637 karl 1.137 className.iParamFound(duplicateParameter);
|
2638 kumpf 1.104 }
|
2639 karl 1.137 else if(deepInheritance.get(parser, name, emptyTag))
|
2640 kumpf 1.104 {
|
2641 karl 1.137 deepInheritance.iParamFound(duplicateParameter);
|
2642 kumpf 1.104 }
|
2643 karl 1.137 // This attribute is accepted for compatibility reasons, but is
2644 // not honored because it is deprecated.
2645 else if(localOnly.get(parser, name, emptyTag))
|
2646 kumpf 1.104 {
|
2647 karl 1.137 localOnly.iParamFound(duplicateParameter);
|
2648 kumpf 1.104 }
|
2649 karl 1.137 else if(includeQualifiers.get(parser, name, emptyTag))
|
2650 kumpf 1.104 {
|
2651 karl 1.137 includeQualifiers.iParamFound(duplicateParameter);
|
2652 kumpf 1.104 }
|
2653 karl 1.137 else if(includeClassOrigin.get(parser, name, emptyTag))
|
2654 kumpf 1.104 {
|
2655 karl 1.137 includeClassOrigin.iParamFound(duplicateParameter);
|
2656 kumpf 1.104 }
|
2657 karl 1.137 else if(propertyList.get(parser, name, emptyTag))
|
2658 kumpf 1.104 {
|
2659 karl 1.137 propertyList.iParamFound(duplicateParameter);
|
2660 kumpf 1.104 }
|
2661 karl 1.137 else
|
2662 kumpf 1.104 {
|
2663 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2664 kumpf 1.104 }
2665
|
2666 karl 1.137 // generate exception if endtag error or duplicate attributes
2667 _checkMissingEndTagOrDuplicateParamValue(
2668 parser, duplicateParameter, emptyTag);
|
2669 kumpf 1.104 }
2670
|
2671 karl 1.137 _testRequiredParametersExist(className.got);
|
2672 karl 1.135
|
2673 kumpf 1.104 AutoPtr<CIMEnumerateInstancesRequestMessage> request(
2674 new CIMEnumerateInstancesRequestMessage(
2675 messageId,
2676 nameSpace,
|
2677 karl 1.137 className.value,
2678 deepInheritance.value,
|
2679 h.sterling 1.97 #ifdef PEGASUS_DISABLE_INSTANCE_QUALIFIERS
|
2680 kumpf 1.104 false,
|
2681 h.sterling 1.97 #else
|
2682 karl 1.137 includeQualifiers.value,
|
2683 h.sterling 1.97 #endif
|
2684 karl 1.137 includeClassOrigin.value,
2685 propertyList.value,
|
2686 kumpf 1.104 QueueIdStack(queueId, _returnQueueId)));
2687
2688 STAT_SERVERSTART
2689
2690 return request.release();
2691 }
2692
2693 CIMEnumerateInstanceNamesRequestMessage*
2694 CIMOperationRequestDecoder::decodeEnumerateInstanceNamesRequest(
2695 Uint32 queueId,
2696 XmlParser& parser,
2697 const String& messageId,
2698 const CIMNamespaceName& nameSpace)
2699 {
2700 STAT_GETSTARTTIME
2701
|
2702 karl 1.137 classNameIParam className("ClassName");
2703
|
2704 kumpf 1.104 Boolean duplicateParameter = false;
2705 Boolean emptyTag;
2706
2707 for (const char* name;
2708 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2709 {
|
2710 karl 1.137 if(className.get(parser, name, emptyTag))
|
2711 kumpf 1.104 {
|
2712 karl 1.137 className.iParamFound(duplicateParameter);
|
2713 kumpf 1.104 }
2714 else
2715 {
|
2716 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2717 kumpf 1.104 }
2718
|
2719 karl 1.137 // generate exception if endtag error or duplicate attributes
2720 _checkMissingEndTagOrDuplicateParamValue(
2721 parser, duplicateParameter, emptyTag);
|
2722 kumpf 1.104 }
2723
|
2724 karl 1.137 _testRequiredParametersExist(className.got);
|
2725 kumpf 1.104
2726 AutoPtr<CIMEnumerateInstanceNamesRequestMessage> request(
2727 new CIMEnumerateInstanceNamesRequestMessage(
2728 messageId,
2729 nameSpace,
|
2730 karl 1.137 className.value,
|
2731 kumpf 1.104 QueueIdStack(queueId, _returnQueueId)));
2732
2733 STAT_SERVERSTART
2734
2735 return request.release();
2736 }
2737
2738 CIMDeleteInstanceRequestMessage*
2739 CIMOperationRequestDecoder::decodeDeleteInstanceRequest(
2740 Uint32 queueId,
2741 XmlParser& parser,
2742 const String& messageId,
2743 const CIMNamespaceName& nameSpace)
2744 {
2745 STAT_GETSTARTTIME
2746
|
2747 karl 1.137 instanceNameIParam instanceName;
2748
|
2749 kumpf 1.104 Boolean duplicateParameter = false;
2750 Boolean emptyTag;
2751
2752 for (const char* name;
2753 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2754 {
|
2755 karl 1.137 if(instanceName.get(parser, name, emptyTag))
|
2756 kumpf 1.104 {
|
2757 karl 1.137 instanceName.iParamFound(duplicateParameter);
|
2758 kumpf 1.104 }
2759 else
2760 {
|
2761 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2762 kumpf 1.104 }
2763
|
2764 karl 1.137 // generate exception if endtag error or duplicate attributes
2765 _checkMissingEndTagOrDuplicateParamValue(
2766 parser, duplicateParameter, emptyTag);
|
2767 kumpf 1.104 }
2768
|
2769 karl 1.137 _testRequiredParametersExist(instanceName.got);
|
2770 kumpf 1.104
2771 AutoPtr<CIMDeleteInstanceRequestMessage> request(
2772 new CIMDeleteInstanceRequestMessage(
2773 messageId,
2774 nameSpace,
|
2775 karl 1.137 instanceName.value,
|
2776 kumpf 1.104 QueueIdStack(queueId, _returnQueueId)));
2777
2778 STAT_SERVERSTART
2779
2780 return request.release();
2781 }
2782
2783 CIMSetQualifierRequestMessage*
2784 CIMOperationRequestDecoder::decodeSetQualifierRequest(
2785 Uint32 queueId,
2786 XmlParser& parser,
2787 const String& messageId,
2788 const CIMNamespaceName& nameSpace)
2789 {
2790 STAT_GETSTARTTIME
2791
2792 CIMQualifierDecl qualifierDeclaration;
2793 Boolean duplicateParameter = false;
2794 Boolean gotQualifierDeclaration = false;
2795 Boolean emptyTag;
2796
2797 kumpf 1.104 for (const char* name;
2798 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2799 {
2800 if (System::strcasecmp(name, "QualifierDeclaration") == 0)
2801 {
2802 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2803 XmlReader::getQualifierDeclElement(parser, qualifierDeclaration);
2804 duplicateParameter = gotQualifierDeclaration;
2805 gotQualifierDeclaration = true;
2806 }
2807 else
2808 {
|
2809 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2810 kumpf 1.104 }
2811
|
2812 karl 1.137 // generate exception if endtag error or duplicate attributes
2813 _checkMissingEndTagOrDuplicateParamValue(
2814 parser, duplicateParameter, emptyTag);
|
2815 kumpf 1.104 }
2816
|
2817 karl 1.137 _testRequiredParametersExist(gotQualifierDeclaration);
|
2818 kumpf 1.104
2819 AutoPtr<CIMSetQualifierRequestMessage> request(
2820 new CIMSetQualifierRequestMessage(
2821 messageId,
2822 nameSpace,
2823 qualifierDeclaration,
2824 QueueIdStack(queueId, _returnQueueId)));
2825
2826 STAT_SERVERSTART
2827
2828 return request.release();
2829 }
2830
2831 CIMGetQualifierRequestMessage*
2832 CIMOperationRequestDecoder::decodeGetQualifierRequest(
2833 Uint32 queueId,
2834 XmlParser& parser,
2835 const String& messageId,
2836 const CIMNamespaceName& nameSpace)
2837 {
2838 STAT_GETSTARTTIME
2839 kumpf 1.104
2840 String qualifierNameString;
2841 CIMName qualifierName;
2842 Boolean duplicateParameter = false;
2843 Boolean gotQualifierName = false;
2844 Boolean emptyTag;
2845
2846 for (const char* name;
2847 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2848 {
2849 if (System::strcasecmp(name, "QualifierName") == 0)
2850 {
2851 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2852 XmlReader::getStringValueElement(parser, qualifierNameString, true);
2853 qualifierName = qualifierNameString;
2854 duplicateParameter = gotQualifierName;
2855 gotQualifierName = true;
2856 }
2857 else
2858 {
|
2859 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2860 kumpf 1.104 }
2861
|
2862 karl 1.137 // generate exception if endtag error or duplicate attributes
2863 _checkMissingEndTagOrDuplicateParamValue(
2864 parser, duplicateParameter, emptyTag);
|
2865 kumpf 1.104 }
2866
|
2867 karl 1.137 _testRequiredParametersExist(gotQualifierName);
|
2868 kumpf 1.104
2869 AutoPtr<CIMGetQualifierRequestMessage> request(
2870 new CIMGetQualifierRequestMessage(
2871 messageId,
2872 nameSpace,
2873 qualifierName,
2874 QueueIdStack(queueId, _returnQueueId)));
2875
2876 STAT_SERVERSTART
2877
2878 return request.release();
2879 }
2880
2881 CIMEnumerateQualifiersRequestMessage*
2882 CIMOperationRequestDecoder::decodeEnumerateQualifiersRequest(
2883 Uint32 queueId,
2884 XmlParser& parser,
2885 const String& messageId,
2886 const CIMNamespaceName& nameSpace)
2887 {
2888 STAT_GETSTARTTIME
2889 kumpf 1.104 Boolean emptyTag;
2890
2891 for (const char* name;
2892 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2893 {
2894 // No IPARAMVALUEs are defined for this operation
|
2895 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2896 kumpf 1.104 }
2897
2898 AutoPtr<CIMEnumerateQualifiersRequestMessage> request(
2899 new CIMEnumerateQualifiersRequestMessage(
2900 messageId,
2901 nameSpace,
2902 QueueIdStack(queueId, _returnQueueId)));
2903
2904 STAT_SERVERSTART
2905
2906 return request.release();
2907 }
2908
2909 CIMDeleteQualifierRequestMessage*
2910 CIMOperationRequestDecoder::decodeDeleteQualifierRequest(
2911 Uint32 queueId,
2912 XmlParser& parser,
2913 const String& messageId,
2914 const CIMNamespaceName& nameSpace)
2915 {
2916 STAT_GETSTARTTIME
2917 kumpf 1.104
2918 String qualifierNameString;
2919 CIMName qualifierName;
2920 Boolean gotQualifierName = false;
|
2921 karl 1.137
|
2922 kumpf 1.104 Boolean emptyTag;
|
2923 karl 1.137 Boolean duplicateParameter = false;
|
2924 kumpf 1.104
2925 for (const char* name;
2926 XmlReader::getIParamValueTag(parser, name, emptyTag); )
2927 {
2928 if (System::strcasecmp(name, "QualifierName") == 0)
2929 {
2930 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
2931 XmlReader::getStringValueElement(parser, qualifierNameString, true);
2932 qualifierName = qualifierNameString;
2933 duplicateParameter = gotQualifierName;
2934 gotQualifierName = true;
2935 }
2936 else
2937 {
|
2938 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2939 kumpf 1.104 }
2940
2941
|
2942 karl 1.137 // generate exception if endtag error or duplicate attributes
2943 _checkMissingEndTagOrDuplicateParamValue(
2944 parser, duplicateParameter, emptyTag);
|
2945 kumpf 1.104 }
2946
|
2947 karl 1.137 _testRequiredParametersExist(gotQualifierName);
|
2948 kumpf 1.104
2949 AutoPtr<CIMDeleteQualifierRequestMessage> request(
2950 new CIMDeleteQualifierRequestMessage(
2951 messageId,
2952 nameSpace,
2953 qualifierName,
2954 QueueIdStack(queueId, _returnQueueId)));
2955
2956 STAT_SERVERSTART
2957
2958 return request.release();
2959 }
2960
2961 CIMReferenceNamesRequestMessage*
2962 CIMOperationRequestDecoder::decodeReferenceNamesRequest(
2963 Uint32 queueId,
2964 XmlParser& parser,
2965 const String& messageId,
2966 const CIMNamespaceName& nameSpace)
2967 {
2968 STAT_GETSTARTTIME
|
2969 karl 1.137 objectNameIParam objectName;
2970 classNameIParam resultClass("ResultClass");
2971 stringIParam role("role", false);
|
2972 kumpf 1.104
|
2973 karl 1.137 Boolean duplicateParameter = false;
|
2974 kumpf 1.104 Boolean emptyTag;
2975
2976 for (const char* name;
|
2977 karl 1.137 XmlReader::getIParamValueTag(parser, name, emptyTag); )
|
2978 kumpf 1.104 {
|
2979 karl 1.137 if(objectName.get(parser, name, emptyTag))
|
2980 kumpf 1.104 {
|
2981 karl 1.137 objectName.iParamFound(duplicateParameter);
|
2982 kumpf 1.104 }
|
2983 karl 1.137 else if (resultClass.getOptional(parser, name, emptyTag))
|
2984 kumpf 1.104 {
|
2985 karl 1.137 resultClass.iParamFound(duplicateParameter);
|
2986 kumpf 1.104 }
|
2987 karl 1.137 else if(role.get(parser, name, emptyTag))
|
2988 kumpf 1.104 {
|
2989 karl 1.137 role.iParamFound(duplicateParameter);
|
2990 kumpf 1.104 }
2991 else
2992 {
|
2993 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
2994 kumpf 1.104 }
2995
|
2996 karl 1.137 // generate exception if endtag error or duplicate attributes
2997 _checkMissingEndTagOrDuplicateParamValue(
2998 parser, duplicateParameter, emptyTag);
|
2999 kumpf 1.104 }
3000
|
3001 karl 1.137 _testRequiredParametersExist(objectName.got);
|
3002 kumpf 1.104
3003 AutoPtr<CIMReferenceNamesRequestMessage> request(
3004 new CIMReferenceNamesRequestMessage(
3005 messageId,
3006 nameSpace,
|
3007 karl 1.137 objectName.value,
3008 resultClass.value,
3009 role.value,
|
3010 karl 1.135 QueueIdStack(queueId, _returnQueueId),
|
3011 karl 1.137 objectName.isClassNameElement));
|
3012 kumpf 1.104
3013 STAT_SERVERSTART
3014
3015 return request.release();
3016 }
3017
3018 CIMReferencesRequestMessage*
3019 CIMOperationRequestDecoder::decodeReferencesRequest(
3020 Uint32 queueId,
3021 XmlParser& parser,
3022 const String& messageId,
3023 const CIMNamespaceName& nameSpace)
3024 {
3025 STAT_GETSTARTTIME
3026
|
3027 karl 1.137 objectNameIParam objectName;
3028 classNameIParam resultClass("ResultClass");
3029 stringIParam role("role", false);
3030 booleanIParam includeQualifiers("IncludeQualifiers");
3031 booleanIParam includeClassOrigin("IncludeClassOrigin");
3032 propertyListIParam propertyList;
3033
3034 Boolean duplicateParameter = false;
|
3035 kumpf 1.104 Boolean emptyTag;
3036
3037 for (const char* name;
3038 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3039 {
|
3040 karl 1.137 if(objectName.get(parser, name, emptyTag))
|
3041 kumpf 1.104 {
|
3042 karl 1.137 objectName.iParamFound(duplicateParameter);
|
3043 kumpf 1.104 }
|
3044 karl 1.137 else if(role.get(parser, name, emptyTag))
|
3045 kumpf 1.104 {
|
3046 karl 1.137 role.iParamFound(duplicateParameter);
|
3047 kumpf 1.104 }
|
3048 karl 1.137 else if (resultClass.getOptional(parser, name, emptyTag))
|
3049 kumpf 1.104 {
|
3050 karl 1.137 resultClass.iParamFound(duplicateParameter);
|
3051 kumpf 1.104 }
|
3052 karl 1.137 else if(includeQualifiers.get(parser, name, emptyTag))
|
3053 kumpf 1.104 {
|
3054 karl 1.137 includeQualifiers.iParamFound(duplicateParameter);
|
3055 kumpf 1.104 }
|
3056 karl 1.137 else if(includeClassOrigin.get(parser, name, emptyTag))
|
3057 kumpf 1.104 {
|
3058 karl 1.137 includeClassOrigin.iParamFound(duplicateParameter);
|
3059 kumpf 1.104 }
|
3060 karl 1.137 else if(propertyList.get(parser, name, emptyTag))
|
3061 kumpf 1.104 {
|
3062 karl 1.137 propertyList.iParamFound(duplicateParameter);
|
3063 kumpf 1.104 }
3064 else
3065 {
|
3066 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
3067 kumpf 1.104 }
3068
|
3069 karl 1.137 // generate exception if endtag error or duplicate attributes
3070 _checkMissingEndTagOrDuplicateParamValue(
3071 parser, duplicateParameter, emptyTag);
|
3072 kumpf 1.104 }
3073
|
3074 karl 1.137 _testRequiredParametersExist(objectName.got);
|
3075 kumpf 1.104
3076 AutoPtr<CIMReferencesRequestMessage> request(
3077 new CIMReferencesRequestMessage(
3078 messageId,
3079 nameSpace,
|
3080 karl 1.137 objectName.value,
3081 resultClass.value,
3082 role.value,
3083 includeQualifiers.value,
3084 includeClassOrigin.value,
3085 propertyList.value,
|
3086 karl 1.135 QueueIdStack(queueId, _returnQueueId),
|
3087 karl 1.137 objectName.isClassNameElement));
|
3088 kumpf 1.104
3089 STAT_SERVERSTART
3090
3091 return request.release();
3092 }
3093
3094 CIMAssociatorNamesRequestMessage*
3095 CIMOperationRequestDecoder::decodeAssociatorNamesRequest(
3096 Uint32 queueId,
3097 XmlParser& parser,
3098 const String& messageId,
3099 const CIMNamespaceName& nameSpace)
3100 {
3101 STAT_GETSTARTTIME
3102
|
3103 karl 1.137 objectNameIParam objectName;
3104 classNameIParam assocClass("AssocClass");
3105 classNameIParam resultClass("ResultClass");
3106 stringIParam role("role", false);
3107 stringIParam resultRole("Resultrole", false);
3108
|
3109 kumpf 1.104 Boolean emptyTag;
|
3110 karl 1.137 Boolean duplicateParameter = false;
|
3111 kumpf 1.104
3112 for (const char* name;
3113 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3114 {
|
3115 karl 1.137 if(objectName.get(parser, name, emptyTag))
|
3116 kumpf 1.104 {
|
3117 karl 1.137 objectName.iParamFound(duplicateParameter);
|
3118 kumpf 1.104 }
|
3119 karl 1.137 else if (assocClass.getOptional(parser, name, emptyTag))
|
3120 kumpf 1.104 {
|
3121 karl 1.137 assocClass.iParamFound(duplicateParameter);
|
3122 kumpf 1.104 }
|
3123 karl 1.137 else if (resultClass.getOptional(parser, name, emptyTag))
|
3124 kumpf 1.104 {
|
3125 karl 1.137 resultClass.iParamFound(duplicateParameter);
|
3126 kumpf 1.104 }
|
3127 karl 1.137 else if(role.get(parser, name, emptyTag))
|
3128 kumpf 1.104 {
|
3129 karl 1.137 role.iParamFound(duplicateParameter);
|
3130 kumpf 1.104 }
|
3131 karl 1.137 else if(resultRole.get(parser, name, emptyTag))
|
3132 kumpf 1.104 {
|
3133 karl 1.137 resultRole.iParamFound(duplicateParameter);
|
3134 kumpf 1.104 }
3135 else
3136 {
|
3137 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
3138 kumpf 1.104
3139 }
3140
|
3141 karl 1.137 // generate exception if endtag error or duplicate attributes
3142 _checkMissingEndTagOrDuplicateParamValue(
3143 parser, duplicateParameter, emptyTag);
|
3144 kumpf 1.104 }
3145
|
3146 karl 1.137 _testRequiredParametersExist(objectName.got);
|
3147 kumpf 1.104
3148 AutoPtr<CIMAssociatorNamesRequestMessage> request(
3149 new CIMAssociatorNamesRequestMessage(
3150 messageId,
3151 nameSpace,
|
3152 karl 1.137 objectName.value,
3153 assocClass.value,
3154 resultClass.value,
3155 role.value,
3156 resultRole.value,
|
3157 karl 1.135 QueueIdStack(queueId, _returnQueueId),
|
3158 karl 1.137 objectName.isClassNameElement));
|
3159 kumpf 1.104
3160 STAT_SERVERSTART
3161
3162 return request.release();
3163 }
3164
3165 CIMAssociatorsRequestMessage*
3166 CIMOperationRequestDecoder::decodeAssociatorsRequest(
3167 Uint32 queueId,
3168 XmlParser& parser,
3169 const String& messageId,
3170 const CIMNamespaceName& nameSpace)
3171 {
3172 STAT_GETSTARTTIME
3173
|
3174 karl 1.137 // Associator Operation Parameters
3175 objectNameIParam objectName;
3176 classNameIParam assocClass("AssocClass");
3177 classNameIParam resultClass("ResultClass");
3178 stringIParam resultRole("Resultrole", false);
3179 stringIParam role("role", false);
3180 booleanIParam includeQualifiers("IncludeQualifiers");
3181 booleanIParam includeClassOrigin("IncludeClassOrigin");
3182 propertyListIParam propertyList;
3183
3184 Boolean duplicateParameter = false;
|
3185 kumpf 1.104 Boolean emptyTag;
3186
3187 for (const char* name;
3188 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3189 {
|
3190 karl 1.137 if(objectName.get(parser, name, emptyTag))
|
3191 kumpf 1.104 {
|
3192 karl 1.137 objectName.iParamFound(duplicateParameter);
|
3193 kumpf 1.104 }
|
3194 karl 1.137 else if (assocClass.getOptional(parser, name, emptyTag))
|
3195 kumpf 1.104 {
|
3196 karl 1.137 assocClass.iParamFound(duplicateParameter);
|
3197 kumpf 1.104 }
|
3198 karl 1.137 else if (resultClass.getOptional(parser, name, emptyTag))
|
3199 kumpf 1.104 {
|
3200 karl 1.137 resultClass.iParamFound(duplicateParameter);
|
3201 kumpf 1.104 }
|
3202 karl 1.137 else if(role.get(parser, name, emptyTag))
|
3203 kumpf 1.104 {
|
3204 karl 1.137 role.iParamFound(duplicateParameter);
|
3205 kumpf 1.104 }
|
3206 karl 1.137 else if(resultRole.get(parser, name, emptyTag))
|
3207 kumpf 1.104 {
|
3208 karl 1.137 resultRole.iParamFound(duplicateParameter);
|
3209 kumpf 1.104 }
|
3210 karl 1.137 else if(includeQualifiers.get(parser, name, emptyTag))
|
3211 kumpf 1.104 {
|
3212 karl 1.137 includeQualifiers.iParamFound(duplicateParameter);
|
3213 kumpf 1.104 }
|
3214 karl 1.137 else if(includeClassOrigin.get(parser, name, emptyTag))
|
3215 kumpf 1.104 {
|
3216 karl 1.137 includeClassOrigin.iParamFound(duplicateParameter);
|
3217 kumpf 1.104 }
|
3218 karl 1.137 else if(propertyList.get(parser, name, emptyTag))
|
3219 kumpf 1.104 {
|
3220 karl 1.137 propertyList.iParamFound(duplicateParameter);
|
3221 kumpf 1.104 }
3222 else
3223 {
|
3224 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
3225 kumpf 1.104 }
3226
|
3227 karl 1.137 // generate exception if endtag error or duplicate attributes
3228 _checkMissingEndTagOrDuplicateParamValue(
3229 parser, duplicateParameter, emptyTag);
|
3230 kumpf 1.104 }
3231
|
3232 karl 1.137 _testRequiredParametersExist(objectName.got);
|
3233 kumpf 1.104
3234 AutoPtr<CIMAssociatorsRequestMessage> request(
3235 new CIMAssociatorsRequestMessage(
3236 messageId,
3237 nameSpace,
|
3238 karl 1.137 objectName.value,
3239 assocClass.value,
3240 resultClass.value,
3241 role.value,
3242 resultRole.value,
3243 includeQualifiers.value,
3244 includeClassOrigin.value,
3245 propertyList.value,
|
3246 karl 1.135 QueueIdStack(queueId, _returnQueueId),
|
3247 karl 1.137 objectName.isClassNameElement));
|
3248 kumpf 1.104
3249 STAT_SERVERSTART
3250
3251 return request.release();
3252 }
3253
3254 CIMGetPropertyRequestMessage*
3255 CIMOperationRequestDecoder::decodeGetPropertyRequest(
3256 Uint32 queueId,
3257 XmlParser& parser,
3258 const String& messageId,
3259 const CIMNamespaceName& nameSpace)
3260 {
3261 STAT_GETSTARTTIME
3262
3263 CIMObjectPath instanceName;
3264 String propertyName;
3265 Boolean duplicateParameter = false;
3266 Boolean gotInstanceName = false;
3267 Boolean gotPropertyName = false;
3268 Boolean emptyTag;
3269 kumpf 1.104
3270 for (const char* name;
3271 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3272 {
3273 if (System::strcasecmp(name, "InstanceName") == 0)
3274 {
3275 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
3276 XmlReader::getInstanceNameElement(parser, instanceName);
3277 duplicateParameter = gotInstanceName;
3278 gotInstanceName = true;
3279 }
3280 else if (System::strcasecmp(name, "PropertyName") == 0)
3281 {
3282 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
3283 XmlReader::getStringValueElement(parser, propertyName, true);
3284 duplicateParameter = gotPropertyName;
3285 gotPropertyName = true;
3286 }
3287 else
3288 {
|
3289 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
3290 kumpf 1.104 }
3291
|
3292 karl 1.137 // generate exception if endtag error or duplicate attributes
3293 _checkMissingEndTagOrDuplicateParamValue(
3294 parser, duplicateParameter, emptyTag);
|
3295 kumpf 1.104 }
3296
|
3297 karl 1.137 _testRequiredParametersExist(gotInstanceName && gotPropertyName);
|
3298 kumpf 1.104
3299 AutoPtr<CIMGetPropertyRequestMessage> request(
3300 new CIMGetPropertyRequestMessage(
3301 messageId,
3302 nameSpace,
3303 instanceName,
3304 propertyName,
3305 QueueIdStack(queueId, _returnQueueId)));
3306
3307 STAT_SERVERSTART
3308
3309 return request.release();
3310 }
3311
3312 CIMSetPropertyRequestMessage*
3313 CIMOperationRequestDecoder::decodeSetPropertyRequest(
3314 Uint32 queueId,
3315 XmlParser& parser,
3316 const String& messageId,
3317 const CIMNamespaceName& nameSpace)
3318 {
3319 kumpf 1.104 STAT_GETSTARTTIME
3320
3321 CIMObjectPath instanceName;
3322 String propertyName;
3323 CIMValue propertyValue;
3324 Boolean duplicateParameter = false;
3325 Boolean gotInstanceName = false;
3326 Boolean gotPropertyName = false;
3327 Boolean gotNewValue = false;
3328 Boolean emptyTag;
3329
3330 for (const char* name;
3331 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3332 {
3333 if (System::strcasecmp(name, "InstanceName") == 0)
3334 {
3335 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
3336 XmlReader::getInstanceNameElement(parser, instanceName);
3337 duplicateParameter = gotInstanceName;
3338 gotInstanceName = true;
3339 }
3340 kumpf 1.104 else if (System::strcasecmp(name, "PropertyName") == 0)
3341 {
3342 XmlReader::rejectNullIParamValue(parser, emptyTag, name);
3343 XmlReader::getStringValueElement(parser, propertyName, true);
3344 duplicateParameter = gotPropertyName;
3345 gotPropertyName = true;
3346 }
3347 else if (System::strcasecmp(name, "NewValue") == 0)
3348 {
3349 if (emptyTag || !XmlReader::getPropertyValue(parser, propertyValue))
3350 {
3351 propertyValue.setNullValue(CIMTYPE_STRING, false);
3352 }
3353 duplicateParameter = gotNewValue;
3354 gotNewValue = true;
3355 }
3356 else
3357 {
|
3358 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
3359 kumpf 1.104 }
3360
|
3361 karl 1.137 // generate exception if endtag error or duplicate attributes
3362 _checkMissingEndTagOrDuplicateParamValue(
3363 parser, duplicateParameter, emptyTag);
|
3364 kumpf 1.104 }
3365
|
3366 karl 1.137 _testRequiredParametersExist(gotInstanceName && gotPropertyName);
|
3367 kumpf 1.104
3368 AutoPtr<CIMSetPropertyRequestMessage> request(
3369 new CIMSetPropertyRequestMessage(
3370 messageId,
3371 nameSpace,
3372 instanceName,
3373 propertyName,
3374 propertyValue,
3375 QueueIdStack(queueId, _returnQueueId)));
|
3376 kumpf 1.29
|
3377 kumpf 1.104 STAT_SERVERSTART
|
3378 sage 1.41
|
3379 kumpf 1.104 return request.release();
|
3380 kumpf 1.29 }
3381
3382 CIMExecQueryRequestMessage* CIMOperationRequestDecoder::decodeExecQueryRequest(
|
3383 kumpf 1.104 Uint32 queueId,
3384 XmlParser& parser,
3385 const String& messageId,
3386 const CIMNamespaceName& nameSpace)
3387 {
3388 STAT_GETSTARTTIME
3389
|
3390 karl 1.137 // define execQuery parameters. Values are required parameters exist.
3391 stringIParam queryLanguage("QueryLanguage", true);
3392 stringIParam query("Query", true);
3393
3394 Boolean emptyTag;
|
3395 kumpf 1.104 Boolean duplicateParameter = false;
3396
3397 for (const char* name;
3398 XmlReader::getIParamValueTag(parser, name, emptyTag); )
3399 {
|
3400 karl 1.137 if(queryLanguage.get(parser, name, emptyTag))
|
3401 kumpf 1.104 {
|
3402 karl 1.137 queryLanguage.iParamFound(duplicateParameter);
|
3403 kumpf 1.104 }
|
3404 karl 1.137 else if(query.get(parser, name, emptyTag))
|
3405 kumpf 1.104 {
|
3406 karl 1.137 query.iParamFound(duplicateParameter);
|
3407 kumpf 1.104 }
3408 else
3409 {
|
3410 karl 1.137 _throwCIMExceptionInvalidIParamName();
|
3411 kumpf 1.104 }
3412
|
3413 karl 1.137 // generate exception if endtag error or duplicate attributes
3414 _checkMissingEndTagOrDuplicateParamValue(parser,
3415 duplicateParameter, emptyTag);
|
3416 kumpf 1.104 }
3417
|
3418 karl 1.137 _testRequiredParametersExist(queryLanguage.got && query.got);
|
3419 kumpf 1.104
3420 AutoPtr<CIMExecQueryRequestMessage> request(
3421 new CIMExecQueryRequestMessage(
3422 messageId,
3423 nameSpace,
|
3424 karl 1.137 queryLanguage.value,
3425 query.value,
|
3426 kumpf 1.104 QueueIdStack(queueId, _returnQueueId)));
3427
3428 STAT_SERVERSTART
3429
3430 return request.release();
3431 }
3432
3433 CIMInvokeMethodRequestMessage*
3434 CIMOperationRequestDecoder::decodeInvokeMethodRequest(
3435 Uint32 queueId,
3436 XmlParser& parser,
3437 const String& messageId,
3438 const CIMObjectPath& reference,
3439 const String& cimMethodName)
3440 {
3441 STAT_GETSTARTTIME
3442
3443 CIMParamValue paramValue;
3444 Array<CIMParamValue> inParameters;
3445
3446 while (XmlReader::getParamValueElement(parser, paramValue))
3447 kumpf 1.104 {
3448 inParameters.append(paramValue);
3449 }
3450
3451 AutoPtr<CIMInvokeMethodRequestMessage> request(
3452 new CIMInvokeMethodRequestMessage(
3453 messageId,
3454 reference.getNameSpace(),
3455 reference,
3456 cimMethodName,
3457 inParameters,
3458 QueueIdStack(queueId, _returnQueueId)));
|
3459 kumpf 1.9
|
3460 kumpf 1.104 STAT_SERVERSTART
|
3461 mike 1.2
|
3462 kumpf 1.104 return request.release();
|
3463 mike 1.2 }
3464
3465 void CIMOperationRequestDecoder::setServerTerminating(Boolean flag)
3466 {
|
3467 kumpf 1.104 _serverTerminating = flag;
|
3468 mike 1.2 }
3469
3470 PEGASUS_NAMESPACE_END
|