This document describes the IRIS proxy plugin and provides instructions
for running and configuring the plugin.
Overview
The IRIS proxy plugin provides the following capabilities:
- A lightweight RMI protocol.
- A Java implementation for the protocol using Java Proxies for
interface-based APIs.
- A .NET implementation of the protocol.
- Stub generation for .NET APIs. This includes interfaces,
instances and static accessors.
- Configuration files in IRIS which enable UI separation.
The proxy code is designed to be as light-weight and simple as
possible, and was custom-written for IRIS. As a historical note, note
that the initial protocol implementation and algorithms were developed
as the OAA (Open Agent Architecture) .NET interface. The following
locations in the IRIS source tree contain the proxy code:
- iris/thirdparty/proxy
Contains the protocol implementation, tcp transport implementation as
well as common serializers. Also contains the CSharp .NET generation
code. This package also contains unit tests for the proxy plugin.
- iris/plugins-src/proxy
Contains the proxy plugin source specific to IRIS. Also contains the
IRIS configuration files which allow UI separation startup options.
Building the Proxy plugin
The proxy plugin builds when IRIS is built. The following is the
generated output after building the plugin:
- iris/plugins/proxy
Contains the IRIS Proxy plugin code and configuration files. This
directory also contains the 2 startup option files which allow IRIS to
be run in "Server" and "Client" mode.
- iris/plugins-src/proxy/project/IrisDotNet/IrisDotNet.csproj
After building, this file is generated which is the .NET project
containing .NET stub interfaces and the .NET protocol implementation.
- iris/plugins-src/proxy/dest/csharp/src/csharp
Contains the generated C# stubs. Note that the generated project file
contains links to these files.
Note that the .NET library must be built manually. To build the .NET
library follow these steps:
- Make sure IRIS is built and the Proxy plugin builds.
- Open the file iris/plugins-src/proxy/project/IrisDotNet.sln
using Microsoft Visual Studio .NET 2003.
- Choose "Rebuild Solution" from the Build menu.. The .NET assembly
will be outputted to src/proxy/project/IrisDotNet/bin/Debug/IrisDotNet.dll
Note that by default the assembly is built in Debug mode, but
that can be changed by changing the build configuration options.
Note that there is a test .NET application. To build the test
application, first build the .NET library and then open/build the
solution iris/plugins-src/proxy/project//TestApp/TestApp.sln
Also note that when building IrisDotNet.dll some warnings are
generated. Those warnings can be ignored.
Running the proxy plugin
The proxy plugin loads automatically when IRIS is run. After IRIS
is run the following output shows that the Proxy plugin loaded
successfully:
INFO IrisRemoteProxyServer listening on port 4012 for client connections
Once the Proxy plugin has started, remote clients can connect. For
example, the .NET TestApp application can be run to connect to IRIS.
Security
Note that currently there is nos ecurity restrictions for accepting
client connections to the Proxy plugin. It is very important that IRIS
only be run on a secure network. If the network is not secure, then the
Proxy plugin should be disabled by modifying the IRIS startup options.
Note that any application can
access the entire JVM through the Proxy plugin. This is why it is
critical that the network be secure, and/or that the TCP connection be
made securely (for example, using ssh tunneling).
Concepts
Remote Sessions
For each remote connection, IRIS maintains a remote object database
that contains all remote references. Remote references follow an
addref/release model. When no more references exist for an instance,
the reference is removed from the object database. All this happens
transparently and the client application does not need to handle
reference counting. Note, however, that in the case the client
connection is terminated there are 2 scenarios that can happen:
- If the client terminates the connection because the client is
shutting down, or the client code terminates the connection through the
remote API, then the object database is destroyed. If the client wishes
to reconnect, the client needs to construct a new connection and re-retrieve all remote references.
This last part is important; the client cannot re-use any previous
remote references because the object database for those references will
have been destructed.
- If the client connection fails for some other reason then the
object database will be maintained by the server. For example, the
connection may fail because a network interface has gone down. In this
case IRIS will hold onto the object database for a short time. The
client can then re-use the existing remote references. When it does,
the client will attempt to reconnect to IRIS and re-establish the
remote session. Note that the timeout for destructing the remote
database is determined by inspecting the property
"DataMarshalServerImpl.session.maxTimeout" on the JVM IRIS is running
in. The default value is 1 hour.
Communication between mutiple clients
The Proxy plugin allows a client to obtain remote references to
other Proxy clients. The APIs are transparent and are interface-based
using the Java dynamic Proxy mechanism.
Asynchronous
Callbacks
A Callback refers to a
method invocation that IRIS makes back to a Proxy client. In the
interest of speeding up communications, it is possible to make
callbacks which do not return any data (ie, a void return type) execute
asynchrnously. This is enabled by default. The parameter value can be
changed by changing the Proxy plugi configuration, as specified below.
Custom
Serialization
The Proxy protocol has a serialization setup phase when a client
connects. It works as follows:
- When IRIS starts it has Serializers
which are set up by reading the proxy.xml configuration file (see
below).
- A client can inspect the installed serializers and communicate to
IRIS which serializers the client also supports. For example, a Java
client will use reflection on the serializer class names and
constructor arguments to determine if the serializer is supported. A
.NET client has some serializers built-in and provides a way for
clients to implements new ones. However, note that not all Java
serializers have been ported to .NET. This means .NET uses a subset of
the serializers installed on the client.
Why use serializers? The main reason is that using serializers can
drastically improve the performance of the application. The existing
serializers in IRIS have been tuned to ensure that IRIS performs as
fast as possible over the RMI proxy. Another reason to use serializers
is that often times the API is not entirely interface based and it is
necessary to pass instances. Int his case, new serializers can be
written for tht einstance classes. Finally, note that athe proxy plugin
does support serialization using java.io.Serializable. Of course, this
only applies towards Java clients. See the API sestion below for more
information on how to write serializers, and the configuration section
for information on how to specify the serializer in the Proxy
configuration file.
For
more information on concepts, see the API documentation for IJavaClient
referenced below.
APIs
See the following Javadoc APIs for more information on accessing the
Proxy plugin: Note that in order for these links to work, you must run
the "ant javadoc" task from the IRIS build. Or, if you have an IRIS
distribution, unzip the API docs and make sure the folder iris/doc/api
exists.
Note that in order to use IrisRemoteProxy, you must include the 2 jar
files which reside in iris/plugins/proxy in the classpath. In additionn
imany other jar files are required for logging, spring, etc. An ant
target can be run to gather all the jar files needed to get the remote
proxy working. From the iris/plugins-src/proxy/src directory, execute "ant assmbleClientAPI" and view the
output. Of course, this requires the IRIS source. For reference the
list of jar files is provided below, but it is recommended that the ant
target be used.
- All jar files in iris/plugins/proxy
- All jar file in iris/dest/jar
- In iris/lib, the following jar files:
- log4j-*.jar,concurrent.jar,som.jar,lucene*.jar,spring*.jar,jena*.jar
Currently this listing of jar files produces:
$ ls ../dest/clientjars/
bootstrap.jar*
iris.jar*
lucene-1.4.3.jar* spring-beandoc.jar* spring-remoting.jar*
concurrent.jar* irisproxyagent.jar*
proxy.jar*
spring-beans.jar*
iris-jena.jar*
jena.jar*
som.jar*
spring-context.jar*
iris-kernel.jar* log4j-1.2.13.jar*
spring-aop.jar* spring-core.jar*
Note that for .NET functionality, only the "IrisDotNet.dll"
assembly is needed. See the documentation on Building the Proxy plugin
for more information.
See the section below on Examples for example applications.
Configuration
The proxy configuration file can be found at iris/plugins/proxy/proxy.xml..
This configuration file is documented to explain the various
configurations that can be modified. This configuration file is also
used during UI separation (documented below). Please see this
configuration file for mor information.
For .NET support, remote stubs must be generated at compile time. These
remote stubs are specified in the proxy build.xml file.
The ant target "generateJavaBeanSource" lists all classes for API
genration. Currently hundreds of classes are supported. However, there
are many IRIS services and it may be that some APIs are missing. If you
would like APIs added, please notify the IRIS team or you can email richard.giuli@sri.com.
UI Separation
The proxy plugin provides 2 startup
options files for IRIS:
When IRIS starts there is a drop-down list. To run UI separation, first
run IRIS and choose "IRIS Server" from the list. Then after IRIS has
finished loading, run IRIS again and choose "IRIS Client".
Note that it is possible to run more than one IRIS client. However,
this has not beenheavily tested. Also note that you can run IRIS client
from another machine by changning the connect address which is
specified in proxy.xml (see above on Configuration).
Examples
Pub/Sub
Java example
This example application can be found in the directory iris/plugins/proxy/javaexampleapp
To run the example, make sure IRIS has started. Also, the latest
version of ant is required. Once
in this directory, run "ant run".
This will build and run the xample app and you chould see the following
output:
[java]
Connecting to remote IRIS
[java] Connected to remote IRIS
[java] Registered for events.
The source for this example can be found in the directory iris/plugins/proxy/javaexampleapp/java/com/sri/iris/event/sample/remote.
In this directory are located the following source files (note that
clicking the source file links navigates directly to them):
- EventTestMain.java
Connects to IRIS remotely. Also registers for a BrowserLocationEvent
and prints the page location and source.
- CalendarEventListener.java
Registers for 3 calendar specific events and prints the event
information.
This example demonstrates the following consepts:
- How to access IRIS remotely from Java
- Working with Pub/Sub
- Working with Ontology POJO objects
The source code is simple enough that it is not walked through here.
For more information, see the source files and also see the JavaDoc for
the related classes. For reference, here is a link to the JavaDoc for
IMessageManager: com.sri.iris.message.IMessageManager
..NET example
Follow the instructions at the top for building the .NET example
"TestApp.sln". After building, run TestApp after IRIS is run. It will
connect to IRIS and do a query for all people. It will print the
results of the query.
In addition, the TestApp demonstrates working with Ontology POJOs from
.NET, the IRIS suggestion framework, Pub/Sun and more. Please see the
source for more details.