801 lines
27 KiB
C#

//----------------------------------------------------------------------------
//
// Copyright (c) Intel Corporation, 2008 - 2009 All Rights Reserved.
//
// File: CimObject.cs
//
// Contents: CimObject is a part of the CimFramework project.
// It contains a class representing an untyped CIM object.
//
//----------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Xml;
using Intel.Manageability.Exceptions;
using Intel.Manageability.WSManagement;
namespace Intel.Manageability.Cim.Untyped
{
using Property = KeyValuePair<string, string>;
/// <summary>
/// A Struct that represents a pair of CimObject and CimReference
/// </summary>
public struct CimObjectReferencePair
{
/// <summary>
///
/// </summary>
public CimObject cimObject { set; get; }
/// <summary>
///
/// </summary>
public CimReference cimReference { set; get; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="obj">The CimObject parameter</param>
/// <param name="reference">The CimReference parameter</param>
public CimObjectReferencePair(CimObject obj, CimReference reference)
: this()
{
cimObject = obj;
cimReference = reference;
}
}
/// <summary>
/// Class which represent input / output parameters for invoke functions
/// </summary>
public class CimParams
{
/// <summary>
/// Cim data field
/// </summary>
public CimData cimDataObject { get; set; }
/// <summary>
/// Cim params field
/// </summary>
/// <param name="xmlNamespace"></param>
public CimParams(string xmlNamespace)
{
cimDataObject = new CimData("tempName", xmlNamespace);
}
/// <summary>
/// Serialize the CIM object to XML
/// </summary>
/// <returns>XML representing the CIM object</returns>
public string Serialize()
{
return cimDataObject.Serialize();
}
/// <summary>
/// Deserialize the CIM object from XML
/// </summary>
/// <param name="xml">XML representing the CIM object</param>
public void Deserialize(string xml)
{
cimDataObject.Deserialize(xml);
}
/// <summary>
/// Gets a CIM Field
/// </summary>
/// <param name="name">CIM Field name</param>
/// <returns>Array of the field's values</returns>
public string[] GetField(string name)
{
return cimDataObject.GetField(name);
}
/// <summary>
/// Sets or adds a CIM Field
/// If the field does not exist, the function adds it, otherwise the function sets its values.
/// </summary>
/// <param name="name">CIM Field name</param>
/// <param name="values">Field values</param>
public virtual void SetOrAddField(string name, string[] values)
{
cimDataObject.SetOrAddField(name, values);
}
/// <summary>
/// Sets or adds a CIM Field
/// If the field does not exist, the function adds it, otherwise the function sets its value.
/// </summary>
/// <param name="name">CIM Field name</param>
/// <param name="value">Field value</param>
public virtual void SetOrAddField(string name, string value)
{
cimDataObject.SetOrAddField(name, value);
}
/// <summary>
/// Copy the CIM data
/// </summary>
/// <param name="other">CIM data to be copied</param>
public void Copy(CimParams other)
{
if (other == null)
throw new ArgumentNullException("other");
cimDataObject = other.cimDataObject;
}
/// <summary>
/// Checks if a given Field exists in the current CIM object
/// </summary>
/// <param name="name">CIM Field name</param>
/// <returns>True if the given field exists in the CIM object, otherwise false</returns>
public bool ContainsField(string name)
{
return cimDataObject.ContainsField(name);
}
/// <summary>
/// Get/Set CIM Field
/// </summary>
/// <param name="name">CIM Field Name</param>
/// <returns>Array of the field's values</returns>
public string[] this[string name]
{
get
{
return cimDataObject.GetField(name);
}
set
{
cimDataObject.SetField(name, value);
}
}
}
/// <summary>
/// Represents an untyped CIM object
/// </summary>
public class CimObject : CimObjectData
{
/// <summary>
/// WS-Management client
/// </summary>
public IWSManClient WSManClient { get; set; }
/// <summary>
/// Get / Set the object's class resource URI
/// </summary>
public Uri ResourceURI { get; protected set; }
/// <summary>
/// Get / Set the object's class XmlNamespace
/// </summary>
public string XmlNamespace{get{return _xmlNamespace;}protected set{_xmlNamespace = value;}}
/// <summary>
/// Constructor
/// </summary>
/// <param name="className">Name of the actual class of the object</param>
/// <param name="nameSpace">Namespace of the object's class</param>
/// <param name="client">WS-Management client</param>
public CimObject(string className, string nameSpace, IWSManClient client)
: base(className, nameSpace)
{
//Arguments sanity check
if (className == null)
throw new ArgumentNullException("className");
if (nameSpace == null)
throw new ArgumentNullException("nameSpace");
if (client == null)
throw new ArgumentNullException("client");
_xmlNamespace = nameSpace;
ResourceURI = new Uri(nameSpace);
WSManClient = client;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="className">Name of the actual class of the object</param>
/// <param name="nameSpace">Namespace of the object's class</param>
public CimObject(string className, string nameSpace)
: base(className, nameSpace)
{
//Arguments sanity check
if (className == null)
throw new ArgumentNullException("className");
if (nameSpace == null)
throw new ArgumentNullException("nameSpace");
_xmlNamespace = nameSpace;
ResourceURI = new Uri(nameSpace);
}
/// <summary>
/// Copy constructor
/// </summary>
/// <param name="other"></param>
public CimObject(CimObject other): base(other)
{
//Arguments sanity check
if (other == null)
throw new ArgumentNullException("other");
ResourceURI = other.ResourceURI;
XmlMembers = other.XmlMembers;
_xmlNamespace = other._xmlNamespace;
}
/// <summary>
/// Add a new CIM Field
/// </summary>
/// <param name="name">Field name</param>
/// <param name="value">Field value</param>
public void AddField(string name, string value)
{
AddField(name, new string[1] { value });
}
/// <summary>
/// Add a new CIM Field
/// </summary>
/// <param name="item">KeyValuePair that contains the field's name and value</param>
public void AddField(KeyValuePair<string, string> item)
{
AddField(item.Key, new string[1] { item.Value });
}
/// <summary>
/// Add a new CIM Field
/// </summary>
/// <param name="item">KeyValuePair that contains the field's name and values</param>
public void AddField(KeyValuePair<string, string[]> item)
{
AddField(item.Key, item.Value);
}
/// <summary>
/// Set a CIM field's value
/// </summary>
/// <param name="name">Field name</param>
/// <param name="value">Field value</param>
public void SetField(string name, string value)
{
SetField(name, new string[1] { value });
}
/// <summary>
/// Sets an existing field's value, or adds the value for a new field
/// </summary>
/// <param name="name">Field name</param>
/// <param name="value">Field value</param>
public override void SetOrAddField(string name, string value)
{
SetOrAddField(name, new string[1] { value });
}
/// <summary>
/// Retrieve a list of the object's fields
/// </summary>
public List<Property> Properties
{
get
{
List<Property> res = new List<Property>();
XmlNode root = XmlMembers.DocumentElement;
IEnumerator ienum = root.GetEnumerator();
XmlNode field;
while (ienum.MoveNext())
{
field = (XmlNode)ienum.Current;
res.Add(new Property(field.LocalName, field.InnerXml));
}
return res;
}
}
/// <summary>
/// Copy constructor
/// </summary>
/// <param name="other">CimObject to be copied</param>
public void Copy(CimObject other)
{
if (other == null)
throw new ArgumentNullException("other");
XmlMembers = other.XmlMembers;
_xmlNamespace = other._xmlNamespace;
WSManClient = other.WSManClient;
ResourceURI = other.ResourceURI;
}
/// <summary>
/// Create an object from an XML string
/// </summary>
/// <param name="wsmanClient">WS-Management client</param>
/// <param name="resourceUri">Resource URI</param>
/// <param name="xml">XML to deserialize</param>
/// <returns>Object built from the XML data</returns>
private static CimObject CreateObject(IWSManClient wsmanClient, Uri resourceUri, string xml)
{
CimObject obj = new CimObject(GetClassNameFromNamespace(resourceUri.ToString()), resourceUri.ToString());
obj.ResourceURI = resourceUri;
obj.Deserialize(xml);
obj.WSManClient = wsmanClient;
return obj;
}
/// <summary>
/// Create an object from an XML string
/// </summary>
/// <param name="wsmanClient">WS-Management client</param>
/// <param name="className">The object's class name</param>
/// <param name="namespaceUri">The object's class namespace</param>
/// <param name="xml">XML to deserialize</param>
/// <returns>Object built from the XML data</returns>
private static CimObject CreateObject(IWSManClient wsmanClient, string className, string namespaceUri, string xml)
{
CimObject obj = new CimObject(className, namespaceUri);
obj.ResourceURI = new Uri(namespaceUri);
obj.Deserialize(xml);
obj.WSManClient = wsmanClient;
return obj;
}
/// <summary>
/// Get an instance of a CIM class
/// </summary>
public void Get()
{
if (WSManClient == null)
throw new CimException("Transport client not initialized");
string xml = (WSManClient.Get(ResourceURI, null)).OuterXml;
// get the updated instance
CimObject obj = CreateObject(WSManClient, ResourceURI, xml);
// Save the data
Copy(obj);
}
/// <summary>
/// Get an instance of a CIM class
/// </summary>
/// <param name="keys">Keys of the object to get</param>
/// <returns>CIM object</returns>
public void Get(CimObject.CimKeys keys)
{
//Arguments sanity check
if (keys == null)
throw new ArgumentNullException("selectors");
if (WSManClient == null)
throw new CimException("Transport client not initialized");
string xml = (WSManClient.Get(ResourceURI, keys.cimKeys)).OuterXml;
// get the updated instance
CimObject obj = CreateObject(WSManClient, ResourceURI, xml);
// Save the data
Copy(obj);
}
/// <summary>
/// Get an instance of a CIM class
/// </summary>
/// <param name="reference">Reference to a CIM object</param>
/// <returns>CIM object</returns>
public void Get(CimReference reference)
{
//Arguments sanity check
if (reference == null)
throw new ArgumentNullException("reference");
if (WSManClient == null)
throw new CimException("Transport client not initialized");
string xml = (WSManClient.Get(reference)).OuterXml;
// get the updated instance
CimObject obj = CreateObject(WSManClient, ResourceURI, xml);
// Save the data
Copy(obj);
}
/// <summary>
/// Enumerate instances of a CIM class
/// </summary>
/// <param name="wsmanClient">WS-Management client</param>
/// <param name="resourceUri">CIM class resource URI</param>
/// <param name="options">Enumeration options</param>
/// <returns>Collection of pairs - CimObject, CimReference</returns>
public static Collection<CimObjectReferencePair> Enumerate(IWSManClient wsmanClient, EnumerationOptions options)
{
if (wsmanClient == null)
throw new ArgumentNullException("wsmanClient");
if (options == null)
throw new ArgumentNullException("options");
Uri resourceUri = new Uri(EnumerationOptions.FILTER_URI);
Collection<CimObjectReferencePair> enumRes = new Collection<CimObjectReferencePair>();
XmlElement[] xmlRes;
xmlRes = wsmanClient.Enumerate(resourceUri, null, options);
switch (options.EnumMode)
{
case EnumerationOptions.EnumerationMode.ENUMERATION_REFERENCE:
for (int i = 0; i < xmlRes.Length; i++)
{
String str = xmlRes[i].OuterXml;
CimReference reference = CimReference.Deserialize(str);
CimObjectReferencePair pair = new CimObjectReferencePair(null, reference);
enumRes.Add(pair);
}
break;
case EnumerationOptions.EnumerationMode.ENUMERATION_OBJ_AND_REFERENCE:
for (int i = 0; i < xmlRes.Length; i++)
{
// the response is pairs of objects & references that are related to this object
String CimLateStr = xmlRes[i].FirstChild.OuterXml;
String eprStr = xmlRes[i].LastChild.OuterXml;
string namespaceUri = xmlRes[i].FirstChild.NamespaceURI;
string objName = xmlRes[i].FirstChild.LocalName;
CimReference reference = CimReference.Deserialize(eprStr);
CimObjectReferencePair pair = new CimObjectReferencePair(CreateObject(wsmanClient, objName, namespaceUri, CimLateStr), reference);
enumRes.Add(pair);
}
break;
default: // EnumerationOptions.EnumerationMode.NONE
for (int i = 0; i < xmlRes.Length; i++)
{
String str = xmlRes[i].OuterXml;
string namespaceUri = xmlRes[i].NamespaceURI;
string objName = xmlRes[i].LocalName;
CimObjectReferencePair pair = new CimObjectReferencePair(CreateObject(wsmanClient, objName, namespaceUri, str), null);
enumRes.Add(pair);
}
break;
};
return enumRes;
}
/// <summary>
/// Enumerate Cim objects.
/// </summary>
/// <param name="wsmanClient">WS-MAN client</param>
/// <param name="resourceUri">resourceUri of the class to enumerate</param>
/// <param name="keys">keys of the class to enumerate</param>
/// <returns></returns>
public static Collection<CimObject> Enumerate(IWSManClient wsmanClient, Uri resourceUri, CimObject.CimKeys keys)
{
if (wsmanClient == null)
throw new ArgumentNullException("wsmanClient");
if (keys == null)
throw new ArgumentNullException("selectors");
Collection<CimObject> enumRes = new Collection<CimObject>();
XmlElement[] xmlRes;
//Create a Enumeration options with selector filter
EnumerationOptions enumOption = new EnumerationOptions();
enumOption.Filter = new SelectorFilter(keys.cimKeys);
enumOption.EnumMode = EnumerationOptions.EnumerationMode.NONE;
xmlRes = wsmanClient.Enumerate(resourceUri, keys.cimKeys);
for (int i = 0; i < xmlRes.Length; i++)
{
String str = xmlRes[i].OuterXml;
enumRes.Add(CreateObject(wsmanClient, resourceUri, str));
}
return enumRes;
}
/// <summary>
/// Enumerate Cim objects.
/// </summary>
/// <param name="wsmanClient">WS-MAN client</param>
/// <param name="resourceUri">resourceUri of the class to enumerate</param>
/// <returns></returns>
public static Collection<CimObject> Enumerate(IWSManClient wsmanClient, Uri resourceUri)
{
if (wsmanClient == null)
throw new ArgumentNullException("wsmanClient");
Collection<CimObject> enumRes = new Collection<CimObject>();
XmlElement[] xmlRes;
xmlRes = wsmanClient.Enumerate(resourceUri, null);
for (int i = 0; i < xmlRes.Length; i++)
{
String str = xmlRes[i].OuterXml;
enumRes.Add(CreateObject(wsmanClient, resourceUri, str));
}
return enumRes;
}
/// <summary>
/// Deletes an object at an endpoint, specified by the keys
/// </summary>
/// <param name="keys">Keys of the object to delete</param>
public void Delete(CimObject.CimKeys keys)
{
if (WSManClient == null)
throw new CimException("Transport client not initialized");
//Arguments sanity check
if (keys == null)
throw new ArgumentNullException("keys");
WSManClient.Delete(ResourceURI, keys.cimKeys);
}
/// <summary>
/// Deletes an object that is specified by a CimReference
/// </summary>
/// <param name="wsmanClient">WS-Management client</param>
/// <param name="reference">A reference to the object to be deleted</param>
public static void Delete(IWSManClient wsmanClient, CimReference reference)
{
//Arguments sanity check
if (wsmanClient == null)
throw new ArgumentNullException("wsmanClient");
if (reference == null)
throw new ArgumentNullException("reference");
wsmanClient.Delete(reference);
}
/// <summary>
/// Deletes an object at an endpoint, specified by the keys and the resourceURI
/// </summary>
/// <param name="wsmanClient">WS-Management client</param>
/// <param name="resourceUri">CIM class resource URI</param>
/// <param name="keys">Keys of the object to delete</param>
public static void Delete(IWSManClient wsmanClient, Uri resourceUri, CimObject.CimKeys keys)
{
//Arguments sanity check
if (wsmanClient == null)
throw new ArgumentNullException("wsmanClient");
if (resourceUri == null)
throw new ArgumentNullException("resourceUri");
if (keys == null)
throw new ArgumentNullException("keys");
wsmanClient.Delete(resourceUri, keys.cimKeys);
}
/// <summary>
/// Deletes an object that is specified by a ResourceUri
/// This method will succeed only if there is a single instance of this type at the endpoint
/// </summary>
/// <param name="wsmanClient">WS-Management client</param>
/// <param name="resourceUri">CIM class resource URI</param>
public static void Delete(IWSManClient wsmanClient, Uri resourceUri)
{
//Arguments sanity check
if (wsmanClient == null)
throw new ArgumentNullException("wsmanClient");
if (resourceUri == null)
throw new ArgumentNullException("resourceUri");
wsmanClient.Delete(resourceUri, null);
}
/// <summary>
/// Updates an object at an endpoint
/// </summary>
/// <param name="keys">Keys of the object to delete</param>
public void Put(CimObject.CimKeys keys)
{
//Arguments sanity check
if (WSManClient == null)
throw new CimException("Transport client not initialized");
if (keys == null)
throw new ArgumentNullException("keys");
WSManClient.Put(ResourceURI, XmlMembers.DocumentElement, keys.cimKeys);
}
/// <summary>
/// Creates an object at an endpoint
/// </summary>
/// <returns>CimReference that represents the created object</returns>
public CimReference Create()
{
if (WSManClient == null)
throw new CimException("Transport client not initialized");
CimReference refOut = WSManClient.Create(ResourceURI, XmlMembers.DocumentElement);
return refOut;
}
/// <summary>
/// Invoke a CIM method
/// </summary>
/// <param name="methodName">The name of the method to be invoked</param>
/// <param name="keys">Keys of the object on which to invoke a method</param>
/// <param name="input">The input parameters</param>
/// <param name="output">The output parameters</param>
public uint Invoke(string methodName, CimObject.CimKeys keys, CimParams input, out CimParams output)
{
if (WSManClient == null)
throw new CimException("Transport client not initialized");
//Arguments sanity check
if (input == null)
throw new ArgumentNullException("input");
if (keys == null)
throw new ArgumentNullException("keys");
uint returnValue = 0;
Uri methodNameUri = new Uri(ResourceURI.AbsoluteUri + "/" + methodName);
// TODO: create XML with outer tag of methodName + _input
XmlDocument inputXML = new XmlDocument();
inputXML.LoadXml(input.Serialize());
string temp = inputXML.InnerText;
XmlElement root = XmlMembers.DocumentElement;
root = XmlMembers.CreateElement(methodName + "_INPUT", ResourceURI.AbsoluteUri);
root.InnerXml = inputXML.DocumentElement.InnerXml;
string res = (WSManClient.Invoke(ResourceURI, methodNameUri, root, keys.cimKeys)).OuterXml;
output = null;
if (res != null)
{
output = new CimParams(ResourceURI.AbsoluteUri);
output.Deserialize(res);
returnValue = uint.Parse(output.GetField("ReturnValue")[0], CultureInfo.InvariantCulture);
}
return returnValue;
}
/// <summary>
/// Generic class that represents the keys of a CIM class.
/// </summary>
public class CimKeys
{
/// <summary>
/// A list containing the keys (pairs of name and value)
/// </summary>
public List<Key> cimKeys { get; private set; }
/// <summary>
/// Constructor
/// </summary>
public CimKeys()
{
cimKeys = new List<Key>();
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="keysList">List of keys</param>
public CimKeys(List<Key> keysList)
{
cimKeys = new List<Key>();
cimKeys = keysList;
}
/// <summary>
/// Set an existing key's value, or add a new key.
/// </summary>
/// <param name="name">Name of the key</param>
/// <param name="value">Value of the key</param>
public void SetOrAddKey(string name, Object value)
{
int index = getIndex(name);
Key k = new Key(name, value);
if (index == -1)
{
cimKeys.Add(k);
}
else
{
cimKeys[index] = k;
}
}
/// <summary>
/// Retrieves a key's value.
/// </summary>
/// <param name="name">Name of the key</param>
/// <returns>Value of the key</returns>
public string GetKey(string name)
{
if (name == null)
throw new ArgumentNullException("name");
int index = getIndex(name);
if (index == -1)
{
throw new CimPropertyException("Key with the name " + name + " does not exist");
}
else
{
return cimKeys[index].Value;
}
}
private int getIndex(string name)
{
int i;
for (i = 0; i < cimKeys.Count; i++)
{
if (cimKeys[i].Name.Equals(name))
{
break;
}
}
if (i == cimKeys.Count)
return -1;
return i;
}
}
}
}