This is the documentation of the implementation of Siena for the Java language.
Copyright © 2000-2005 University of Colorado.
Copyright © 2005-2008 Antonio Carzaniga.
Authors: Antonio Carzaniga, Amir Malekpour.
Lats update on 01/06/2012 reflecting Siena DVDRP 2.0.1

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

Please, send comments, suggestions, complaints about this documentation to Antonio Carzaniga <(firstname.lastname@usi.ch)>.


Basics

Siena is a publish/subscribe service. The abstract interface of Siena is embodied in the {@link siena.Siena} interface. An application typically uses an implementation of the Siena interface to {@link siena.Siena#publish(siena.Notification) publish} {@link siena.Notification}s or to {@link siena.Siena#subscribe(siena.Filter, siena.Notifiable) subscribe} for some notifications of interest.

Notifications

An event notifications is a set of named attributes. Each attribute has a type and a value (see {@link siena.AttributeValue}). For example:

string stock "XYZ"
int quantity 2500
float price 3.1415

Attribute names must be unique in a notifications.

Selection Mechanisms for Subscriptions

Siena offers two kinds of selection mechanisms:

How Notifications are Delivered to Subscribers

A subscriber must implement the {@link siena.Notifiable} interface. Siena delivers notifications to a subscriber by calling the notify method on the subscriber object. Notifiable has two variants of the notify method: {@link siena.Notifiable#notify(siena.Notification) notify(Notification n)} is called to notify a single notification, while {@link siena.Notifiable#notify(siena.Notification[]) notify(Notification s[])} is called to notify a sequence of notifications.

A subscriber must provide both implementations, even if it will never receive sequences of notifications. In this case, the subscriber can implement:

    public void notify(Notification[] s) {};

How to Set Up a Siena Service

How to Access the Siena Service

Objects can publish or subscribe by accessing an implementation of Siena. The simplest way to access a Siena service is through a remote service interface object. This is essentially a proxy object that sends every request to an external Siena server, and receives incoming notifications. The implementation of the proxy is provided through the {@link siena.ThinClient} class. A ThinClient object implements the Siena interface, but it does not provide a Siena service itself: it simply forwards every publication and every subscription to the remote server, and passes any incoming notification to its subscriber.

Clients use a ThinClient just like any other Siena interface. A publisher creates a ThinClient object and publishes notifications to it. A subscriber creates a ThinClient object and subscribes.

For example:


    ThinClient mySiena = new ThinClient("ka:host.domain:1111");
    Notifiable subscriber;
    // ... subscriber = ...

    Filter f = new Filter();
    f.addConstraint("message", OP.ANY, null);
    mySiena.subscribe(f, subscriber);

    // ...
    Notification n = new Notification();
    n.putAttribute("message","Hello, World!");
    mySiena.publish(n);
    // ...

How to Set Up a Network of Siena Servers

You can run a stand-alone Siena server with {@link siena.StartDVDRPServer}. For example:

    java siena.StartDVDRPServer -id server1 -receiver ka:myhost.mydomain:1111
starts up a Siena server on the local host, giving this server the identifier "server1". This server is also given a packet receiver based on persistent TCP connections ("ka" type) on port 1111, and this receiver is also given the host name "myhost.mydomain", so that it would, if necessary, advertise that host name to other servers.

Once a server is up and running, you can control the configuration of that server using the {@link siena.DVDRPControl} utility, and in particular you can establish a connection between two servers. Suppose that, in addition to the server started above, you also start another server on some other machine otherhost.mydomain:

    java siena.StartDVDRPServer -id server2 -receiver ka:otherhost.mydomain:2222
and yet another server

    java siena.StartDVDRPServer -id server3 -receiver ka:thirdhost.mydomain:3333

Now, you can tell the first server to connect to the other two:

    java siena.DVDRPControl ka:myhost.mydomain:1111 connect server2 ka:otherhost.mydomain:2222
    java siena.DVDRPControl ka:myhost.mydomain:1111 connect server3 ka:thirdhost.mydomain:3333
which forms a triangle-shaped network of Siena DVDRP servers. As the example shows, the broker topology need not be a tree. When a cyclic topology like above is formed, brokers route messages on trees in order to avoid cycles. By default the cost of each inter-broker link is one. You can specify the cost of a link by passing a last argument to siena.DVDRPControl. In this case brokers route messages on the shortest path they compute given the cost of each link. As an example the following link has a cost of 10:
    java siena.DVDRPControl ka:myhost.mydomain:1111 connect server2 ka:otherhost.mydomain:2222 10

To disconnect an already established inter-broker link, use the command disconnect. For example, to remove the above link issue the following:

    java siena.DVDRPControl ka:myhost.mydomain:1111 disconnect server2

To create large topologies you can specify a configuration file to the control tool, with one command per line. Lines starting with '#' will be ignored.

    java siena.DVDRPControl -f <configuration-file>

Receivers and Transport Protocols

The communication of brokers with other brokers and clients can be over TCP or UDP. This is specified as a command line option as you saw before, when starting a Siena broker:

    java siena.StartDVDRPServer -id server2 -receiver ka:otherhost.mydomain:2222

This specifier tells the broker how to receive incoming requests. The format of receiver specifier is as follows :

    transport_type:host_address:listening_port:[receiver_threads_num]

Where the last part (receiver_threads_num) determines the number of threads to be used to maintain persistent TCP connection (with ka transport explained below). This part of specifier is optional and has a default value of 5.
transport_type must be one of the following:

tcp: On demand TCP connection. With this option a TCP connection is made to send each message and is terminated once sending is complete. Note that if you have very high message send/receive rates this type of connection is very likely to cause message loss since closing and initiating connections takes a relatively long time. You can detect this problem, for instance by seeing a client throwing an instance of siena.comm.PacketSenderException upon publishing a message.

ka: Persistent TCP connection (keep-alive). With this option a TCP connection begins the first time a message is to be sent and is maintained until explicitly terminated. This connection type is best appropriate for inter-broker links or for high rate publishers/subscribers.

udp: UDP connection. With this type of connection messages incur smaller delivery delays. It is suitable in cases where a broker serves many clients (e.g., more than 1 thousand concurrent clients).