📄 cimoperationrequestdispatcher.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 "CIMOperationRequestDispatcher.h"#include <Pegasus/Common/Constants.h>#include <Pegasus/Common/XmlReader.h> // stringToValue(), stringArrayToValue()#include <Pegasus/Common/ContentLanguageList.h>#include <Pegasus/Common/StatisticalData.h>#include <Pegasus/Common/MessageLoader.h>#include <Pegasus/Common/AuditLogger.h>#include <Pegasus/Common/Tracer.h>#include <Pegasus/Common/Formatter.h>#include <Pegasus/Server/reg_table.h>#include <Pegasus/Server/QuerySupportRouter.h>PEGASUS_NAMESPACE_BEGIN//PEGASUS_USING_STD;//#define CDEBUG(X) cout << "CIMOpReqDsptchr " << X << endl#define CDEBUG(X)// Test tool to limit enumerations to a single level. This is not// production and is used only to debug special problems in the requests// that issue multiple provider operations.//#define LIMIT_ENUM_TO_ONE_LEVELstatic DynamicRoutingTable _routing_table;// Variable to control whether we do search or simply single provider for// reference and associatior lookups.// ATTN: KS 5 April 2003 This is to be removed ATTN:// static bool singleProviderType = true;// Local save for host name. save host name here. NOTE: Problem if hostname// changes.// Set by object init. Used by aggregator.String cimAggregationLocalHost;// A helper function that resets the Propagated and ClassOrigin attributes on// properties of CIMInstance and CIMClass objects. This is used during// Create/Modify Instance and Create/Modify Class operations, where the// Propagated and ClassOrigin attributes must be ignored.template <class ObjectClass>void removePropagatedAndOriginAttributes(ObjectClass& newObject);// static counter for aggretation serial numbers.// can be used to determine lost aggregations.Uint64 CIMOperationRequestDispatcher::cimOperationAggregationSN = 0;OperationAggregate::OperationAggregate( CIMRequestMessage* request, Uint32 msgRequestType, String messageId, Uint32 dest, CIMName className, CIMNamespaceName nameSpace, QueryExpressionRep* query, String queryLanguage) : _messageId(messageId), _msgRequestType(msgRequestType), _dest(dest), _nameSpace(nameSpace), _className(className), _query(query), _queryLanguage(queryLanguage), _request(request){ _totalIssued = 0; _totalReceived = 0; _totalReceivedComplete = 0; _totalReceivedExpected = 0; _totalReceivedErrors = 0; _totalReceivedNotSupported = 0; _magicNumber = 12345; _aggregationSN = 0;}OperationAggregate::~OperationAggregate(){ _magicNumber = 0; delete _request; delete _query;}Boolean OperationAggregate::valid() const{ return (_magicNumber == 12345) ? true : false;}void OperationAggregate::setTotalIssued(Uint32 i){ _totalIssued = i;}Boolean OperationAggregate::appendResponse(CIMResponseMessage* response){ AutoMutex autoMut(_appendResponseMutex); _responseList.append(response); Boolean returnValue = (_totalIssued == numberResponses()); return returnValue;}Uint32 OperationAggregate::numberResponses() const{ //AutoMutex autoMut(_appendResponseMutex); Uint32 size = _responseList.size(); return size;}CIMRequestMessage* OperationAggregate::getRequest(){ return _request;}CIMResponseMessage* OperationAggregate::getResponse(const Uint32& pos){ AutoMutex autoMut(_appendResponseMutex); CIMResponseMessage* tmp = _responseList[pos]; return tmp;}CIMResponseMessage* OperationAggregate::removeResponse(const Uint32& pos){ AutoMutex autoMut(_appendResponseMutex); CIMResponseMessage* tmp = _responseList[pos]; _responseList.remove(pos); return tmp;}void OperationAggregate::deleteResponse(const Uint32&pos){ AutoMutex autoMut(_appendResponseMutex); delete _responseList[pos]; _responseList.remove(pos);}Uint32 OperationAggregate::getRequestType() const{ return _msgRequestType;}// There are many response pieces (chunks) from potentially many// threads funneling through this function in random order. This isolates a// single response (by locking) from a given thread and "resequences" the// response as part of one large response. It is crucial that the first// response to come through here be sequenced (or indexed) as 0 and the last// response from the last thread be marked as "isComplete"// NOTE: for now this assumes no chunks can come AFTER a "isComplete" message// of the LAST thread.void OperationAggregate::resequenceResponse(CIMResponseMessage& response){ static const String func = "OperationAggregate::resequenceResponse: "; CIMStatusCode error = response.cimException.getCode(); bool notSupportedReceived = false; if (error != CIM_ERR_SUCCESS) { if (error == CIM_ERR_NOT_SUPPORTED) { notSupportedReceived = true; _totalReceivedNotSupported++; } _totalReceivedErrors++; PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, String(func + "Response has error. " "Namespace: $0 Class name: $1 Response Sequence: $2"), _nameSpace.getString(), _className.getString(), _totalReceived)); } Boolean isComplete = response.isComplete(); if (isComplete == true) { _totalReceivedComplete++; _totalReceivedExpected += response.getIndex() + 1; } response.setIndex(_totalReceived++); // set to incomplete until ALL completed messages have come in isComplete = false; // NOTE: // _totalReceivedExpected is calculated by adding up every response index // count WHEN the message is marked complete. This may differ from the // following reasons: // 1. An exception occurred in which the correct index could not be set. // 2. Somehow the completed response arrived before the other // (non-completed) responses ? (shouldnt happen with the current // synchronous code). // In either case, a message will be logged and attempt to continue if (_totalReceivedComplete == _totalIssued) { if (_totalReceivedExpected == _totalReceived) { PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4, Formatter::format( func + "message is complete. " "total responses: $0, " "total chunks: $1, " "total errors: $2", _totalReceivedComplete, _totalReceived, _totalReceivedErrors)); } else { PEG_LOGGER_TRACE(( Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, func + "All completed responses ($0) for current request " "have been accounted for but expected count ($1) does " "not match the received count ($2). error count ($3). " "Attempting to continue ...", _totalReceivedComplete, _totalReceivedExpected, _totalReceived, _totalReceivedErrors)); Tracer::trace( __FILE__, __LINE__, TRC_DISCARDED_DATA, Tracer::LEVEL2, "All completed responses (%u) for current request " "have been accounted for but expected count (%u) does " "not match the received count (%u). error count (%u).", _totalReceivedComplete, _totalReceivedExpected, _totalReceived, _totalReceivedErrors); } // If all of the errors received were NOT_SUPPORTED and // all of the responses were errors, then keep the last // NOT_SUPPORTED error. // The condition below is the oposite of that. If there was an error // besides NOT_SUPPORTED, or a non-error response was received, and // the last response was a NOT_SUPPORTED error, then clear the error if ((_totalReceivedErrors != _totalReceivedNotSupported || _totalReceivedErrors != _totalReceived) && notSupportedReceived) { response.cimException = CIMException(); } isComplete = true; _totalReceivedComplete = 0; _totalReceivedExpected = 0; _totalReceivedErrors = 0; _totalReceivedNotSupported = 0; _totalReceived = 0; } else if (notSupportedReceived) { // Clear the NOT_SUPPORTED exception // We ignore it unless it's the only response received response.cimException = CIMException(); } response.setComplete(isComplete);}CIMOperationRequestDispatcher::CIMOperationRequestDispatcher( CIMRepository* repository, ProviderRegistrationManager* providerRegistrationManager) : Base(PEGASUS_QUEUENAME_OPREQDISPATCHER), _repository(repository), _providerRegistrationManager(providerRegistrationManager){ PEG_METHOD_ENTER(TRC_DISPATCHER, "CIMOperationRequestDispatcher::CIMOperationRequestDispatcher"); // // Check whether AssociationTraversal is supported. // ConfigManager* configManager = ConfigManager::getInstance(); _enableAssociationTraversal = ConfigManager::parseBooleanValue( configManager->getCurrentValue("enableAssociationTraversal")); _enableIndicationService = ConfigManager::parseBooleanValue( configManager->getCurrentValue("enableIndicationService")); // // Get the maximum breadth of enum parameter from config if it exists. // // ATTN: KS 20030602 Bypass param acquistion until we get it into the // config manager // Config param removed for Pegasus 2.2 and until PEP 66 resolved. // In place, we simply allow anything through by setting the breadth too // large number.// #define MAXENUMBREADTHTESTENABLED#ifdef MAXENUMBREADTHTESTENABLED String maxEnumBreadthOption; try { maxEnumBreadthOption = configManager->getCurrentValue("maximumEnumerationBreadth"); if (maxEnumBreadthOption != String::EMPTY) _maximumEnumerateBreadth = atol(maxEnumBreadthOption.getCString()); } catch (...) { _maximumEnumerateBreadth = 50; }#else // As part of disabling the test for now, we set to very large number. _maximumEnumerateBreadth = 1000;#endif#ifdef PEGASUS_ENABLE_OBJECT_NORMALIZATION _enableNormalization = ConfigManager::parseBooleanValue( configManager->getCurrentValue("enableNormalization")); if (_enableNormalization) { String moduleList = configManager->getCurrentValue("excludeModulesFromNormalization"); for (Uint32 pos = moduleList.find(','); moduleList.size() != 0; pos = moduleList.find(',')) { String moduleName = moduleList.subString(0, pos); _excludeModulesFromNormalization.append(moduleName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -