version 1.5.2.6, 2012/02/21 17:22:10
|
version 1.5.2.7, 2013/06/03 22:35:12
|
|
|
// | // |
////////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////////// |
// | // |
|
// Class CIMResponseData encapsulates the possible types of response data |
|
// representations and supplies conversion methods between these types. |
|
// PEP#348 - The CMPI infrastructure using SCMO (Single Chunk Memory Objects) |
|
// describes its usage in the server flow. |
|
// The design document can be found on the OpenPegasus website openpegasus.org |
|
// at https://collaboration.opengroup.org/pegasus/pp/documents/21210/PEP_348.pdf |
|
// |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#include "CIMResponseData.h" | #include "CIMResponseData.h" |
|
|
#define LOCAL_MIN(a, b) ((a < b) ? a : b) | #define LOCAL_MIN(a, b) ((a < b) ? a : b) |
// C++ objects interface handling | // C++ objects interface handling |
| |
// KS_TODO Remove this completely. |
// KS_TODO Remove this completely when finished testing. |
bool CIMResponseData::sizeValid() | bool CIMResponseData::sizeValid() |
{ | { |
TRACELINE; | TRACELINE; |
//////cout << _size << endl; |
|
PEGASUS_ASSERT(valid()); | PEGASUS_ASSERT(valid()); |
if (_size > 1000000) | if (_size > 1000000) |
{ | { |
TRACELINE; | TRACELINE; |
|
cout << "CIMResponseData::PSVALID _size too big " << _size << endl; |
PEG_TRACE((TRC_XML, Tracer::LEVEL4, | PEG_TRACE((TRC_XML, Tracer::LEVEL4, |
"CIMResponseData::PSVALID _size too big %u",_size )); | "CIMResponseData::PSVALID _size too big %u",_size )); |
return false; | return false; |
|
|
| |
// SCMO representation, single instance stored as one element array | // SCMO representation, single instance stored as one element array |
// object paths are represented as SCMOInstance | // object paths are represented as SCMOInstance |
|
// Resolve all of the information in the CIMResponseData container to |
|
// SCMO and return all scmoInstances. |
|
// Note that since the SCMO representation, |
|
// a is single instance stored as one element array and object paths are |
|
// represented as SCMOInstance this returns array of SCMOInstance. |
Array<SCMOInstance>& CIMResponseData::getSCMO() | Array<SCMOInstance>& CIMResponseData::getSCMO() |
{ | { |
TRACELINE; | TRACELINE; |
|
|
|
// This function resolves to instances and so cannot handle responses to |
|
// the associators,etc.requests that return classes (input object path with |
|
// no keys). That issue is resolved however, since CIMResponseData uses the |
|
// _isClassOperation variable (set by the request) to determine whether |
|
// the responses are classpaths or instancepaths and the default is |
|
// false(instancePaths) so that this should always produce instance paths. |
|
|
_resolveToSCMO(); | _resolveToSCMO(); |
return _scmoInstances; | return _scmoInstances; |
} | } |
|
|
break; | break; |
case RESP_INSTANCE: | case RESP_INSTANCE: |
{ | { |
Uint32 moveCount = toMove; |
//// TODO fix this Uint32 moveCount = toMove; |
if (from._instanceData.size() > 0) | if (from._instanceData.size() > 0) |
{ | { |
// temp test to assure all sizes are the same. | // temp test to assure all sizes are the same. |
|
|
PEG_TRACE((TRC_XML, Tracer::LEVEL1, | PEG_TRACE((TRC_XML, Tracer::LEVEL1, |
"Size calc error _size %u rtnSWize = %u", _size, rtnSize)); | "Size calc error _size %u rtnSWize = %u", _size, rtnSize)); |
} | } |
|
|
//PEGASUS_ASSERT(rtnSize == _size); | //PEGASUS_ASSERT(rtnSize == _size); |
| |
return rtnSize; | return rtnSize; |
|
|
// Return the number of CIM objects in the CIM Response data object | // Return the number of CIM objects in the CIM Response data object |
// | // |
#define TEMPLOG PEG_TRACE((TRC_XML, Tracer::LEVEL4, \ | #define TEMPLOG PEG_TRACE((TRC_XML, Tracer::LEVEL4, \ |
"rtnSize %u size %u", rtnSize, _size)) |
"rtnSize %u size %u line %u", rtnSize, _size, __LINE__)) |
|
//#define TEMPLOG cout << "rtnSize " << rtnSize << " _size " << _size |
|
//<< " line " << __LINE__ << endl |
| |
Uint32 CIMResponseData::size() | Uint32 CIMResponseData::size() |
{ | { |
|
|
// but there are many sources of size info and we need to be sure we | // but there are many sources of size info and we need to be sure we |
// have covered them all. | // have covered them all. |
#ifdef PEGASUS_DEBUG | #ifdef PEGASUS_DEBUG |
PEGASUS_ASSERT(valid()); //KS_TEMP |
PEGASUS_ASSERT(valid()); //KS_TEMP KS_TODO |
| |
Uint32 rtnSize = 0; | Uint32 rtnSize = 0; |
TEMPLOG; | TEMPLOG; |
|
|
// Test of actual count against _size variable. | // Test of actual count against _size variable. |
if (rtnSize != _size) | if (rtnSize != _size) |
{ | { |
PSVALID; |
|
TEMPLOG; | TEMPLOG; |
|
PSVALID; |
PEG_TRACE((TRC_XML, Tracer::LEVEL1, | PEG_TRACE((TRC_XML, Tracer::LEVEL1, |
"CIMResponseData::size ERROR. debug size mismatch." | "CIMResponseData::size ERROR. debug size mismatch." |
"Computed = %u. variable = %u",rtnSize, _size )); | "Computed = %u. variable = %u",rtnSize, _size )); |
|
|
for (Uint32 j = 0, n = _scmoInstances.size(); j < n; j++) | for (Uint32 j = 0, n = _scmoInstances.size(); j < n; j++) |
{ | { |
SCMOInstance & scmoInst=_scmoInstances[j]; | SCMOInstance & scmoInst=_scmoInstances[j]; |
if (0 == scmoInst.getHostName()) |
scmoInst.completeHostNameAndNamespace( |
{ |
hnChars, |
scmoInst.setHostName_l(hnChars,hnLen); |
hnLen, |
} |
nsChars, |
if (0 == scmoInst.getNameSpace()) |
nsLen); |
{ |
|
scmoInst.setNameSpace_l(nsChars,nsLen); |
|
} |
|
} | } |
break; | break; |
} | } |
|
|
| |
// NOTE: The reason for the isPullResponse variable is that there are | // NOTE: The reason for the isPullResponse variable is that there are |
// some variations in ouput to Xml depending on whether the responses | // some variations in ouput to Xml depending on whether the responses |
// are one of the pull responses or the original responsed |
// are one of the pull responses or not |
void CIMResponseData::encodeXmlResponse(Buffer& out, Boolean isPullResponse) | void CIMResponseData::encodeXmlResponse(Buffer& out, Boolean isPullResponse) |
{ | { |
TRACELINE; | TRACELINE; |
|
|
{ | { |
for (Uint32 i = 0, n = _instances.size(); i < n; i++) | for (Uint32 i = 0, n = _instances.size(); i < n; i++) |
{ | { |
/// KS_TODO_DELETE |
|
////PrintInstance(cout, _instances[i]); |
|
if (isPullResponse) | if (isPullResponse) |
{ | { |
XmlWriter::appendValueInstanceWithPathElement( | XmlWriter::appendValueInstanceWithPathElement( |
|
|
_objects[i], | _objects[i], |
_includeQualifiers, | _includeQualifiers, |
_includeClassOrigin, | _includeClassOrigin, |
|
_isClassOperation, |
_propertyList); | _propertyList); |
} | } |
} | } |
|
|
XmlWriter::appendValueReferenceElement( | XmlWriter::appendValueReferenceElement( |
out, | out, |
_instanceNames[i], | _instanceNames[i], |
|
_isClassOperation, |
false); | false); |
out << "</OBJECTPATH>\n"; | out << "</OBJECTPATH>\n"; |
} | } |
|
|
PEG_METHOD_EXIT(); | PEG_METHOD_EXIT(); |
} | } |
| |
void CIMResponseData::_resolveXmlToCIM() |
|
|
void CIMResponseData::_deserializeObject(Uint32 idx,CIMObject& cimObject) |
{ | { |
TRACELINE; |
// Only start the parser when instance data is present. |
switch (_dataType) |
if (0 != _instanceData[idx].size()) |
{ | { |
// Xml encoding for instance names and object paths not used |
CIMInstance cimInstance; |
case RESP_OBJECTPATHS: |
CIMClass cimClass; |
case RESP_INSTNAMES: |
|
|
XmlParser parser((char*)_instanceData[idx].getData()); |
|
|
|
if (XmlReader::getInstanceElement(parser, cimInstance)) |
{ | { |
break; |
cimObject = CIMObject(cimInstance); |
|
return; |
} | } |
case RESP_INSTANCE: |
|
{ |
if (XmlReader::getClassElement(parser, cimClass)) |
CIMInstance cimInstance; |
|
// Deserialize instance: |
|
{ | { |
XmlParser parser((char*)_instanceData[0].getData()); |
cimObject = CIMObject(cimClass); |
|
return; |
|
} |
|
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
|
"Failed to resolve XML object data, parser error!"); |
|
} |
|
} |
| |
if (!XmlReader::getInstanceElement(parser, cimInstance)) |
void CIMResponseData::_deserializeInstance(Uint32 idx,CIMInstance& cimInstance) |
{ | { |
cimInstance = CIMInstance(); |
// Only start the parser when instance data is present. |
|
if (0 != _instanceData[idx].size()) |
|
{ |
|
XmlParser parser((char*)_instanceData[idx].getData()); |
|
if (XmlReader::getInstanceElement(parser, cimInstance)) |
|
{ |
|
return; |
|
} |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, | PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
"Failed to resolve XML instance, parser error!"); | "Failed to resolve XML instance, parser error!"); |
} | } |
|
// reset instance when parsing may not be successfull or |
|
// no instance is present. |
|
cimInstance = CIMInstance(); |
} | } |
// Deserialize path: |
|
{ |
|
XmlParser parser((char*)_referencesData[0].getData()); |
|
CIMObjectPath cimObjectPath; |
|
| |
|
Boolean CIMResponseData::_deserializeReference( |
|
Uint32 idx, |
|
CIMObjectPath& cimObjectPath) |
|
{ |
|
// Only start the parser when reference data is present. |
|
if (0 != _referencesData[idx].size()) |
|
{ |
|
XmlParser parser((char*)_referencesData[idx].getData()); |
if (XmlReader::getValueReferenceElement(parser, cimObjectPath)) | if (XmlReader::getValueReferenceElement(parser, cimObjectPath)) |
{ | { |
if (_hostsData.size()) |
if (_hostsData[idx].size()) |
{ | { |
cimObjectPath.setHost(_hostsData[0]); |
cimObjectPath.setHost(_hostsData[idx]); |
} | } |
if (!_nameSpacesData[0].isNull()) |
if (!_nameSpacesData[idx].isNull()) |
{ | { |
cimObjectPath.setNameSpace(_nameSpacesData[0]); |
cimObjectPath.setNameSpace(_nameSpacesData[idx]); |
} | } |
cimInstance.setPath(cimObjectPath); |
return true; |
// only if everything works we add the CIMInstance to the |
|
// array |
|
_instances.append(cimInstance); |
|
} | } |
|
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
|
"Failed to resolve XML reference, parser error!"); |
|
|
} | } |
break; |
return false; |
} | } |
case RESP_INSTANCES: |
|
|
Boolean CIMResponseData::_deserializeInstanceName( |
|
Uint32 idx, |
|
CIMObjectPath& cimObjectPath) |
{ | { |
for (Uint32 i = 0; i < _instanceData.size(); i++) |
// Only start the parser when instance name data is present. |
|
if (0 != _referencesData[idx].size()) |
{ | { |
CIMInstance cimInstance; |
XmlParser parser((char*)_referencesData[idx].getData()); |
// Deserialize instance: |
if (XmlReader::getInstanceNameElement(parser, cimObjectPath)) |
{ | { |
XmlParser parser((char*)_instanceData[i].getData()); |
if (_hostsData[idx].size()) |
|
{ |
if (!XmlReader::getInstanceElement(parser, cimInstance)) |
cimObjectPath.setHost(_hostsData[idx]); |
|
} |
|
if (!_nameSpacesData[idx].isNull()) |
{ | { |
|
cimObjectPath.setNameSpace(_nameSpacesData[idx]); |
|
} |
|
return true; |
|
} |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, | PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
"Failed to resolve XML instance." |
"Failed to resolve XML instance name, parser error!"); |
" Creating empty instance!"); |
|
cimInstance = CIMInstance(); |
|
} | } |
|
return false; |
} | } |
| |
// Deserialize path: |
void CIMResponseData::_resolveXmlToCIM() |
|
{ |
|
TRACELINE; |
|
switch (_dataType) |
{ | { |
XmlParser parser((char*)_referencesData[i].getData()); |
// Xml encoding for instance names and object paths not used |
|
case RESP_OBJECTPATHS: |
|
case RESP_INSTNAMES: |
|
{ |
|
break; |
|
} |
|
case RESP_INSTANCE: |
|
{ |
|
CIMInstance cimInstance; |
CIMObjectPath cimObjectPath; | CIMObjectPath cimObjectPath; |
| |
if (XmlReader::getInstanceNameElement(parser,cimObjectPath)) |
_deserializeInstance(0,cimInstance); |
|
if (_deserializeReference(0,cimObjectPath)) |
{ | { |
if (!_nameSpacesData[i].isNull()) |
|
cimObjectPath.setNameSpace(_nameSpacesData[i]); |
|
|
|
if (_hostsData[i].size()) |
|
cimObjectPath.setHost(_hostsData[i]); |
|
|
|
cimInstance.setPath(cimObjectPath); | cimInstance.setPath(cimObjectPath); |
} |
// A single CIMInstance has to have an objectpath. |
} |
// So only add it when an objectpath exists. |
|
|
_instances.append(cimInstance); | _instances.append(cimInstance); |
} | } |
break; | break; |
} | } |
case RESP_OBJECTS: |
case RESP_INSTANCES: |
{ |
|
for (Uint32 i=0, n=_instanceData.size(); i<n; i++) |
|
{ | { |
CIMObject cimObject; |
for (Uint32 i = 0; i < _instanceData.size(); i++) |
|
|
// Deserialize Objects: |
|
{ | { |
XmlParser parser((char*)_instanceData[i].getData()); |
|
|
|
CIMInstance cimInstance; | CIMInstance cimInstance; |
CIMClass cimClass; |
CIMObjectPath cimObjectPath; |
| |
if (XmlReader::getInstanceElement(parser, cimInstance)) |
_deserializeInstance(i,cimInstance); |
{ |
if (_deserializeInstanceName(i,cimObjectPath)) |
cimObject = CIMObject(cimInstance); |
|
} |
|
else if (XmlReader::getClassElement(parser, cimClass)) |
|
{ | { |
cimObject = CIMObject(cimClass); |
cimInstance.setPath(cimObjectPath); |
} | } |
else |
// enumarate instances can be without name |
{ |
_instances.append(cimInstance); |
PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, |
|
"Failed to get XML object data!"); |
|
} | } |
|
break; |
} | } |
|
case RESP_OBJECTS: |
// Deserialize paths: |
{ |
|
for (Uint32 i=0, n=_instanceData.size(); i<n; i++) |
{ | { |
XmlParser parser((char*)_referencesData[i].getData()); |
CIMObject cimObject; |
CIMObjectPath cimObjectPath; | CIMObjectPath cimObjectPath; |
| |
if (XmlReader::getValueReferenceElement( |
_deserializeObject(i,cimObject); |
parser, |
if (_deserializeReference(i,cimObjectPath)) |
cimObjectPath)) |
|
{ | { |
if (!_nameSpacesData[i].isNull()) |
|
cimObjectPath.setNameSpace(_nameSpacesData[i]); |
|
|
|
if (_hostsData[i].size()) |
|
cimObjectPath.setHost(_hostsData[i]); |
|
|
|
cimObject.setPath(cimObjectPath); | cimObject.setPath(cimObjectPath); |
} | } |
} |
|
_objects.append(cimObject); | _objects.append(cimObject); |
} | } |
break; | break; |
|
|
_instanceNames[i], | _instanceNames[i], |
_defNamespace, | _defNamespace, |
_defNamespaceLen); | _defNamespaceLen); |
// TODO: More description about this. |
if (_isClassOperation) |
if (0 == _instanceNames[i].getKeyBindings().size()) |
|
{ | { |
// if there is no keybinding, this is a class |
|
addme.setIsClassOnly(true); | addme.setIsClassOnly(true); |
} | } |
_scmoInstances.append(addme); | _scmoInstances.append(addme); |
|
|
_propertyList = propertyList; | _propertyList = propertyList; |
} | } |
| |
|
void CIMResponseData::setIsClassOperation(Boolean b) |
|
{ |
|
_isClassOperation = b; |
|
} |
|
|
PEGASUS_NAMESPACE_END | PEGASUS_NAMESPACE_END |