Skip Navigation Links | |
Exit Print View | |
Remote Administration Daemon Developer Guide Oracle Solaris 11.1 Information Library |
Connections to a rad server in Java are made through JMX. A JMX connection is established with the following:
A javax.management.remote.JMXService URL that identifies the protocol to be used, and a host, port, and path where appropriate
A Map<String, Object> of protocol-specific options where appropriate
Several protocols for connecting to a rad server are supported and are defined in the com.oracle.solaris.rad.jmx class. Unless explicitly mentioned, a host, port, path, or options is not applicable.
These protocols are:
A local UNIX domain socket connection. The path is the fully qualified name of the socket.
Example 5-1 RadConnector.PROTOCOL_UNIX
JMXServiceURL url = new JMXServiceURL(RadConnector.PROTOCOL_UNIX, "", 0, "/system/volatile/rad/radsocket"); JMXConnector connector = JMXConnectorFactory.connect(url);
A local/remote TCP connection. A host and/or port may be specified.
Example 5-2 RadConnector.PROTOCOL_TCP
JMXServiceURL url = new JMXServiceURL(RadConnector.PROTOCOL_TCP, "myhost", 0); JMXConnector connector = JMXConnectorFactory.connect(url);
A local/remote TLS connection. A host and/or port may be specified.
Expected parameters:
The full path to a local rad truststore file
The password for the local rad truststore
An instance of com.oracle.solaris.rad.RadTrustManager for key management
Example 5-3 RadConnector.PROTOCOL_TLS
Map<String, Object> env = new HashMap<String, Object>(); env.put(RadConnector.KEY_TLS_TRUSTSTORE, "/etc/myapp/truststore"); env.put(RadConnector.KEY_TLS_TRUSTPASS, "trustpass"); JMXServiceURL url = new JMXServiceURL( RadConnector.PROTOCOL_TLS, host, 0); JMXConnector connector = JMXConnectorFactory.newJMXConnector(url, null); for (;;) { RadTrustManager mtm = new RadTrustManager(); env.put(RadConnector.KEY_TLS_RADMANAGER, mtm); try { connector.connect(env); break; } catch (IOException e) { X509Certificate[] chain = mtm.getBadChain(); if (chain == null) { throw e; } } }
A local connection to a rad instance private to this process, spawned when the connection is established. The resulting rad communicates through its stdin/stdout.
Expected parameters:
A full path to prefix the to each relatively named module in the RadConnector.PRIVATE_MODULES parameter, if specified
A list of modules to load, as with /usr/lib/rad/rad -M module
Additional arguments to pass to the spawned rad instance
Example 5-4 RadConnector.PROTOCOL_PRIVATE
Map<String, Object> env = new HashMap<String, Object>(); String[] auxargs = { "-d", "-e", "30" }; String[] modules = { "mod_usermgmt.so", "mod_nameservice.so" }; env.put(RadConnector.PRIVATE_AUXARGS, auxargs); env.put(RadConnector.PRIVATE_MODULES, modules); env.put(RadConnector.PRIVATE_ROOT, "/usr/share/modules"); JMXServiceURL url = new JMXServiceURL( RadConnector.PROTOCOL_PRIVATE, "", 0); JMXConnector connector = JMXConnectorFactory.newJMXConnector(url, env);
A connection to a non-global zone's local UNIX rad instance, through an existing local or remote rad connection to its global zone. The name of the non-global zone is specified as the host. The non-global zone user is specified as the path.
Expected parameters:
RadConnector.KEY_ZONESBRIDGE_MXBEAN (com.oracle.solaris.rad.zonesbridge.IOMXBean, required)
An IOMXBean from an existing rad connection to the global zone, retrieved with a domain "com.oracle.solaris.rad.zonesbridge" and a "type=IO" key/value pair.
Example 5-5 RadConnector.PROTOCOL_ZONESBRIDGE
// Create a connection to some host MBeanServerConnection mbsc = ... ObjectName zioName = new ObjectName( "com.oracle.solaris.rad.zonesbridge", "type", "IO"); IOMXBean zio = JMX.newMXBeanProxy(mbsc, zioName, IOMXBean.class); // The zone to connect to String zone = "nerd-vpn"; // The non-global-zone user, or "" to connect as root String zoneUser = "talley"; // Create a connection to the non-global zone on the connected host JMXServiceURL zUrl = new JMXServiceURL( RadConnector.PROTOCOL_ZONESBRIDGE, zone, 0, "/" + zoneUser); Map<String, Object> env = new HashMap<String, Object>(); env.put(RadConnector.KEY_ZONESBRIDGE_MXBEAN, zio); JMXConnector connector = JMXConnectorFactory.connect(zUrl, env);
In the Java/JMX environment, elements declared in the module specification are translated to Java classes and interfaces. The tool that does this translation is /usr/bin/radadrgen:
/usr/bin/radadrgen [ -N ] -j dir [ -i ] spec.xml
The Java classes and interfaces generated by radadrgen are as follows, where package is determined from the <api> name or a supplied pragma:
|
See the section on object naming for details.
For example, suppose you have the rad module specification example.xml:
<api xmlns="http://xmlns.oracle.com/radadr" name="com.example.foo"> <enum name="Color"> <value name="Red" /> <value name="Green" /> <value name="Blue" /> </enum> ... </api>
Calling /usr/bin/radadrgen -j dir example.xml generates a native Java enum class:
package com.example.foo; public enum Color { Red, Green, Blue, }
Adding a <struct> to the module API produces a Java interface that models the structured type. For example:
<struct name="Person"> <field type="string" name="name" /> <field type="integer" name="age" /> <field typeref="Color" name="favoriteColor" /> </struct>
resulting Java interface:
package com.example.foo;
public interface Person { String getName(); int getAge(); Color getFavoriteColor(); }
If the -i is also passed to radadrgen, an implementation of the Person interface is also generated:
package com.example.foo; public class PersonImpl implements Person { private String name_; private int age_; private Color favoriteColor_; public PersonImpl() { } public PersonImpl(String name, int age, Color favoriteColor) { name_ = name; age_ = age; favoriteColor_ = favoriteColor; } public String getName() { return name_; } public int getAge() { return age_; } public Color getFavoriteColor() { return favoriteColor_; } public void setName(String arg) { name_ = arg; } public void setAge(int arg) { age_ = arg; } public void setFavoriteColor(Color arg) { favoriteColor_ = arg; } }
This process can be useful in client code to quickly create and use a basic object that implements a structured type's interface.
When adding a discriminated union to a module API, radadrgen produces a Java interface that models the union. For example:
Discriminated Union:
<union name="ColorData" typeref="Color"> <arm value="Red" type="string" /> <arm value="Green" type="integer" /> <arm value="Blue" type="float" /> </union>
Resulting Java interface:
package com.example.foo;
public interface ColorData { Color getArm(); String getData_Red(); Integer getData_Green(); Float getData_Blue(); ... }
To use a union, the getArm() method is first called to determine which of the union arms is active. Based on the return value of that method, the appropriate getData_*() method can be called to get the data encapsulated in the union.
To create a union, the generated Java interface also includes several static convenience classes, as shown in the following example.
public interface ColorData { ... static class arm_Red extends ColorDataImpl { private String armdata_; public arm_Red(String armdata) { super(Color.Red); armdata_ = armdata; } @Override public String getData_Red() { return armdata_; } } static class arm_Green extends ColorDataImpl { ... } static class arm_Blue extends ColorDataImpl { ... } }
These inner classes provide a quick way to quickly create and use a basic object that implements the generated union interface for a given union arm.
Interfaces are the reason that modules exist. For an <interface> added to a module, radadrgen produces a Java MXBean interface. For example:
Interface:
<interface name="Population"> <property name="groupName" access="rw" type="string"/> <property name="people" access="ro"> <list typeref="Person" /> </property> <method name="add"> <argument typeref="Person" name="person" /> </method> </interface>
Resulting Java MXBean interface:
package com.example.foo;
public interface PopulationMXBean { String getgroupName(); void setgroupName(String groupName); java.util.List<Person> getpeople(); void add(Person person); }
This MXBean is implemented by the objects returned by the rad server:
// Retrieve the Population object ObjectName oName = new ObjectName("com.example.foo", "type", "Population"); PopulationMXBean pop = JMX.newMXBeanProxy(mbsc, oName, PopulationMXBean.class); // Access a property List<Person> people = pop.getpeople(); // Call a method pop.add(new PersonImpl("talley", Color.GREEN));
Note the following cautions:
Caution - To eliminate the ambiguity inherent to the JMX ObjectName quoting rules, all key values returned by interfaces that return ObjectNames are quoted by the JMX client connector before being passed to the caller. For compatibility, the JMX client connector will accept object names with unquoted key values. |