300 likes | 307 Views
A proposal outlining Java middleware API, covering requirements, basic principles, interaction diagrams, Java data types, exceptions, and synchronization between threads.
E N D
A Proposal for the Java Public Middleware API Vito Baggiolini SL/CO
Outline • Requirements • Set/Get • basic principle • Interaction diagrams • Java data types • Overloaded vs. simple methods • Exceptions • MonitorOn/Off • Data conversions • Synchronization between threads
Premisses • This is a proposal • intended as a productivecompromise • quite some work, but needs to be discussed • This is not the BeansAPI • rather an enhanced version of Java CDEV API • BeansApi can be placed on top of this • Integration with Private MoM Client API is necessary
Outline • Requirements • Set/Get • basic principle • Interaction diagrams • Java data types • Overloaded vs. simple methods • Exceptions • MonitorOn/Off • Data conversions • Synchronization between threads
Requirements • Functional Requirements • Set/get access to (virtual) devices • sync and async • cycle-dependent or immediate • Monitoring of device properties • on-change or cycle-dependent • Non-functional requirements • Simple but complete • Generic (use in different types of applications) • “True” Java • Type safe (as far as possible)
“Simple” and “True Java” • Objectinstead of Data/DataEntry(user should not have to pack and unpack structures) • Use normal Java classes (not Data) for compo-site data structures • Overloaded methods where appropriate • Use return to return value in get() operations • Use Exceptions for error handling • Use Reflection for generic stuff
Design Overview • One generic RemoteDevice class • one RemoteDevice object per device instance • set/get, monitorOn/Off methods • no Context! • Constructor: RemoteDevice(String devClass, String devInstance); • Set/Get methods: setXXX(PropName, Value, …);XXX = Int, Double, Object etc. Value = getXXX(PropName,…); • Monitoring methods: MonToken = monitorOn(PropName, Listener); MonToken = monitorOn(PropName, CycleSel, Listener); monitorOff(MonToken); • Almost all methods throw exceptions!
Outline • Requirements • Set/Get • basic principle • Interaction diagrams • Java data types • Overloaded vs. simple methods • Exceptions • MonitorOn/Off • Data conversions • Synchronization between threads
Set/Get • Synchronous get/set int getInt(String propName); void setInt(String propName, int value); • Asynchronous get/set void getInt(String propName, ReplyListener rl); • Cycle-dependent, asynchronous get/set void getInt(String propName, CycleSelector sel, ReplyListener rl); • Filtered1, cycle-dependent, asynchronous get/set void getInt(String propName, CycleSelector sel, Filter f, ReplyListener rl); 1) Filter is for server-side filtering of property data
Set/Get Variants void getInt(String propName, CycleSelector sel, Filter f, ReplyListener rl); • CycleSelector == null: same as cycle-independent • Filter == null: no filtering • ReplyListener == null: one-way (“fire&forget”)
Client : RemoteDevice : DataEntry : Data : OrbClient DeviceProxy(String) setInt(String, int) <create> <create> insertInt( ) add( ) set(IoPoint, Data) <error handling> <return> Synchronous set
Synchronous get Client : RemoteDevice : DataEntry : Data : OrbClient DeviceProxy(String) getInt(String) get(IoPoint) <return Data> remove( ) extractInt( ) <return result>
: ResultHandle Async get : RemoteDevice Client : Data : OrbClient <create> <create> getInt(String, ReplyHandler) <create and pack> get(IoPoint) do other slow get things... action handle(Data) <unpack>
Data Types in Java • Java has the following data types: • 8 primitive types (int, long, float, double, byte, boolean, char)they cannot be accessed as Object • All the rest can be treated as Object (even an Array of primitive types is an Object) • Java 1.1 defines Classes corresponding to primitive types (Integer, Long, Float, Double, Byte Boolean, Character)these can be accessed as Object! • Design Issue: separate or combined methods ?
Proposal: separate methods • One group of methods per primitive type setInt() setLong() setFloat() setDouble() setByte() setChar() setBoolean() • One group of methods for Object types setObject() can be used for anything, including Arrays and Data/DataEntry • Complex data types are passed with setObject()they are extracted and packed into Data/Data-Entry using Reflection
Why Methods for primitive Types? • Why not use setObject() also for primitive types? • Example: set/get of an int • set: setInt(value); setObject(new Integer(value)); • get: value = getInt(); value = ((Integer)getObject()).intValue(); A bit clumsy, isn’t it? • Many methods are no problem! • for user: as long as they are consistent and logical (and: IDE’s represent overloaded methods as one) • for performance: methods are dispatched with hashtable
Exceptions • java.rmi.RemoteException: if a problem is encountered in Middleware or in device • java.lang.InvalidArgumentException: if bad information is passed to a method, (e.g. an object with bad contents to setObject)
Outline • Requirements & Design Principles • Set/Get • basic principle • Java data types • Overloaded vs. simple methods • Exceptions • Interaction diagrams • MonitorOn/Off • Data conversions • Synchronization between threads
MonitorOn/Off • Monitor a property on-change: MonToken monitorOn(String propName, monListener l); void monitorOff(MonToken mt); • Monitor with CycleSelector: MonToken monitorOn(String propName, CycleSelector cs, monListener l); • Monitor all properties of an Instance (required?) MonToken MonitorAll(monListener l); • MonitorToken automatically unsubscribes if abandoned • Based on Java Garbage Collection (finalize)
MonitorOn client : DataListener : RemoteDevice : MonitoringToken : Mom/Orb? : SubscriptionHandle <create> monitorOn(String, DataListener) monitorOn(IoPoint, Listener) <create> <return SubscriptionHandle> <create> <return MonitoringToken>
Client JVM : MonitoringToken : RemoteDevice : SubscriptionHandle : Mom/Orb? Client-initiated monitorOff monitorOff(MonitoringToken) getSubHandle( ) monitorOff(SubscriptionHandle) <abandon> Automatic monitorOff finalize( ) via Java getSubHandle( ) Garbage Collection monitorOff(SubscriptionHandle) monitorOff(SubscriptionHandle) MonitorOff
Outline • Requirements & Design Principles • Set/Get • basic principle • Java data types • Overloaded vs. simple methods • Exceptions • Interaction diagrams • MonitorOn/Off • Data conversions • Synchronization between threads
Conversion DataJava types • With a static DataConverter class • Methods: Converter.getAsData(Object val); Converter.getAsObject(Data val); Converter.getAsData(int val); Converter.getAsInt(Data val); etc... • Based on Java Reflection
Outline • Requirements & Design Principles • Set/Get • basic principle • Java data types • Overloaded vs. simple methods • Exceptions • Interaction diagrams • MonitorOn/Off • Data conversions • Synchronization between threads
Callbacks and Synchronization • Problem: primary and callback thread need to be synchronized • Synchronization can be tricky! Provide synchronization facilities in Middleware Framework • Pattern “FutureReply” for Async set/get
FutureReply Pattern • By Greg Lavender and Doug Lea • A pattern... • Based on a 1-slot buffer with locking • Enables a producer and a consumer thread to reliably exchange data items • 3 Methods: • put(): for producer to put data item into buffer • get(timeout): for consumer to wait and take data item when it’s ready (blocking) • isReady(): for consumer to check if data is there
Async get with FutureReply (1) : RemoteDevice Client : Data : OrbClient FutureReply : ResultHandle <create> <create> getInt(String, ReplyHandler) <create and pack> get(IoPoint) slow get do other action things...
: RemoteDevice FutureReply : ResultHandle slow get action do other things... Check if result is avaliable Block until result is available (with timeout) Async get with FutureReply (2) Client : Data : OrbClient isReady( ) getInt(timeout) handle(Data) <unpack> <return of get()>
Our FutureReply Variant • Should have get methods similar to those of RemoteDevice • FutureReply’s getXxx() method matches type of retrieved value • Sync:double res = device.getDouble(propName); • Async: void getString(propName, futureReply); double res = futureReply.getDouble(); • FutureReply’s getXxx() methods throw Exceptions