Go to main content

Remote Administration Daemon Developer's Guide

Exit Print View

Updated: April 2020
 
 

ADR Interface Description Language

The APIs used by RAD are defined by using an XML-based IDL. The normative schema for this language can be found in /usr/share/lib/xml/rng/radadr.rng.1. The namespace name is http://xmlns.oracle.com/radadr.

ADR Overview

The top-level element in an ADR definition document is an api. The api element has one mandatory attribute, name, which is used to name the output files. The element contains one or more derived type or interface definitions. Because there is no requirement that an interface must use derived types, it is not necessary to specify any derived types in an API document. To enable consumers to use the data typing defined by ADR for non-interface purposes, there is no requirement that an interface must be defined. However, note that either a derived type or an interface must be defined.

Three derived types are available for definition and use by interfaces: a structured type that can be defined with a struct element, an enumeration type that can be defined with an enum element, and a dictionary type that can be defined with a dictionary element. Interfaces are defined using interface elements. The derived types defined in an API document are available for use by all interfaces defined in that document.

The following is an example of an API.

Example 46  Skeleton API document
<api xmlns="http://xmlns.oracle.com/radadr" name="com.oracle.solaris.rad.example" register="true">
        <version/>
        <struct>...</struct>
        <struct>...</struct>
        <enum>...</enum>
        <dictionary>...</dictionary>
        <interface>...</interface>
        <interface>...</interface>
</api>

The xmlns is required to indicate the type of the XML document. The name attribute is identifying the name of the API, the namespace within which all subsidiary interfaces are to be found. There are additional attributes to assist in the generation of server module code.

The register attribute is a boolean, which is optional and true by default. If true, then radadrgen automatically generates a _rad_reg() function when generating server implementation code. If false, the function is not generated and the module author will need to provide a _rad_reg() function. This option is primarily provided for the creation of special types of modules, such as protocol or transport modules, in general it does not need to be specified, since the default generated function is enough for most purposes.

Documentation Definitions

The documentation elements allow you to document the RAD module APIs and are defined by the schema specification in /usr/share/lib/xml/rng/radadr-doc.rng.1.

The two main documentation elements are:

<summary />

Container for inline elements.

<doc />

Container for block elements.

<summary /> Element

The <summary /> element is a mandatory element, which represents a short text synopsis of the parent element. The <summary /> element can only text data annotated with the inline elements <code />, <emphasis />, <strong />, and <link />. The output of a <summary /> element is running text with possible typographic modifications and the available inline elements are as follows:

<code />

Indicates small fragments of code.

<emphasis />

Emphasizes a phrase or word in italics.

<strong />

Emphasizes a phrase or word in bold.

<link />

Displays hypertext based on the following values for the hyperlink:

url

An external URL.

interface, [method, property, event]

An interface, method, property, or an event defined within the ADR document.

enum, [value]

An enum data type or an enum value defined within the ADR document.

struct, [field]

A struct data type or a struct field defined within the ADR document.


Note -  The text within the <link> element can be empty. If the value is empty, the text data is auto-generated based on the value of the method attribute.

<doc /> Element

Use the <doc /> element to define larger blocks of content. The <doc /> element might contain inline elements, block elements or text data. The <doc /> element is displayed as separate blocks of data and the available block elements are:

<heading />

Defines a section heading.

<para />

Defines a paragraph.

<list />

Defines a list of items. Items in the list are defined by an <item /> element. The <list /> element takes an optional attribute that defines the type of list to display using the ordered attribute for a numbered list or unordered attribute for a bullet list. The default list type is an unordered list.

<item />

Defines an item in a list. It might contain block or inline elements.

<example />

Displays a program listing. Available attributes are:

language

A mandatory attribute which defines the programming language. It can have any one of c, python, java, rest, or curl. The value must be in lowercase.

caption

An optional attribute, which provides a label for the example.

numbered

An optional attribute. Displays line numbers. Default is to omit line numbers.

<verbatim />

Defines a block of text in which line breaks and whitespace are to be preserved and displayed as is.

For more information about how to use the documentation definitions, see ADR API Example.

Version Element

A version element is required for all APIs.

The initial version of an API must always be defined as follows:

<version major="1" minor="0"/>

This indicates that the module is starting at version 1.0.

Enumeration Definitions

The enum element has a single mandatory attribute, name. The name is used when referring to the enumeration from other derived type or interface definitions. An enum contains one or more value elements, one for each user-defined enumerated value. A value element has a mandatory name attribute that gives the enumerated value a symbolic name. The symbolic name is not used elsewhere in the API definition, only in the server and various client environments. The symbolic name that is exposed in these environments are environment-dependent. An environment offering an explicit interface to RAD must provide an interface that accepts the exact string values defined by the value elements' name attributes.

Some language environments support associating scalar values with enumerated type values, for example C. To provide richer support for these environments, ADR supports this concept as well. By default, an enumerated value has an associated scalar value 1 greater than the preceding enumerated value's associated scalar value. The first enumerated value is assigned a scalar value of 0. Any enumerated value element may override this policy by defining a value attribute with the desired value. A value attribute must not specify a scalar value already assigned, implicitly or explicitly, to an earlier value in the enumeration and value elements contain no other elements.

Example 47  Enumeration Definition
<enum name="Colors">
<value name="RED" /> <!-- scalar value: 0 -->
<value name="ORANGE" /> <!-- scalar value: 1 -->
<value name="YELLOW" /> <!-- scalar value: 2 -->
<value name="GREEN" /> <!-- scalar value: 3 -->
<value name="BLUE" /> <!-- scalar value: 4 -->
<value name="VIOLET" value="6" /> <!-- indigo was EOLed -->
</enum>

Structure Definitions

Similar to the enum element, the struct element has a single mandatory attribute, name. The name is used when referring to the structure from other derived type or interface definitions. A struct contains one or more field elements, one for each field of the structure. A field element has a mandatory name attribute that gives the field a symbolic name. The symbolic name isn't used elsewhere in the API definition, only in the server and various client environments. In addition to a name, each field must specify a type.

You can define the type of a field in multiple ways. If a field is a plain base type or a derived type defined elsewhere in the API document, that type is defined with a type attribute. If a field is an array of some type (base or derived), that type is defined with a nested list element. The type of the array is defined in the same fashion as the type of the field: either with a type attribute, or another nested list element.

A field's value might be declared nullable by setting the field element's nullable attribute to true.


Note -  The structure fields, methods return values, method arguments, attributes, error return values, and events have types, and in the IDL, use identical mechanisms for defining those types.
Example 48  struct Definition
<struct name="Name">
        <field name="familyName" type="string" />
        <field name="givenNames">
                <list type="string" />
        </field>
</struct>

<struct name="Person">
        <field name="name" typeref="Name" />
        <field name="title" type="string" nullable="true" />
        <field name="shoeSize" type="int" />
</struct>

Dictionary Definitions

You can use dictionaries to add a data structure in which the key-value pair mappings can be stored and retrieved. The following example shows how to use the dictionary tag.

<dictionary>
  <key type="<key type>">
  <value type="<value type>">
</dictionary>

You can use the dictionary type similar to any other RAD type such as a field in a structure, a method argument or a return value, a property, an error payload, or as an event payload.

Example 49  Defining a Dictionary

This example shows how to define a dictionary with a key type of integer and value type of string as a read-write property.

...
  <property name="DictProp" access="rw" >
     <dictionary>
        <key type="integer" />
        <value type="string" />
     </dictionary>
  </property>
...

Values can be of any type except for list and dictionary. The value can be a derived type or a reference in which case you must use the "typeref" tag instead of the "type" tag. However, the key must belong to any one of the following basic types:

  • boolean

  • integer

  • unsigned integer

  • long

  • unsigned long

  • float

  • double

  • time

  • string

  • name

Interface Definitions

An interface definition has a name, and one or more attributes, methods, or events. An interface's name is defined with the interface element's mandatory name attribute. This name is used when referring to the inherited interface from other interface definitions, as well as in the server and various client environments. The other characteristics of an interface are defined using child elements of the interface element.

ADR Methods

Each method in an interface is defined by a method element. The name of a method is defined by this element's mandatory name attribute. The other properties of a method are defined by child elements of the method.

If a method has a return value, it is defined using a single result element. The type of the return value is specified in the same way the type is specified for a structure field. If no result element is present, the method has no return value.

If a method can fail for an API-specific reason, it is defined using a single error element. The type of an error is specified the same way the type is specified for a structure field. Unlike a structure field, an error need not specify a type. Such a situation is indicated by an error element with no attributes or child elements. If no error element is present, the method will only fail if there is a connectivity problem between the client and the server.

A method's arguments are defined, in order, with zero or more argument elements. Each argument element has a mandatory name attribute. The type of an argument is specified in the same way the type is specified for a structure field.

Example 50  Method Definition
<struct name="Meal">...</struct>
<struct name="Ingredient">...</struct>

<method name="cook">
        <result typeref="Meal" />
        <error />
        <argument type="string" name="name" nullable="true" />
        <argument name="ingredients">
                <list typeref="Ingredient" />
        </argument>
</method>

ADR Interface Attributes

Each attribute in an interface is defined by a property element. The name of an attribute is defined by this element's mandatory name attribute. The types of access permitted are defined by the mandatory access attribute, which takes a value of ro, wo, or rw, corresponding to read-only access, write-only access, or read-write access, respectively.

The type of an attribute is specified in the same way the type is specified for a structure field.

If access to an attribute can fail for an API-specific reason, it is defined using one or more error elements. An error element in a property may specify a for attribute, which takes a value of ro, wo, or rw, corresponding to the types of access the error return definition applies to. An error element with no for attribute is equivalent to one with a for attribute set to the access level defined on the property. Two error elements may not specify overlapping access types. For example, on a read-write property it is invalid for one error to have no for attribute (implying rw) and one to have a for attribute of wo they both specify an error for writing.

The type of an error is specified the same way the type is specified for a method. It is identical to defining the type of a structure, with the exception that a type need not be defined.

Example 51  Attribute Definition
<struct name="PrivilegeError">...</struct>

<property name="guestList" access="rw">
        <list type="string" />
        <error for="wo" typeref="PrivilegeError" />
        <!-- Reads cannot fail -->
</property>

ADR Interface Event Element

Each event in an interface is defined by a event element. The name of an event is defined by this element's mandatory name attribute. The type of an event is specified in the same way the type is specified for a structure field.

Example 52  Event Definition
<struct name="TremorInfo">...</struct>

<event name="earthquakes" typeref="TremorInfo" />

Combining IDL Files

ADR include feature allows you to include an XML-based IDL file within the parent IDL file. The following example shows how to include the fragment.xml file within the parent.adr file.

/*fragment.xml*/
<?xml version="1.0" encoding="UTF-8"?>
<fragment xmlns="http://xmlns.oracle.com/radadr">
<version major="1" minor="0"/>
    <para>
      Paragraph 1
    </para>
    <para>
      Paragraph 2
    </para>
</fragment>

/*parent.adr*/
 <?xml version="1.0" encoding="UTF-8"?>
 .
 .
 .
 .
<?include href="fragment.xml" major="1" minor="0"?>

The <?include ?> processing instruction has the following mandatory attributes:

href

Path to the included file.

major

Expected major version of the included fragment.

minor

Expected minor version of the included fragment

Version checking provides a warning in case of minor version mismatch and fail with an error in case of major version mismatch.


Note -  You cannot use the standard xi:include directive to include IDL files.

ADR API Example

Example 53  Using the ADR API
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<api xmlns="http://xmlns.oracle.com/radadr" name="com.oracle.solaris.rad.example">
        
         <version major="1" minor="0"/>

         <struct name="StringInfo">
                <field type="integer" name="length" />
                <field name="substrings">
                        <list type="string" />
                </field>
        </struct>

        <struct name="SqrtError">
                <field type="float" name="real" />
                <field type="float" name="imaginary" />
        </struct>

        <enum name="Mood">
                <value name="IRREVERENT" />
                <value name="MAUDLIN" />
        </enum>

        <struct name="MoodStatus">
                <field typeref="Mood" name="mood" />
                <field type="boolean" name="changed" />
        </struct>

        <interface name="GrabBag" stability="private">

                <method name="sqrt">
                        <result type="integer" />
                        <error typeref="SqrtError" />
                        <argument type="integer" name="x" />
                </method>

                <method name="parseString">
                        <result typeref="StringInfo" nullable="true" />
                        <argument type="string" name="str" nullable="true" />
                </method>

                <property typeref="Mood" name="mood" access="rw">
                        <error for="wo" />
                </property>

                <event typeref="MoodStatus" name="moodswings" />
        </interface>
</api>