%
% Copyright (c) 2006-2007 XenSource, Inc.
%
% Permission is granted to copy, distribute and/or modify this document under
% the terms of the GNU Free Documentation License, Version 1.2 or any later
% version published by the Free Software Foundation; with no Invariant
% Sections, no Front-Cover Texts and no Back-Cover Texts.  A copy of the
% license is included in the section entitled
% "GNU Free Documentation License" or the file fdl.tex.
%
% Authors: Ewan Mellor, Richard Sharp, Dave Scott, Jon Harrop.
%

\section{Wire Protocol for Remote API Calls}

API calls are sent over a network to a Xen-enabled host using
the XML-RPC protocol. In this Section we describe how the
higher-level types used in our API Reference are mapped to
primitive XML-RPC types.

In our API Reference we specify the signatures of API functions in the following
style:
\begin{verbatim}
    (ref_vm Set)   VM.get_all()
\end{verbatim}
This specifies that the function with name {\tt VM.get\_all} takes
no parameters and returns a Set of {\tt ref\_vm}s.
These types are mapped onto XML-RPC types in a straight-forward manner:
\begin{itemize}
  \item Floats, Bools, DateTimes and Strings map directly to the XML-RPC {\tt
  double}, {\tt boolean}, {\tt dateTime.iso8601}, and {\tt string} elements.

  \item all ``{\tt ref\_}'' types are opaque references, encoded as the
  XML-RPC's {\tt String} type. Users of the API should not make assumptions
  about the concrete form of these strings and should not expect them to
  remain valid after the client's session with the server has terminated.

  \item fields named ``{\tt uuid}'' of type ``{\tt String}'' are mapped to
  the XML-RPC {\tt String} type. The string itself is the OSF
  DCE UUID presentation format (as output by {\tt uuidgen}, etc).

  \item ints are all assumed to be 64-bit in our API and are encoded as a
  string of decimal digits (rather than using XML-RPC's built-in 32-bit {\tt
  i4} type).

  \item values of enum types are encoded as strings. For example, a value of
  {\tt destroy} of type {\tt on\_normal\_exit}, would be conveyed as:
  \begin{verbatim}
    <value><string>destroy</string></value>
  \end{verbatim}

  \item for all our types, {\tt t}, our type {\tt t Set} simply maps to
  XML-RPC's {\tt Array} type, so for example a value of type {\tt cpu\_feature
  Set} would be transmitted like this:

  \begin{verbatim}
<array>
  <data>
    <value><string>CX8</string></value>
    <value><string>PSE36</string></value>
    <value><string>FPU</string></value>
  </data>
</array> 
  \end{verbatim}

  \item for types {\tt k} and {\tt v}, our type {\tt (k, v) Map} maps onto an
  XML-RPC struct, with the key as the name of the struct.  Note that the {\tt
  (k, v) Map} type is only valid when {\tt k} is a {\tt String}, {\tt Ref}, or
  {\tt Int}, and in each case the keys of the maps are stringified as
  above. For example, the {\tt (String, double) Map} containing a the mappings
  Mike $\rightarrow$ 2.3 and John $\rightarrow$ 1.2 would be represented as:

  \begin{verbatim}
<value>
  <struct>
    <member>
      <name>Mike</name>
      <value><double>2.3</double></value>
    </member>
    <member>
      <name>John</name>
      <value><double>1.2</double></value>
    </member>
  </struct>
</value>
  \end{verbatim}

  \item our {\tt Void} type is transmitted as an empty string.

\end{itemize}

\subsection{Note on References vs UUIDs}

References are opaque types --- encoded as XML-RPC strings on the wire --- understood
only by the particular server which generated them. Servers are free to choose
any concrete representation they find convenient; clients should not make any 
assumptions or attempt to parse the string contents. References are not guaranteed
to be permanent identifiers for objects; clients should not assume that references 
generated during one session are valid for any future session. References do not
allow objects to be compared for equality. Two references to the same object are
not guaranteed to be textually identical.

UUIDs are intended to be permanent names for objects. They are
guaranteed to be in the OSF DCE UUID presentation format (as output by {\tt uuidgen}.
Clients may store UUIDs on disk and use them to lookup objects in subsequent sessions
with the server. Clients may also test equality on objects by comparing UUID strings.

The API provides mechanisms
for translating between UUIDs and opaque references. Each class that contains a UUID
field provides:
\begin{itemize}
\item  A ``{\tt get\_by\_uuid}'' method that takes a UUID, $u$, and returns an opaque reference
to the server-side object that has UUID=$u$; 
\item A {\tt get\_uuid} function (a regular ``field getter'' RPC) that takes an opaque reference,
$r$, and returns the UUID of the server-side object that is referenced by $r$.
\end{itemize}

\subsection{Return Values/Status Codes}
\label{synchronous-result}

The return value of an RPC call is an XML-RPC {\tt Struct}.

\begin{itemize}
\item The first element of the struct is named {\tt Status}; it
contains a string value indicating whether the result of the call was
a ``{\tt Success}'' or a ``{\tt Failure}''.
\end{itemize}

If {\tt Status} was set to {\tt Success} then the Struct contains a second
element named {\tt Value}:
\begin{itemize}
\item The element of the struct named {\tt Value} contains the function's return value.
\end{itemize}

In the case where {\tt Status} is set to {\tt Failure} then
the struct contains a second element named {\tt ErrorDescription}:
\begin{itemize}
\item The element of the struct named {\tt ErrorDescription} contains
an array of string values. The first element of the array is an error code;
the remainder of the array are strings representing error parameters relating
to that code.
\end{itemize}

For example, an XML-RPC return value from the {\tt host.get\_resident\_VMs}
function above
may look like this:
\begin{verbatim}
    <struct>
       <member>
         <name>Status</name>
         <value>Success</value>
       </member>
       <member>
          <name>Value</name>
          <value>
            <array>
               <data>
                 <value>81547a35-205c-a551-c577-00b982c5fe00</value>
                 <value>61c85a22-05da-b8a2-2e55-06b0847da503</value>
                 <value>1d401ec4-3c17-35a6-fc79-cee6bd9811fe</value>
               </data>
            </array>
         </value>
       </member>
    </struct>
\end{verbatim}

\section{Making XML-RPC Calls}

\subsection{Transport Layer}

The following transport layers are currently supported:
\begin{itemize}
\item HTTP/S for remote administration
\item HTTP over Unix domain sockets for local administration
\end{itemize}

\subsection{Session Layer}

The XML-RPC interface is session-based; before you can make arbitrary RPC calls
you must login and initiate a session. For example:
\begin{verbatim}
   session_id    session.login_with_password(string uname, string pwd)
\end{verbatim}
Where {\tt uname} and {\tt password} refer to your username and password
respectively, as defined by the Xen administrator.
The {\tt session\_id} returned by {\tt session.login\_with\_password} is passed
to subequent RPC calls as an authentication token.

A session can be terminated with the {\tt session.logout} function:
\begin{verbatim}
   void          session.logout(session_id session)
\end{verbatim}

\subsection{Synchronous and Asynchronous invocation}

Each method call (apart from methods on ``Session'' and ``Task'' objects 
and ``getters'' and ``setters'' derived from fields)
can be made either synchronously or asynchronously.
A synchronous RPC call blocks until the
return value is received; the return value of a synchronous RPC call is
exactly as specified in Section~\ref{synchronous-result}.

Only synchronous API calls are listed explicitly in this document. 
All asynchronous versions are in the special {\tt Async} namespace.
For example, synchronous call {\tt VM.clone(...)}
(described in Chapter~\ref{api-reference})
has an asynchronous counterpart, {\tt
Async.VM.clone(...)}, that is non-blocking.

Instead of returning its result directly, an asynchronous RPC call
returns a {\tt task-id}; this identifier is subsequently used
to track the status of a running asynchronous RPC. Note that an asychronous
call may fail immediately, before a {\tt task-id} has even been created---to
represent this eventuality, the returned {\tt task-id}
is wrapped in an XML-RPC struct with a {\tt Status}, {\tt ErrorDescription} and
{\tt Value} fields, exactly as specified in Section~\ref{synchronous-result}.

The {\tt task-id} is provided in the {\tt Value} field if {\tt Status} is set to
{\tt Success}.

The RPC call
\begin{verbatim}
    (ref_task Set)   Task.get_all(session_id s)
\end{verbatim} 
returns a set of all task IDs known to the system. The status (including any
returned result and error codes) of these tasks
can then be queried by accessing the fields of the Task object in the usual way. 
Note that, in order to get a consistent snapshot of a task's state, it is advisable to call the ``get\_record'' function.

\section{Example interactive session}

This section describes how an interactive session might look, using the python
XML-RPC client library. 

First, initialise python and import the library {\tt xmlrpclib}:

\begin{verbatim}
\$ python2.4
...
>>> import xmlrpclib
\end{verbatim}

Create a python object referencing the remote server:

\begin{verbatim}
>>> xen = xmlrpclib.Server("http://test:4464")
\end{verbatim}

Acquire a session token by logging in with a username and password
(error-handling ommitted for brevity; the session token is pointed to by the
key {\tt 'Value'} in the returned dictionary)

\begin{verbatim}
>>> session = session.login_with_password("user", "passwd")['Value']
\end{verbatim}

When serialised, this call looks like the following:

\begin{verbatim}
<?xml version='1.0'?>
<methodCall>
  <methodName>session.login_with_password</methodName>
  <params>
    <param>
      <value><string>user</string></value>
    </param>
    <param>
      <value><string>passwd</string></value>
    </param>
  </params>
</methodCall>
\end{verbatim}

Next, the user may acquire a list of all the VMs known to the host: (Note the
call takes the session token as the only parameter)

\begin{verbatim}
>>> all_vms = host.get_resident_VMs(session)['Value']
>>> all_vms
['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ]
\end{verbatim}

The VM references here have the form {\tt OpaqueRef:X}, though they may not be 
that simple in the future, and you should treat them as opaque strings.  
Once a reference to a VM has been acquired a lifecycle operation may be invoked:

\begin{verbatim}
>>> xen.VM.start(session, all_vms[3], False)
{'Status': 'Failure', 'ErrorDescription': ['VM_BAD_POWER_STATE', 'Halted', 'Running']}
\end{verbatim}

In this case the {\tt start} message has been rejected, because the VM is
already running, and so an error response has been returned.  These high-level
errors are returned as structured data (rather than as XML-RPC faults),
allowing them to be internationalised.  Finally, here are some examples of
using accessors for object fields:

\begin{verbatim}
>>> xen.VM.get_name_label(session, all_vms[3])['Value']
'SMP'
>>> xen.VM.get_name_description(session, all_vms[3])['Value']
'Debian for Xen'
\end{verbatim}
