The PropertyCollector uses two relatively complicated argument structures. As was mentioned in PropertyCollector Data, these arguments are PropertySpec and ObjectSpec. PropertySpec is a list of the information desired, and ObjectSpec is a list of instructions indicating where to find the information. In theory, you could directly address an object using its moRef. In that case an ObjectSpec can be very simple. However, getting the initial moRef can be a challenge when a complicated ObjectSpec is required. To formulate a complex ObjectSpec, you need to understand the structure of the available data. This is complicated by the fact that an ObjectSpec can contain recursive elements.

Understanding an ObjectSpec

An ObjectSpec is a list of ObjectSpec elements, each specifying an object type, and giving a “selection spec” for the object. More About Managed Objects describes five types of managed objects: Folder, Datacenter, ComputeResource, ResourcePool, and VirtualMachine. VirtualApp (vApp) is a sixth type. You can “traverse” objects, because one managed object leads to another.

  • Folder – One of the items contained in the Folder is called childEntity, which is a list of moRefs that can contain one of the five managed object types. A Folder can be parent to any of these managed objects.
  • Datacenter – This managed object has two items that lead to other managed objects:
    • hostFolder – A moRef to a Folder containing a list of ComputeResources comprising a Datacenter.
    • vmFolder – A moRef to a Folder containing the VirtualMachines that are part of the Datacenter. If it is your objective to duplicate the display seen in a vSphere Client GUI, then this Folder is of limited use because it does not describe the ResourcePool that is the parent of a virtual machine.
  • ComputeResource – A ComputeResource is basically hardware. A ComputeResource can comprise multiple systems. The hardware represents resources that can be used to implement a VirtualMachine object. VirtualMachine is a child of ResourcePool, which controls the sharing of a physical machine's resources among VirtualMachine objects. A ComputeResource contains an item named resourcePool, which is a moRef to a ResourcePool.
  • VirtualApp – A VirtualApp (vApp) is a collection of VirtualMachines that make up a single application. This is a special form of ResourcePool (defined below). A VirtualApp may have three types of children:
    • VirtualMachine – A folder named vm contains a list of moRefs to child VirtualMachines.
    • resourcePool – A folder containing a list of moRefs pointing to child ResourcePools or VirtualApps.
      • VirtualApp – A VirtualApp can be composed of other VirtualApps.
      • ResourcePool – You can segment the resources of a VirtualApp using a ResourcePool.
  • ResourcePool – This managed object contains two child items:
    • resourcePool – A folder containing a list of moRefs pointing to child ResourcePools or VirtualApps.
    • vm – A list of moRefs to child VirtualMachines that employ the resources of the parent ResourcPool. A VirtualMachine always lists a ResourcePool as its parent.
  • VirtualMachine – The VirtualMachine is often considered an “end object” – so you do not need to describe any traversal for this object.

The ObjectSpec does not have to lead you any farther than the moRef of a target object. You can gather information about the managed object itself using the moRef and the PropertySpec. This is described in detail in the section Understanding a PropertySpec.

A TraversalSpec extends SelectionSpec, a property of ObjectSpec, and contains the following elements:

  • Path – The element contained in the object that is used to steer traversal.
  • SelectSet – An array containing either SelectionSpec or TraversalSpec elements.
  • Skip – Whether or not to filter the object in the Path element.
  • Type – The type of object being referenced.
  • Name – Optional name you can use to reference the TraversalSpec, inherited from SelectionSpec.

SelectionSpec is a direct target for traversal, as is TraversalSpec (a class extending SelectionSpec). It is in the SelectSet that recursion can occur.

If you wish to traverse the entire configuration tree for a server, then you need only the “root node” moRef, which is always a Folder. This root folder moRef is available in the property rootFolder of the ObjectSpec service instance content. All of the above goes into this Java code sample.

// Traversal objects can use a symbolic name.
// First we define the TraversalSpec objects used to fill in the ObjectSpec.
//
// This TraversalSpec traverses Datacenter to vmFolder
TraversalSpec dc2vmFolder = new TraversalSpec();
dc2vmFolder.setType("Datacenter");  // Type of object for this spec
dc2vmFolder.setPath("vmFolder");  // Property name defining the next object
dc2vmFolder.setSelectSet(new SelectionSpec[] {"folderTSpec"});
//
// This TraversalSpec traverses Datacenter to hostFolder
TraversalSpec dc2hostFolder = new TraversalSpec();
dc2hostFolder.setType("Datacenter");
dc2hostFolder.setPath("hostFolder");
//
// We use the symbolic name "folderTSpec" which will be defined when we create the folderTSpec.
dc2vmFolder.setSelectSet(new SelectionSpec[] {"folderTSpec"});
//
// This TraversalSpec traverses ComputeResource to resourcePool
TraversalSpec cr2resourcePool = new TraversalSpec();
cr2resourcePool.setType("ComputeResource");
cr2resourcePool.setPath("resourcePool");
//
// This TraversalSpec traverses ComputeResource to host
TraversalSpec cr2host = new TraversalSpec();
cr2host.setType("ComputeResource");
cr2host.setPath("host");
//
// This TraversalSpec traverses ResourcePool to resourcePool
TraversalSpec rp2rp = new TraversalSpec();
rp2rp.setType("ResourcePool");
rp2rp.setPath("resourcePool");
//
// Finally, we tie it all together with the Folder TraversalSpec
TraversalSpec folderTS = new TraversalSpec();
folderTS.setName{"folderTSpec");  // Used for symbolic reference
folderTS.setType("Folder");
folderTS.setPath("childEntity");
folderTS.setSelectSet(new SelectionSpec[]{ "folderTSpec",
                                           dc2vmFolder, dc2hostFolder, cr2resourcePool, rp2rp});
ObjectSpec ospec = new ObjectSpec();
ospec.setObj(startingPoint); // This is where you supply the starting moRef (usually root folder)
ospec.setSkip(Boolean.FALSE);
ospec.setSelectSet(folderTS); // Attach the TraversalSpec we designed above

Understanding a PropertySpec

A PropertySpec is a list of individual properties that can be found at places identified by the ObjectSpec and its TraversalSpec. Once the PropertyCollector has a moRef, it can then return the properties associated with that moRef. This can include “nested” properties. Nested properties are properties that can be found inside of properties identified at the top level of the managed object. Nested properties are identified by a “dot” notation.

An example of nested properties can be drawn from the VirtualMachine managed object.A VirtualMachine has the property identified as summary, which identifies a VirtualMachineSummary data object. The VirtualMachineSummary contains property config, which identifies a VirtualMachineConfigSummary data object. The VirtualMachineConfigSummary has a property called name, which is a string containing the display name of the VirtualMachine. You can access this name property using the summary.config.name string value. To address all the properties of the VirtualMachineConfigSummary object, you would use the summary.config string value.

The PropertyCollector requires an array of PropertySpec elements. Each element includes:

  • Type – The type of object that contains the enclosed list of properties.
  • PathSet – An array of strings containing names of properties to be returned, including nested properties.

It is necessary to add an element for each type of object that you wish to query for properties. The following is a code sample of a PropertySpec:

// This code demonstrates how to specify a PropertySpec for several types of target objects:
PropertySpec folderSp = new PropertySpec();
folderSp.setType("Folder");
folderSp.setAll(Boolean.FALSE);
folderSp.setPathSet(new String [] {"parent", "name"});
PropertySpec dcSp = new PropertySpec();
dcSp.setType("Datacenter");
dcSp.setAll(Boolean.FALSE);
dcSp.setPathSet(new String [] {"parent","name"});
PropertySpec rpSp = new PropertySpec();
rpSp.setType("ResourcePool");
rpSp.setAll(Boolean.FALSE);
rpSp.setPathSet(new String [] {"parent","name","vm"});
PropertySpec crSp = new PropertySpec();
crSp.setType("ComputeResource");
crSp.setAll(Boolean.FALSE);
crSp.set:PathSet(new String [] {"parent","name"});
PropertySpec vmSp = new PropertySpec();
vmSp.setType("VirtualMachine");
vmSp.setAll(Boolean.FALSE);
vmSp.setPathSet(new String [] {"parent",
                               "name", "summary.config", "snapshot", "config.hardware.device"});
// Tie it all together
PropertySpec [] pspec = new PropertySpec [] {folderSp, dcSp, rpSp, crSp, vmSp};