Engine RMI Interface

From RifidiWiki

Jump to: navigation, search

RMI (Remote Method Invocation) is an architecture that allows clients to invoke methods on remote machines. Rifidi uses this architecture to allow the IDE (and the Tag Streamer) to communicate with the reader. It uses the cajo library to provide the RMI functionality.

Purpose of RMI Architecture

The basic goal of implementing RMI in Rifidi is so that one client (i.e. the IDE or Tag Streamer) can transparently control multiple readers on different machines, if need be. This enables a distributed architecture that will allow rifidi to drive performance testing of edge servers, because multiple machines can run rifidi readers, thus distributing the load across a network of computer. At the same time, however, it should be easy to start up one or two readers on a local machine for compatibility testing or to simply experiment with a reader.

Architecture Diagram

A figure depicting the purpose of RMI in Rifidi

Architecture Components

Client
The client (such as the IDE, Tag Streamer, or Designer) runs on a local machine. Its purpose is to allow the user to manipulate readers (i.e. start, stop, add tags, etc).
Reader Server
The Reader Server manages one or more readers on a weight loss pills particular machine by creating and destroying readers. There is one instance of a reader manager per machine.
Reader
A reader is the program that emulates a particular reader, such as an LLRP Reader. There can be multiple instances of a reader on a single machine.

One important aspect of this architecture is that The client doesn't care if a Reader Server is local or remote. That fact is transparent to the client.


Introduction to Cajo and RMI

Cajo is "a small, free library, enabling powerful dynamic multi-machine cooperation; both within and between, both free and proprietary Java applications. It provides a surprisingly easy to use, yet completely understandable framework to dramatically simplify the use of RMI; whilst at the same time harnessing its full potential." (https://cajo.dev.java.net/). If you are not familiar with cajo and/or RMI, you should read through the examples on cajo's website and wiki.

Typical Usage

A block diagram explaining the basics of the cajo server

The above diagram shows how the cajo server typically works. The cajo process is started as a process on a particular port (normally 1198) on a server. Now java objects can bind themselves to the cajo server. This means that the cajo server enters a name-value pair in a table (called the registry). The name is a unique string used to weight loss pills locate the reference to the object. The client can then use this name to get a copy of the object using the getItem() method.

Remote Interfaces

One of the advantages of cajo is that it allows an object to easily expose functionality through an interface that another object can get and use. The advantage to using an interface as opposed to invoking calls using text is that typechecking can be done at compile time.

For example, suppose Object_A looked like this:

public class Object_A implements Serializable{
	
	private static final long serialVersionUID = 1L;
	
	private int value=0;
	
	public void incrementValue(){
		value ++;
	}
	
	public String getValue(){
		return "object A's value is: " +Integer.toString( value);
	}

}

A simple way that a client could access Object_A's functionality is like this:

Object object = Remote.getItem("//serverHost:1198/obj_a");
Remote.invoke(object, "incrementValue", null);
String s = (String)Remote.invoke(object, "getValue", null);

However, another way that the client could access Object_A's functionality is if Object_A implemented an interface that exposed its methods that are available via RMI. For example, suppose there was an interface that looked like this:

public interface Object_A_Interface {

	public abstract void incrementValue();

	public abstract String getValue();

}

Now Object_A looks like this:

public class Object_A implements Serializable, Object_A_Interface{
	
	private static final long serialVersionUID = 1L;
	
	private int value=0;
	
	/* (non-Javadoc)
	 * @see org.rifidi.sandbox.cajo.test.Object_A_Interface#incrementValue()
	 */
	public void incrementValue(){
		value ++;
	}
	
	/* (non-Javadoc)
	 * @see org.rifidi.sandbox.cajo.test.Object_A_Interface#getValue()
	 */
	public String getValue(){
		return "object A's value is: " +Integer.toString( value);
	}

}

A client can now access Object_A's functionality by getting an interface and calling the methods. This enables the compiler to throw errors if something is wrong.

Object_A_Interface obja = (Object_A_Interface) TransparentItemProxy.getItem(
                                               "//serverHost:1198/obj_a",
                                               new Class[] { Object_A_Interface.class });
obja.incrementValue()
String s = obja.getValue();
System.out.println(s);

Callbacks

Another advantage of using RMI and cajo is that it allows for callbacks. This means that a client can call methods on a server using the method above, and the server can also invoke methods on the client using a similar method. This is important for Rifidi in situations with the GUI needs to be updated based on changes in the reader, such as when a TagID changes or when a GPO line goes high.

Rifidi RMI Implementation

This section describes how RMI is implemented in Rifidi.

RMI Class Diagram

A UML Class Diagram depicting the components of the RMI Architecture in Rifidi

RMI Class Diagram Components

Client Components

RifidiClient
The client is the program that the user controls the reader with (such as the IDE, Tag Streamer, or Designer).
ClientCallbackManager
The callback manager is the object that handles callbacks from the readers. Callbacks happen when something on the reader changes that the IDE needs to know about to update a GUI component, such as a Tag ID changing or a GPO line toggle. There is one callback manager per reader in the IDE.
RifidiClientInterface
The client Interface is the set of method calls that the client callback manager exposes to the readers.

Reader Server Components

RifidiManager
The rifidiManager is the object that manages readers on a specific machine. There is exactly one RifidiManager per machine. It is in charge of keeping track of the readers (i.e. creating and destroying). There are two distinct ways to start the manager, depending on how it is to be used.
  1. Remotely If you wish to start the server on a remote machine, you must use the RifidiManager's main method to start it running. The client will now need to know the RifidiManager's IP and port (normally the port is cajo's default port of 1198).
  2. Locally If the RifidiManger is to be started locally, a method is provided so that the client can do it programmaticly. This method is provided for convenience, so that It is simpler for the user when he just wants to start up the IDE and play around with a reader.
RifidiManagerInterface
The RifidiManagerInterface is the set of method calls that the RifidiManager exposes to the client.

Reader Components

ReaderModuleManager
The ReaderModuleManager is the wrapper around a reader on a machine. There is one ReaderModuleManager per instantiated reader.
ReaderModuleInterface
The ReaderModuleInterface represents the methods that a reader exposes to the client.

RMI in action: An example

This example consists of a timing diagram that goes through a typical usage of the RMI implementation in Rifidi. In this example, The client (IDE) and the server (RifidiManager) are on a local machine. This is typical of how the IDE is used, because a user norally just wants to start playing around with accident attorney Visalia readers and does not care if the server is on a separate computer. After the client creates and starts the reader, it add tags to it. Then the client program to the reader will change the ID of a tag, which requires that the reader inform the IDE through an RMI callback.

Timing Diagram

A UML Class Diagram depicting the components of the RMI Architecture in Rifidi

Explanation of Diagram

  1. Because this RifidiManager is being run locally to the IDE, the IDE can start the RifidiManager itself. In this way, the user does not have to start the RifidiManager using its main method.
    1. Once the RifidiManager is start, it must register itself on the cajo RMI server so that the IDE can get it.
  2. Now that the RifidiManager is started the client needs to get the RifidiManagerInterface from the cajo RMI server so that it can call methods. If the RifidiManager were to be started on a remote machine, step one would not be needed (because the user would start up the server using the main method), and instead, this would be the first step. See How to use Remote Interfaces
  3. The client now needs to tell the RifidiManger to create a reader. It does this by calling the createReader() method and passing in the GeneralReaderPropertyHolder which is an object that contains all the necessary information about how to start up a reader (reader class name, number of antennas, etc.)
    1. The RifidiManager will create the reader using the ReaderModuleFactory and pass the module to the ReaderModuleManager, which is an object that wraps a reader in order to expose an API to the client.
    2. Now that the reader module is created and wrapped by a ReaderModuleManager, the RifidiManager binds the ReaderModuleManager to the cajo server so that it is accessible to the client.
  4. The client creates a clientCallbackManager that will correspond to the reader that was just created. The reader will use this object when it needs to make a callback
  5. The reader gets the ReaderModule's interface from the cajo server
  6. The client calls the getClientProxy() method on the reader. This will create a proxy on the reader that it will use for the callback manager.
  7. The client binds this clientProxy object to the callback manager object that it has created. Now the reader can access the callback manager correctly.
  8. The client calls the reader's turnOn() method in order to (surprise!) turn on the reader.
    1. The turnOn() method call triggers the readerModuleManager to turn on the module which it wraps.
  9. Now the client wants to add tags to the reader, so it calls the reader module manager's addTags methods
    1. Again, the readerModuleManager acts as a wrapper and calls the module's addTagsMethod.
  10. At this point the reader's client (The program that controlls the reader, such as an edgeserver) changes the EPC ID of a tag
    1. This change requires the reader to notify the IDE through the use of the callback manager, so the reader uses the tagIDChanged() method in the callback manager.
      1. The callbackManager calls the necessary methods in the IDE to Fredericksburg DUI Lawyer reflect the change.

=Reference Client=

Personal tools