Accessing and Manipulating Multiple Tasks
Use the ViewManager’s ListView method to identify the set of Tasks you want to monitor.
You can specify a smaller and more efficient data set using one of the ViewManager views with the Property Collector. Each view represents objects you have selected on the server. Views are more efficient because you only need a single instance of a PropertyCollector object, instead of multiple instances with multiple filter specifications.
Gathering Data with a ViewManager Object
Use one of the ViewManager methods to obtain information about Task objects and references while the session is running. The ViewManager’s ListView method allows you to customize your view with an input object list, the ContainerView method lets you view all objects in a folder, datacenter, resource pool, or other data container, and the InventoryView method lets you monitor the entire inventory. The smallest view you can create will be the most efficient way to retrieve task data.
The ViewManager has the following property:
viewList – An array of view references. Each array entry is a managed object reference to a view created by this View Manager.
See PropertyCollector Example (RetrievePropertiesEx) for an example that uses the ContainerView method to access Inventory data.
Task Monitoring Example Using the ListView Object
Use the ViewManager’s ListView method to specify the set of tasks that you want to monitor.
The following example uses the ViewManager service interface with a ListView method to access and manipulate Task objects. This example uses the property collector to monitor tasks that are created in the process of virtual machine cloning. This program creates two clones of the specified virtual machine and then monitors the tasks and prints out status and reference values when the tasks have completed.
The following steps describe the procedure for creating a program that uses the ListView managed object.
You can run the example below as a stand-alone program against your own server by copying the code sections into a .java file, compiling it, and then using the following command line syntax:
>cloneVMTask server-name username password vm-name
To create a program that uses the ListView managed object
1
import com.vmware.vim25.*;
2
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;
3
public class cloneVMTask {
4
// Services and methods
static ManagedObjectReference pCollector;
static ManagedObjectReference viewMgr;
static ServiceContent serviceContent;
static VimPortType methods;
/**
* getVmRef() retrieves a reference to the specified virtual machine.
*
* vmName - name of the virtual machine specified on the command line
*
* This function retrieves references to all of the virtual machines
* in the datacenter and looks for a match to the specified name.
*/
5
Create a function that retrieves references to all of the virtual machines in the datacenter and looks for a match to the specified name. The function in this example uses getVMRef(String, vmName), which retrieves a reference to the virtual machine that you specify on the command line (vmName) when you run this sample. The function also initializes the vmRef variable to null.
private static ManagedObjectReference getVmRef( String vmName )
throws Exception
{
ManagedObjectReference vmRef = null;
6
List<String> vmList = new ArrayList<String>();
vmList.add("VirtualMachine");
ManagedObjectReference cViewRef = methods.createContainerView(viewMgr,
serviceContent.getRootFolder(),
vmList,
true);
7
Create an ObjectSpec to define the beginning of the traversal. Use the setObj method to specify that the container view is the root object for this traversal. Set the setSkip method to true to indicate that you don't want to include the container in the results.
ObjectSpec oSpec = new ObjectSpec();
oSpec.setObj(cViewRef);
oSpec.setSkip(true);
8
TraversalSpec tSpec = new TraversalSpec();
tSpec.setName("traverseEntities");
tSpec.setPath("view");
tSpec.setSkip(false);
tSpec.setType("ContainerView");
9
oSpec.getSelectSet().add(tSpec);
10
PropertySpec pSpec = new PropertySpec();
pSpec.setType("VirtualMachine");
pSpec.getPathSet().add("name");
11
PropertyFilterSpec fSpec = new PropertyFilterSpec();
fSpec.getObjectSet().add(oSpec);
fSpec.getPropSet().add(pSpec);
12
List<PropertyFilterSpec> fSpecList = new ArrayList<PropertyFilterSpec>();
fSpecList.add(fSpec);
13
RetrieveOptions ro = new RetrieveOptions();
RetrieveResult props = methods.retrievePropertiesEx(pCollector,fSpecList,ro);
14
if (props != null) {
for (ObjectContent oc : props.getObjects()) {
String vmname = null;
List<DynamicProperty> dps = oc.getPropSet();
if (dps != null) {
for (DynamicProperty dp : dps) {
vmname = (String) dp.getVal();
// If the name of this virtual machine matches
// the specified name, save the managed object reference.
if (vmname.equals(vmName)) {
vmRef = oc.getObj();
break;
}
}
if (vmRef != null) { break; }
}
}
}
if (vmRef == null) {
System.out.println("Specified Virtual Machine not found.");
throw new Exception();
}
return vmRef;
 
}
15
private static ManagedObjectReference getVMParent(ManagedObjectReference vmRef)
throws Exception {
16
Create an Object Spec to define the property collection. Use the setObj method to specify that the vmRef is the root object for this traversal. Set the setSkip method to true to indicate that you don't want to include the virtual machine in the results.
// don't include the virtual machine in the results
ObjectSpec oSpec = new ObjectSpec();
oSpec.setObj(vmRef);
oSpec.setSkip(false);
17
PropertySpec pSpec = new PropertySpec();
pSpec.setType("VirtualMachine");
pSpec.getPathSet().add("parent");
18
PropertyFilterSpec fSpec = new PropertyFilterSpec();
fSpec.getObjectSet().add(oSpec);
fSpec.getPropSet().add(pSpec);
19
List<PropertyFilterSpec> fSpecList = new ArrayList<PropertyFilterSpec>();
fSpecList.add(fSpec);
20
RetrieveOptions ro = new RetrieveOptions();
RetrieveResult props = methods.retrievePropertiesEx(pCollector,fSpecList,ro);
21
ManagedObjectReference folderRef = null;
if (props != null) {
for (ObjectContent oc : props.getObjects()) {
List<DynamicProperty> dps = oc.getPropSet();
if (dps != null) {
for (DynamicProperty dp : dps) {
folderRef = (ManagedObjectReference) dp.getVal();
}
}
}
}
 
if (folderRef == null) {
System.out.println("Folder not found.");
throw new Exception();
}
return folderRef;
}
Now that we have the reference information for the virtual machine that you specified on the command line (vmRef) and a reference for the parent directory (folderRef), we are ready to create the clone virtual machines.
22
To create clones, use the cloneVM method and pass in the vmRef that we retrieved previously.
private static void cloneVM(ManagedObjectReference vmRef) throws Exception {
23
VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
VirtualMachineRelocateSpec vmrs = new VirtualMachineRelocateSpec();
cloneSpec.setLocation(vmrs);
cloneSpec.setPowerOn(true);
cloneSpec.setTemplate(false);
24
ManagedObjectReference folder = getVMParent( vmRef );
25
ManagedObjectReference cloneTask = methods.cloneVMTask( vmRef, folder, "clone__1", cloneSpec);
ManagedObjectReference cloneTask2 = methods.cloneVMTask( vmRef, folder, "clone__2", cloneSpec);
26
List<ManagedObjectReference> taskList = new ArrayList<ManagedObjectReference>();
taskList.add(cloneTask);
taskList.add(cloneTask2);
ManagedObjectReference cloneTaskList = methods.createListView(viewMgr, taskList);
Next we will set up a property filter for WaitForUpdatesEx. This includes creating an object spec, a traversal spec, a property spec, a filter spec, and finally a property filter. The next six steps will describe these procedures.
27
ObjectSpec oSpec = new ObjectSpec();
oSpec.setObj(cloneTaskList);
oSpec.setSkip(true);
28
TraversalSpec tSpec = new TraversalSpec();
tSpec.setName("traverseTasks");
tSpec.setPath("view");
tSpec.setSkip(false);
tSpec.setType("ListView");
29
oSpec.getSelectSet().add(tSpec);
30
PropertySpec pSpec = new PropertySpec();
pSpec.setType("Task");
pSpec.setAll(false);
pSpec.getPathSet().add("info.state");
pSpec.getPathSet().add("info.result");
31
PropertyFilterSpec fSpec = new PropertyFilterSpec();
fSpec.getObjectSet().add(oSpec);
fSpec.getPropSet().add(pSpec);
32
ManagedObjectReference pFilter = methods.createFilter(pCollector, fSpec, true);
In the next section, we use the waitForUpdatesEx method to look for a change in cloneTask.info.state and cloneTask.info.result. When the state is “success”, cloneTask.info.result is the managed object reference of the clone. Note that the order of property retrieval is not guaranteed, and it may take more than one call to waitForUpdatesEx to retrieve both properties for a task.
This code does not set a time-out (WaitOptions.maxWaitSeconds is unset), so after it has retrieved all of the property values, waitForUpdatesEx will block the thread, waiting for the TCP connection with the vSphere Server to time-out.
How a client application handles the session depends on the particular context. (The client can call WaitForUpdatesEx from its own thread, look for specific updates and then stop calling the method.)
For more information about WaitOptions and the waitForUpdatesEx method, see Client Data Synchronization (WaitForUpdatesEx).
33
String version = "";
Boolean wait = true;
WaitOptions waitOptions = new WaitOptions();
 
while ( wait ) {
34
UpdateSet uSet = methods.waitForUpdatesEx(pCollector, version, waitOptions);
 
if (uSet == null) {
wait = false;
}
else {
35
version = uSet.getVersion();
36
List<PropertyFilterUpdate> pfUpdates = uSet.getFilterSet();
for (PropertyFilterUpdate pfu : pfUpdates) {
37
List<ObjectUpdate> oUpdates = pfu.getObjectSet();
for (ObjectUpdate ou : oUpdates) {
38
if (ou.getKind() == ObjectUpdateKind.MODIFY) {
 
String name = "";
TaskInfoState state;
ManagedObjectReference cloneRef = new ManagedObjectReference();
39
List<PropertyChange> pChanges = ou.getChangeSet();
40
for (PropertyChange pc : pChanges) {
name = pc.getName();
 
//The task property names are info.state or info.result;
//pc.val is an xsd:anyType:
//-- for info.state, it is the state value
//-- for info.result, it is the clone reference
if (name.equals("info.state")) {
state = (TaskInfoState)pc.getVal();
System.out.println("State is "+state.value());
}
else if (name.equals("info.result")) {
cloneRef = (ManagedObjectReference)pc.getVal();
System.out.println("Clone reference is "+cloneRef.getValue());
}
}
Authentication is handled 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;
}
}
Now we are set to retrieve the task information, so we implement the main method.
// cloneVMTask( server, user, password, virtual-machine )
public static void main(String [] args) throws Exception {
41
String serverName = args[0];
String userName = args[1];
String password = args[2];
String vmName = args[3];
String url = "https://"+serverName+"/sdk/vimService";
42
// -- 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;
43
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
44
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());
45
HttpsURLConnection.setDefaultHostnameVerifier(hv);
46
SVC_INST_REF.setType("ServiceInstance");
SVC_INST_REF.setValue("ServiceInstance");
47
vimService = new VimService();
methods = vimService.getVimPort();
Map<String, Object> ctxt = ((BindingProvider) methods).getRequestContext();
48
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);
49
serviceContent = methods.retrieveServiceContent(SVC_INST_REF);
methods.login(serviceContent.getSessionManager(),
userName,
password,
null);
50
pCollector = serviceContent.getPropertyCollector();
viewMgr = serviceContent.getViewManager();
51
ManagedObjectReference vmRef = getVmRef( vmName );
52
cloneVM( vmRef );
53
methods.logout(serviceContent.getSessionManager());
}
}
Note For general task monitoring, it is a best practice to use a ViewManager to monitor specific tasks. See the API Reference for more information about using views.
Gathering Data with a TaskManager Interface
TaskManager is a service interface that you can also use for accessing and manipulating Task objects. This approach uses a PropertyCollector that includes the recentTask property of the TaskManager managed object that corresponds to the Recent Tasks pane at the bottom of the vSphere client User Interface.
You can use the following TaskManager properties in your client application.
descriptionTaskDescription object that includes a methodInfo property. methodInfo contains a key-based array that TaskManager uses to populate the value of a TaskInfo data object’s descriptionId property with the name of the operation. Examples of two elements from this key-based array are methodInfo["Folder.createVm"] and methodInfo["Folder.createClusterEx"].
recentTask – Array of Task managed object references that are queued to run, running, or completed within the past 10 minutes. On ESX/ESXi hosts that are managed by a vCenter Server, a completed task must also be one of the 200 most recent tasks to be included in the array. A vSphere Client connected to a vSphere Server displays queued, running, and completed tasks in the Recent Tasks pane.
In addition to these properties, TaskManager has the following methods:
CreateTask – Used by other methods to create a custom Task object. Developers creating extensions can use this method to create custom Task objects.
CreateCollectorForTasks – Creates an object that contains all tasks from the vCenter Server database that meet specific criteria. You cannot run this method against an ESX/ESXi system. See Using a TaskHistoryCollector.
TaskManager and Task Managed Objects shows a UML class diagram for TaskManager and associated objects.
TaskManager and Task Managed Objects
Examining Recent Tasks with TaskManager
To obtain the list of recent tasks, use a PropertyCollector to obtain references to the TaskManager and to all Task objects from the recentTask property of the TaskManager. Example: PropertyFilterSpec Definition to Obtain recentTask Property Values shows an excerpt from the TaskList.java sample that creates the ObjectSpec, PropertySpec, and a TraversalSpec to obtain references to all Task objects on the server from the TaskList. See also Property Collector.
Example: PropertyFilterSpec Definition to Obtain recentTask Property Values
private PropertyFilterSpec[] createPFSForRecentTasks(ManagedObjectReference taskManagerRef) {
PropertySpec pSpec = new PropertySpec();
pSpec.setAll(Boolean.FALSE);
pSpec.setType("Task");
pSpec.setPathSet(new String[] {"info.entity", "info.entityName", "info.name",
"info.state", "info.cancelled", "info.error"});
ObjectSpec oSpec = new ObjectSpec();
oSpec.setObj(taskManagerRef);
oSpec.setSkip(Boolean.FALSE);
TraversalSpec tSpec = new TraversalSpec();
tSpec.setType("TaskManager");
tSpec.setPath("recentTask");
tSpec.setSkip(Boolean.FALSE);
oSpec.setSelectSet(new SelectionSpec[]{tSpec});
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
pfSpec.setPropSet(new PropertySpec[]{pSpec});
pfSpec.setObjectSet(new ObjectSpec[]{oSpec});
return new PropertyFilterSpec[]{pfSpec};
}
 
For ESXi hosts managed by vCenter Server, use a TaskHistoryCollector. See Using a TaskHistoryCollector.