Inventory Traversal
Example: Simple PropertyCollector Example (Java) uses a ContainerView to specify the objects that start the collection process. This is the simplest way to set up a filter, using a single reference to a view to provide the PropertyCollector with access to a set of objects. To select objects from the inventory, a filter includes TraversalSpec and possibly SelectionSpec objects. Use these objects to make object selections based on the references in a view, and to extend inventory traversal beyond those objects (or beyond the object specified in ObjectSpec.obj).
TraversalSpec Traversal
Use a TraversalSpec object to identify a managed object type and a traversal property in that type. TraversalSpec contains the following properties:
type – identifies an inventory object type.
path – specifies a managed object reference property in the type object. This property provides the traversal path extending from this object.
selectSet – specifies an optional list of selection objects for additonal object traversal paths. The PropertyCollector applies the TraversalSpec objects in the selectSet array to the result of the traversal (the target of TraversalSpec.path). The selectSet array can also contain SelectionSpec objects; a SelectionSpec is a reference to a TraversalSpec. See SelectionSpec Traversal.
skip – indicates whether to collect properties for the path object.
During inventory traversal, the PropertyCollector applies the PropertySpec object or objects (PropertyFilterSpec.propSet) to objects. Inventory traversal begins with the object identified by ObjectSpec.obj and continues by following TraversalSpec paths. If PropertySpec.type matches the current object type, and the skip property is false, the PropertyCollector sends the PropertySpec.pathSet properties to your client.
Inventory Navigation is a representation of a PropertyFilterSpec that defines traversal of VirtualMachine objects. The filter uses a ContainerView as a starting point. The TraversalSpec for the ContainerView specifies the view property for access to the view’s virtual machines. The figure shows TraversalSpec objects that extend navigation from a VirtualMachine object to the associated Network and ResourcePool objects. The PropertyCollector applies these TraversalSpec objects to each of the VirtualMachine objects in the view list. The figure also shows the PropertySpec objects for collecting data from VirtualMachine, Network, and ResourcePool objects.
Inventory Navigation
Example: Inventory Traversal shows a Java code fragment, based on Example: Simple PropertyCollector Example (Java), that implements the inventory traversal shown in Inventory Navigation.
To define inventory traversal
1
Create a ContainerView for virtual machines.
2
Create an ObjectSpec that uses the container view as the collection starting point.
3
Create a TraversalSpec be applied to the ContainerView to select VirtualMachine objects.
4
Create additional TraversalSpec objects to select additional objects.
The SelectSet list for the container view TraversalSpec has two TraversalSpec objects. Both specify a VirtualMachine object context. One object uses the network property to extend traversal to the Network managed object. The other uses the resourcePool property to extend traversal to the ResourcePool managed object.
5
Create PropertySpec objects to retrieve VirtualMachine, Network, and ResourcePool properties.
To retrieve properties that are embedded in data objects, the PropertySpec.PathSet property uses dot notation to specify the property paths.
Example: Inventory Traversal
import com.vmware.vim25.*;
 
import java.util.*;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.soap.SOAPFaultException;
 
 
// PropertyCollector example
// command line input: server name, user name, password
 
public class PCollector_traversal {
 
private static void collectProperties(VimPortType methods,
ServiceContent sContent) throws Exception {
 
// Get references to the ViewManager and PropertyCollector
ManagedObjectReference viewMgrRef = sContent.getViewManager();
ManagedObjectReference propColl = sContent.getPropertyCollector();
 
// use a container view for virtual machines to define the traversal
// - invoke the VimPortType method createContainerView (corresponds
// to the ViewManager method) - pass the ViewManager MOR and
// the other parameters required for the method invocation
// (use a List<String> for the type parameter's string[])
List<String> vmList = new ArrayList<String>();
vmList.add("VirtualMachine");
 
ManagedObjectReference cViewRef =
methods.createContainerView(viewMgrRef,
sContent.getRootFolder(),
vmList,
true);
 
// create an object spec to define the beginning of the traversal;
// container view is the root object for this traversal
ObjectSpec oSpec = new ObjectSpec();
oSpec.setObj(cViewRef);
oSpec.setSkip(true);
 
// create a traversal spec to select all objects in the view
TraversalSpec tSpec = new TraversalSpec();
tSpec.setName("traverseEntities");
tSpec.setPath("view");
tSpec.setSkip(false);
tSpec.setType("ContainerView");
 
// add the traversal spec to the object spec;
// the accessor method (getSelectSet) returns a reference
// to the mapped XML representation of the list; using this
// reference to add the spec will update the selectSet list
oSpec.getSelectSet().add(tSpec);
 
// extend from virtual machine to network
TraversalSpec tSpecVmN = new TraversalSpec();
tSpecVmN.setType("VirtualMachine");
tSpecVmN.setPath("network");
tSpecVmN.setSkip(false);
 
// extend from virtual machine to resourcepool
TraversalSpec tSpecVmRp = new TraversalSpec();
tSpecVmRp.setType("VirtualMachine");
tSpecVmRp.setPath("resourcePool");
tSpecVmRp.setSkip(false);
 
// add the network and resource pool traversal specs
// to the virtual machine traversal;
// the accessor method (getSelectSet) returns a reference
// to the mapped XML representation of the list; using this
// reference to add the spec will update the selectSet list
tSpec.getSelectSet().add(tSpecVmN);
tSpec.getSelectSet().add(tSpecVmRp);
 
// specify the properties for retrieval
// (virtual machine name, network summary accessible, rp runtime props);
// the accessor method (getPathSet) returns a reference to the mapped
// XML representation of the list; using this reference to add the
// property names will update the pathSet list
PropertySpec pSpec = new PropertySpec();
pSpec.setType("VirtualMachine");
pSpec.getPathSet().add("name");
 
PropertySpec pSpecNs = new PropertySpec();
pSpecNs.setType("Network");
pSpecNs.getPathSet().add("summary.accessible");
 
PropertySpec pSpecRPr = new PropertySpec();
pSpecRPr.setType("ResourcePool");
pSpecRPr.getPathSet().add("runtime.cpu.maxUsage");
pSpecRPr.getPathSet().add("runtime.memory.maxUsage");
pSpecRPr.getPathSet().add("runtime.overallStatus");
 
// create a PropertyFilterSpec and add the object and
// property specs to it; use the getter methods to reference
// the mapped XML representation of the lists and add the specs
// directly to the objectSet and propSet lists
PropertyFilterSpec fSpec = new PropertyFilterSpec();
fSpec.getObjectSet().add(oSpec);
fSpec.getPropSet().add(pSpec);
fSpec.getPropSet().add(pSpecNs);
fSpec.getPropSet().add(pSpecRPr);
 
// Create a list for the filters and add the spec to it
List<PropertyFilterSpec> fSpecList = new ArrayList<PropertyFilterSpec>();
fSpecList.add(fSpec);
 
// get the data from the server
RetrieveOptions ro = new RetrieveOptions();
RetrieveResult props = methods.retrievePropertiesEx(propColl,fSpecList,ro);
 
// go through the returned list and print out the data
if (props != null) {
for (ObjectContent oc : props.getObjects()) {
String value = null;
String path = null;
List<DynamicProperty> dps = oc.getPropSet();
if (dps != null) {
for (DynamicProperty dp : dps) {
path = dp.getName();
if (path.equals("name")) {
value = (String) dp.getVal();
}
else if (path.equals("summary.accessible")) {
// summary.accessible is a boolean
value = String.valueOf( dp.getVal() );
}
else if (path.equals("runtime.cpu.maxUsage")) {
// runtime.cpu.maxUsage is an xsd:long
value = String.valueOf( dp.getVal() );
}
else if (path.equals("runtime.memory.maxUsage")) {
// runtime.memory.maxUsage is an xsd:long
value = String.valueOf( dp.getVal() );
}
else if (path.equals("runtime.overallStatus")) {
// runtime.overallStatus is a ManagedEntityStatus enum
value = String.valueOf( dp.getVal() );
}
 
System.out.println(path + " = " + value);
}
}
}
}
}//end collectProperties()
 
// Authentication is handled by using a TrustManager and supplying
// a host name verifier method. (The host name verifier is declared
// in the main function.)
//
// For the purposes of this example, this TrustManager implementation
// will accept all certificates. This is only appropriate for
// a development environment. Production code should implement certificate support.
private static class TrustAllTrustManager implements javax.net.ssl.TrustManager,
javax.net.ssl.X509TrustManager {
 
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
 
public boolean isServerTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
 
public boolean isClientTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
}
 
public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
String authType)
throws java.security.cert.CertificateException {
return;
}
 
public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
String authType)
throws java.security.cert.CertificateException {
return;
}
}
 
public static void main(String [] args) throws Exception {
 
// arglist variables
String serverName = args[0];
String userName = args[1];
String password = args[2];
String url = "https://"+serverName+"/sdk/vimService";
 
// Variables of the following types for access to the API methods
// and to the vSphere inventory.
// -- ManagedObjectReference for the ServiceInstance on the Server
// -- VimService for access to the vSphere Web service
// -- VimPortType for access to methods
// -- ServiceContent for access to managed object services
ManagedObjectReference SVC_INST_REF = new ManagedObjectReference();
VimService vimService;
VimPortType vimPort;
ServiceContent serviceContent;
 
// Declare a host name verifier that will automatically enable
// the connection. The host name verifier is invoked during
// the SSL handshake.
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
 
// Create the trust manager.
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new TrustAllTrustManager();
trustAllCerts[0] = tm;
 
// Create the SSL context
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
 
// Create the session context
javax.net.ssl.SSLSessionContext sslsc = sc.getServerSessionContext();
 
// Initialize the contexts; the session context takes the trust manager.
sslsc.setSessionTimeout(0);
sc.init(null, trustAllCerts, null);
 
// Use the default socket factory to create the socket for the secure connection
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
 
// Set the default host name verifier to enable the connection.
HttpsURLConnection.setDefaultHostnameVerifier(hv);
 
// Set up the manufactured managed object reference for the ServiceInstance
SVC_INST_REF.setType("ServiceInstance");
SVC_INST_REF.setValue("ServiceInstance");
 
// Create a VimService object to obtain a VimPort binding provider.
// The BindingProvider provides access to the protocol fields
// in request/response messages. Retrieve the request context
// which will be used for processing message requests.
vimService = new VimService();
vimPort = vimService.getVimPort();
Map<String, Object> ctxt = ((BindingProvider) vimPort).getRequestContext();
 
// Store the Server URL in the request context and specify true
// to maintain the connection between the client and server.
// The client API will include the Server's HTTP cookie in its
// requests to maintain the session. If you do not set this to true,
// the Server will start a new session with each request.
ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
ctxt.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
// Retrieve the ServiceContent object and login
serviceContent = vimPort.retrieveServiceContent(SVC_INST_REF);
vimPort.login(serviceContent.getSessionManager(),
userName,
password,
null);
 
// retrieve data
collectProperties( vimPort, serviceContent );
 
// close the connection
vimPort.logout(serviceContent.getSessionManager());
 
}
}
 
SelectionSpec Traversal
The selectSet array in ObjectSpec and TraversalSpec objects can include TraversalSpec objects and SelectionSpec objects. SelectionSpec is the base class for TraversalSpec objects. SelectionSpec defines the name property. You can use a SelectionSpec object in a selectSet array as a reference to a named TraversalSpec object. By using SelectionSpec references, you can reuse a TraversalSpec and you can define recursive traversal.
Simple Reference SelectionSpec
Use SelectionSpec references to avoid writing duplicate TraversalSpec declarations. The TraversalSpec identified in a SelectionSpec reference must be within the same PropertyFilterSpec. SelectionSpec Reference shows the use of SelectionSpec references to a virtual machine TraversalSpec. The SelectionSpec references are associated with Network and Datastore traversals.
SelectionSpec Reference
If the ObjectSpec.selectSet array contains a SelectionSpec, the referenced TraversalSpec must identify the same object type. TraversalSpec.type must match the type of the object specified in ObjectSpec.obj. The PropertyCollector applies the TraversalSpec to the object and use the TraversalSpec.path property to extend its traversal.
Recursive Traversal
Use a SelectionSpec to apply a TraversalSpec to the results of its own traversal. To use a recursive filter construction, create a SelectionSpec that specifies the name of a TraversalSpec and add it to the named TraversalSpec selection set. The recursive construction extends inventory traversal beyond the paths directly represented by TraversalSpec objects.
You can use recursive traversal on any inventory objects that can be nested. See Inventory Hierarchies and ServiceInstance for a general representation of the structure of an inventory. For example, on a vCenter Server, folders can nest to arbitrary depths. To describe a traversal path through a succession of folders, you can add a SelectionSpec to the Folder TraversalSpec. The SelectionSpec must reference the TraversalSpec. Recursive TraversalSpec and SelectionSpec shows a representation of a TraversalSpec and its associated SelectionSpec for nested folder traversal.
Recursive TraversalSpec and SelectionSpec
Example: Nested Folder Traversal shows a Java code fragment that creates a recursive filter for nested folder traversal.
To define recursive inventory traversal
1
Use the SearchIndex managed object to retrieve the managed object reference for the top-level virtual machine folder.
This folder is used as the beginning of the inventory traversal. For more information see SearchIndex.
2
Create an ObjectSpec object that references the top-level virtual machine folder.
3
Create a SelectionSpec object that references the Folder TraversalSpec by name.
4
Create a named TraversalSpec for Folder objects.
The TraversalSpec.path property identifies the Folder.childEntity property for traversal to any child objects.
5
Add the SelectionSpec to the TraversalSpec to create the recursive filter.
6
Add the TraversalSpec to the ObjectSpec.
7
Create a PropertySpec for the Folder name.
8
9
Call the RetrievePropertiesEx method.
Example: Nested Folder Traversal
import com.vmware.vim25.*;
 
import java.util.*;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.soap.SOAPFaultException;
 
// PropertyCollector example
// command line input: server name, user name, password
 
public class nestedTraversal {
 
private static void collectProperties(VimPortType methods,
ServiceContent sContent) throws Exception {
 
// Get reference to the PropertyCollector
ManagedObjectReference propColl = sContent.getPropertyCollector();
 
// get the top-level vm folder mor
ManagedObjectReference sIndex = sContent.getSearchIndex();
ManagedObjectReference rootVmFolder =
methods.findByInventoryPath(sIndex,"datacenter1/vm");
 
// create an object spec to define the beginning of the traversal;
// root vm folder is the root object for this traversal
ObjectSpec oSpec = new ObjectSpec();
oSpec.setObj(rootVmFolder);
oSpec.setSkip(true);
 
// folder traversal reference
SelectionSpec sSpecF = new SelectionSpec();
sSpecF.setName("traverseFolder");
 
// create a folder traversal spec to select childEntity
TraversalSpec tSpecF = new TraversalSpec();
tSpecF.setType("Folder");
tSpecF.setPath("childEntity");
tSpecF.setSkip(false);
tSpecF.setName("traverseFolder");
 
// use the SelectionSpec as a reflexive spec for the folder traversal;
// the accessor method (getSelectSet) returns a reference to the
// mapped XML representation of the list; using this reference
// to add the spec will update the list
tSpecF.getSelectSet().add(sSpecF);
 
// add folder traversal to object spec
oSpec.getSelectSet().add(tSpecF);
 
// specify the property for retrieval (folder name)
PropertySpec pSpec = new PropertySpec();
pSpec.setType("Folder");
pSpec.getPathSet().add("name");
 
// create a PropertyFilterSpec and add the object and
// property specs to it; use the getter method to reference
// the mapped XML representation of the lists and add the specs
// directly to the lists
PropertyFilterSpec fSpec = new PropertyFilterSpec();
fSpec.getObjectSet().add(oSpec);
fSpec.getPropSet().add(pSpec);
 
// Create a list for the filter and add the spec to it
List<PropertyFilterSpec> fSpecList = new ArrayList<PropertyFilterSpec>();
fSpecList.add(fSpec);
 
// get the data from the server
RetrieveOptions ro = new RetrieveOptions();
RetrieveResult props = methods.retrievePropertiesEx(propColl,fSpecList,ro);
 
// go through the returned list and print out the data
if (props != null) {
for (ObjectContent oc : props.getObjects()) {
String folderName = null;
String path = null;
List<DynamicProperty> dps = oc.getPropSet();
if (dps != null) {
for (DynamicProperty dp : dps) {
folderName = (String) dp.getVal();
path = dp.getName();
System.out.println(path + " = " + folderName);
}
}
}
}
}//end collectProperties()
 
// Authentication is handled by using a TrustManager and supplying
// a host name verifier method. (The host name verifier is declared
// in the main function.)
//
// For the purposes of this example, this TrustManager implementation
// will accept all certificates. This is only appropriate for
// a development environment. Production code should implement certificate support.
private static class TrustAllTrustManager implements javax.net.ssl.TrustManager,
javax.net.ssl.X509TrustManager {
 
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
 
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
 
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
 
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
 
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
}
 
public static void main(String [] args) throws Exception {
 
// arglist variables
String serverName = args[0];
String userName = args[1];
String password = args[2];
String url = "https://"+serverName+"/sdk/vimService";
 
// Variables of the following types for access to the API methods
// and to the vSphere inventory.
// -- ManagedObjectReference for the ServiceInstance on the Server
// -- VimService for access to the vSphere Web service
// -- VimPortType for access to methods
// -- ServiceContent for access to managed object services
ManagedObjectReference SVC_INST_REF = new ManagedObjectReference();
VimService vimService;
VimPortType vimPort;
ServiceContent serviceContent;
 
// Declare a host name verifier that will automatically enable
// the connection. The host name verifier is invoked during
// the SSL handshake.
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
 
// Create the trust manager.
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new TrustAllTrustManager();
trustAllCerts[0] = tm;
// Create the SSL context
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
// Create the session context
javax.net.ssl.SSLSessionContext sslsc = sc.getServerSessionContext();
// Initialize the contexts; the session context takes the trust manager.
sslsc.setSessionTimeout(0);
sc.init(null, trustAllCerts, null);
 
// Use the default socket factory to create the socket for the secure connection
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
 
// Set the default host name verifier to enable the connection.
HttpsURLConnection.setDefaultHostnameVerifier(hv);
 
// Set up the manufactured managed object reference for the ServiceInstance
SVC_INST_REF.setType("ServiceInstance");
SVC_INST_REF.setValue("ServiceInstance");
 
// Create a VimService object to obtain a VimPort binding provider.
// The BindingProvider provides access to the protocol fields
// in request/response messages. Retrieve the request context
// which will be used for processing message requests.
vimService = new VimService();
vimPort = vimService.getVimPort();
Map<String, Object> ctxt = ((BindingProvider) vimPort).getRequestContext();
 
// Store the Server URL in the request context and specify true
// to maintain the connection between the client and server.
// The client API will include the Server's HTTP cookie in its
// requests to maintain the session. If you do not set this to true,
// the Server will start a new session with each request.
ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
ctxt.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
 
// Retrieve the ServiceContent object and login
serviceContent = vimPort.retrieveServiceContent(SVC_INST_REF);
vimPort.login(serviceContent.getSessionManager(),
userName,
password,
null);
 
// retrieve data
collectProperties( vimPort, serviceContent );
 
// close the connection
vimPort.logout(serviceContent.getSessionManager());
 
}
}