Smart Proxy Demo
Summary
This example shows how Newton can be used to wire up Jini based smart proxies.
Smart proxies are written by service providers and transparently downloaded by clients when they start to use the service. They allow service providers to take responsibility for both sides of the remote protocol their service implements, and to present a simplified facade to their clients.
The basic model is shown below.

These issues were well understood by Jini's creators, and smart proxies have always been a central Jini theme.
Newton tries to simplify the process of writing and deploying smart proxies so as to make them accessible to developers with no understanding of Jini. A little RMI knowledge is required, but not very much.
Overview
In this demo the Server composite constains two local components:
- a SessionManager component that provides authenticated users with SessionToken credential objects.
- a PerUseTable component that allows holders of an authenticated SessionToken to manipulate their private name-value table
It also provides a smart proxy component called SessionTable. This has a single interface that combines both login and table manipulation, simplifying things for the client by hiding the fact that there are two remote interfaces and the details of SessionToken handling.
A CLI based client is used to communicate with this service. It binds to a SessionTable reference, unaware that it is implemented as a smart proxy.
The system we are going to create is shown below.

The CLI descriptor and code is much as in the other examples so we'll only look at the Server composite in detail.
The Server composite creates its SessionManager and PerUseTable components in the usual way. The SessionTable smart proxy component is created in the same way, but uses a special jini-proxy implementation type. It It provides a SessionTable service at Jini scope in the usual way. The full server template XML is shown below.
<?xml version="1.0"?>
<composite name="serverTemplate">
<description>session table service template</description>
<service name="sessionTable-export">
<interface.java interface="org.cauldron.newton.example.sessiontable.proxyapi.SessionTable"/>
<binding.rmi/>
</service>
<component name="sessionManager">
<description>session manager</description>
<implementation.java.callback impl="org.cauldron.newton.example.sessiontable.server.SessionManagerImpl"/>
</component>
<component name="perUserTable">
<description>session scoped table</description>
<interface.java name="perUserTable" interface="org.cauldron.newton.example.sessiontable.serverapi.PerUserTable"/>
<reference name="sessionManager"/>
<implementation.java.callback impl="org.cauldron.newton.example.sessiontable.server.PerUserTableImpl"/>
</component>
<!-- remote proxy -->
<component name="sessionTable">
<description>session scoped table proxy</description>
<reference name="sessionManager"/>
<reference name="perUserTable"/>
<implementation.jini.proxy impl="org.cauldron.newton.example.sessiontable.proxy.SessionTableProxy"/>
</component>
<wire>
<source.uri>perUserTable/sessionManager</source.uri>
<target.uri>sessionManager</target.uri>
</wire>
<wire>
<source.uri>sessionTable/perUserTable</source.uri>
<target.uri>perUserTable</target.uri>
</wire>
<wire>
<source.uri>sessionTable/sessionManager</source.uri>
<target.uri>sessionManager</target.uri>
</wire>
<wire>
<source.uri>sessionTable-export</source.uri>
<target.uri>sessionTable</target.uri>
</wire>
</composite>
Here the <implementation.jini.proxy ..> tag implies the same lifecycle as in the <implementation.java.callback ..> case, with the following important differences:
- All of its references must be satisfied by components within its own composite. This is because once a proxy leaves the composite that created it it will no longer be able to receive updates if the composites's external connections change, whereas internal connections are static and thus unaffected by this problem.
- All of its referenced interfaces are automatically remoted at JVM level, and the proxy is passed these as remote stubs rather than as local references. This is so that the proxy can still communicate with its dependencies after it has left the component that created it.
- The proxy should not be referred to by any other component in the composite. This is because once it has left the originating JVM the local copy will not be in sync with deserialized remote copies of the service.
Note that if any of the proxies referenced interaces do not implement Remote then they will be transparently wrapped prior to being exported, and throw unchecked ConnectionException instances rather than RemoteException instances to indicate remoting errors.
As in all of the Jini demos an RMI-Codebase manifest attribute must be set so that the proxy can be deserialized. See the ant build.xml file for this demo for more details.
Running the example.
Prerequisites
Try the Local Chainlink Demo and Remote Chainlink Demo before this one. These will introduce you to The Newton Component Model and the basics of Jini in Newton.
Booting two Newton containers
In order to run the demo it is first necessary to start two Newton containers. In order to see each other these need to be running as part of the same fabric. To start the two containers on a single machine open two terminals in the Newton bin directory and run
In terminal 1
$ ./container -console -fabricName=myfabric -instance=1
In terminal 2
$ ./container -console -fabricName=myfabric -instance=2
Note that this demo will also work when running across several machines (firewalls permitting)
Here we've used the -console flag to tell newton to run as a console application rather than as a service.
The -fabricName flag sets the fabric name. We've used 'myfabric' but you should choose your own name to prevent clashes. Note that if the fabric name is not set it defaults to the current user name. This means that simple tests on a single machine will work without the fabricName being set. However it should always be set when more than one machine is involved.
The -instance flag is used to separate the state belonging to the two conatiner instances. This is only necessary because we are running the two instances out of the same Newton install. If the instances were running on different machines there would be no need for this flag.
After starting Newton wait for the "Boot complete" message, after which Newton makes a command line available.
Booting the distributed runtime
Newton's distributed infrastructure makes use of multicast, so it is essential that your network and computers are in a configuration that allows multicast traffic. If you are unsure of your setup, or having difficulty running this example the please see Troubleshooting Multicast.
Every instance of Newton starts up with the client side of the distributed infrastructure already installed. At present it is necessary to manually boot the server side infrastructure. In one of the Newton containers run
> installer install etc/instances/reggie.composite > installer install etc/instances/server-cds.composite
This installs the remote services registry, which Newton uses to detect and wire up services in different JVMs. It also starts the remote zone of CDS. All Newton containers share a common view of the content in CDS's remote zone.
This remote infrastructure is itself implemented as an SCA system built from Newton composites.
Optionally you can start the jinibrowser composite, a GUI tool for viewing the remote registry. You can use this to see the services that available to your group remotely.
> installer install etc/instances/jinibrowser.composite
The services may take a few seconds to come up - you'll get an error message at the next step if you are too quick.
Loading bundles into CDS
At this point the bundles used by the session table demo are not present in the CDS, so they must be loaded. Note that this doesn't install anything, it just makes resources available for future installations.
To load the demo bundles run the following in one of your Newton instances.
> cds scan remote examples/sessiontable/build/lib
This loads all of the bundles in demo/build/lib into the remote zone of CDS, extracting metadata and indexing the bundles as they are loaded. Resources in the remote zone can be seen by all Newton containers in the same fabric.
Using SessionTable
First create the CLI part on container 1.
> installer install examples/sessiontable/build/etc/cli.composite
If you now type help you'll see a new command group called sessiontable. This CLI composite has a reference to a SessionTable interface. At the moment there is nothing for it to connect to so lets start the Server composite in container 2.
> installer install examples/sessiontable/build/etc/server.composite
If you opted to run the jinibrowser composite you'll be able to see the exported proxy there.
Newton detects the presence of the SessionTable export and wires it up to the CLI. This involves downloading the smart proxy into the CLI's JVM and deserializing it. The CLI composite doesn't have to worry about these details, it just references the interface.
We now have the system shown in the diagram above and can run some tests with it. First, in container 1, enter the sessiontable command group as follwos:
> enter sessiontable
You can leave the command group at any time by typing leave
The available commands are login to switch user get to get values in a user's table and put to put values in a user's table. The following session manipulates the private tables of two users.
sessiontable> login fred pass logged in sessiontable> put age 51 sessiontable> get age age->51 sessiontable> put name fred sessiontable> get name name->fred sessiontable> login bill pass logged in sessiontable> get age age->null sessiontable> get name name->null sessiontable> put age 34 sessiontable> put name bill sessiontable> get age age->34 sessiontable> get name name->bill sessiontable> login fred pass logged in sessiontable> get age age->51 sessiontable> get name name->fred


