IBM Research Report (RT0245), Apr. 17

InfoBus Repeater:
A Java-based Publish/Subscribe Middleware

04/17/98
Authors:
Hiroshi MARUYAMA, IBM Research, Tokyo Research Laboratory
Naohiko URAMOTO, IBM Research, Tokyo Research Laboratory

Contents

  1. Introduction
  2. InfoBus Overview
  3. Sample Code
  4. Application Programming with InfoBus Repeater
  5. Conclusion

1. Introduction

InfoBus Repeater is a Java middleware for publish/subscribe communication. Publish/subscribe is a new model of network programming, whereby a message sender does not explicitly specify the address of a receiver. Instead, the sender publishes an event with a subject, while the receivers who are subscribing to the subject will receive an asynchronous event. This is quite different from traditional request/response programming using stream sockets (TCP) and remote procedure calls (RPC), in which an application program synchronously waits for a return from a blocking I/O call.

The design goal of InfoBus Repeater is three fold: 1) to use an industry-standard pub/sub API, 2) to achieve scalability through the IP multicast technology, and 3) to provide public-key based security. This paper describes the architecture of InfoBus Repeater and discusses application programming using it. In particular, we show that Lotus e-Suite can be made a distributed application in which a large number of users can share the same document real time.

In the next section, we briefly overview the InfoBus API. Section 3 describes the InfoBus Repeater architecture, followed by example codes. We present the distributed e-Suite as a sample application and discuss application programming based on the publish/subscribe model in Section 4.


2. InfoBus Overview

Before going into the InfoBus Repeater architecture, we briefly explain InfoBus [1]. InfoBus is designed as a vehicle for communication among JavaBean components such as e-Suite components. For example, a spread sheet bean publishes new cell data that is immediately taken by components such as a chart bean. See the figure below that shows an Lotus e-Suite application consisting of a spread sheet and a chart. These two independent components are communicating via an InfoBus so that a change of the value in the spread sheet is immediately reflected in the chart. That is, the spread sheet bean publishers a new value to which the char bean subscribes.

[eSuite screen]

Since publish/subscribe is an event-driven programming model, InfoBus API is also event-driven, as you see in the following diagram. Members who wish to participate in publish/subscribe communication must join an InfoBus first. Depending on a member's role (either producer or consumer, or both), it registers EventListeners in the bus using addDataProducer() or addDataConsumer(). When a producer generates a new event, it calls fireItemAvailable() to notify the event to the bus. The bus in turn announces the event to every consumer by calling dataItemAvailable() of the EventListner. When a consumer wants data from some producer, it calls findDataItem(), which in turn causes an event to be caught by producers through dataItemRequested().

One of its distinctive characteristics in comparison with other publish/subscribe APIs is that InfoBus is symmetric, meaning that it is possible not only for a publisher to publish an event to subscribers but also for a subscriber to request data from any publisher.


3. InfoBus Repeater Architecture

3.1 Design Goals

Our design goals of InfoBus Repeater are:

Publish/subscribe API

There are several publish/subscribe API's.

We selected the InfoBus API because it is an industry standard and will be a part of the next release of Java Development Kit (JDK 1.2). Although the original InfoBus is defined as an intra-VM communication middleware, it is possible to naturally extend its model to a networked hosts by relaying local events through objects called repeaters as we will show in this paper. In addition, InfoBus has technical advantages over the other API's, such as 1) it is symmetric, meaning that not only a producer can publish data but a consumer can ask for data from unspecified producer (sometimes called anycast), 2) it is based on the Java 1.1 event model so InfoBus events can be treated consistently with other events such as AWT events, 3) InfoBus clearly separates an event from the data object that caused the event, which enables "tightly-coupled" pub/sub applications such as Lotus e-Suite (we will discuss this point later).

Scalability

Generally in publish/subscribe communication, there are multiple recipients of a message. Use of a peer-to-peer communication protocol such as TCP/IP will be inefficient when the number of recipients is large. To cope with this scalability problem, we adapted the Reliable Multicast Transport Protocol (RMTP) [2] developed jointly by IBM Tokyo Research Laboratory and NTT (Nippon Telephone and Telegram). RMTP is optimized for medium-scale operation (with up to 10,000 recipients), which covers most situations including Intranet solutions.

RMTP uses the IP multicast function as its delivery system. On top of IP multicast, it realizes the following reliability functions: data transport reliability based on retransmission, handshake-based session control, and notification to the sender (server) application of successful transmission for the purpose of updating information.

See Reliable Multicast Transport Protocol for more details.

Public-Key Security

It is becoming a general practice to use HTTP/SSL for secure request/response communication, thanks to the rapid deployment of SSL-enabled browsers and Web servers. SSL provides authenticity, confidentiality, and integrity of messages. On the other hand, there is no SSL counterpart in publish/subscribe communication. One of the reasons for this is the difficulty of managing keys for a large number of recipients. We invented a new key management scheme that enables very efficient session-key updates. InfoBus Repeater incorporates this key management scheme coupled with SSL/X.509-based user authentication.

3.2 InfoBus Repeater

InfoBus Repeater relays local events to remote InfoBuses by means of a special InfoBus member called a repeater. A repeater acts as both a producer and a consumer for a local InfoBus. InfoBus Repeater architecture allows different transport protocols including multicast-based RMTP and peer-to-peer TCP.

To send events to remote InfoBuses, you need to attach a repeater object to your local InfoBus. A repeater can act as either a producer or a consumer, or both, for a local InfoBus. When an event is published on a local InfoBus, a repeater first checks if the data item associated with the event is distributable (a data item can be declared distributable by implementing the Distributable interface). If it is, the event is serialized along with the data item and relayed to remote InfoBuses using either RMTP or TCP. Repeaters on the remote machines receive the message and generate another event locally. Likewise, a consumer can create findData events that are also relayed over the network. Both producers and consumers can generate dataChanged events.

To connect two InfoBuses, use the TCP transport as in the following figure. You have to specify a port and the IP address of the peer repeater. To bridge three or more InfoBuses, you can attach multiple repeaters to same InfoBus.

If many InfoBuses need to be interconnected, using TCP connection is inefficient because the same event is transmitted over and over again. In this case, you should consider using the RMTP transport instead. To use the RMTP transport, you need to set up a hub that acts as a transmitter.

An event triggered by the producer in InfoBus 1 is caught by the repeater, which relays it to the hub. The hub then transmits the event, using the RMTP protocol. This message is received by other repeaters listening to the same hub, and a new event is regenerated locally.

Thus, the RMTP transport uses two sets of protocols:

The hub is implemented as a servlet running on an HTTP server. One HTTP server can host multiple hubs, each of which is specified by a URL. For example, http://ibctlr.foo.com/servlet/myChannelHub is a hub. An SSL-based secure hub has a name beginning with https: instead of http:.

Access control privileges are given to a repeater based on its identity. There are many ways of obtaining a repeater's identity in the uplink protocol, just as in normal HTTP servers. They include

When SSL/3 authentication is used, repeaters and the hub must posses an X.509-based certificate and a corresponding private key. These keys are used for authentication during HTTP/SSL connection. The hub also has a special signature key for signing broadcast messages.

A common set of session keys is used for downlink packets. When a new member joins, it receives the current set of session keys as a return value of the JOIN request through HTTP/SSL. When a member leaves a hub and no longer has access rights, his/her session keys are revoked and new session keys are generated and distributed.

The cipher suite to be used for the downlink is determined according to the security policy when the downlink is started. Therefore, all the repeaters and the hub share the same cipher suite for the downlink. On the other hand, the cipher suite to be used for SSL uplink is determined whenever a new uplink connection is established.


4. Sample Code

InfoBus Repeater does not extend the InfoBus API, so it requires little additional knowledge if you are familiar with InfoBus.

The following subsections introduce some InfoBus Repeater-specific classes and interfaces with programing examples.

4.1 Repeater Class

A repeater is used to transmit data items and events to other JVMs. It joins an InfoBus as both a producer and a consumer. When some producer announces that a data item is available, the producer calls the fireItemAvailabe method. This causes an InfoBusItemAvailableEvent that reaches the repeater as well as consumers. The following are samples of code for creating a data repeater.

// TCPPORT
Repeater repeater = new Repeater("degaz.trl.ibm.com", 9999);
// RMTPPORT
Repeater repeater = new Repeater(new URL("http://corot.trl.ibm.com/Hub001"));

If you want to use a TCP/IP port, you should create a repeater object with a hostname and a port address. In the first examples above, the repeater object (which we will assume is running on monet.trl.ibm.com) connects to a remote machine (degaz.trl.ibm.com). A repeater on degaz.trl.ibm.com must be created by using "monet.trl.ibm.com" and 9999.

Alternatively, if you want to use an RMTP port, a repeater object should be created by using the URL of an RMTP server called a hub. A hub broadcasts Infobus Repeater events and data items to its members.

Note that only one repeater per a local InfoBus is necessary, regardless how many applications share the same InfoBus. It is because a repeater is not concerned with the internals of an event as long as the data item is distributable.

4.2. Distributable interface

In InfoBus, data to be exchanged between beans must implement a DataItem interface. In InfoBus Repeater, you also need to implement the Distributable interface if you want this dataitem to be distributed over a network. Repeater only transmits data items that implement this interface. Note that the interface has no methods.

Data items are serialized before transmission, so all the objects referenced in it should also implement the Serializable interface. Sometimes it is impossible or undesirable to do this. For example, a DataItemChangedListener is not serializable by default, and in fact it should not be transmitted to a remote InfoBus, because DataItemChanged events will be generated from the local copy of the dataitem, which maintains the correct list of (local) listeners. In such cases, you should declare these members transient, to prevent them from being serialized.

DistributableDataItem class is an implementation class of DataItem and distributable interface provided for your convenience. In the current implementation of Repeater, you should create your data item class as a child class of Repeater.

4.3 Programming Examples

The following is sample code for an application that has a producer, a consumer, and a repeater. There are five typical operations on InfoBus:

  1. Joining InfoBus (producer, consumer, repeater)
  2. Announcing a data item (producer)
  3. Finding a data item (consumer)
  4. Announcing data change (data item, consumer)
  5. Revoking a data item (producer)

Note that the code is not specific to InfoBus Repeater. You can write codes for consumers and producers by using InfoBus API. A Repeater's existence is transparent to any producer or consumer.

Joining InfoBus

import com.ibm.infobusrepeater.*;
public class Test {
  static void main(String args) {
      Repeater repeater;  
      Consumer consumer;
      Producer producer;
      InfoBus  bus;
      // Create a repeater with an RMTP port       
      repeater = new Repeater(new URL("http://corot.trl.ibm.com/servlet/TRLChatHub"));
      repeater.joinInfoBus("ib001");
      InfoBus bus = repeater.getInfoBus();
      // Register the repeater both as consumer and producer     
      bus.addDataConsumer(repeater);
      bus.addDataProducer(repeater);
      // Create a data producer
      producer = new Producer();
      bus.addDataProducer(producer);
      // Create a data consumer
      consumer = new Consumer();
      bus.addDataConsumer(consumer);
}

Announcing a data item from a producer

The producer announces a data item by calling the fireItemAvailable method.

// Producer side
// The producer announces a data item whose name is "data001"
bus.fireItemAvailable("data001", producer);

When the fireItemAvailable method class is called, InfoBusDataConsumer#dataItemAvailable(InfoBusItemAvailableEvent e) method is called. The consumer checks the data item name if it is needed, and submits the findDataItem method to get the data item.

// Consumer side
public void dataItemAvailable(InfoBusItemAvailableEvent e){
  // get name of data item
  String itemName = e.getDataItemName();
  // get data item object
  if (isUseful(itemName) {
    DataItem ditem = getInfoBus().findDataItem(itemName, this, (InfoBusDataProducer )e.getSource());
  }
}

Finding a data item from consumer

The consumer can use findDataItem to require a data item by using its data item name.

//Consumer side
bus.findDataItem("data002", consumer);
The method causes the dataItemRequested(InfoBusItemRequestedEvent e) method to be called on all producers. Here is an example of the implementation of the method:
// Producer side
public void dataItemRequested(InfoBusItemRequestedEvent e) {
  String itemName = e.getDataItemName();
  DataItem item;
  if (hasItem(itemName) {
    item = getItem(itemName);
    e.setDataItem(item);
  }
}

Announcing a data item change

One of the interesting features of InfoBus is that a consumer can add a listener to a data item in order to get an event when the data is changed.

DataItem item;
item.addDataItemChangedListener(consumer);

When the data is changed, it creates a DataItemChangedEvent event, and calls the itemValueChanged method for each listener. In InfoBus Repeater, you can announce the change by calling DistributableDataItem#updateItem method after the data is changed. The event is transmitted to remote consumers by the repeater. In consumers, itemValueChanged(DataItemChangedEvent e) is called.

// Consumer side
public void itemValueChanged(DataItemChangedEvent e) {
  DataItem newdata = e.getDataItem();
  ...
}

Note that if you want to know when the change of data items are changed, you should add listeners to the data, and implement itemValueChanged to update it. The updated data item is not the same as the old one, so you have to update the reference to the old data item if necessary.

Revoking data

If a producer want to revoke a published data item, it calls fireItemRevoked.

// Producer side
bus.fireItemRevoked("data001", producer);

When the fireItemRevoked method class is called, the InfoBusDataConsumer#dataItemRevoked(InfoBusItemRevokedEvent e) method is called.

// Consumer side
public void dataItemRevoked(InfoBusItemRevokedEvent e){
  ...

5. Application Programming with InfoBus Repeater

The idea of program components communicating asynchronously using publish/subscribe style is not completely new. Rule based languages such as OPS-5 were implemented based on so-called blackboard model where independent knowledge sources put a new finding into a common data pool, which may in turn triggers the execution of other knowledge sources. Tuple Space [4] developed by IBM Almaden Research Center is another example of asynchronous publish/subscribe model.

However, perhaps partly due to lack of standardization effort, not many application programs have been written with this paradigm. From our experience with InfoBus Repeater, we found that there are at least two relatively distinct programming styles of a publish/subscribe application, depending on whether components have a shared data structure or not. We call these two programming styles loosely-coupled and tightly-coupled from an analogy with the names of paralell computer architecture.

5.1 Loosely-coupled pub/sub application

The loosely-coupled pub/sub programming is represented by TIBCO's model as shown in the diagram below. A publisher publishes an event which has an embedded data in it. Subscribes who are interested in the subject of the event pick up the event and parse the embedded data. There is no shared data among the bus members.

For example, in the following piece of code of TIBCO's Rendezvous, the variable sender represents a "channel" and an event is created by calling the send method of the channel. You have to supply the data (a string) at the same time the event is created.

    RvSession  session  = new RvSession(); 
    RvSender sender =  session.newSender("news.sport.baseball");
    sender.send("NY Yankees beat ...");

Loosely-coupled pub/sub applications can be realized in InfoBus Repeater by declaring a data item as Distributable. An event with a distributable data item will be automatically transferred to remote nodes via a repeater.

5.2 Tightly-coupled pub/sub application

On the other hand, you may wish to share a complex data structure among the bus members. A good example is Lotus e-Suite. A spread sheet bean and a chart bean share a sheet object, a fairly complex data structure containing all the cell data, formatting data, and so on. A change in this complex data is notified by publishing an event from the producer bean. In this case, declaring the complex data as distributable and serializing the whole structure every time an event occurs is costly. It is desirable that only a modified portion of the data structure is transmitted.

For tightly-coupled pub/sub applications such as Lotus e-Suite, you need an application dependent component called an adapter that transforms a modified portion of data into a distributable event. An adapter is another ordinary InfoBus member that monitors the bus events, and if it finds an event about the associated data structure, it accesses the data structure, extracts the modified portion, creates a distributable event, and publishes it. The distributable event is then relayed to remote notes by the repeater attached to the local bus.

In the following diagram showing e-Suite that is made distributed by InfoBus Repeater, first the initial data is downloaded from a common server to local VM's to form a shared data structure in each VM. When a sheet been modifies the data, it publishes a local event, which is picked up by both a local chart bean and also by the local adapter. However, this event is not transmitted through repeater because it is non distributable.

Instead, the adapter accesses the shared data structure and creates a distributable event that contains the modified data, and publishes it to the local InfoBus, which in turn transmitted by the local repeater, the hub, and the remote repeaters. A remote repeater reproduces the event, which a remote adapter catches and updates the remote shared data to synchronize the data. That triggers a new event from the remote sheet bean that notifies the change in the data.

Note that with this architecture, there is no need to modify the application itself nor the repeater. Adapter should know how to access the data structure and how to serialize modified data, but that is it.

If there is some standard set of commonly used share data, such as RowColumnAccess as defined in InfoBus or Document Object Model (DOM), it makes a perfect sense to prepare an adapter for each of these. For example, a DOM adapter can synchronize DOM trees among networked computers.

5.3 Sample Application - eSuite with InfoBus Repeater

As a non-trivial application of InfoBus Repeater, we present a demonstration of distributed e-Suite. eSuite is a set of Java beans provided by Lotus. It consists of small independent beans for particular purpose such as spread sheet, chart, and word processor, and they communicate by using InfoBus. For example, consider a spreadsheet and chart beans are running on a Web browser. The spreadsheet joins a InfoBus as a producer, and the chart joins it as a consumer. When a value of a cell is updated, the spreadsheet bean announces the change to the InfoBus. The notification event is transmitted to the chart bean, and consequently shape of the graph in the chart is updated. The screen shot in Section 2 is a typical e-Suite application consisting or a spread sheet and a chart.

Using InfoBus Repeater, we made this application into a distributed one as shown in the figure below. Here, multiple clients are interconnected through LAN and they are running the same version of the spread sheet/chart application. A repeater and an adapter are also attached to each local InfoBus. Whenever a cell value is changed in any one of the clients, it is propagated to the other clients. Note that the underlying transport is RMTP so it scales to thousands of clients without any significant performance penalty.


6. Conclusion

InfoBus Repeater is a Java middleware that enables networked publish/subscribe programming. It allows existing InfoBus-based applications to be made a distributed one without changing the application itself. It also provides a secure scalable delivery of events, which is another distinctive feature of InfoBus Repeater compared with other technologies such as TIBCO. We are planning to further enhance InfoBus Repeater technology by optimizing the protocol using global flush [6] proposed by Mohan Ahuja, who is a visiting scientist at Tokyo Research Laboratory.


References

  1. JavaSoft, InfoBus 1.1 Specification Draft, v0.06A http://java.sun.com/beans/infobus/index.html, 1998.
  2. N. Yamanouchi, et. al, "Reliable Multicast Transfer Protocol," 1997. See also GetCoTi '96 presentation
  3. TIBCO, "TIB/Rendezvous Release 4.1," http://www.rv.tibco.com/, 1997
  4. P. Wychkoff, S. W. McLaughry, T. J. Lehman, and D. A. Ford, "IBM TSpaces," 1998.
  5. H. Maruyama, T. Tokuyama, and N. Uramoto, "A Key Update Method for Multiparty Communication," http://maruyama-www.cs.titech.ac.jp/~maruyama/papers/globecom98/, submitted to GlobeComm '98, 1998.
  6. M. Ahuja, "Assertions about past and future in Highways: Global flush broadcast and flush-vector-time," Information Processing Letters, Vol. 48, pp. 21-28, 1993.

Last modified: Mon Mar 09 23:36:06 1998