When you create an HTML-based action extension to the vSphere Web Client, you must create an actions controller class on the Virgo server to respond to the REST API requests from the client code.

A best practice is to implement the controller class as a simple dispatcher that maps the action UIDs to Java services. You can invoke custom services or translate REST API requests to Data Manager requests.

In the example, the invoke method must return a JSON map that signals the framework to update its object lists in the client. The map must contain a result key whose value is the result of the service call. A utility class ActionResult is provided to define additional result parameters.

If the action adds, updates, or deletes objects, you should use an instance of ActionResult to notify the vSphere Web Client framework, so it can update object lists in the client. Use the ActionResult methods setObjectAddedResult, setObjectChangedResult, or setObjectDeletedResult. Pass the result returned by the service as the first parameter to the method.

The ActionResult methods accept an optional second parameter that contains a message key that the client code can use to report an error in the UI if the result is false or null. Alternatively, you can use the setErrorMessage method to add the error message key to the results map.

Note

Headless actions cannot display error messages or otherwise report the results of the action. To display results in the UI, you must handle your action request from a UI action dialog.

...
   @RequestMapping(method = RequestMethod.POST)
   @ResponseBody
public Map invoke(
@RequestParam(value = "actionUid", required = true) String actionUid,
@RequestParam(value = "targets", required = false) String targets,
@RequestParam(value = "json", required = false) String json)
throws Exception {
...
 
ActionResult actionResult = new ActionResult(actionUid, RESOURCE_BUNDLE);
 
if (actionUid.equals("com.vmware.samples.chassis.editChassis")) {
boolean result = _chassisService.updateChassis(objectRef, chassisInfo);
actionResult.setObjectChangedResult(result, "editAction.notFound");
 
} else if (actionUid.equals("com.vmware.samples.chassis.deleteChassis")) {
boolean result = _chassisService.deleteChassis(objectRef);
actionResult.setObjectDeletedResult(result, "deleteAction.notFound");
 
} else if (actionUid.equals("com.vmware.samples.chassis.createChassis")) {
Object result = _chassisService.createChassis(chassisInfo);
if (result != null) {
actionResult.setObjectAddedResult((URI)result, "samples:Chassis", null);
} else {
// Case where the name is already taken
String[] params = new String[] { chassisInfo.name };
actionResult.setErrorMessage("createAction.nameTaken", params);
}
 
} else {
String warning = "Action not implemented yet! "+ actionUid;
_logger.warn(warning);
actionResult.setErrorLocalizedMessage(warning);
}
return actionResult.getJsonMap();
}
...