<?xml version="1.0"?>
<document>

<properties>
  <title>Bridge</title>
  <author email="m.b.taylor@bristol.ac.uk">Mark Taylor</author>
</properties>

<body>

<section name="Bridge">

<subsection name="Introduction">

<p>JSAMP provides a special client called the Bridge.
Its purpose is to link up two or more hubs, so that clients registered 
with one of the linked hubs can communicate with clients registered with 
any of the other hubs as if they were registered on the same one.
Usage instructions are given in the
<a href="commands.html#Bridge">commands reference</a>.
</p>

<p>The bridge works by registering a proxy client on all the remote hubs
for each client on a local hub.
These proxy clients can be communicated with just like non-proxy ones,
but the client metadata is adjusted so that a user can see that they
are proxies; the icons are mangled, the names have "(proxy)" appended,
and a metadata entry with the key "<code>bridge.proxy.source</code>"
is added to indicate which hub the client is proxied from.
</p>

<p>You can see some slides from October 2008 explaining how it works here:
<a href="bridge.pdf">Bridge presentation</a>.
</p>

</subsection>

<subsection name="Usage">

<p>In order to set it up, you need to specify which hubs will be connected.
There are various ways you can do this, as explained in the usage
documentation.  In most cases, you will want to bridge the local
'standard' hub with a remote one.
If you can see a <code>.samp</code> file (for instance from another user's home
directory) you can specify it by name like this:
</p>
<pre>
   jsamp bridge -sampfile /home/foo/.samp
</pre>
<p>
or by directory like this (the name "<code>.samp</code>" is assumed):
</p>
<pre>
   jsamp bridge -sampdir /home/foo
</pre>
<p>
or by URL like this:
</p>
<pre>
   jsamp bridge -sampurl file://localhost/home/foo/.samp
</pre>
<p>If you can't see the SAMP lockfile (for instance if it is on a 
remote machine), you can specify the XML-RPC endpoint and samp.secret
string directly.  You might exchange this information with a collaborator
by email or instant messaging if you want to set up a collaboration.
In this case, one (not both) parties would execute a command like:
</p>
<pre>
   jsamp bridge -keys http://foo.star.com:46557/xmlrpc 3c3135435de76ef5
</pre>
<p>
The keys here are obtained by looking in the remote user's .samp lockfile
(the <code>samp.hub.xmlrpc.url</code> and <code>samp.secret</code>
entries respectively).  Note that if the URL uses a loopback hostname
like "localhost" or "127.0.0.1" you may need to replace it with the
fully qualified domain name.
</p>

<p>By default the local standard-profile hub is used in addition to any 
others specified on the command line, but you can inhibit this
with the "<code>-nostandard</code>" flag;
for instance the following sets up a three-way bridge between the standard
profile hubs running in the home directories of users foo, bar and baz:
</p>
<pre>
   jsamp bridge -nostandard
                -sampdir /home/foo -sampdir /home/bar -sampdir /home/baz
</pre>
<p>
without the <code>-nostandard</code> flag it would have been a four-way
bridge between the hubs of foo, bar, baz, and the user running the
command.
</p>

<p>By use of the <code>-profile</code> flag, non-standard profiles
can be used as well.  The bridge can thus enable two communities
of SAMP clients using different profiles to communicate together,
with no other changes to the client source code or configurations.
</p>

<p>The bridge can be run programmatically using the 
<a target="samp-javadoc"
   href="apidocs/org/astrogrid/samp/bridge/Bridge.html"
                >org.astrogrid.samp.bridge.Bridge</a>
class as well - see the javadocs.
</p>

</subsection>

<subsection name="Experimenting">

<p>If you want to experiment with the bridge without having multiple
accounts or multiple hosts you can do so by using the <code>SAMP_HUB</code>
environment variable to set up different 
hubs and communities of clients for connection with bridges.  
</p>
<pre>
   // Start up a hub and a client using the standard profile.
   java -jar jsamp.jar hub
   java -jar jsamp.jar hubmonitor

   // Start a hub and client using a non-standard lockfile location.
   setenv SAMP_HUB std-lockurl:file://localhost/tmp/samp1
   java -jar jsamp.jar hub &amp;
   java -jar topcat.jar &amp;
   unsetenv SAMP_HUB

   // Bridge them together.
   java -jar jsamp.jar bridge -sampfile /tmp/samp1
</pre>
<p>The syntax here is C-shell-like - something similar can be done in
other environments.
</p>

</subsection>

<subsection name="Issues">

<p>In principle, once set up the bridge should work with no further 
intervention.  However, in the case of a bridge between different
machines, there may be some communications issues related to URLs.
Although URLs are formally intended for locating a resource 
regardless of where you are, in practice there may be problems
accessing a URL from a machine other than the one it was constructed on.
These problems fall into two categories.
</p>
<ol>
<li>SAMP clients and the hub usually use HTTP over high-numbered ports
    for communications.  If either machine is behind a firewall which
    blocks such ports, the bridge won't work.  There's not much you 
    can do about this, other than reconfiguring or disabling the firewall.
    </li>
<li>Many of SAMP's MTypes work by exchanging URLs between clients,
    for instance <code>table.load.votable</code> messages pass the 
    location of the table to load as a URL.
    Although in general a URL is intended to specify the absolute location
    of a resource, in some cases a URL can only be resolved on the machine
    on which it was generated.  This is true in two main cases:
    firstly if it is a "<code>file://...</code>"-type URL, which is 
    specific to the current host's filesystem, and secondly if it 
    names the host in some way other than with its fully-qualified
    domain name, for instance using a loopback name such as
    <code>localhost</code> or <code>127.0.0.1</code>.
    Exchanging such URLs between bridged hubs on different hosts 
    will not work.
    The bridge can mitigate these problems to some extent,
    by attempting to <em>export</em> problematic URLs.  In this mode,
    strings in message bodies and responses which appear to be URLs
    are examined, and if they appear to be host-specific
    for a remote host, they are rephrased to make them remotely readable.
    This involves replacing loopback hostnames with fully-qualified ones,
    and where possible exporting <code>file</code>-protocol URLs with
    HTTP ones.  File URL exporting can only work from the host that
    the bridge is running on though, not in the other direction.
    For this reason it may be a good idea to have the bridge running on the
    machine providing most of the data rather than the one receiving
    most of the data, if there's a choice.
    This URL exporting is done by default if there appear to be multiple
    hosts involved in the bridge, but may be controlled by 
    supplying the <code>-[no]exporturls</code> flag on the bridge command line.
    This kind of message manipulation necessarily involves a bit of
    guesswork, so it is possible that it may cause problems.
    </li>
</ol>

<p>The bridge is somewhat experimental; what (if anything) it's useful
for and whether it needs adjustment or new features are still under
consideration.  Please contact the author or discuss it on the apps-samp 
list if you've got any comments or queries.
</p>

</subsection>

<subsection name="Example">

<p>Here is an illustration of how it looks when two hubs have been
connected together using a bridge.
</p>

<p>Prior to the bridge we have two separate hubs, as shown in the 
images below.  
The left hand one shows a JSAMP hub
(displayed using the JSAMP graphical hub view) with TOPCAT registered.
The right hand one shows the state of a SAMPy hub 
(displayed using the JSAMP hubmonitor), running on a different machine, 
with registered clients HubMonitor and SPLAT.
</p>
<table>
<tr align="center">
  <td><img src="images/bridge1pre.png" /></td>
  <td><img src="images/bridge2pre.png" /></td></tr>
</table>
<p>Following a suitable bridge command, they look like this:
</p>
<table>
<tr align="center">
  <td><img src="images/bridge1post.png" /></td>
  <td><img src="images/bridge2post.png" /></td></tr>
</table>
<p>As well as the original, directly registered clients, 
each hub now has the bridge client itself, and a proxy copy 
of each (non-hub) client registered on the other hub.
The proxy ones are easy to identify because their names
(<code>samp.name</code> metadata) have "(proxy)" appended,
and their icons (<code>samp.icon.url</code> metadata) 
have been adjusted (currently the bottom right corner is cut
off, though some other visual idiom may be used in future releases).
In other respects these proxy clients appear to other clients on their
remote hubs just the same as any other client, and can be treated
accordingly.
</p>

</subsection>

</section>
</body>
</document>
