Home > vSphere API > Introducing A Tiny Yet Powerful API to Manage and Automate vSphere

Introducing A Tiny Yet Powerful API to Manage and Automate vSphere

February 3rd, 2010 Leave a comment Go to comments

In yesterday’s blog, I talked about a little known secret of vSphere MOB – the invisible embedded XML in the HTML pages. To take advantage of the secret, I created a client side REST API which was shipped in VI Java API 2.0.

Note that I call it a Client side REST, because it is different from conventional REST API whose boundary is on the wire. With the Client side REST, the boundary is on the client side over the Java API. It implies that you cannot use a Web browser to “GET” information as would you with most conventional REST API. Anyway, the difference is not big enough for you to think twice because even if you use conventional REST API, most likely you will use a wrapper layer instead of tweaking XML data directly.

Time to learn how to "Google" and manage your VMware and clouds in a fast and secure

HTML5 App

The API is very powerful and easy to use, and can do almost everything the SOAP APIs can do. There are a few developers tried it and fell in love with it, but most people don’t know much about it.

When Would You Want to Use It?

As said, the Client REST API provides similar functionality as SOAP based API. The key advantages of the API are

  • Super fast loading time compared with VI SDK. Already impressed by the VI Java API SOAP implementation, this API is about 20 times faster than that in loading time.
  • Super simple and light-weighted. Only 4 Java classes involved and zero dependency on any third party library other than J2SE.
  • XML centric so that you can easily apply XPATH, XSLT, XQuery on the data returned from the API.
  • Version Neutral. It works with 2.0, 2.5, and 4.0 without any change in your code.
  • Can be easily ported to other languages. I actually did a Python version and then handled it over to my colleagues. Consider the amount of code involved, it’s not a big project.

Once you are clear with these benefits, you can decide how it fits your projects. Before you make the final decision, please read on to the discussion part.

Architecture Overview

As you can see from the following figure, there are two layers: REST API layer and the managed object wrapper/cache layer. The later is built on top of the former. You can build your applications on either or both of these two layers.

The REST API layer talks to the vCenter/ESX(i) as a MOB client. It takes REST-like URL from the callers and makes HTTP calls to the server. When the responses come back, it converts them back to XML and returns to the caller.

The managed object wrapper/cache layer provides a bit higher level services, so you can speak in terms like managed object, properties, data object, etc. The caching is a little interesting here. It basically provides a caching around a wrapper. The cache holds the whole property XML so that you can retrieve multiple properties without going to the server twice.

The following diagram shows the object models. RestClient is the REST API layer. The RestManagedObject and CachedManagedObject are Managed Object wrapper/cache layer.

The ResultConverter is a helper class that you don’t even need to know, but it does the heavy lifting in the back. The challenge for the ResultConvert is that the responses of method calls do NOT have any XML embedded, therefore the code has to parse the HTML tables to XML. It can be tricky when you have tables embedded in tables for several layers.

 
 

As a long time software professional, I know how important the samples are to learn a new APIs. Let’s move onto the HelloWorld like sample.

A Sample Using Both API Layers

This is a sample included with the VI Java API that shows how you can use the API. It has two methods that demo the usage of the REST level API and managed object level API. I believe it is clear enough for me not to add any additional explanation. Click here to check out the full code from the code repository.

public class RestAppDemo
{
  public static void main(String[] args) throws Exception
  {
    RestClient rc = new RestClient("https://8.8.8.8", "root", "pass");
    runRestLevel(rc);
    runMOLevel(rc);
  }

  public static void runMOLevel(RestClient rc) throws Exception
  {

    RestManagedObject si = new RestManagedObject(rc, "ServiceInstance");

    System.out.println("name:" + si.getPropertyAsString("content.about.fullName"));
    System.out.println(si.invoke("currentTime"));
    System.out.println(si.invoke("retrieveContent"));

    String allXml = si.getAllProperties();
    System.out.println(allXml);
    CachedManagedObject csi = new CachedManagedObject(allXml);
    System.out.println("name:" + csi.getProperty("content.about.fullName"));
    System.out.println("root:" + csi.getProperty("content.rootFolder"));
    System.out.println("cap:" + si.getPropertyAsString("capability.multiHostSupported"));

    String em_id = si.getPropertyAsString("content.eventManager");
    RestManagedObject eventMgr = new RestManagedObject(rc, em_id);
    System.out.println("latest evt:" + eventMgr.getPropertyAsString("latest.fullFormattedMessage"));

    RestManagedObject vm = new RestManagedObject(rc, "48");
    System.out.println("reload:" + vm.invoke("reload"));
    CachedManagedObject cvm = new CachedManagedObject(vm.getAllProperties());
    System.out.println("Roles:" + cvm.getProperty("effectiveRole"));
  }

  public static void runRestLevel(RestClient rc) throws Exception
  {
    String contentXml = rc.get("moid=ServiceInstance&doPath=content");
    System.out.println(contentXml);

    XPath xpath = XPathFactory.newInstance().newXPath();
    String emMOR = xpath.evaluate("//eventManager/text()", new InputSource(new StringReader(contentXml)));
    System.out.println("view:" + emMOR);
    String lastEventXml = rc.get("moid=" + emMOR + "&doPath=latestEvent");
    xpath.reset();
    String eMessage = xpath.evaluate("//fullFormattedMessage/text()", new InputSource(new StringReader(lastEventXml)));
    System.out.println("Latest Event: " + eMessage);

    System.out.println(rc.get(null));
    System.out.println(rc.get("?moid=ServiceInstance&doPath=content%2eabout"));
    long start = System.currentTimeMillis();
    System.out.println(rc.get("?moid=48"));
    long end = System.currentTimeMillis();
    System.out.println("time taken:" + (end-start));
    Map para = new Hashtable();
    para.put("newName", "Melody_SuSe");
    System.out.println(rc.post("moid=48&method=rename", para));
    Map para1 = new Hashtable();
    System.out.println(rc.post("http://10.20.143.205/mob/?moid=48&method=acquireMksTicket", para1));
  }
}

Discussion

Although the Client REST API works perfectly fine, it’s not supported by VMware but the open source community. The underlying MOB may change over the time. Without the secret XML, the whole stuff just doesn’t work unless much more efforts there to convert the property HTML to XML.

Having said that, it’s still a good choice for you to write small applications, especially small utilities, automation scripts, XML centric applications, etc.

Are you ready to give it a try? Visit the VI Java API project home. Everything is there.

  1. Bar
    February 3rd, 2011 at 06:54 | #1

    Hello Steve,
    I have the following problem:
    I have 170 vms and I’m trying to get all the vm’s xml.
    After a couple of restClient calls the server locks itself.
    Is there a limit of restclient calls?

    thanks

  2. February 3rd, 2011 at 10:47 | #2

    I don’t know a limit like that. What version of vCenter/ESX(i) do you have and talk to? Are they licensed?
    -Steve

  3. Bar
    February 6th, 2011 at 08:06 | #3

    I’m using vcenter 4.0 and it licensed.
    I have a client installed on my machine and it talks with remote server.
    For every vms it opens a connection with restClient to extract the xml.
    Every 15 min the client rescan the vms to see if the file has changed.
    The problem is that every rescan new sessions are opened (for already scanned vms) and after a couple of scans of the client I have 598 open session and the server locks itself.
    I thought the cookie in the restClient should trace existing sessions, but somehow it fails in my case.
    I read that in vcenter 4.0 there is a limit on the number of opened connections.

    thanks

  4. February 6th, 2011 at 12:40 | #4

    OK. From your description, you’ve found the problem of too many sessions. I have a post discussing session management, just search for it.
    You can actually, and should, re-use a session for many managed objects. Good luck!
    Steve

  5. Bar
    February 7th, 2011 at 04:24 | #5

    Thanks a lot for your help!
    where can I find the code samples under
    http://vijava.svn.sourceforge.net/viewvc/vijava/trunk/src/com/vmware/vim25/mo/samples/ ?
    The webpage is not available.

  6. February 7th, 2011 at 10:50 | #6

    Sorry about it. Sourceforge has technical issue recently. I think Hudson project has a copy on its website. You can search it there – you need source jar for sample code.

    -Steve

  7. Juno
    March 1st, 2011 at 03:48 | #7

    Hello Steve,
    Is there some kind of xml file under the api that gathers all the vms moid against their real names?
    I mean, is there a less expensive way to collect all the machines names besides going through every machine xml (via moid) and than to get its name field?

  8. March 1st, 2011 at 11:00 | #8

    Unfortunately there is no such XML. You can however use PropertyCollector to grab all the VMs and their names.

    Steve

  1. June 13th, 2011 at 09:06 | #1
  2. September 7th, 2011 at 00:01 | #2