//%LICENSE//////////////////////////////////////////////////////////////// // // Licensed to The Open Group (TOG) under one or more contributor license // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with // this work for additional information regarding copyright ownership. // Each contributor licenses this file to you under the OpenPegasus Open // Source License; you may not use this file except in compliance with the // License. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ////////////////////////////////////////////////////////////////////////// // //%///////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include "CIMOperationRequestDecoder.h" #include #include #include PEGASUS_USING_STD; PEGASUS_NAMESPACE_BEGIN CIMOperationRequestDecoder::CIMOperationRequestDecoder( MessageQueue* outputQueue, Uint32 returnQueueId) : Base(PEGASUS_QUEUENAME_OPREQDECODER), _outputQueue(outputQueue), _returnQueueId(returnQueueId), _serverTerminating(false) { } CIMOperationRequestDecoder::~CIMOperationRequestDecoder() { } void CIMOperationRequestDecoder::sendResponse( Uint32 queueId, Buffer& message, Boolean closeConnect) { MessageQueue* queue = MessageQueue::lookup(queueId); if (queue) { AutoPtr httpMessage(new HTTPMessage(message)); httpMessage->setCloseConnect(closeConnect); queue->enqueue(httpMessage.release()); } } void CIMOperationRequestDecoder::sendIMethodError( Uint32 queueId, HttpMethod httpMethod, const String& messageId, const String& iMethodName, const CIMException& cimException, Boolean closeConnect) { Buffer message; message = XmlWriter::formatSimpleIMethodErrorRspMessage( iMethodName, messageId, httpMethod, cimException); sendResponse(queueId, message,closeConnect); } void CIMOperationRequestDecoder::sendMethodError( Uint32 queueId, HttpMethod httpMethod, const String& messageId, const String& methodName, const CIMException& cimException, Boolean closeConnect) { Buffer message; message = XmlWriter::formatSimpleMethodErrorRspMessage( methodName, messageId, httpMethod, cimException); sendResponse(queueId, message,closeConnect); } void CIMOperationRequestDecoder::sendHttpError( Uint32 queueId, const String& status, const String& cimError, const String& pegasusError, Boolean closeConnect) { Buffer message; message = XmlWriter::formatHttpErrorRspMessage( status, cimError, pegasusError); sendResponse(queueId, message,closeConnect); } void CIMOperationRequestDecoder::handleEnqueue(Message* message) { if (!message) return; switch (message->getType()) { case HTTP_MESSAGE: handleHTTPMessage((HTTPMessage*)message); break; default: // Unexpected message type PEGASUS_ASSERT(0); break; } delete message; } void CIMOperationRequestDecoder::handleEnqueue() { Message* message = dequeue(); if (message) handleEnqueue(message); } //------------------------------------------------------------------------------ // // From the HTTP/1.1 Specification (RFC 2626): // // Both types of message consist of a start-line, zero or more header fields // (also known as "headers"), an empty line (i.e., a line with nothing // preceding the CRLF) indicating the end of the header fields, and possibly // a message-body. // // Example CIM request: // // M-POST /cimom HTTP/1.1 // HOST: www.erewhon.com // Content-Type: application/xml; charset="utf-8" // Content-Length: xxxx // Man: http://www.dmtf.org/cim/operation ; ns=73 // 73-CIMOperation: MethodCall // 73-CIMMethod: EnumerateInstances // 73-CIMObject: root/cimv2 // //------------------------------------------------------------------------------ void CIMOperationRequestDecoder::handleHTTPMessage(HTTPMessage* httpMessage) { PEG_METHOD_ENTER(TRC_DISPATCHER, "CIMOperationRequestDecoder::handleHTTPMessage()"); // Set the Accept-Language into the thread for this service. // This will allow all code in this thread to get // the languages for the messages returned to the client. Thread::setLanguages(httpMessage->acceptLanguages); // Save queueId: Uint32 queueId = httpMessage->queueId; // Save userName and authType: String userName; String authType; Boolean closeConnect = httpMessage->getCloseConnect(); PEG_TRACE(( TRC_HTTP, Tracer::LEVEL4, "CIMOperationRequestDecoder::handleHTTPMessage()- " "httpMessage->getCloseConnect() returned %d", closeConnect)); userName = httpMessage->authInfo->getAuthenticatedUser(); authType = httpMessage->authInfo->getAuthType(); // Parse the HTTP message: String startLine; Array headers; char* content; Uint32 contentLength; httpMessage->parse(startLine, headers, contentLength); // Parse the request line: String methodName; String requestUri; String httpVersion; HttpMethod httpMethod = HTTP_METHOD__POST; HTTPMessage::parseRequestLine( startLine, methodName, requestUri, httpVersion); // // Set HTTP method for the request // if (methodName == "M-POST") { httpMethod = HTTP_METHOD_M_POST; } // Unsupported methods are caught in the HTTPAuthenticatorDelegator PEGASUS_ASSERT(methodName == "M-POST" || methodName == "POST"); // // Mismatch of method and version is caught in HTTPAuthenticatorDelegator // PEGASUS_ASSERT(!((httpMethod == HTTP_METHOD_M_POST) && (httpVersion == "HTTP/1.0"))); // Process M-POST and POST messages: if (httpVersion == "HTTP/1.1") { // Validate the presence of a "Host" header. The HTTP/1.1 specification // says this in section 14.23 regarding the Host header field: // // All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad // Request) status code to any HTTP/1.1 request message which lacks // a Host header field. // // Note: The Host header value is not validated. const char* hostHeader; Boolean hostHeaderFound = HTTPMessage::lookupHeader( headers, "Host", hostHeader, false); if (!hostHeaderFound) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder.MISSING_HOST_HEADER", "HTTP request message lacks a Host header field."); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } } // Validate the "CIMOperation" header: const char* cimOperation; Boolean operationHeaderFound = HTTPMessage::lookupHeader( headers, "CIMOperation", cimOperation, true); // If the CIMOperation header was missing, the HTTPAuthenticatorDelegator // would not have passed the message to us. PEGASUS_ASSERT(operationHeaderFound); if (System::strcasecmp(cimOperation, "MethodCall") != 0) { // The Specification for CIM Operations over HTTP reads: // 3.3.4. CIMOperation // If a CIM Server receives CIM Operation request with this // [CIMOperation] header, but with a missing value or a value // that is not "MethodCall", then it MUST fail the request with // status "400 Bad Request". The CIM Server MUST include a // CIMError header in the response with a value of // unsupported-operation. MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "CIMOPERATION_VALUE_NOT_SUPPORTED", "CIMOperation value \"$0\" is not supported.",cimOperation); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "unsupported-operation", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } // Validate the "CIMBatch" header: const char* cimBatch; if (HTTPMessage::lookupHeader(headers, "CIMBatch", cimBatch, true)) { // The Specification for CIM Operations over HTTP reads: // 3.3.9. CIMBatch // If a CIM Server receives CIM Operation Request for which the // CIMBatch header is present, but the Server does not support // Multiple Operations, then it MUST fail the request and // return a status of "501 Not Implemented". sendHttpError( queueId, HTTP_STATUS_NOTIMPLEMENTED, "multiple-requests-unsupported", String::EMPTY, closeConnect); PEG_METHOD_EXIT(); return; } // Save these headers for later checking const char* cimProtocolVersion; if (!HTTPMessage::lookupHeader( headers, "CIMProtocolVersion", cimProtocolVersion, true)) { // Mandated by the Specification for CIM Operations over HTTP cimProtocolVersion = "1.0"; } String cimMethod; if (HTTPMessage::lookupHeader(headers, "CIMMethod", cimMethod, true)) { if (cimMethod == String::EMPTY) { // This is not a valid value, and we use EMPTY to mean "absent" MessageLoaderParms parms( "Server.CIMOperationRequestDecoder.EMPTY_CIMMETHOD_VALUE", "Empty CIMMethod value."); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } try { cimMethod = XmlReader::decodeURICharacters(cimMethod); } catch (const ParseError&) { // The CIMMethod header value could not be decoded MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "CIMMETHOD_VALUE_SYNTAX_ERROR", "CIMMethod value syntax error."); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } } String cimObject; if (HTTPMessage::lookupHeader(headers, "CIMObject", cimObject, true)) { if (cimObject == String::EMPTY) { // This is not a valid value, and we use EMPTY to mean "absent" MessageLoaderParms parms( "Server.CIMOperationRequestDecoder.EMPTY_CIMOBJECT_VALUE", "Empty CIMObject value."); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } try { cimObject = XmlReader::decodeURICharacters(cimObject); } catch (const ParseError&) { // The CIMObject header value could not be decoded MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "CIMOBJECT_VALUE_SYNTAX_ERROR", "CIMObject value syntax error."); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } } // Validate the "Content-Type" header: const char* cimContentType; Boolean contentTypeHeaderFound = HTTPMessage::lookupHeader( headers, "Content-Type", cimContentType, true); String type; String charset; Boolean binaryRequest = false; if (!contentTypeHeaderFound || !HTTPMessage::parseContentTypeHeader(cimContentType, type, charset) || (((!String::equalNoCase(type, "application/xml") && !String::equalNoCase(type, "text/xml")) || !String::equalNoCase(charset, "utf-8")) && !(binaryRequest = String::equalNoCase(type, "application/x-openpegasus")) )) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder.CIMCONTENTTYPE_SYNTAX_ERROR", "HTTP Content-Type header error."); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } // Calculate the beginning of the content from the message size and // the content length. if (binaryRequest) { // binary the "Content" also contains a few padding '\0' to align // data structures to 8byte boundary // the padding '\0' are also part of the counted contentLength Uint32 headerEnd = httpMessage->message.size() - contentLength; Uint32 binContentStart = CIMBuffer::round(headerEnd); contentLength = contentLength - (binContentStart - headerEnd); content = (char*) httpMessage->message.getData() + binContentStart; } else { content = (char*) httpMessage->message.getData() + httpMessage->message.size() - contentLength; } // Validating content falls within UTF8 // (required to be complaint with section C12 of Unicode 4.0 spec, // chapter 3.) if (!binaryRequest) { Uint32 count = 0; while(countbinaryResponse=binaryResponse; // If it is a method call, then dispatch it to be handled: handleMethodCall( queueId, httpMethod, content, contentLength, cimProtocolVersion, cimMethod, cimObject, authType, userName, httpMessage->ipAddress, httpMessage->acceptLanguages, httpMessage->contentLanguages, closeConnect, binaryRequest, binaryResponse); PEG_METHOD_EXIT(); } void CIMOperationRequestDecoder::handleMethodCall( Uint32 queueId, HttpMethod httpMethod, char* content, Uint32 contentLength, // used for statistics only const char* cimProtocolVersionInHeader, const String& cimMethodInHeader, const String& cimObjectInHeader, const String& authType, const String& userName, const String& ipAddress, const AcceptLanguageList& httpAcceptLanguages, const ContentLanguageList& httpContentLanguages, Boolean closeConnect, Boolean binaryRequest, Boolean binaryResponse) { PEG_METHOD_ENTER(TRC_DISPATCHER, "CIMOperationRequestDecoder::handleMethodCall()"); // // If CIMOM is shutting down, return "Service Unavailable" response // if (_serverTerminating) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder.CIMSERVER_SHUTTING_DOWN", "CIM Server is shutting down."); sendHttpError( queueId, HTTP_STATUS_SERVICEUNAVAILABLE, String::EMPTY, MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } PEG_TRACE((TRC_XML,Tracer::LEVEL4, "CIMOperationRequestdecoder - XML content: %s", content)); // // Handle binary messages: // AutoPtr request; if (binaryRequest) { CIMBuffer buf(content, contentLength); CIMBufferReleaser buf_(buf); request.reset(BinaryCodec::decodeRequest(buf, queueId, _returnQueueId)); if (!request.get()) { sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "Corrupt binary request message", String::EMPTY, closeConnect); PEG_METHOD_EXIT(); return; } } else try { XmlParser parser(content); XmlEntry entry; String messageId; const char* cimMethodName = ""; // // Process // // These values are currently unused const char* xmlVersion = 0; const char* xmlEncoding = 0; XmlReader::getXmlDeclaration(parser, xmlVersion, xmlEncoding); // Expect const char* cimVersion = 0; const char* dtdVersion = 0; XmlReader::getCimStartTag(parser, cimVersion, dtdVersion); if (!XmlReader::isSupportedCIMVersion(cimVersion)) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder.CIM_VERSION_NOT_SUPPORTED", "CIM version \"$0\" is not supported.", cimVersion); sendHttpError( queueId, HTTP_STATUS_NOTIMPLEMENTED, "unsupported-cim-version", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } if (!XmlReader::isSupportedDTDVersion(dtdVersion)) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder.DTD_VERSION_NOT_SUPPORTED", "DTD version \"$0\" is not supported.", dtdVersion); sendHttpError( queueId, HTTP_STATUS_NOTIMPLEMENTED, "unsupported-dtd-version", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } // Expect String protocolVersion; if (!XmlReader::getMessageStartTag( parser, messageId, protocolVersion)) { MessageLoaderParms mlParms( "Server.CIMOperationRequestDecoder.EXPECTED_MESSAGE_ELEMENT", "expected MESSAGE element"); throw XmlValidationError(parser.getLine(), mlParms); } // Validate that the protocol version in the header matches the XML if (!String::equalNoCase(protocolVersion, cimProtocolVersionInHeader)) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "CIMPROTOCOL_VERSION_MISMATCH", "CIMProtocolVersion value \"$0\" does not match CIM request " "protocol version \"$1\".", cimProtocolVersionInHeader, protocolVersion); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } // Accept protocol version 1.x (see Bugzilla 1556) if (!XmlReader::isSupportedProtocolVersion(protocolVersion)) { // See Specification for CIM Operations over HTTP section 4.3 MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "CIMPROTOCOL_VERSION_NOT_SUPPORTED", "CIMProtocolVersion \"$0\" is not supported.", protocolVersion); sendHttpError( queueId, HTTP_STATUS_NOTIMPLEMENTED, "unsupported-protocol-version", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } if (XmlReader::testStartTag(parser, entry, "MULTIREQ")) { // We wouldn't have gotten here if CIMBatch header was specified, // so this must be indicative of a header mismatch MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "MULTI_REQUEST_MISSING_CIMBATCH_HTTP_HEADER", "Multi-request is missing CIMBatch HTTP header"); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; // Future: When MULTIREQ is supported, must ensure CIMMethod and // CIMObject headers are absent, and CIMBatch header is present. } // Expect XmlReader::expectStartTag(parser, entry, "SIMPLEREQ"); // Check for if (XmlReader::getIMethodCallStartTag(parser, cimMethodName)) { // The Specification for CIM Operations over HTTP reads: // 3.3.6. CIMMethod // // This header MUST be present in any CIM Operation Request // message that contains a Simple Operation Request. // // It MUST NOT be present in any CIM Operation Response message, // nor in any CIM Operation Request message that is not a // Simple Operation Request. // // The name of the CIM method within a Simple Operation Request // is defined to be the value of the NAME attribute of the // or element. // // If a CIM Server receives a CIM Operation Request for which // either: // // - The CIMMethod header is present but has an invalid value, // or; // - The CIMMethod header is not present but the Operation // Request Message is a Simple Operation Request, or; // - The CIMMethod header is present but the Operation Request // Message is not a Simple Operation Request, or; // - The CIMMethod header is present, the Operation Request // Message is a Simple Operation Request, but the // CIMIdentifier value (when unencoded) does not match the // unique method name within the Simple Operation Request, // // then it MUST fail the request and return a status of // "400 Bad Request" (and MUST include a CIMError header in the // response with a value of header-mismatch), subject to the // considerations specified in Errors. if (!String::equalNoCase(cimMethodName, cimMethodInHeader)) { // ATTN-RK-P3-20020304: How to decode cimMethodInHeader? if (cimMethodInHeader == String::EMPTY) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "MISSING_CIMMETHOD_HTTP_HEADER", "Missing CIMMethod HTTP header."); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); } else { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "CIMMETHOD_VALUE_DOES_NOT_MATCH_REQUEST_METHOD", "CIMMethod value \"$0\" does not match CIM request " "method \"$1\".", cimMethodInHeader, cimMethodName); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); } PEG_METHOD_EXIT(); return; } // Expect String nameSpace; if (!XmlReader::getLocalNameSpacePathElement(parser, nameSpace)) { MessageLoaderParms mlParms( "Server.CIMOperationRequestDecoder." "EXPECTED_LOCALNAMESPACEPATH_ELEMENT", "expected LOCALNAMESPACEPATH element"); throw XmlValidationError(parser.getLine(), mlParms); } // The Specification for CIM Operations over HTTP reads: // 3.3.7. CIMObject // // This header MUST be present in any CIM Operation Request // message that contains a Simple Operation Request. // // It MUST NOT be present in any CIM Operation Response message, // nor in any CIM Operation Request message that is not a // Simple Operation Request. // // The header identifies the CIM object (which MUST be a Class // or Instance for an extrinsic method, or a Namespace for an // intrinsic method) on which the method is to be invoked, using // a CIM object path encoded in an HTTP-safe representation. // // If a CIM Server receives a CIM Operation Request for which // either: // // - The CIMObject header is present but has an invalid value, // or; // - The CIMObject header is not present but the Operation // Request Message is a Simple Operation Request, or; // - The CIMObject header is present but the Operation Request // Message is not a Simple Operation Request, or; // - The CIMObject header is present, the Operation Request // Message is a Simple Operation Request, but the ObjectPath // value does not match (where match is defined in the section // section on Encoding CIM Object Paths) the Operation Request // Message, // // then it MUST fail the request and return a status of // "400 Bad Request" (and MUST include a CIMError header in the // response with a value of header-mismatch), subject to the // considerations specified in Errors. if (!String::equalNoCase(nameSpace, cimObjectInHeader)) { if (cimObjectInHeader == String::EMPTY) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "MISSING_CIMOBJECT_HTTP_HEADER", "Missing CIMObject HTTP header."); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); } else { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "CIMOBJECT_VALUE_DOES_NOT_MATCH_REQUEST_OBJECT", "CIMObject value \"$0\" does not match CIM request " "object \"$1\".", cimObjectInHeader, nameSpace); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); } PEG_METHOD_EXIT(); return; } // This try block only catches CIMExceptions, because they must be // responded to with a proper IMETHODRESPONSE. Other exceptions are // caught in the outer try block. try { // Delegate to appropriate method to handle: if (System::strcasecmp(cimMethodName, "GetClass") == 0) request.reset(decodeGetClassRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp(cimMethodName, "GetInstance") == 0) request.reset(decodeGetInstanceRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp( cimMethodName, "EnumerateClassNames") == 0) request.reset(decodeEnumerateClassNamesRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp(cimMethodName, "References") == 0) request.reset(decodeReferencesRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp( cimMethodName, "ReferenceNames") == 0) request.reset(decodeReferenceNamesRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp( cimMethodName, "AssociatorNames") == 0) request.reset(decodeAssociatorNamesRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp(cimMethodName, "Associators") == 0) request.reset(decodeAssociatorsRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp( cimMethodName, "CreateInstance") == 0) request.reset(decodeCreateInstanceRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp( cimMethodName, "EnumerateInstanceNames")==0) request.reset(decodeEnumerateInstanceNamesRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp( cimMethodName, "DeleteQualifier") == 0) request.reset(decodeDeleteQualifierRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp(cimMethodName, "GetQualifier") == 0) request.reset(decodeGetQualifierRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp(cimMethodName, "SetQualifier") == 0) request.reset(decodeSetQualifierRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp( cimMethodName, "EnumerateQualifiers") == 0) request.reset(decodeEnumerateQualifiersRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp( cimMethodName, "EnumerateClasses") == 0) request.reset(decodeEnumerateClassesRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp( cimMethodName, "EnumerateInstances") == 0) request.reset(decodeEnumerateInstancesRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp(cimMethodName, "CreateClass") == 0) request.reset(decodeCreateClassRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp(cimMethodName, "ModifyClass") == 0) request.reset(decodeModifyClassRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp( cimMethodName, "ModifyInstance") == 0) request.reset(decodeModifyInstanceRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp(cimMethodName, "DeleteClass") == 0) request.reset(decodeDeleteClassRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp( cimMethodName, "DeleteInstance") == 0) request.reset(decodeDeleteInstanceRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp(cimMethodName, "GetProperty") == 0) request.reset(decodeGetPropertyRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp(cimMethodName, "SetProperty") == 0) request.reset(decodeSetPropertyRequest( queueId, parser, messageId, nameSpace)); else if (System::strcasecmp(cimMethodName, "ExecQuery") == 0) request.reset(decodeExecQueryRequest( queueId, parser, messageId, nameSpace)); else { throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED, MessageLoaderParms( "Server.CIMOperationRequestDecoder." "UNRECOGNIZED_INTRINSIC_METHOD", "Unrecognized intrinsic method: $0", cimMethodName)); } } catch (CIMException& e) { sendIMethodError( queueId, httpMethod, messageId, cimMethodName, e, closeConnect); PEG_METHOD_EXIT(); return; } catch (XmlException&) { // XmlExceptions are handled below throw; } catch (Exception& e) { // Caught an unexpected exception from decoding. Since we must // have had a problem reconstructing a CIM object, we'll treat // it as an invalid parameter sendIMethodError( queueId, httpMethod, messageId, cimMethodName, PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, e.getMessage()), closeConnect); PEG_METHOD_EXIT(); return; } // Expect XmlReader::expectEndTag(parser, "IMETHODCALL"); } // Expect else if (XmlReader::getMethodCallStartTag(parser, cimMethodName)) { CIMObjectPath reference; // The Specification for CIM Operations over HTTP reads: // 3.3.6. CIMMethod // // This header MUST be present in any CIM Operation Request // message that contains a Simple Operation Request. // // It MUST NOT be present in any CIM Operation Response message, // nor in any CIM Operation Request message that is not a // Simple Operation Request. // // The name of the CIM method within a Simple Operation Request // is defined to be the value of the NAME attribute of the // or element. // // If a CIM Server receives a CIM Operation Request for which // either: // // - The CIMMethod header is present but has an invalid value, // or; // - The CIMMethod header is not present but the Operation // Request Message is a Simple Operation Request, or; // - The CIMMethod header is present but the Operation Request // Message is not a Simple Operation Request, or; // - The CIMMethod header is present, the Operation Request // Message is a Simple Operation Request, but the // CIMIdentifier value (when unencoded) does not match the // unique method name within the Simple Operation Request, // // then it MUST fail the request and return a status of // "400 Bad Request" (and MUST include a CIMError header in the // response with a value of header-mismatch), subject to the // considerations specified in Errors. // Extrinic methods can have UTF-8! String cimMethodNameUTF16(cimMethodName); if (cimMethodNameUTF16 != cimMethodInHeader) { // ATTN-RK-P3-20020304: How to decode cimMethodInHeader? if (cimMethodInHeader == String::EMPTY) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "MISSING_CIMMETHOD_HTTP_HEADER", "Missing CIMMethod HTTP header."); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); } else { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "CIMMETHOD_VALUE_DOES_NOT_MATCH_REQUEST_METHOD", "CIMMethod value \"$0\" does not match CIM request " "method \"$1\".", (const char*)cimMethodInHeader.getCString(), cimMethodName); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); } PEG_METHOD_EXIT(); return; } // // Check for or // if (!(XmlReader::getLocalInstancePathElement(parser, reference) || XmlReader::getLocalClassPathElement(parser, reference))) { MessageLoaderParms parms( "Common.XmlConstants.MISSING_ELEMENT_LOCALPATH", MISSING_ELEMENT_LOCALPATH); // this throw is not updated with MLP because // MISSING_ELEMENT_LOCALPATH is a hardcoded variable, // not a message throw XmlValidationError(parser.getLine(), parms); } // The Specification for CIM Operations over HTTP reads: // 3.3.7. CIMObject // // This header MUST be present in any CIM Operation Request // message that contains a Simple Operation Request. // // It MUST NOT be present in any CIM Operation Response message, // nor in any CIM Operation Request message that is not a // Simple Operation Request. // // The header identifies the CIM object (which MUST be a Class // or Instance for an extrinsic method, or a Namespace for an // intrinsic method) on which the method is to be invoked, using // a CIM object path encoded in an HTTP-safe representation. // // If a CIM Server receives a CIM Operation Request for which // either: // // - The CIMObject header is present but has an invalid value, // or; // - The CIMObject header is not present but the Operation // Request Message is a Simple Operation Request, or; // - The CIMObject header is present but the Operation Request // Message is not a Simple Operation Request, or; // - The CIMObject header is present, the Operation Request // Message is a Simple Operation Request, but the ObjectPath // value does not match (where match is defined in the section // section on Encoding CIM Object Paths) the Operation Request // Message, // // then it MUST fail the request and return a status of // "400 Bad Request" (and MUST include a CIMError header in the // response with a value of header-mismatch), subject to the // considerations specified in Errors. if (cimObjectInHeader == String::EMPTY) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "MISSING_CIMOBJECT_HTTP_HEADER", "Missing CIMObject HTTP header."); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } CIMObjectPath headerObjectReference; try { headerObjectReference.set(cimObjectInHeader); } catch (Exception&) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "COULD_NOT_PARSE_CIMOBJECT_VALUE", "Could not parse CIMObject value \"$0\".", cimObjectInHeader); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } if (!reference.identical(headerObjectReference)) { MessageLoaderParms parms( "Server.CIMOperationRequestDecoder." "CIMOBJECT_VALUE_DOES_NOT_MATCH_REQUEST_OBJECT", "CIMObject value \"$0\" does not match CIM request " "object \"$1\".", cimObjectInHeader, reference.toString()); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "header-mismatch", MessageLoader::getMessage(parms), closeConnect); PEG_METHOD_EXIT(); return; } // This try block only catches CIMExceptions, because they must be // responded to with a proper METHODRESPONSE. Other exceptions are // caught in the outer try block. try { // Delegate to appropriate method to handle: request.reset(decodeInvokeMethodRequest( queueId, parser, messageId, reference, cimMethodNameUTF16)); // contains UTF-16 converted from UTF-8 } catch (CIMException& e) { sendMethodError( queueId, httpMethod, messageId, cimMethodNameUTF16, // contains UTF-16 converted from UTF-8 e, closeConnect); PEG_METHOD_EXIT(); return; } catch (XmlException&) { // XmlExceptions are handled below throw; } catch (Exception& e) { // Caught an unexpected exception from decoding. Since we must // have had a problem reconstructing a CIM object, we'll treata // it as an invalid parameter sendMethodError( queueId, httpMethod, messageId, cimMethodNameUTF16, // contains UTF-16 converted from UTF-8 PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, e.getMessage()), closeConnect); PEG_METHOD_EXIT(); return; } // Expect XmlReader::expectEndTag(parser, "METHODCALL"); } else { MessageLoaderParms mlParms( "Server.CIMOperationRequestDecoder.EXPECTED_IMETHODCALL_ELEMENT", "expected IMETHODCALL or METHODCALL element"); throw XmlValidationError(parser.getLine(),mlParms); } // Expect XmlReader::expectEndTag(parser, "SIMPLEREQ"); // Expect XmlReader::expectEndTag(parser, "MESSAGE"); // Expect XmlReader::expectEndTag(parser, "CIM"); } catch (XmlValidationError& e) { PEG_TRACE((TRC_XML,Tracer::LEVEL1, "CIMOperationRequestDecoder::handleMethodCall - " "XmlValidationError exception has occurred. Message: %s", (const char*) e.getMessage().getCString())); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "request-not-valid", e.getMessage(), closeConnect); PEG_METHOD_EXIT(); return; } catch (XmlSemanticError& e) { PEG_TRACE((TRC_XML,Tracer::LEVEL1, "CIMOperationRequestDecoder::handleMethodCall - " "XmlSemanticError exception has occurred. Message: %s", (const char*) e.getMessage().getCString())); // ATTN-RK-P2-20020404: Is this the correct response for these errors? sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "request-not-valid", e.getMessage(), closeConnect); PEG_METHOD_EXIT(); return; } catch (XmlException& e) { PEG_TRACE((TRC_XML,Tracer::LEVEL1, "CIMOperationRequestDecoder::handleMethodCall - " "XmlException has occurred. Message: %s", (const char*) e.getMessage().getCString())); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "request-not-well-formed", e.getMessage(), closeConnect); PEG_METHOD_EXIT(); return; } catch (TooManyElementsException& e) { PEG_TRACE((TRC_XML,Tracer::LEVEL1, "CIMOperationRequestDecoder::handleMethodCall - " "TooManyElementsException has occurred. Message: %s", (const char*) e.getMessage().getCString())); sendHttpError( queueId, HTTP_STATUS_BADREQUEST, "request-with-too-many-elements", e.getMessage(), closeConnect); PEG_METHOD_EXIT(); return; } catch (Exception& e) { // Don't know why I got this exception. Seems like a bad thing. // Any exceptions we're expecting should be caught separately and // dealt with appropriately. This is a last resort. sendHttpError( queueId, HTTP_STATUS_INTERNALSERVERERROR, String::EMPTY, e.getMessage(), closeConnect); PEG_METHOD_EXIT(); return; } catch (...) { // Don't know why I got whatever this is. Seems like a bad thing. // Any exceptions we're expecting should be caught separately and // dealt with appropriately. This is a last resort. sendHttpError( queueId, HTTP_STATUS_INTERNALSERVERERROR, String::EMPTY, String::EMPTY, closeConnect); PEG_METHOD_EXIT(); return; } STAT_BYTESREAD request->authType = authType; request->userName = userName; request->ipAddress = ipAddress; request->setHttpMethod (httpMethod); request->binaryResponse = binaryResponse; //l10n start // l10n TODO - might want to move A-L and C-L to Message // to make this more maintainable // Add the language headers to the request CIMMessage* cimmsg = dynamic_cast(request.get()); if (cimmsg != NULL) { cimmsg->operationContext.insert(IdentityContainer(userName)); cimmsg->operationContext.set( AcceptLanguageListContainer(httpAcceptLanguages)); cimmsg->operationContext.set( ContentLanguageListContainer(httpContentLanguages)); } else { ; // l10n TODO - error back to client here } // l10n end request->setCloseConnect(closeConnect); _outputQueue->enqueue(request.release()); PEG_METHOD_EXIT(); } CIMCreateClassRequestMessage* CIMOperationRequestDecoder::decodeCreateClassRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { PEG_METHOD_ENTER(TRC_DISPATCHER, "CIMOperationRequestDecoder::decodeCreateClassRequest()"); STAT_GETSTARTTIME CIMClass newClass; Boolean duplicateParameter = false; Boolean gotClass = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "NewClass") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); if (!XmlReader::getClassElement(parser, newClass)) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, "NewClass"); } duplicateParameter = gotClass; gotClass = true; } else { PEG_METHOD_EXIT(); throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { PEG_METHOD_EXIT(); throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotClass) { PEG_METHOD_EXIT(); throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMCreateClassRequestMessage( messageId, nameSpace, newClass, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART PEG_METHOD_EXIT(); return request.release(); } CIMGetClassRequestMessage* CIMOperationRequestDecoder::decodeGetClassRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { PEG_METHOD_ENTER(TRC_DISPATCHER, "CIMOperationRequestDecoder::decodeGetClassRequest()"); STAT_GETSTARTTIME CIMName className; Boolean localOnly = true; Boolean includeQualifiers = true; Boolean includeClassOrigin = false; CIMPropertyList propertyList; Boolean duplicateParameter = false; Boolean gotClassName = false; Boolean gotLocalOnly = false; Boolean gotIncludeQualifiers = false; Boolean gotIncludeClassOrigin = false; Boolean gotPropertyList = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ClassName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getClassNameElement(parser, className, true); duplicateParameter = gotClassName; gotClassName = true; } else if (System::strcasecmp(name, "LocalOnly") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, localOnly, true); duplicateParameter = gotLocalOnly; gotLocalOnly = true; } else if (System::strcasecmp(name, "IncludeQualifiers") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeQualifiers, true); duplicateParameter = gotIncludeQualifiers; gotIncludeQualifiers = true; } else if (System::strcasecmp(name, "IncludeClassOrigin") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeClassOrigin, true); duplicateParameter = gotIncludeClassOrigin; gotIncludeClassOrigin = true; } else if (System::strcasecmp(name, "PropertyList") == 0) { if (!emptyTag) { CIMValue pl; if (XmlReader::getValueArrayElement(parser, CIMTYPE_STRING, pl)) { Array propertyListArray; pl.get(propertyListArray); Array cimNameArray; for (Uint32 i = 0; i < propertyListArray.size(); i++) { cimNameArray.append(propertyListArray[i]); } propertyList.set(cimNameArray); } } duplicateParameter = gotPropertyList; gotPropertyList = true; } else { PEG_METHOD_EXIT(); throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { PEG_METHOD_EXIT(); throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotClassName) { PEG_METHOD_EXIT(); throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request(new CIMGetClassRequestMessage( messageId, nameSpace, className, localOnly, includeQualifiers, includeClassOrigin, propertyList, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART PEG_METHOD_EXIT(); return request.release(); } CIMModifyClassRequestMessage* CIMOperationRequestDecoder::decodeModifyClassRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMClass modifiedClass; Boolean duplicateParameter = false; Boolean gotClass = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ModifiedClass") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); if (!XmlReader::getClassElement(parser, modifiedClass)) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, "ModifiedClass"); } duplicateParameter = gotClass; gotClass = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotClass) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMModifyClassRequestMessage( messageId, nameSpace, modifiedClass, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMEnumerateClassNamesRequestMessage* CIMOperationRequestDecoder::decodeEnumerateClassNamesRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMName className; Boolean deepInheritance = false; Boolean duplicateParameter = false; Boolean gotClassName = false; Boolean gotDeepInheritance = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ClassName") == 0) { // // ClassName may be NULL // if (!emptyTag) { XmlReader::getClassNameElement(parser, className, false); } duplicateParameter = gotClassName; gotClassName = true; } else if (System::strcasecmp(name, "DeepInheritance") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, deepInheritance, true); duplicateParameter = gotDeepInheritance; gotDeepInheritance = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } AutoPtr request( new CIMEnumerateClassNamesRequestMessage( messageId, nameSpace, className, deepInheritance, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMEnumerateClassesRequestMessage* CIMOperationRequestDecoder::decodeEnumerateClassesRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMName className; Boolean deepInheritance = false; Boolean localOnly = true; Boolean includeQualifiers = true; Boolean includeClassOrigin = false; Boolean duplicateParameter = false; Boolean gotClassName = false; Boolean gotDeepInheritance = false; Boolean gotLocalOnly = false; Boolean gotIncludeQualifiers = false; Boolean gotIncludeClassOrigin = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ClassName") == 0) { // // ClassName may be NULL // if (!emptyTag) { XmlReader::getClassNameElement(parser, className, false); } duplicateParameter = gotClassName; gotClassName = true; } else if (System::strcasecmp(name, "DeepInheritance") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, deepInheritance, true); duplicateParameter = gotDeepInheritance; gotDeepInheritance = true; } else if (System::strcasecmp(name, "LocalOnly") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, localOnly, true); duplicateParameter = gotLocalOnly; gotLocalOnly = true; } else if (System::strcasecmp(name, "IncludeQualifiers") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeQualifiers, true); duplicateParameter = gotIncludeQualifiers; gotIncludeQualifiers = true; } else if (System::strcasecmp(name, "IncludeClassOrigin") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeClassOrigin, true); duplicateParameter = gotIncludeClassOrigin; gotIncludeClassOrigin = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } AutoPtr request( new CIMEnumerateClassesRequestMessage( messageId, nameSpace, className, deepInheritance, localOnly, includeQualifiers, includeClassOrigin, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMDeleteClassRequestMessage* CIMOperationRequestDecoder::decodeDeleteClassRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMName className; Boolean duplicateParameter = false; Boolean gotClassName = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ClassName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getClassNameElement(parser, className); duplicateParameter = gotClassName; gotClassName = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotClassName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMDeleteClassRequestMessage( messageId, nameSpace, className, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMCreateInstanceRequestMessage* CIMOperationRequestDecoder::decodeCreateInstanceRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMInstance newInstance; Boolean duplicateParameter = false; Boolean gotInstance = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "NewInstance") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getInstanceElement(parser, newInstance); duplicateParameter = gotInstance; gotInstance = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotInstance) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMCreateInstanceRequestMessage( messageId, nameSpace, newInstance, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMGetInstanceRequestMessage* CIMOperationRequestDecoder::decodeGetInstanceRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMObjectPath instanceName; Boolean includeQualifiers = false; Boolean includeClassOrigin = false; CIMPropertyList propertyList; Boolean duplicateParameter = false; Boolean gotInstanceName = false; Boolean gotLocalOnly = false; Boolean gotIncludeQualifiers = false; Boolean gotIncludeClassOrigin = false; Boolean gotPropertyList = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "InstanceName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getInstanceNameElement(parser, instanceName); duplicateParameter = gotInstanceName; gotInstanceName = true; } else if (System::strcasecmp(name, "LocalOnly") == 0) { // This attribute is accepted for compatibility reasons, but is // not honored because it is deprecated. Boolean localOnly; XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, localOnly, true); duplicateParameter = gotLocalOnly; gotLocalOnly = true; } else if (System::strcasecmp(name, "IncludeQualifiers") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeQualifiers, true); duplicateParameter = gotIncludeQualifiers; gotIncludeQualifiers = true; } else if (System::strcasecmp(name, "IncludeClassOrigin") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeClassOrigin, true); duplicateParameter = gotIncludeClassOrigin; gotIncludeClassOrigin = true; } else if (System::strcasecmp(name, "PropertyList") == 0) { if (!emptyTag) { CIMValue pl; if (XmlReader::getValueArrayElement(parser, CIMTYPE_STRING, pl)) { Array propertyListArray; pl.get(propertyListArray); propertyList.append(propertyListArray); } } duplicateParameter = gotPropertyList; gotPropertyList = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotInstanceName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMGetInstanceRequestMessage( messageId, nameSpace, instanceName, #ifdef PEGASUS_DISABLE_INSTANCE_QUALIFIERS false, #else includeQualifiers, #endif includeClassOrigin, propertyList, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMModifyInstanceRequestMessage* CIMOperationRequestDecoder::decodeModifyInstanceRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMInstance modifiedInstance; Boolean includeQualifiers = true; CIMPropertyList propertyList; Boolean duplicateParameter = false; Boolean gotInstance = false; Boolean gotIncludeQualifiers = false; Boolean gotPropertyList = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ModifiedInstance") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getNamedInstanceElement(parser, modifiedInstance); duplicateParameter = gotInstance; gotInstance = true; } else if (System::strcasecmp(name, "IncludeQualifiers") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeQualifiers, true); duplicateParameter = gotIncludeQualifiers; gotIncludeQualifiers = true; } else if (System::strcasecmp(name, "PropertyList") == 0) { if (!emptyTag) { CIMValue pl; if (XmlReader::getValueArrayElement(parser, CIMTYPE_STRING, pl)) { Array propertyListArray; pl.get(propertyListArray); Array cimNameArray; for (Uint32 i = 0; i < propertyListArray.size(); i++) { cimNameArray.append(propertyListArray[i]); } propertyList.set(cimNameArray); } } duplicateParameter = gotPropertyList; gotPropertyList = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotInstance) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMModifyInstanceRequestMessage( messageId, nameSpace, modifiedInstance, includeQualifiers, propertyList, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMEnumerateInstancesRequestMessage* CIMOperationRequestDecoder::decodeEnumerateInstancesRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMName className; Boolean deepInheritance = true; Boolean includeQualifiers = false; Boolean includeClassOrigin = false; CIMPropertyList propertyList; Boolean duplicateParameter = false; Boolean gotClassName = false; Boolean gotDeepInheritance = false; Boolean gotLocalOnly = false; Boolean gotIncludeQualifiers = false; Boolean gotIncludeClassOrigin = false; Boolean gotPropertyList = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ClassName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getClassNameElement(parser, className, true); duplicateParameter = gotClassName; gotClassName = true; } else if (System::strcasecmp(name, "DeepInheritance") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, deepInheritance, true); duplicateParameter = gotDeepInheritance; gotDeepInheritance = true; } else if (System::strcasecmp(name, "LocalOnly") == 0) { // This attribute is accepted for compatibility reasons, but is // not honored because it is deprecated. Boolean localOnly; XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, localOnly, true); duplicateParameter = gotLocalOnly; gotLocalOnly = true; } else if (System::strcasecmp(name, "IncludeQualifiers") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeQualifiers, true); duplicateParameter = gotIncludeQualifiers; gotIncludeQualifiers = true; } else if (System::strcasecmp(name, "IncludeClassOrigin") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeClassOrigin, true); duplicateParameter = gotIncludeClassOrigin; gotIncludeClassOrigin = true; } else if (System::strcasecmp(name, "PropertyList") == 0) { if (!emptyTag) { CIMValue pl; if (XmlReader::getValueArrayElement(parser, CIMTYPE_STRING, pl)) { Array propertyListArray; pl.get(propertyListArray); propertyList.append(propertyListArray); } } duplicateParameter = gotPropertyList; gotPropertyList = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotClassName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMEnumerateInstancesRequestMessage( messageId, nameSpace, className, deepInheritance, #ifdef PEGASUS_DISABLE_INSTANCE_QUALIFIERS false, #else includeQualifiers, #endif includeClassOrigin, propertyList, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMEnumerateInstanceNamesRequestMessage* CIMOperationRequestDecoder::decodeEnumerateInstanceNamesRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMName className; Boolean duplicateParameter = false; Boolean gotClassName = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ClassName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getClassNameElement(parser, className, true); duplicateParameter = gotClassName; gotClassName = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotClassName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMEnumerateInstanceNamesRequestMessage( messageId, nameSpace, className, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMDeleteInstanceRequestMessage* CIMOperationRequestDecoder::decodeDeleteInstanceRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMObjectPath instanceName; Boolean duplicateParameter = false; Boolean gotInstanceName = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "InstanceName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getInstanceNameElement(parser, instanceName); duplicateParameter = gotInstanceName; gotInstanceName = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotInstanceName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMDeleteInstanceRequestMessage( messageId, nameSpace, instanceName, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMSetQualifierRequestMessage* CIMOperationRequestDecoder::decodeSetQualifierRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMQualifierDecl qualifierDeclaration; Boolean duplicateParameter = false; Boolean gotQualifierDeclaration = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "QualifierDeclaration") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getQualifierDeclElement(parser, qualifierDeclaration); duplicateParameter = gotQualifierDeclaration; gotQualifierDeclaration = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotQualifierDeclaration) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMSetQualifierRequestMessage( messageId, nameSpace, qualifierDeclaration, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMGetQualifierRequestMessage* CIMOperationRequestDecoder::decodeGetQualifierRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME String qualifierNameString; CIMName qualifierName; Boolean duplicateParameter = false; Boolean gotQualifierName = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "QualifierName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getStringValueElement(parser, qualifierNameString, true); qualifierName = qualifierNameString; duplicateParameter = gotQualifierName; gotQualifierName = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotQualifierName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMGetQualifierRequestMessage( messageId, nameSpace, qualifierName, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMEnumerateQualifiersRequestMessage* CIMOperationRequestDecoder::decodeEnumerateQualifiersRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { // No IPARAMVALUEs are defined for this operation throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } AutoPtr request( new CIMEnumerateQualifiersRequestMessage( messageId, nameSpace, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMDeleteQualifierRequestMessage* CIMOperationRequestDecoder::decodeDeleteQualifierRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME String qualifierNameString; CIMName qualifierName; Boolean duplicateParameter = false; Boolean gotQualifierName = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "QualifierName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getStringValueElement(parser, qualifierNameString, true); qualifierName = qualifierNameString; duplicateParameter = gotQualifierName; gotQualifierName = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotQualifierName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMDeleteQualifierRequestMessage( messageId, nameSpace, qualifierName, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMReferenceNamesRequestMessage* CIMOperationRequestDecoder::decodeReferenceNamesRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMObjectPath objectName; CIMName resultClass; String role; Boolean duplicateParameter = false; Boolean gotObjectName = false; Boolean gotResultClass = false; Boolean gotRole = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ObjectName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getObjectNameElement(parser, objectName); duplicateParameter = gotObjectName; gotObjectName = true; } else if (System::strcasecmp(name, "ResultClass") == 0) { // // ResultClass may be NULL // if (!emptyTag) { XmlReader::getClassNameElement(parser, resultClass, false); } duplicateParameter = gotResultClass; gotResultClass = true; } else if (System::strcasecmp(name, "Role") == 0) { // // Role may be NULL // if (!emptyTag) { XmlReader::getStringValueElement(parser, role, false); } duplicateParameter = gotRole; gotRole = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotObjectName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMReferenceNamesRequestMessage( messageId, nameSpace, objectName, resultClass, role, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMReferencesRequestMessage* CIMOperationRequestDecoder::decodeReferencesRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMObjectPath objectName; CIMName resultClass; String role; Boolean includeQualifiers = false; Boolean includeClassOrigin = false; CIMPropertyList propertyList; Boolean duplicateParameter = false; Boolean gotObjectName = false; Boolean gotResultClass = false; Boolean gotRole = false; Boolean gotIncludeQualifiers = false; Boolean gotIncludeClassOrigin = false; Boolean gotPropertyList = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ObjectName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getObjectNameElement(parser, objectName); duplicateParameter = gotObjectName; gotObjectName = true; } else if (System::strcasecmp(name, "ResultClass") == 0) { // // ResultClass may be NULL // if (!emptyTag) { XmlReader::getClassNameElement(parser, resultClass, false); } duplicateParameter = gotResultClass; gotResultClass = true; } else if (System::strcasecmp(name, "Role") == 0) { // // Role may be NULL // if (!emptyTag) { XmlReader::getStringValueElement(parser, role, false); } duplicateParameter = gotRole; gotRole = true; } else if (System::strcasecmp(name, "IncludeQualifiers") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeQualifiers, true); duplicateParameter = gotIncludeQualifiers; gotIncludeQualifiers = true; } else if (System::strcasecmp(name, "IncludeClassOrigin") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeClassOrigin, true); duplicateParameter = gotIncludeClassOrigin; gotIncludeClassOrigin = true; } else if (System::strcasecmp(name, "PropertyList") == 0) { if (!emptyTag) { CIMValue pl; if (XmlReader::getValueArrayElement(parser, CIMTYPE_STRING, pl)) { Array propertyListArray; pl.get(propertyListArray); propertyList.append(propertyListArray); } } duplicateParameter = gotPropertyList; gotPropertyList = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotObjectName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMReferencesRequestMessage( messageId, nameSpace, objectName, resultClass, role, includeQualifiers, includeClassOrigin, propertyList, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMAssociatorNamesRequestMessage* CIMOperationRequestDecoder::decodeAssociatorNamesRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMObjectPath objectName; CIMName assocClass; CIMName resultClass; String role; String resultRole; Boolean duplicateParameter = false; Boolean gotObjectName = false; Boolean gotAssocClass = false; Boolean gotResultClass = false; Boolean gotRole = false; Boolean gotResultRole = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ObjectName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getObjectNameElement(parser, objectName); duplicateParameter = gotObjectName; gotObjectName = true; } else if (System::strcasecmp(name, "AssocClass") == 0) { // // AssocClass may be NULL // if (!emptyTag) { XmlReader::getClassNameElement(parser, assocClass, false); } duplicateParameter = gotAssocClass; gotAssocClass = true; } else if (System::strcasecmp(name, "ResultClass") == 0) { // // ResultClass may be NULL // if (!emptyTag) { XmlReader::getClassNameElement(parser, resultClass, false); } duplicateParameter = gotResultClass; gotResultClass = true; } else if (System::strcasecmp(name, "Role") == 0) { // // Role may be NULL // if (!emptyTag) { XmlReader::getStringValueElement(parser, role, false); } duplicateParameter = gotRole; gotRole = true; } else if (System::strcasecmp(name, "ResultRole") == 0) { // // ResultRole may be NULL // if (!emptyTag) { XmlReader::getStringValueElement(parser, resultRole, false); } duplicateParameter = gotResultRole; gotResultRole = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotObjectName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMAssociatorNamesRequestMessage( messageId, nameSpace, objectName, assocClass, resultClass, role, resultRole, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMAssociatorsRequestMessage* CIMOperationRequestDecoder::decodeAssociatorsRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMObjectPath objectName; CIMName assocClass; CIMName resultClass; String role; String resultRole; Boolean includeQualifiers = false; Boolean includeClassOrigin = false; CIMPropertyList propertyList; Boolean duplicateParameter = false; Boolean gotObjectName = false; Boolean gotAssocClass = false; Boolean gotResultClass = false; Boolean gotRole = false; Boolean gotResultRole = false; Boolean gotIncludeQualifiers = false; Boolean gotIncludeClassOrigin = false; Boolean gotPropertyList = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "ObjectName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getObjectNameElement(parser, objectName); duplicateParameter = gotObjectName; gotObjectName = true; } else if (System::strcasecmp(name, "AssocClass") == 0) { // // AssocClass may be NULL // if (!emptyTag) { XmlReader::getClassNameElement(parser, assocClass, false); } duplicateParameter = gotAssocClass; gotAssocClass = true; } else if (System::strcasecmp(name, "ResultClass") == 0) { // // ResultClass may be NULL // if (!emptyTag) { XmlReader::getClassNameElement(parser, resultClass, false); } duplicateParameter = gotResultClass; gotResultClass = true; } else if (System::strcasecmp(name, "Role") == 0) { // // Role may be NULL // if (!emptyTag) { XmlReader::getStringValueElement(parser, role, false); } duplicateParameter = gotRole; gotRole = true; } else if (System::strcasecmp(name, "ResultRole") == 0) { // // ResultRole may be NULL // if (!emptyTag) { XmlReader::getStringValueElement(parser, resultRole, false); } duplicateParameter = gotResultRole; gotResultRole = true; } else if (System::strcasecmp(name, "IncludeQualifiers") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeQualifiers, true); duplicateParameter = gotIncludeQualifiers; gotIncludeQualifiers = true; } else if (System::strcasecmp(name, "IncludeClassOrigin") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getBooleanValueElement(parser, includeClassOrigin, true); duplicateParameter = gotIncludeClassOrigin; gotIncludeClassOrigin = true; } else if (System::strcasecmp(name, "PropertyList") == 0) { if (!emptyTag) { CIMValue pl; if (XmlReader::getValueArrayElement(parser, CIMTYPE_STRING, pl)) { Array propertyListArray; pl.get(propertyListArray); propertyList.append(propertyListArray); } } duplicateParameter = gotPropertyList; gotPropertyList = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotObjectName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMAssociatorsRequestMessage( messageId, nameSpace, objectName, assocClass, resultClass, role, resultRole, includeQualifiers, includeClassOrigin, propertyList, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMGetPropertyRequestMessage* CIMOperationRequestDecoder::decodeGetPropertyRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMObjectPath instanceName; String propertyName; Boolean duplicateParameter = false; Boolean gotInstanceName = false; Boolean gotPropertyName = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "InstanceName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getInstanceNameElement(parser, instanceName); duplicateParameter = gotInstanceName; gotInstanceName = true; } else if (System::strcasecmp(name, "PropertyName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getStringValueElement(parser, propertyName, true); duplicateParameter = gotPropertyName; gotPropertyName = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotInstanceName || !gotPropertyName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMGetPropertyRequestMessage( messageId, nameSpace, instanceName, propertyName, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMSetPropertyRequestMessage* CIMOperationRequestDecoder::decodeSetPropertyRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME CIMObjectPath instanceName; String propertyName; CIMValue propertyValue; Boolean duplicateParameter = false; Boolean gotInstanceName = false; Boolean gotPropertyName = false; Boolean gotNewValue = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "InstanceName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getInstanceNameElement(parser, instanceName); duplicateParameter = gotInstanceName; gotInstanceName = true; } else if (System::strcasecmp(name, "PropertyName") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getStringValueElement(parser, propertyName, true); duplicateParameter = gotPropertyName; gotPropertyName = true; } else if (System::strcasecmp(name, "NewValue") == 0) { if (emptyTag || !XmlReader::getPropertyValue(parser, propertyValue)) { propertyValue.setNullValue(CIMTYPE_STRING, false); } duplicateParameter = gotNewValue; gotNewValue = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotInstanceName || !gotPropertyName) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMSetPropertyRequestMessage( messageId, nameSpace, instanceName, propertyName, propertyValue, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMExecQueryRequestMessage* CIMOperationRequestDecoder::decodeExecQueryRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMNamespaceName& nameSpace) { STAT_GETSTARTTIME String queryLanguage; String query; Boolean duplicateParameter = false; Boolean gotQueryLanguage = false; Boolean gotQuery = false; Boolean emptyTag; for (const char* name; XmlReader::getIParamValueTag(parser, name, emptyTag); ) { if (System::strcasecmp(name, "QueryLanguage") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getStringValueElement(parser, queryLanguage, true); duplicateParameter = gotQueryLanguage; gotQueryLanguage = true; } else if (System::strcasecmp(name, "Query") == 0) { XmlReader::rejectNullIParamValue(parser, emptyTag, name); XmlReader::getStringValueElement(parser, query, true); duplicateParameter = gotQuery; gotQuery = true; } else { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY); } if (!emptyTag) { XmlReader::expectEndTag(parser, "IPARAMVALUE"); } if (duplicateParameter) { throw PEGASUS_CIM_EXCEPTION( CIM_ERR_INVALID_PARAMETER, String::EMPTY); } } if (!gotQueryLanguage || !gotQuery) { throw PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_PARAMETER, String::EMPTY); } AutoPtr request( new CIMExecQueryRequestMessage( messageId, nameSpace, queryLanguage, query, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } CIMInvokeMethodRequestMessage* CIMOperationRequestDecoder::decodeInvokeMethodRequest( Uint32 queueId, XmlParser& parser, const String& messageId, const CIMObjectPath& reference, const String& cimMethodName) { STAT_GETSTARTTIME CIMParamValue paramValue; Array inParameters; while (XmlReader::getParamValueElement(parser, paramValue)) { inParameters.append(paramValue); } AutoPtr request( new CIMInvokeMethodRequestMessage( messageId, reference.getNameSpace(), reference, cimMethodName, inParameters, QueueIdStack(queueId, _returnQueueId))); STAT_SERVERSTART return request.release(); } void CIMOperationRequestDecoder::setServerTerminating(Boolean flag) { _serverTerminating = flag; } PEGASUS_NAMESPACE_END