Hello everyone,



I am very enthousiast to write this first blog post and share what I've learned about programing with VMware sdk in Java.

In this tutorial, I am going to explain the basis of retrieving object's properties with the VMware SDK and also talk about a project that I started few month ago. I didn't really find the time to finish it and I thought it would be great to share with the community sample codes that you can use to retrieve datas from your VMware infrastructure.I won't share the code of my project but don't worry, I will guide you through the process of coding your own "Vmware SDK" based app.


I know that programing with the VMware Java SDK can be a real pain and especially when we deal with the propertyCollector and filters. Retrieving a simple property on a VMware object requires lot of lines of code, knowing that my app needed to get the properties VMs + VM's hardware (which represente quite a lot of information), after working some time I found the task too time-consuming.

So I decided to try the VI Java API which is a set of Java libraries that sits on top of the existing vSphere SDK Web Services interface.I recoded my app and I found out that retrieving datas with this API was much faster than using the original VMware SDK, it did the work perfectly and made my code more readable.


But before talking about this great API, let me first introduce the basis of the vSphere SDK.



1) Object Model and Property Collector


In order to retrieve properties, perform operations or modify entities within the vSphere API, it is important to understand the vSphere Object Model’s structure and relationships. The vSphere API consists of three types of objects:


- Managed Object: is a server side object like VMs or Hosts

- Managed Object Reference: is a client reference to a Managed Object

- Data Object: contains information about a Managed Object and can also be used to transfer data between a client and server


Now, imagine you want to get the names of all hosts in the inventory, or maybe you want to monitor for changes to the power state of all VMs in the inventory, or you want to keep track of the host that each VM is running on, you have to use the Property Collector.

The PropertyCollector gives you the ability to retrieve properties of the ManagedObject and also monitor the changes of any properties youinterested in.

In order to use the PropertyCollector to retrieve informations from Managed Object, you need to specify what data you want to retrieve and this is done with something called PropertyFilterSpec and this object has at least 2 properties:


- PropertySpec : What property you want to retrieve, the name of a VM for exemple

- ObjectSpec: It identifies the starting object in the inventory

- TraversalSpec: (optional): Define how to traverse the inventory


And those objects have other objects as parameter,and you need to create. Obviously, you see that it requires many lines of code before retrieving the name of a VM or whatever properties you want to get from your vCenter.



2) VI Java API Introduction


Virtual Infrastructure API is an open source project created by Steve Jin from VMware R&D. It aims to simplify the use of VI SDK and improve the performance.

This API encapsulate the PropertyCollector behind Java methods and provide a whole bunch of ManagedObject that will allow you to manipulate vmware objects without any effort.


The picture below represent the object architecture that will be very helpful to code you program and you will see further in this article that Imanipulate those objects to retrieve specific properties.


Using vSphere VI Java API - tutorial_about

Let's go back to my own projet where my goal was to recreate a vSphere "VM edit settings" panel in order to do modification of multiple VM at the same times.

Think about it, your boss ask you to apply VM advanced settings such as "isolation.tools" for security reason to VMs of the whole infrastructure. You can certainly spend less than an hour making a PowerCLI script which is something I did before my project, or having a flexible GUI tool that contains all the predifined settings and allow admins to modify settings of 1000 VMs in one shot.


What you need to start coding a VI Java API project:


- Your favorite IDE (for my project I used NetBeans IDE 7.3.1)

- The VMware Java SDK which is a Jar file called vim25, you can download it here: http://www.vmware.com/support/developer/vc-sdk/index.html

- The Vi Java API, you can download it here: http://sourceforge.net/projects/vijava/files/

- You are good to go!



3) Start coding


Create a new project and add the correct Jar files to your project (the Jar from the VMware SDK and the Jar from the VI Java API + dom4j if I remember right).

Now I am going to explain lines of code from my project that you can easily use an modify.



3.1) Connect to vCenter


  1. public ServiceInstance Initialisation(String url, String username, String password) throws RemoteException, MalformedURLException{  

  2.        ServiceInstance si = new ServiceInstance(new URL(url), username, password, true);  

  3. return si;  

  4.    }  



This is the method I use to connect my vCenter Server. The initialization method takes 3 parameters which are:


- Url: this is the URL of the vCenter plateform and it look like this https://192.168.1.1/sdk

- Username: nothing special

- Password: nothing special


This method will return a ServiceInstance object which will be used to have access to your VMware object tree (see the picture in section 2). If you're doing GUI app, don't call this method from the UI thread otherwise it will freeze your Java window.



3.2) Retrieve ManagedEntity from Inventory Navigator


  1. public ManagedEntity[] RetreiveVM(ServiceInstance si) throws InvalidProperty, RuntimeFault, RemoteException{  

  2.        Folder rootFolder = si.getRootFolder();  

  3.        ManagedEntity[] mes = new InventoryNavigator(rootFolder).searchManagedEntities("VirtualMachine");  

  4. return mes;  

  5.    }  


This method take the ServiceInstance object that we had in the previous section. Here we have to create a rootFolder object from our ServiceInstance object.

And next we can already retrieve ManagedObject (VirtualMachine in my exemple) with the searchManagedEntities method and fill the mes[] table with all the VMs of your infrastructure.

From the InventoryNavigator object, you can use:


-searchManagedEntities("VirtualMachine")

-searchManagedEntities("HostSystem")

-searchManagedEntities("Datacenter")

- and some other that i am not aware of...


With these methods, you can already retrieve VMs from your vCenter. The next will be to retrieve information of the VM and you will see that in the next section.



3.3) Convert ManagedEntity object and retrieve VM properties


First of all, you will have to convert the "mes" object into a "virtualMachine" object. Then you are free to exploit the hundreds of properties of the VM object.


  1. publicvoid setSelectedVM(int index) {  

  2.        VirtualMachine vm = (VirtualMachine) mes[index];  

  3.        System.out.println("Guest OS:"+vm.getSummary().getConfig().guestFullName);  

  4.        System.out.println("VM Version:"+vm.getConfig().version);  

  5.        System.out.println("CPU:"+vm.getConfig().getHardware().numCPU+" vCPU");  

  6.        System.out.println("Memory:"+vm.getConfig().getHardware().memoryMB+" MB");  

  7.        System.out.println("Memory Overhead:"+(long)vm.getConfig().initialOverhead.initialMemoryReservation/1000000f+" MB");  

  8.        System.out.println("VMware Tools:"+vm.getGuest().toolsRunningStatus);  

  9.        System.out.println("IP Addresses:"+vm.getSummary().getGuest().getIpAddress());        

  10.        System.out.println("State:"+vm.getGuest().guestState);  

  11.    }  


Here is almost all the information you can get in the General Section of the Sumary tab in the vSphere client. But you can actually retrieve every single attribute that are visible in the vSphere Client, and you can see the screenshot below showing the tones of properties available:


Using vSphere VI Java API - tutorial_really_02



And here is screenshot of a part of my app where you can recognize the option tab of a VM's setting.


Using vSphere VI Java API - tutorial_about_03



3.4) Retrieve hardware properties


Let's dive into hardware properties. For each VMs, I want to be able to get the the hardware objects and retrieve properties from them. For each virtualMachine object, you can use this code to get the attached hardware:


  1. for (VirtualDevice vd : vm.getConfig().getHardware().getDevice()) {  

  2. try {  

  3. if (vd instanceof VirtualMachineVideoCard) {  

  4.                    VirtualMachineVideoCard vVideoCard = (VirtualMachineVideoCard) vd;  

  5.                } elseif (vd instanceof VirtualMachineVMCIDevice) {  

  6.                    VirtualMachineVMCIDevice vVMCI = (VirtualMachineVMCIDevice) vd;  

  7.                } elseif (vd instanceof VirtualSCSIPassthrough) {  

  8.                    VirtualSCSIPassthrough vSCSI = (VirtualSCSIPassthrough) vd;  

  9.                } elseif (vd instanceof VirtualDisk) {  

  10.                    VirtualDisk vDisk = (VirtualDisk) vd;  

  11.                    VirtualDiskFlatVer2BackingInfo vbi = (VirtualDiskFlatVer2BackingInfo) vd.getBacking();  

  12.                } elseif (vd instanceof VirtualCdrom) {  

  13.                    VirtualCdrom vCDrom = (VirtualCdrom) vd;  

  14. if (vCDrom.getBacking() instanceof VirtualCdromRemoteAtapiBackingInfo) {  

  15.                    } elseif (vCDrom.getBacking() instanceof VirtualCdromAtapiBackingInfo) {  

  16.                        VirtualCdromAtapiBackingInfo vabi = (VirtualCdromAtapiBackingInfo) vCDrom.getBacking();  

  17.                    } elseif (vCDrom.getBacking() instanceof VirtualCdromIsoBackingInfo) {  

  18.                        VirtualCdromIsoBackingInfo vibi = (VirtualCdromIsoBackingInfo) vCDrom.getBacking();  

  19.                    } elseif (vCDrom.getBacking() instanceof VirtualCdromRemotePassthroughBackingInfo) {  

  20.                        VirtualCdromRemotePassthroughBackingInfo vpbi = (VirtualCdromRemotePassthroughBackingInfo) vCDrom.getBacking();  

  21.                    }  

  22.                } elseif (vd instanceof VirtualEthernetCard) {  

  23.                    VirtualEthernetCard vEth = (VirtualEthernetCard) vd;  

  24.                }  

  25.            } catch (Exception e) {  

  26.            }  

  27.        }  


With those lines of code, you can easily get the following hardware devices: VideoCard, VMCIDevice, VirtualSCSIPassThrough, VirtualDisk, VirtualCdrom and VirtualEthernetCard.

There are still missing hardware that I didn't have time to integrate to my project but you have the most of it here.


So let's take for exemple the VirtualEthernetCard. In my app, I have a Java class for each hardware type and I pass each hardware objects to the constructor of the corresponding hardware classes.

This is a sample code to see you VM's network card properties:


  1. VirtualEthernetCard vEth = (VirtualEthernetCard) vd;  

  2. if (vEth instanceof VirtualE1000) {  

  3.                        System.out.println("Adapter type: E1000");  

  4.                    } elseif (vEth instanceof VirtualE1000E) {  

  5.                        System.out.println("Adapter type: E1000E");  

  6.                    } elseif (vEth instanceof VirtualPCNet32) {  

  7.                        System.out.println("Adapter type: PCnet32");  

  8.                    } elseif (vEth instanceof VirtualVmxnet) {  

  9.                        System.out.println("Adapter type: Vmxnet");  

  10.                    } elseif (vEth instanceof VirtualVmxnet2) {  

  11.                        System.out.println(Adapter type: "Vmxnet2");  

  12.                    } elseif (vEth instanceof VirtualVmxnet3) {  

  13.                        System.out.println("Adapter type: Vmxnet3");  

  14.                    }  

  15.                    System.out.println("connected"+vEth.getConnectable().connected);  

  16.                    System.out.println("Connect at power on"+vEth.getConnectable().startConnected);  

  17.                    System.out.println("Manual"+vEth.addressType);  

  18.                    System.out.println("MAC address:"+vEth.macAddress);  

You are now able to read properties of every single object by following this technique and the picture in section 2. However, some of the advanced hardware properties are tricky to find and it can take long before you find out the right object to use.

But Steve Jin came up with another great tool, this is called "vSphere Code Generator".



3.5) vSphere Code Generator


Let's take an introduction of this tools from the doublecloud.org website:


If you have used Onyx for generating PowerCLI code before, you can think it as Java version of Onyx. Even better, it generates complete Java code which is ready to run once you supply the URL, username, and password. It’s so easy that from now on, all the system administrators have no excuse for not trying open source vSphere Java API.


At its heart, the code generator is a reversed proxy which sits between a vSphere Client and vCenter or ESX(i) server, and intercepts the SOAP XML messages. With the XML messages, I designed the algorithm to automatically generate the Java code based on the open source Java API code.

Unlike Onyx, the Java code generator provides richer GUI which allows you to:

  • Record both the requests and responses.

  • Sort the recorded messages in any order.

  • Generate complete code of any selected requests.

  • Save recorded messages to a local file, and read it back later.

  • Support raw HTTP data, XML, Java simultaneously in different tabs.


Ok now let's use this tool to find the correct object in the Java API. You want to get the checkbox value of "Force a VM to enter BIOS setup screen on next reboot" in VM settings > Options > Boot Options, first thing to do is to launch the vSphere code generator from command line "java -jar steveproxy.jar". Then you have to connect the proxy to your VMware infrastructure and connect your vSphere client to https://127.0.0.1:1545, there you have a quick tutorial: http://www.doublecloud.org/doublecloud-proxy/

Once your vSphere client is connected to your VMware infrastructure through the proxy, select a VM and change the "Force a VM to enter BIOS setup screen on next reboot" checkbox value:


Using vSphere VI Java API - tutorial_everyone_04


Now switch to your vSphere code generator window and try to find the ReconfigVM_Task:


Using vSphere VI Java API - tutorial_everyone_05

Each time a user close the "Edit Settings" window of a virtual machine on vSphere, even if the user didn't do any modification to a virtual machine settings, a "reconfigure" task is sent. So with the vSphere code generator you can actually find the "reconfigure" request sent when you changed the "Force a VM to enter BIOS setup screen on next reboot" checkbox value.

You can see in the screenshot above the Java code you can run to change this value and it gives you informations about the Java object that is concerned by this parameter.

Now let's take a look at the Java code:

Using vSphere VI Java API - tutorial_really_06

And here you find the "enterBIOSSetup" boolean value which refer to the "Force a VM to enter BIOS setup screen on next reboot" checkbox value.



4) Conclusion


The VI Java API is a fast and easy way to create application based on the features of the vSphere Client. In this article you have all the informations needed to retrieve properties of VMware vSphere object, and with the vSphere code generator you have all you need to execute "reconfigureVM" task from your Java app.

I hope you enjoy this first article and don't forget to post a comment if you liked it or give me suggestion for future blog post.