This example shows the use of a recursive TraversalSpec with the property collector. The recursive traversal spec enables the property collector to navigate a chain of nested objects of the same type.
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()); } }