📄 operationresponsehandler.cpp
字号:
//%2006//////////////////////////////////////////////////////////////////////////// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation, The Open Group.// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; Symantec Corporation; The Open Group.//// 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 "OperationResponseHandler.h"#include "CIMOMHandleContext.h"#include <Pegasus/Common/Logger.h>#include <Pegasus/Common/AutoPtr.h>#include <Pegasus/Provider/CIMOMHandle.h>PEGASUS_NAMESPACE_BEGIN//// OperationResponseHandler//OperationResponseHandler::OperationResponseHandler( CIMRequestMessage* request, CIMResponseMessage* response, PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback) : _request(request), _response(response), _responseChunkCallback(responseChunkCallback), _responseObjectTotal(0), _responseMessageTotal(0), _responseObjectThreshold(0){#ifndef PEGASUS_RESPONSE_OBJECT_COUNT_THRESHOLD# define PEGASUS_RESPONSE_OBJECT_COUNT_THRESHOLD 100#elif PEGASUS_RESPONSE_OBJECT_COUNT_THRESHOLD == 0# undef PEGASUS_RESPONSE_OBJECT_COUNT_THRESHOLD# define PEGASUS_RESPONSE_OBJECT_COUNT_THRESHOLD ~0#endif if (!request) { _responseObjectThreshold = ~0; } else { _responseObjectThreshold = PEGASUS_RESPONSE_OBJECT_COUNT_THRESHOLD;#ifdef PEGASUS_DEBUG static const char* responseObjectThreshold = getenv("PEGASUS_RESPONSE_OBJECT_COUNT_THRESHOLD"); if (responseObjectThreshold) { Uint32 i = (Uint32)atoi(responseObjectThreshold); if (i > 0) { _responseObjectThreshold = i; } }#endif }}OperationResponseHandler::~OperationResponseHandler(){ _request = 0; _response = 0;}CIMRequestMessage* OperationResponseHandler::getRequest() const{ return _request;}CIMResponseMessage* OperationResponseHandler::getResponse() const{ return _response;}void OperationResponseHandler::setStatus( const Uint32 code, const String& message){ _response->cimException = PEGASUS_CIM_EXCEPTION(CIMStatusCode(code), message);}void OperationResponseHandler::setStatus( const Uint32 code, const ContentLanguageList& langs, const String& message){ _response->cimException = PEGASUS_CIM_EXCEPTION_LANG( langs, CIMStatusCode(code), message);}void OperationResponseHandler::setCIMException( const CIMException& cimException){ // Assign the cimException argument to _response->cimException. Note that // there is no need to use the PEGASUS_CIM_EXCEPTION_LANG() macro to create // a TraceableCIMException since both _response->cimException and // cimException are of type CIMException and the TraceableCIMException // constructor has no side effects. _response->cimException = cimException;}Boolean OperationResponseHandler::isAsync() const{ return _responseChunkCallback != 0;}// This is only called from SimpleResponseHandler.deliver() but lives in this// class because all asyncronous response must have a "response" pointer// to go through. Only operation classes have a response pointervoid OperationResponseHandler::send(Boolean isComplete){ // It is possible to instantiate this class directly (not a derived // class, which would also inherit from SimpleResponseHandler). // The caller would do this only if the operation does not have any // data to be returned. SimpleResponseHandler* simpleP = dynamic_cast<SimpleResponseHandler*>(this); if (simpleP == 0) { // if there is no data to be returned, then the message should NEVER be // incomplete (even on an error) PEGASUS_ASSERT(isComplete); return; } // some handlers do not send async because their callers cannot handle // partial responses. If this is the case, stop here. if (!isAsync()) { // preserve traditional behavior if (isComplete) { if (_response != 0) { _response->operationContext.set( ContentLanguageListContainer(simpleP->getLanguages())); } transfer(); } return; } SimpleResponseHandler& simple = *simpleP; PEGASUS_ASSERT(_response); Uint32 objectCount = simple.size(); // have not reached threshold yet if ((isComplete == false) && (objectCount < _responseObjectThreshold)) { return; } CIMResponseMessage* response = _response; // for complete responses, just use the one handed down from caller // otherwise, create our own that the caller never sees but is // utilized for async responses underneath if (isComplete == false) { _response = _request->buildResponse(); } _response->setComplete(isComplete); _responseObjectTotal += objectCount; // since we are reusing response for every chunk, keep track of original // count _response->setIndex(_responseMessageTotal++); // set the originally allocated response to one more than the current. // The reason for doing this is proactive in case of an exception. This // allows the last response to be set as it may not re-enter this code. if (isComplete == false) { response->setIndex(_responseMessageTotal); } validate(); if (_response->cimException.getCode() != CIM_ERR_SUCCESS) { simple.clear(); } String function = getClass() + "::" + "transfer"; Logger::put( Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, function); transfer(); simple.clear(); _response->operationContext.set( ContentLanguageListContainer(simple.getLanguages())); // call thru ProviderManager to get externally declared entry point if (isComplete == false) { _responseChunkCallback(_request, _response); } // put caller's allocated response back in place. Note that _response // is INVALID after sending because it has been deleted externally _response = response;}void OperationResponseHandler::transfer(){}void OperationResponseHandler::validate(){}String OperationResponseHandler::getClass() const{ return String("OperationResponseHandler");}Uint32 OperationResponseHandler::getResponseObjectTotal() const{ return _responseObjectTotal;}Uint32 OperationResponseHandler::getResponseMessageTotal() const{ return _responseMessageTotal;}Uint32 OperationResponseHandler::getResponseObjectThreshold() const{ return _responseObjectThreshold;}//// GetInstanceResponseHandler//GetInstanceResponseHandler::GetInstanceResponseHandler( CIMGetInstanceRequestMessage* request, CIMGetInstanceResponseMessage* response, PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback) : OperationResponseHandler(request, response, responseChunkCallback){#ifdef PEGASUS_ENABLE_OBJECT_NORMALIZATION // Attempt to get the cached class definition used to validate results of // this operation. If it does not exist, then this feature is disabled // for this operation. CIMClass cimClass; if (request->operationContext.contains( CachedClassDefinitionContainer::NAME)) { CachedClassDefinitionContainer container = request->operationContext.get( CachedClassDefinitionContainer::NAME); cimClass = container.getClass(); } AutoPtr<NormalizerContext> tmpContext(new CIMOMHandleContext()); ObjectNormalizer tmpNormalizer( cimClass, request->includeQualifiers, request->includeClassOrigin, request->nameSpace, tmpContext); _normalizer = tmpNormalizer;#endif}void GetInstanceResponseHandler::deliver(const CIMInstance& cimInstance){ if (cimInstance.isUninitialized()) { MessageLoaderParms message( "Common.Exception.UNINITIALIZED_OBJECT_EXCEPTION", "The object is not initialized."); throw CIMException(CIM_ERR_FAILED, message); } if (SimpleInstanceResponseHandler::size() != 0) { MessageLoaderParms message( "Server.OperationResponseHandler.TOO_MANY_OBJECTS_DELIVERED", "Too many objects delivered."); throw CIMException(CIM_ERR_FAILED, message); }#ifdef PEGASUS_ENABLE_OBJECT_NORMALIZATION // The normalizer expects an object path embedded in instances even // though it is not required by this operation. Use the requested // object path is missing from the instance. CIMInstance localInstance(cimInstance); if (localInstance.getPath().getKeyBindings().size() == 0) { // ATTN: should clone before modification localInstance.setPath(static_cast<CIMGetInstanceRequestMessage*>( getRequest())->instanceName); } SimpleInstanceResponseHandler::deliver( _normalizer.processInstance(localInstance));#else SimpleInstanceResponseHandler::deliver(cimInstance);#endif}void GetInstanceResponseHandler::complete(){ if (SimpleInstanceResponseHandler::size() == 0) { MessageLoaderParms message( "Server.OperationResponseHandler.TOO_FEW_OBJECTS_DELIVERED", "Too few objects delivered."); // Provider claims success, no instances returned. -V see Bug #4104 setStatus(CIM_ERR_NOT_FOUND); throw CIMException(CIM_ERR_FAILED, message); } SimpleInstanceResponseHandler::complete();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -