Remote Administration Daemon Developer Guide

Exit Print View

Updated: July 2014
 
 

Interface Components

An API is defined by a module developer and contains a variety of components designed to accomplish a task. These components are:

  • Enums

    • Values

  • Structs

    • Fields

  • Interfaces

    • Properties

    • Methods

    • Events

These components are all defined in an ADR Interface Description Language document. The radadrgen utility is used to process the document to generate language specific components which facilitate client/server interactions within RAD. More details in the role of ADR and rad can be found in Abstract Data Representation. Brief descriptions of each component follows.

Enumerations

Enumerations are primarily used to offer a restricted range of choices for a property, an interface method parameter, result, or error.

Using Enumeration Types

To access an enumerated type, simply import the generated class and interact with the enumeration.

Example 3-24  Using Enumerations
import com.oracle.solaris.rad.zonemgr.ErrorCode;

System.out.println(ErrorCode.NONE);
System.out.println(ErrorCode.COMMAND_ERROR);

Structs

Structs are used to define new types and are composed from existing built-in types and other user defined types. In essence, they are simple forms of interfaces. They do not have methods or events and are not present in the RAD namespace.

Using Struct Types

The zonemgr module defines a Property struct which represents an individual Zone configuration property. The structure has the following members name, type, value, listValue, and complexValue. Like enumerations, structures can be interacted with directly once the binding is imported.

Example 3-25   Using Structs
import com.oracle.solaris.rad.zonemgr.Property;

Property prop = new Property();
prop.setName("my name");
prop.setValue("a value");
System.out.println(prop.getName());
System.out.println(prop.getValue());

Interfaces/Objects

Interfaces (also known as objects) are the entities which populate the RAD namespace. They must have a "name". An interface is composed of Events, Properties and Methods.

Obtaining an Object Reference

See the Rad Namespace section.

Working with Object References

Once we have an object reference we can use this to interact with RAD in a very straightforward fashion. All attributes and methods defined in the IDL are accessible directly as attributes and methods of the Java objects which are returned by getObject(). Attributes are accessed using automatically generated getters/setters. For example, if the property is name, then you would use getname()/ setname(<value>). Here is an example which gets a reference to a zone and then boots the zone.

Example 3-26   Invoking a Remote Method
import com.oracle.solaris.rad.client.ADRName;
import com.oracle.solaris.rad.client.ADRGlobPattern;
import com.oracle.solaris.rad.connect.Connection;
import com.oracle.solaris.rad.zonemgr.Zone;
    
Connection con = Connection.connectUnix();
System.out.println("Connected: " + con.toString());

String keys[] = { "name" };
String values[] = { "test-0" };
ADRGlobPattern pat = new ADRGlobPattern(keys, values);
for (ADRName name: con.listObjects(new Zone(), pat)) {
    Zone z = (Zone) con.getObject(name);
    z.boot(null);
}

In the above example we have connected to our RAD instance, created a search for a specific object, retrieved a reference to the object and invoked a remote method on it.

Accessing a Remote Property

Accessing a remote property is just as simple as using a remote method.

Example 3-27   Accessing a Remote Property
import com.oracle.solaris.rad.client.ADRName;
import com.oracle.solaris.rad.client.ADRGlobPattern;
import com.oracle.solaris.rad.connect.Connection;
import com.oracle.solaris.rad.zonemgr.*;

Connection con = Connection.connectUnix();
System.out.println("Connected: " + con.toString());

String keys[] = { "name" };
String values[] = { "test-0" };
ADRGlobPattern pat = new ADRGlobPattern(keys, values);
for (ADRName name: con.listObjects(new Zone(), pat)) {
    Zone z = (Zone) con.getObject(name);
    Resource filter = new Resource("global", null, null);
    List<Property> props = z.getResourceProperties(filter, null);
    System.out.println("Properties:");
    for (Property prop: props) {
        System.out.printf("\t%s = %s\n",prop.getName(), prop.getValue());
    }
}

In this example, we accessed the list of Zone global resource properties and printed out the name and value of every Property.

RAD Event Handling

In this next example we are going to look at events. The ZoneManager instance defines a "stateChange" event which clients can subscribe to for information about changes in the runtime state of a zone.

Example 3-28   Subscribing and Handling Events
import com.oracle.solaris.rad.client.ADRName;
import com.oracle.solaris.rad.client.RadEvent;
import com.oracle.solaris.rad.client.RadEventHandler;
import com.oracle.solaris.rad.connect.Connection;
import com.oracle.solaris.rad.zonemgr.*;

ZoneManager zmgr = con.getObject(new ZoneManager());
    con.subscribe(zmgr, "statechange", new StateChangeHandler());
    Thread.currentThread().sleep(100000000);

class StateChangeHandler extends RadEventHandler {

    public void handleEvent(RadEvent event, Object payload) {
        StateChange obj = (StateChange) payload;
        System.out.printf("Event: %s", event.toString());
        System.out.printf("\tcode: %s\n", obj.getZone());
        System.out.printf("\told: %s\n", obj.getOldstate());
        System.out.printf("\tnew: %s\n", obj.getNewstate());
       }
}

To handle an event, implement the RadEventInterface. The com.oracle.solaris.rad.client package provides a default implementation (RadEventHandler) with limited functionality. This class may be extended to provide additional event handling logic as in example above.

In this simple example we subscribe to the single event and pass in a handler and a reference to our ZoneManager object. The handler will be invoked asynchronously by the framework with the various event details and the supplied user data.

RAD Error Handling

Finally, a quick look at error handling when manipulating remote references. Python provides a rich exception handling mechanism and RAD errors are propagated using this mechanism. There are a variety of errors which can be delivered by RAD, but the main one which requires handling is RadObjectException. The following snippet, shows how it can be used:

Example 3-29   Handling RAD Errors
<imports..>

Connection con = Connection.connectUnix();
    for (ADRName name: con.listObjects(new Zone())) {
        Zone zone =  con.getObject(name);
        try {
            zone.boot(null);
        }catch (RadObjectException oe) {
            Result res = (Result) oe.getPayload();
            System.out.println(res.getCode());
            if (res.getStdout() != null)
                System.out.println(res.getStdout());
            if (res.getStderr() != null)
                System.out.println(res.getStderr());
       }
}

Note -  With RadException exceptions you may get a payload. This is only present if your interface method or property has defined an "error" element, in which case the payload is the content of that error. If there is no "error" element for the interface method (or property), then there is no payload and it will have a value of null.