HealthSpa (using Jini’s SOA)

The requirements for this project were:

Build a system and end-user application for a health spa, utilising the service orientated architecture framework Jini, such that a timetable of rooms, staff, and member bookings can be maintained, edited, paid-for and viewed by administrators and members. Should a member’s room of choice be unavailable to book, they can choose to be informed in the event of a cancellation.

The main purpose isto demonstrate the inner workings and underlying capabilites of Jini and particlarly how to implement leasing in Jini.

System Design

The client application itself is built on Swing and communicates to the Health Spa server via Jini. It always has a consistent view of the Health Spa server, and never requests more than it requires. From here, the user can perform all actions as defined in the specification (and a few more). THe UI has different views depending on the type of user logged in (admin or normal member). Any number of clients can be executed on another number of machines simltaneously.

ClientUI is the end-user UI client. When first executed, it informs the user that the application will be usable once it has found a relevant server. It then creates a LookupDiscovery and hands it a listener.

When LookupDiscovery discovers one or more lookup servers, the listener checks to see if the server has a matching service. If so, it will look no further, and will retrieve and utilise the proxy to populate the ClientUI with data. If no matching service is found, it requests via another listener, to be notified from the lookup service(s) in the event that a suitable service becomes available. In time, if a lookup service finds a matching service, it will fire an event and ClientUI will retrieve the proxy and populate itself as necessary.

HealthSpaServer is the server itself which is responsible for persisting state, publishing its services and dealing with remote events and leases. After an initial join to a Jini community, it saves all the relevant data (ID, entry attributes, groups it belongs to, etc) to disk, which allows it to retrieve after any restart/crash, etc.

In a real-world application, the system would probably use the Unicast Discovery Protocol to communicate with a lookup service, as it would be operating over the internet, and not an internal network – and therefore shouldn’t be expected to automatically find a lookup service.

In relation to remote events and leasing, HealthSpaServer provides a method to the client application (ClientUI), through its RMI stub, which allows it to register for notification in the event that a certain slot has been cancelled.

To register, the client provides the time slot and room in question, an event listener, and a lease duration request. HealthSpaServer then creates a CancellationCookie which holds the event type (this current system only uses the one (0)), and the slot the user is interested in being notified about. HealthSpaServer then uses a RegistrationLandlord, which implements the Landlord protocol/interface, to request an expiration time. A Registration is then created which holds the cookie, expiration time, and the listener. This is then added to a collection of registered listeners.

The RegistrationLandlord.Factory creates a lease, which is also handed back to the client in an EventRegistration, amongst other things. The client application then regularly tries to renew to lease, to make sure it is informed of a relevant cancellation.

When a user cancels a booking (by choosing “Cancel Booking” from the user account section of the application), HealthSpaServer attempts to send out CancellationEvents to the relevant users (if any). To do this, it firstly checks for expired leases and removes them from the list. It then iterates through the list, and checks all the registration’s cookies and compares them to the cancelled slot. If anyone was interested in this cancellation, the event is sent, and ClientUI informs the user and provides them with the option to book the slot which has just become free.

As described by the Jini 1.1. API:

The call to notify is synchronous to allow the party making the call to know if the call succeeded. However, it is not part of the semantics of the call that the notification return can be delayed while the recipient of the call reacts to the occurrence of the event. Simply put, the best strategy on the part of the recipient is to note the occurrence in some way and then return from the notify method as quickly as possible.

Therefore, the ClientUI listener’s notify method spawns a new thread (presenting the user with a chance to book into the cancelled slot) so HealthSpaServer does not become blocked. The clients who were then informed have their leases cancelled by RegistrationLandlord, to prevent them being informed repeatedly (i.e., if, for some reason, the room/slot kept being booked and cancelled). This was a design decision: it is unlikely any user would want that.

Note: this is a simplified explanation, and only describes the core of how the remote events and leases work (which is really what the project aims to demonstrate). I have omitted all the details of how user interface ties together and how it synchronises with the HealthSpaServer, etc.

Screenshots

Requirements

  • Java 1.5 or later
  • Jini 1.1

Files and Running

As compiling and running Jini applications is an error-prone task, I have provided Jini 1.1, and pre-compiled classes, policy files, etc., and relevant batch files to get the system to run.

Download Jini 1.1 here, download the pre-compiled classes and batch files here.

Without the need to edit any of the batch files, the following must be true:

  1. A folder c:\tmp exists
  2. Jini 1.1 is extracted to c:\jini1_1
  3. The compiled sources and batch files are extracted to c:\files

To run the HealthSpa system:

  1. Change directory to c:\files
  2. Run clean.bat (removes log files from previous runs, which can cause errors)
  3. Run goRmiStubs.bat (creates stubs in service-dl and client-dl)
  4. Run goRmid.bat (starts the RMI Activation System Daemon)
  5. Run goHttpServerForClient.bat (HTTP server to provide the event proxy)
  6. Run goHttpServerForService.bat (HTTP server to provide service proxy)
  7. Run goHttpServerForReggie.bat (HTTP server to provide reggie proxy)
  8. Run goReggie.bat (to start the lookup service, reggie)
  9. Run goRunService.bat (to start the service (HealthSpaServer))
  10. Run (any number of times) goRunClient.bat (to start the client’s graphical user interface application (ClientUI))

The system should now be up and running. If there are any errors, please close all the opened instances of rmid.exe, java.exe, etc and retry.

A list of the source code files:

Or click here to download all the source files in one file.