The simple javascript example I wrote about last time is actually a great deal more interesting when it’s combined with Firefox and Firebug. Using Firebug it’s possible to both view the xmlrpc requests and also to browse the fields in the objects returned by the API calls. This becomes particularly enlightening when we have a up-to-date local cache of API objects, enabling the browsing of all of the fields available to API users. This is really useful for everyone developing against the XenServer API, not just web application developers. However, first of all we need to know how to get and maintain this cache, so I’ll describe that first.

Using the methods in my last post, to find out about changes in the fields of objects we’d have to poll the XenServer every so often. This would involve large amounts of data transfer, especially when the objects of interest are VMs, which are by far the largest objects in our datamodel. There is a much nicer method of keeping track of the changes on the XenServer, and that is by using two API calls: ‘event.register’ and ‘event.next’.

The basic idea is that you register for xapi to keep a note of changes in classes in which you’re interested, e.g. VMs, hosts, or just everything, and when you call ‘Event.next’ it will give you back all of the objects in those classes that have changed since last time. When there are no events ready to send back, the call will block until one happens, which makes it perfect for an asychronous XHR request. Using the modified jquery.rpc library, making an asynchronous call just involves putting the callback as the last argument to the API call – for example:

 rpc.VM.get_all_records(session)

is synchronous, and returns the VM references and records, whereas

rpc.VM.get_all_records(session,callback_fn)

is asynchronous, returns nothing, and the callback function is called with the result when the RPC completes.

In order that we don’t miss out any events, we register for events before populating the local cache. So the sequence of calls is:

rpc.event.register(session,[<span class="code-quote">"vm"</span>]);  <span class="code-comment">// <span class="code-keyword">case</span> insensitive
</span>cache['vm']=rpc.VM.get_all_records(session);
rpc.event.next(session,eventcallback);

Here we’ve registered for events on VMs – you can specify multiple classes to listen out for or use “*” to mean all classes (except those we don’t generate events for, like sessions!) The event callback then updates the cache whenever it receives data, and then in turn again calls event.next:

function eventcallback(evts) {
    <span class="code-keyword">for</span>(<span class="code-keyword">var</span> i=0; i&lt;evts.length; i++) {
        evt=evts[i];
        <span class="code-keyword">if</span>(cache[evt['class']]) {
            cache[evt['class']][evt.ref]=evt.snapshot;
        }
    }
    rpc.event.next(session,eventcallback);
}

For the demo application, we register for all classes, but only pay attention to the modification events to VM objects – in this case we simply print out the names of the VMs in <div>s styled according to the power state. To see the event system working, just start or stop a VM, and the page will be updated accordingly. The demo is available here. Once again, to install it, it’s easiest to have it served up by the XenServer itself, so ssh in and mkdir /opt/xensource/www – then copy the files from the demo zip in. Edit the ‘demo.js’ file to put in the correct username and password, then just point your web browser at the server.

As I mentioned at the beginning though, it’s much more interesting to look at the demo with Firebug installed, where you can see the xmlrpc requests (note that to take this screenshot I changed the ‘use_json’ param to ‘false’):

Using the DOM browser, you can see the contents of the local cache, including the names and values of all of the fields available to XenAPI clients: