# Rio FAQ

The following topics are presented in this FAQ

- OperationalString
- Developer aides
- Runtime Environment

### Operational String

This section provides an overview of some common questions in dealing with the OperationalString:

- How do I use Logging?
- What is the DeploymentSchedule?
- What is the SystemRequirements element and what does it mean?
- How do I use the SLA element?
- What is a SharedComponent and how do I use it?
- What does global configuration mean and how do I use it?
- What is a SoftwareLoad?
- Whats the difference between ProvisionType of fixed and dynamic?
- Whats the difference betewen Parameters and Configuration and when should I use which one?
- What is the reason for having a Group in the opstring? Don't all service must run in the same group as the provisioner?
- How do I declare a ServiceUI in the OperationalString?

### Developer aides

This section provides an overview of some common questions in developing and debugging services with Rio

- How can I debug a service?
- How do I know whether a service has been provisioned for the first time or whether the service is being provisioned as a result of failure

### Runtime Environment

This section provides an overview of some common questions in dealing with the Runtime Environment

- I'm running on a Microsot Windows platform and the Rio Viewer does not show any of the services that are running, whats wrong?
- On a Linux platform when I execute the shell scripts in rio/bin why does it say: bad interpreter: No such file or directory

Q: How do I use Logging?
A: The Logging element has been provided to be able to declare named Logger attributes (Levels, Handlers, etc...) at runtime without depending on logger.properties attributes and values to be set.
Using the Logging element in the OperationalString Document :
<Logging>
<Logger Name="org.jini.rio.demos.hello" Level="ALL">
<Handler Class="java.util.logging.ConsoleHandler" Level="ALL"/>
</Logger>
</Logging>
If we were to choose a java.util.FileHandler as the Handler the declaration would be as follows:
<Logging>
<Logger Name="org.jini.rio.demos.hello" Level="ALL">
<Handler Class="java.util.logging.FileHandler" Level="ALL">
<Parameters>
<Parameter Name="java.lang.String" Value="${RIO_LOG_DIR}${/}hello%u.log"/>
<Parameter Name="boolean" Value="true"/>
</Parameters>
<Formatter Class="java.util.logging.SimpleFormatter"/>
</Handler>
</Logger>
</Logging>
Note the use of ${RIO_LOG_DIR} and ${/}. These values refer to the values of system properties by using the syntax ${propertyName} within the Value literal. The ${/}refers to the file name separator character. Its use is identical to that found with the Jini Configuration approach.
Information on Logger names for Rio components can be found here
Q: What is the DeploymentSchedule?
A: The DeploymentSchedule element allows a deployer to specify a time in the fture when an OperationalString will be deployed and how long it will remain deployed (the deployment duration).
Scheduling of an OperationalString is part of the OperationalString itself, the schedule itself is an optional declarative attribute, and if not declared the OperationalString will be deployed immediately.
The OperationalString is scheduled as part of the OperationalString element. An example of a
schedule follows:
<DeploymentSchedule>
<DeployDate DayOfWeek="Thursday" Hour="8" Minute="30" Format="PM"/>
<Duration Minutes="30"/>
<Repeats Count="10">
<Interval Days="1" Hours="1" Minutes="1"/>
</Repeats>
</DeploymentSchedule>
This DeploymentSchedule produces the following:

- Deploy the OperationalString every Thursday at 8:30 PM
- The OperationalString shall remain deployed for 30 minutes
- The OperationalString deployment repeats 10 times, waiting 1 day, 1 hour and 1 minute between
- deployments

Once the DeploymentSchedule element is parsed, a org.jini.rio.core.Schedule object is created and
set to the enclosing org.jini.rio.core.OperationalString object.
Once the OperationalString is deployed, the Schedule is consulted to determine the semantics of when to optionally schedule the OperationalString deployment.
Q: What is the SystemRequirements element and what does it mean?
A: The SystemRequirements element is a child of the ServiceLevelAgreements element and provides information specific to what system components and measures must be present on a compute resource in order for a ServiceBean to be provisioned. These capabilities allow better control over resources and better provisioning behaviour.
Declaring SystemRequirements for a ServiceBean allows specific matching to occur, ensuring the declared properties are matched to advertised Cybernode capabilities. Cybernode provides (and updates) a org.jini.rio.qos.ResourceCapability object with it's registration to discovered ProvisionMonitor instances.
The SystemRequirements element allows the declaration of SystemComponent and Utilization elements.Determination of whether a platform capability can be met is decided by the PlatformCapability itself. Declared Utilization requirements are verified against the org.jini.rio.core.MeasuredResource objects obtained from the org.jini.rio.qos.ResourceCapability object.
If there are no Cybernode instances which support declared SystemRequirements, the service will not be provisioned, and the corresponding log message "No compute resources found that meet requirements" will be logged by the ProvisionMonitor.
Q: How do I use the SLA element?
The definition of a SLA typically represents a contractural service commitment, describing the minimum performance criteria to meet while delivering a service. In this context the SLA element provides the means to specify low and high limits (defining an acceptable range) for a SLA with a given identifier. Additionally the SLA provides a mechanism to associate a SLA policy handler, which can be used to process policies specific to SLAs as they occur, taking specific actions appropriate for the ServiceBean.
Rio provides 3 SLA policy handlers. Additional policy handlers can be created by extending the policy handler class.
The Service Grid provides 3 SLA policy handlers. Additional policy handlers can be created by extending the policy handler class.
A: The definition of a SLA typically represents a contractural service commitment, describing the minimum performance criteria to meet while delivering a service. In this context the SLA element provides the means to specify low and high limits (defining an acceptable range) for a SLA with a given identifier. Additionally the SLA provides a mechanism to associate a SLA policy handler, which can be used to process policies specific to SLAs as they occur, taking specific actions appropriate for the ServiceBean.
Rio provides 3 SLA policy handlers. Additional policy handlers can be created by extending the policy handler class.

Configuration Key | Behavior
--- | ---
notify | If a threshold is crossed (breached or cleared), the SLAPolicyHandler will fire a SLAThresholdEvent
relocation | Extends org.jini.rio.qos.SLAThresholdHandler, and if thresholds are crossed, will inform the OperationalStringManager to relocate the ServiceBean
scaling | Extends org.jini.rio.qos.SLAThresholdHandler, and will increment and optionally decrement instances of the ServiceBean it is associated to based on limits set for the SLA

When a SeviceBean is instantiated by a Cybernode, the SLA element's ID is used to match a Watch that has been created by the ServiceBean, or declaratively created. If the SLA ID cannot be matched to a watch, the SLA will not be associated.
Once associated the SLAPolicyHandler will be notified based on the thresholds that have been set.
An example SLA declaration follows:
<SLA ID="backlog" Low="100" High="500">
<PolicyHandler type="scaling" max="10"
lowerDampener="3000" upperDampener="3000"/>
</SLA>
This SLA declares that a scaling policy handler be attached to a watch with the name of "backlog", that the number of services scale up to 10. This declaration also inlcudes lowerDampener and upperDampener configuration. The lowerDampener and upperDampener attributes have to do with the avoidance of oscillating around a threshold which is breached. These values behave as a smoothing filter, taking into account the reality that action on a threshold breach may need to be delayed.
Other discussion items:

- If the "type' is either relocation or notify, the max attribute is ignored
- If the type is notify, the lowerDampener and upperDampener attributes are ignored

The SLA is not always tied to the SLA ID attribute for matching up to a Watch. By declaring the <Monitor> element within the scope of the <SLA> element, a Watch will be dynamically added, using the declared attributes to obtain the information needed to observe the declared SLA thresholds. The SLA will be associated to the name of the <Monitor> (which is a Watch). This is illustrated here:
<SLA ID="backlog" Low="100" High="500">
<PolicyHandler type="scaling" max="10"
lowerDampener="3000" upperDampener="3000"/>
<Monitor name="collector" property="count" period="5000/
</SLA>
The Monitor declaration tells the Rio runtime to create and register watch wit the name of "collector", reading the getCount method every 5 seconds. (note: If the Watch already exists in the bean's WatchRegistry, the watch will not be added). The bean must declare a Java bean getter method that has as it's return type one of the following:

- Supported primitive types: int.class, long.class, float.class, double.class
- Supported types: Integer.class, Long.class, Lloat.class, Double.class

The read property return type is verified prior to watch creation. For example, given a bean called Foo, which declares a method called getCollector :
public class Foo {
...
public long getCollector() {
return(value);
}
...
}
Q: What is a SharedComponent and how do I use it?
A: A SharedComponent is a class which can be dynamically installed into the shared ComponentLoader and used by all active services. Access to the ComponentLoader is from the ServiceBeanContext.
The shared component concept was originally created to deal with the issue of loading and sharing native libraries, but other uses can be thought of. Examples:

- Creating a shared blackboard for local communications
- Creating transient PlatformCapabilities
- Creating a common capability to share across service instances like a Jxta peer or a database connection

Declaring a shared component is done as part of the Resources element. Example:
<ImplementationClass>org.jini.rio.demos.jni.JNITest
<Resources>
<JAR>jni.jar</JAR>
<JAR>rio.jar</JAR>
<SharedComponent>
<ClassName>org.jini.rio.demos.jni.component.JNIObject</Class>
<JAR>jni-component.jar</JAR>
</SharedComponent>
</Resources>
</ImplementationClass>
Q: What does global configuration mean and how do I use it?
A: Global configuration is simply the capability to declare common attributes of services declared in the OperationalString as direct children of the OperationalString element. This provides ease of use reducing the amount of (potential) repetitive definitions for services in an OperationalString.
The benefit to doing this is you define common attributes once, and all ServiceBean and Service definitions essentially 'inherit' those declarations. If attributes are declared at both levels (OperationalString and ServiceBean) , declared ServiceBean attributes would take precedence. That is if an OperationalString-level Parameter is defined, and the same name is defined at the ServiceBean-level the ServiceBean defined parameter would override the parameter declared at the OperationalString level for that specific Service's parameter configuration.
Elements that can be globally declared are:

- Cluster
- Codebase
- Configuration
- Groups
- Locators
- Logging
- Organization
- Parameters

If global elements are declared in both the OperationalString element and either the ServiceBean or Service element, they are replaced with the ServiceBean or Service declared values. If the declared elements contain child elements (Cluster, Groups, Locators, Parameters, Logging, Configuration, Cluster) the element's attribute of IncludeGlobalDecl is used to determine if the globally declared value should be added to the currect declaration, or the current declaration should override the global declaration. If IncludeGlobalDecl is set to "yes" then the globally declared value is included. If "no" then the locally (the element in the ServiceBean or Service element) is used.
Example 1
<OperationalString Name="Hello World">
<Parameters>
<Parameter Name="param4" Value="baz"/>
</Parameters>
...
<ServiceBean Name="Hello World" MatchOnName="yes" ProvisionType="fixed">
...
<Parameters IncludeGlobalDecl="yes">
<Parameter Name="param1" Value="foo"/>
<Parameter Name="param2" Value="bar"/>
<Parameter Name="param3" Value="foobar"/>
</Parameters>
...
</ServiceBean>
</OperationalString>
In this example the resulting Parameters are:
param1=foo
param2=bar
param3=foobar
param4=baz
Example 2
<OperationalString Name="Hello World">
<Parameters>
<Parameter Name="param4" Value="baz"/>
</Parameters>
...
<ServiceBean Name="Hello World" MatchOnName="yes" ProvisionType="fixed">
...
<Parameters>
<Parameter Name="param1" Value="foo"/>
<Parameter Name="param2" Value="bar"/>
<Parameter Name="param3" Value="foobar"/>
</Parameters>
...
</ServiceBean>
</OperationalString>
In this example the resulting Parameters are:
param1=foo
param2=bar
param3=foobar
Example 3:
<OperationalString Name="Hello World">
<Parameters>
<Parameter Name="param4" Value="baz"/>
</Parameters>
...
<ServiceBean Name="Hello World" MatchOnName="yes" ProvisionType="fixed">
...
</ServiceBean>
</OperationalString>
In this example the resulting Parameters are:
param4=baz
In addition to this processing if a globally declared value contains child elements, and the child element is of the form key/value (Parameters, Configuration, Logging), the declared value at the <ServiceBean> or <Service> element will override the key/value of the global element
Example 4
<OperationalString Name="Hello World">
<Parameters>
<Parameter Name="param2" Value="baz"/>
</Parameters>
...
<ServiceBean Name="Hello World" MatchOnName="yes" ProvisionType="fixed">
...
<Parameters>
<Parameter Name="param1" Value="foo"/>
<Parameter Name="param2" Value="bar"/>
<Parameter Name="param3" Value="foobar"/>
</Parameters>
...
</ServiceBean>
</OperationalString>
In this example the resulting Parameters are:
param1=foo
param2=bar
param3=foobar
Q: What is a SoftwareLoad?
A: The SoftwareLoad element is declared by a ServiceBean as an optional parameter, which is used to install required software on a compute resource if the compute resource does not have the requisite software available (as determined by advertised PlatformCapability objects).
A SoftwareLoad can only be provisioned to a Cybernode if and only if the Cybernode supports persistent provisioning (as determined by the org.jini.rio.cybernode.provisionEnabled property set by the Cybernode) and there is adequate diskspace on the targetted machine.
If the SoftwareLoad can be provisioned to the Cybernode, the SoftwareLoad element defines an installable software element with a post install helper to configure the downloaded software. The SoftwareLoad additionally provides a RemoveOnDestroy attribute which will cause the SoftwareLoad to be removed from the compute resource when the ServiceBean has terminated. If the RemoveOnDestroy is declared as no, then the SoftwareLoad will remain on the compute resource after the ServiceBean has terminated. Additionally, the compute resource's PlatformCapability collection will be updated to reflect the addition of the SoftwareLoad.
If the SoftwareLoad is installed on the compute resource a org.jini.rio.core.provision.SoftwareDownloadRecord is created and used to document disk space use as part of the org.jini.rio.core.provision.ServiceRecord and org.jini.rio.core.provision.ServiceStatement created documenting service instantiation time and usage.
Q: Whats the difference between ProvisionType of fixed and dynamic?
A: The ProvisionType is an attribute of the ServiceBean element and indicates how the ServiceBean will be provisioned and allocated through the network.

- The dynamic type indicates that the service will be provisioned to available compute resources that meet declared SystemRequirements up to the amount specified by the Maintain element (the number of planned instances). This is the default ProvisionType
- The fixed type indicates that the service will be provisioned to to available compute resources that meet declared SystemRequirements. The number of services provisioned to each compute resource is the number specifed in the Maintain element

So when to use dynamic and when to use fixed?
Use dynamic when you want to have a certain amount of services running on machines which meet the declared SystemRequirements for the service. For example if you need 10 services running across a collection of compute resources at all times, then use dynamic.
If however you want to make sure that every compute resource that advertises a certain capability has a service running on it use fixed. If you have 100 compute resources online, you'll have 100 services. If there are 5 omnline, you'll have 5 services.
Q: Whats the difference between Parameters and Configuration and when should I use which one?
A: Right off the bat the Configuration element produces net.jini.config.Configuration object and the Parameters element creates a java.util.Map with name/value keys populated from the element. The Configuration is obtained by using the org.jini.rio.core.jsb.ServiceBeanContext.getConfiguration() invocation. The name/value pairs obtained from the Parameters element are accessible using the org.jini.rio.core.jsb.ServiceBeanContext.getInitParameterNames() and org.jini.rio.core.jsb.ServiceBeanContext.getInitParameter(String name) methods.
The Parameters element initially creates String name/value pairs. You can add to the parameters as well during service execution, creating name/value pairs where the value can be something other then a String.
Use the Configuration if you need to construct complicated Object types at intialization, otherwise the Parameters element serves the purpose for setting runtime properties.
Q: What is the reason for having a Group in the opstring? Don't all services use the same group as the ProvisionMonitor?
A: Groups are specified in the OperationalString to indicate the set of groups the Service will use for discovery. These groups do not need to be the same as the set of goups configured for the ProvisionMonitor. The ProvisionMonitor uses the Groups declared by the service to discover instances of the service in order to monitor, and when needed allocate instances of the service to compute resources which meet declared requirements of the service.
The groups a ProvisionMonitor uses for discovery do not need to match the groups a service uses. If this were the case then you would need to modify the set of groups the ProvisionMonitor has been set with to match the set of all groups for all services the ProvisionMonitor is monitoring. Alternatively you could deploy a ProvisionMonitor each time a service were added to the network which had a different set of groups then the groups the ProvisionMonitor knows about. Neither of these cases are preferred.
Q: How do I declare a ServiceUI in the OperationalString?
A Service UI can be declared in the OperationalString using <Configuration> approach.
The org.jini.rio.jsb.ServiceBeanAdapter will use the net.jini.config.Configuration object returned from org.jini.rio.core.jsb.ServiceBeanContext.getConfiguration() to get a configuration property named <package-name-of-the-service>.serviceUIs. In this example the configuration entry is org.jini.rio.demos.hello.serviceUIs
This approach was chosen instead of a more general "get initial attributes" approach because additional data is being provided to resolve the host address and port where the service UI can be located on the network.
An example of the declaration of a serviceUI for the Hello service:
<Component Name="org.jini.rio.demos.hello">
<Parameter
Name="serviceUIs"
Value="new net.jini.core.entry.Entry[]{
org.jini.rio.entry.UIDescriptorFactory.getUIDescriptor(
net.jini.lookup.ui.MainUI.ROLE,
net.jini.lookup.ui.factory.JComponentFactory.TYPE_NAME,
(String)$data,
&quot;hello-ui.jar&quot;,
&quot;org.jini.rio.demos.hello.HelloUI&quot;,
)}
"/>
</Component>
To declare the same service UI which additionally computes a message digest using the codebase :
<Component Name="org.jini.rio.demos.hello">
<Parameter
Name="serviceUIs"
Value="new net.jini.core.entry.Entry[]{
org.jini.rio.entry.UIDescriptorFactory.getUIDescriptor(
net.jini.lookup.ui.MainUI.ROLE,
net.jini.lookup.ui.factory.JComponentFactory.TYPE_NAME,
(String)$data,
&quot;hello-ui.jar&quot;,
&quot;org.jini.rio.demos.hello.HelloUI&quot;,
true,
&quot;sha&quot;
)}
"/>
</Component>

Q: How can I debug a service?
A: To debug a service, you need to do the following:

- Make sure Java compiler generates debug info when compiling the source code of the service. If you use command line javac compiler, specify "-g" option. If you use Ant, specify "debug" and, optionally, "debuglevel" parameters for the <javac> task. If you use an IDE, make sure the compiler generates debug info.

- Run JVM that hosts Cybernode with the options that enable remote debugging:
  -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,address=8888,suspend=y

If you use the cybernode.bat (Windows) or cybernode.sh (Unix) script to start Cybernode, make a copy of the script (name it e.g. cybernoded.bat or cybernoded.sh) and modify it to pass the debugging options to JVM:
On Windows:
set DEBUG_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,address=8888,suspend=y
%JAVA_HOME%\bin\java -server %classpath% -Djava.security.policy=%RIO_HOME%\policy\policy.all -Djava.protocol.handler.pkgs=net.jini.url -DRIO_HOME=%RIO_HOME% -DJINI_HOME=%JINI_HOME% -DRIO_LOG_DIR=%RIO_LOG_DIR% %DEBUG_OPTS% %launchTarget% %RIO_HOME%\configs\start-cybernode.config
On Unix (bash):
DEBUG_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,address=8888,suspend=y"
$JAVA_HOME/bin/java -server $classpath -Djava.security.policy=$RIO_HOME/policy/policy.all -Djava.protocol.handler.pkgs=net.jini.url -DRIO_HOME=$RIO_HOME -DJINI_HOME=$JINI_HOME -DRIO_LOG_DIR=$RIO_LOG_DIR $DEBUG_OPTS $launchTarget $RIO_HOME/configs/start-cybernode.config
Now use the modified script to start Cybernode. Note that "suspend=y" means that JVM will suspend until you connect to it with a debugger. For more details see e.g. http://java.sun.com/j2se/1.5.0/docs/guide/jpda/conninv.html. If you use the startall script to start Rio infrastructure, create and use the debug version of this script in the same way.

- Attach your Java debugger to the JVM. For instance, if you use NetBeans 4.0, click the "Attach Debugger..." toolbar button, make sure "dt_socket" transport is in use and "SocketAttach ..." is selected in the "Connector" field, type 8888 in the "Port" field, and click "OK". Once the debugger is attached, JVM usually resumes automatically; otherwise you should do this manually. Now you can set breakpoints in your code (in most of the IDEs you can also set breakpoints before you attach the debugger). To test that debugging works, set a breakpoint in the service's initialize() method. Now deploy the opstring using OpString Monitor. This should instantiate the service, so if you have a breakpoint in the initialize() method, the debugger should stop on it. Now you are able to debug the code. Note that the debugger should know where the source code of the service is located. In NetBeans it is enough to have the corresponding project opened.

Note that you can also debug Rio code itself. Rio is built with debug info turned on by default, so all you need is to tell the debugger where Rio sources are located. In NetBeans you can add lib/rio.jar to the collection of libraries and indicate that the sources are located in the modules/core/src directory of the Rio distribution.
Of course, this is not the only way to debug Rio services, but, perhaps, a simple one. This approach has been verified on Solaris, not on Windows or OS X.
Q: How do I know whether a service has been provisioned for the first time or whether the service is being provisioned as a result of failure?
A: The easiest way is to check the Host History for the service. Every service will have a history of the hosts it has been instantiated on. If the service has never been instantiated on a host, it's host history will have a length of zero. Example :
java.util.List hostList =
(java.util.List)context.getServiceBeanConfig().
getConfigurationParamaters().
get(ServiceBeanConfig.HOST_HISTORY);
if(hostList.size()==0) {
System.out.println("First time");
} else {
for(java.util.Iterator it=hostList.iterator(); it.hasNext();)
System.out.println("\t"+it.next());
}
Another approach is to add a service-defined initialization parameter. this can be done very easily in the ServiceBean initialize() method as follows:
public void initialize(ServiceBeanContext context) throw Exception {
super.initialize(context);
String cookie = (String)context.getInitParameter("service-cookie");
if(cookie!=null) {
System.out.println("cookie="+cookie);
} else {
System.out.println("First time, create service cookie");
context.getServiceBeanConfig().addInitParameter("service-cookie", "some-value");
}
}
It should be noted that the ServiceBeanConfig survives service crashes, and can be used to store service specific attributes.

Q: I'm running on a Microsot Windows platform and the Rio Viewer does not show any of the services that are running, whats wrong?
Make sure NetBIOS over TCP/IP is turned on. This may also affect other communications between Rio services executing on Windows. To turn NetBIOS on:

1. Open Network Connections
2. Select Properties for the network adapter being used
3. Highlight Internet Protocol (TCP/IP)
4. Select Properties
5. Select Advanced
6. Choose the WINS tab
7. Select Enable NetBios over TCP/IP
8. Click OK

Q: On a Linux platform when I execute the shell scripts in rio/bin why does it say: bad interpreter: No such file or directory
The shell script interpreter being used may not be found or there may be extra control characters at the end of each line.
Check to make sure the other scripts can be run using /bin/bash. Check to make sure the first line of the Rio script includes the correct interpreter line. For example: #!/bin/bash
If there are \r characters for carriage returns at the end of each line, they need to be removed for Linux. These are ok in Windows. The control characters can be removed using the following command:
tr -d '\r' < inputfilename > outputfilename