API Announcements How to VMware {code}

vSphere management with Java and VI/JSON APIs

Introduction

This blog post demonstrates how to generate client-side Java bindings from the VI/JSON OpenAPI specification and use them in a simple application to communicate with a vCenter instance. We will create a Java project with Gradle and use the openapi-generator-gradle-plugin to generate bindings code. The sample application will then use the classes provided by the bindings code to log in to a live VC instance, create a datacenter and add a host. In addition, we will provide some sample code demonstrating how to use the PropertyCollector API to monitor the VC inventory for changes.

Using the OpenAPI generator to produce API bindings from the VI/JSON spec

The OpenAPI Tools suite uses the OpenAPI spec to generate client and server-side bindings (SDKs) for various programming languages. The tooling is controlled via numerous parameters, possibly resulting in bindings with incompatible interfaces. This example uses the Gradle plugin to generate typical bindings that will be later used in a simple Java project.

The first step is to download the VI/JSON spec – Virtual Infrastructure JSON OpenAPI Specification 8.0 U1. Then we apply the openapi-generator-gradle-plugin and use its openApiGenerate function in our project’s build.gradle file to define the binding generation configuration. Check out the sample from the build.gradle file below. Note that our project uses Gradle 8.0.2, and some details might differ if using other versions. If you are unfamiliar with Gradle, make sure to check the official documentation for more details

The bindings code would get generated before project compilation. 

Using OpenAPI Java bindings to interact with vCenter

This example assumes some prior knowledge of the vSphere Web Services API Programming Model. For a refresh, please refer to the vSphere Web Services SDK Programming Guide (8.0U1).  The specifics around using the VI/JSON protocol are discussed here.  You could also refer to the Virtual Infrastructure JSON API Reference Guide.

Add a Host to a Datacenter

Adding a Host (ESXi) to a Datacenter involves retrieving the root ServiceContent object that serves as a catalog for the various available APIs. We use it to get references to various managed objects like the SessionManager we use for login, the ViewManager, the root folder of the inventory, etc.

Initialize an API client

In order to establish connection to the Virtual Infrastructure JSON API’s endpoint we would need an instance of the com.vmware.vijson.bindings.client.ApiClient class. In the general case we would extend the ApiClient class and overwrite its buildRestTemplate() method to account for some specifics of the VI/JSON API.

The buildRestTemplate() method returns org.springframework.web.client.RestTemplate so you can refer to Spring’s documentation for more details. The highlight here is that we add a new request interceptor (ClientHttpRequestInterceptor) that stores the session id after login and appends it as a header to each subsequent request to the VI/JSON API. Since the VI/JSON API does not allow null values in the incoming json, we also need to add a message converter (MappingJackson2HttpMessageConverter) which filters all null values in the request body before passing it to the VI/JSON API endpoint.

Once we setup the SessionAwareNullDisallowingApiClient instance we just need to pass the VI/JSON API endpoint address via the setBasePath method

The API client’s base path should point to the server URL from the OpenAPI spec

Retrieve  root service content 

This code snipped demonstrates how to obtain a reference to the ServiceInstance object. This is done by initializing a ServiceInstanceApi stub and calling the getContent method.

Login

This code snippet demonstrates how to obtain a reference to the SessionManager via the ServiceContent instance and use the SessionManagerAPI to log in using username and password. Additional login parameters can be passed via an instance of the LoginRequestType class.

Create a datacenter, add a host, and obtain the host’s resource pool reference

The following code snippet demonstrates how to use the FolderAPI to create a new Datacenter folder in the inventory. Here we use the serviceContent instance to obtain a reference to the root folder and call the createDatacenter method, passing an instance of the CreateDatacenterRequestType where we have specified the datacenter’s name.

As a next step,  we use the DatacenterAPI to obtain a reference to the HostFolder within the newly created Datacenter and pass it to the addStandaloneHostTask method along with an AddHostRequestType instance to add a new Host. We use the AddHostRequestType instance to pass login credentials and additional configuration. Since adding a host is usually a long-running task, it is executed asynchronously and the addStandaloneHostTask method returns a Task reference that we can later use to monitor whether the add host action is completed successfully, handle errors if not, etc. This is done in the next step by initializing an instance of the TaskAPI class and passing it along with the Task reference to TaskInfo’s waitForTask method. We can use the resulting TaskInfo object to obtain information about the Add host task’s status.

Monitoring the VM inventory for changes using the PropertyCollector API

This section demonstrates how to use the PropertyCollectorAPI to monitor the state of some parts of the inventory, given filters and property specs. Please refer to this section of the programming guide if you are unfamiliar with the PropertyCollectorAPI. The PropertyCollector API is quite complex, so a thorough understanding of the underlying programming model is strongly recommended.

Create a ContainerView and an Object spec.

Creating a ContainerView is the first step. It provides information about what type of ManagedObjects we want to monitor. ViewManagerApi is used to create a ContainerView instance given a reference to the ViewManager instance and some configuration supplied via a CreateContainerViewRequestType object. A reference to the newly initialized ContainerView is passed to an ObjectSpec instance which is part of the PropertyCollector’s filter configuration. More on that later in the blog post.

Create property spec

Another essential part of PropertyCollector’s configuration is the PropertySpec. It defines the actual ManagedObject properties that we want to monitor for changes. The code snipped below shows how to set it up.

Instantiate a PropertyCollector object and create a persistent filter

After initializing an ObjectSpec and a PropertySpec, we are ready to set up the PropertyCollector. We start by obtaining a reference to a PropertyCollector instance for the serviceContent object. We then use an instance of the PropertyCollectorAPI to create a filter passing the necessary configuration via a  CreateFilterRequestType object instance. See the code snipped below for more details.

Initiate monitoring

This section demonstrates how to start the monitoring task. This is usually done in a separate thread, but we skip this part for simplicity. To start monitoring for changes, we call the waitForUpdatesEx method of the propertyCollector instance we just configured. It requires a WaitOptions object that provides some configuration, like a timeout and an initial version of the inventory state. Once the waitForUpdatesEx method is called, it will return a UpdateSet object each time the state of the inventory changes.

Summary

So this is how one can use the VI/JSON OpenAPI specification to generate Java bindings and utilize the VC Automation API(s) to interact with a VC instance. Please mind the disclaimer below. Feel free to explore the vSphere Web Services SDK Programming Guide (8.0U1) for more examples with regard to API usage and programming models.

Disclaimer

The VMware-provided OpenAPI spec formally describes the officially-supported VI/JSON wire protocol. Although the spec is standard-compliant, due to VI APIs’ size and complexity, only some 3rd-party tools are capable of producing bindings with sufficient quality from it. This blog post presents Java-based examples based on the bindings produced by one of the most advanced tools: the OpenAPI Generator. The build scripts and code samples are provided as-is for convenience and are UNSUPPORTED by VMware in any way or form.

This blog post is part of a series with examples that examine the protocol in depth.
Follow us on Twitter @VMware_API_team and send us any feedback.