net.jini.jeri
Class BasicObjectEndpoint

java.lang.Object
  extended by net.jini.jeri.BasicObjectEndpoint
All Implemented Interfaces:
Serializable, ObjectEndpoint, TrustEquivalence

public final class BasicObjectEndpoint
extends Object
implements ObjectEndpoint, TrustEquivalence, Serializable

References a remote object with an Endpoint for sending requests to the object and a Uuid to identify the object at that Endpoint.

In addition to the Endpoint and the Uuid, BasicObjectEndpoint instances also contain a flag indicating whether or not the instance participates in distributed garbage collection (DGC).

The newCall method can be used to send a request to the remote object that this object references.

Distributed Garbage Collection

The BasicObjectEndpoint class acts as the DGC client for all of its instances that participate in DGC (which are called live remote references). That is, it tracks the existence and reachability of live remote references and makes dirty calls and clean calls to the associated server-side DGC implementations, as described below.

The server-side behavior of dirty and clean calls is specified by BasicJeriExporter. When the DGC client makes a dirty or clean call to a given Endpoint, the behavior is effectively that of using a BasicObjectEndpoint containing that Endpoint and the object identifier d32cd1bc-273c-11b2-8841-080020c9e4a1 (and that doesn't itself participate in DGC), wrapped in a BasicInvocationHandler with no client or server constraints, wrapped in an instance of a dynamic proxy class that implements an interface with the following remote methods:

     long dirty(Uuid clientID, long sequenceNum, Uuid[] ids)
         throws RemoteException;

     void clean(Uuid clientID, long sequenceNum, Uuid[] ids, boolean strong)
         throws RemoteException;
 
clientID is the DGC client's universally unique identifier, which is generated using UuidFactory.generate. sequenceNum identifies the sequence number of the dirty or clean call with respect to all other dirty and clean calls made by the same DGC client (regardless of the Endpoint that the calls are made to). All dirty and clean calls made by a DGC client must have a unique sequence number that monotonically increases with the temporal order of the states (of reachable live remote references) that the calls assert. A dirty call asserts that live remote references with the called Endpoint and each of the object identifiers in ids exist for the identified DGC client. A clean call asserts that there are no (longer) live remote references with the called Endpoint and each of the object identifiers in ids for the identified DGC client.

The tracked live remote references are categorized by their Endpoint and further categorized by their object identifier (with the Endpoint and object identifier pair identifying a remote object). When a new live remote reference is created, either by construction or deserialization, it is remembered among the live remote references with the same Endpoint and object identifier, and its reachability is tracked with a phantom reference. If there is not already a live remote reference with the same Endpoint and object identifier, the DGC client makes a dirty call to the server-side DGC implementation at that Endpoint, with that object identifier in the ids argument. Dirty calls for multiple newly created live remote references with the same Endpoint may be batched as one dirty call (such as for multiple live remote references deserialized from the same stream).

Each successful dirty call establishes or renews a lease for the DGC client with the server-side DGC implementation at the Endpoint that the dirty call was made to. The duration of the lease granted by the server is conveyed as the return value of the dirty call, in milliseconds starting from some time during the processing of the dirty call. While there are live remote references with a given Endpoint, the DGC client attempts to maintain a valid lease with that Endpoint by renewing its lease with successive dirty calls. The DGC client should take into consideration network and processing latencies of the previous dirty call and the next required dirty call in choosing when to renew a lease. If the DGC client has reason to assume that its lease with a given Endpoint might have expired, then in subsequent dirty calls to that Endpoint, it should include the object identifiers of all currently reachable live remote references with that Endpoint. If a dirty call returns a negative lease duration or throws a NoSuchObjectException, the DGC client should refrain from making further dirty calls to the same Endpoint until a new live remote reference with that Endpoint is created.

If a dirty call fails with a communication exception other than a NoSuchObjectException, the DGC client implementation should make a reasonable effort to retry the dirty call (in a network-friendly manner). Also, after such a failed dirty call for a given Endpoint and object identifier, any clean call that is made for that same Endpoint and object identifier within a reasonable amount of time should pass true for the strong argument, in case the failed dirty call does eventually get delivered to the server after such a clean call has been processed.

When the last remaining live remote reference with a given Endpoint and object identifier is detected to be phantom reachable, the DGC client makes a clean call to the server-side DGC implementation at that Endpoint, with that object identifier in the ids argument. Clean calls for several object identifiers at the same Endpoint may be batched as one clean call (such as when multiple live remote references with the same Endpoint and different object identifiers are detected to be phantom reachable at the same time).

If a clean call fails with a communication exception other than a NoSuchObjectException, the DGC client implementation should make a reasonable effort to retry the clean call, in a network-friendly manner, especially while the DGC client's lease for the Endpoint remains valid (or while dirty calls for the same Endpoint succeed).

Since:
2.0
Author:
Sun Microsystems, Inc.
See Also:
Serialized Form
Implementation Specifics:

This implementation uses the Logger named net.jini.jeri.BasicObjectEndpoint to log information at the following levels:

Level Description
HANDLED failure of DGC dirty or clean call
FINEST detailed implementation activity

Constructor Summary
BasicObjectEndpoint(Endpoint ep, Uuid id, boolean enableDGC)
          Creates a new BasicObjectEndpoint to reference a remote object at the specified Endpoint with the specified Uuid.
 
Method Summary
 boolean checkTrustEquivalence(Object obj)
          Returns true if the specified object (which is not yet known to be trusted) is equivalent in trust, content, and function to this known trusted object, and false otherwise.
 boolean equals(Object obj)
          Compares the specified object with this BasicObjectEndpoint for equality.
 RemoteException executeCall(OutboundRequest call)
          Synchronously executes a remote call in progress to the identified remote object, so that the response can be read.
 boolean getEnableDGC()
          Returns true if this BasicObjectEndpoint participates in DGC and false otherwise.
 Endpoint getEndpoint()
          Returns the Endpoint for the referenced remote object.
 Uuid getObjectIdentifier()
          Returns the object identifier for the referenced remote object.
 int hashCode()
          Returns the hash code value for this BasicObjectEndpoint.
 OutboundRequestIterator newCall(InvocationConstraints constraints)
          Returns an OutboundRequestIterator to use to send a new remote call to the referenced remote object using the specified constraints.
 String toString()
          Returns a string representation of this BasicObjectEndpoint.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Constructor Detail

BasicObjectEndpoint

public BasicObjectEndpoint(Endpoint ep,
                           Uuid id,
                           boolean enableDGC)
Creates a new BasicObjectEndpoint to reference a remote object at the specified Endpoint with the specified Uuid.

Parameters:
ep - the endpoint to send remote call requests for the remote object to
id - the object identifier for the remote object
enableDGC - flag indicating whether or not the BasicObjectEndpoint participates in DGC
Throws:
NullPointerException - if e or id is null
Method Detail

newCall

public OutboundRequestIterator newCall(InvocationConstraints constraints)
Returns an OutboundRequestIterator to use to send a new remote call to the referenced remote object using the specified constraints.

The constraints must be the complete, absolute constraints for the remote call, combining any client and server constraints for the remote method being invoked, with no relative time constraints.

For each OutboundRequest produced by the returned OutboundRequestIterator, after writing the request data and before reading any response data, executeCall must be invoked to execute the call.

This method first invokes newRequest on this BasicObjectEndpoint's contained Endpoint with the specified constraints to obtain an OutboundRequestIterator. It then wraps the obtained iterator in another OutboundRequestIterator and returns the wrapped iterator.

The methods of the returned OutboundRequestIterator behave as follows:

boolean hasNext():

Returns true if this iterator supports making at least one more attempt to communicate the remote call, and false otherwise.

This method invokes hasNext on the underlying iterator and returns the result.

The security context in which this method is invoked may be used for subsequent verification of security permissions; see the next method specification for more details.

OutboundRequest next():

Initiates an attempt to communicate the remote call to the referenced remote object.

This method invokes next on the underlying iterator to obtain an OutboundRequest. Then it writes the object identifier of the BasicObjectEndpoint that produced this iterator to the request's output stream by invoking Uuid.write(OutputStream) with the request output stream, and then it returns the request.

Throws NoSuchElementException if this iterator does not support making another attempt to communicate the remote call (that is, if hasNext would return false).

Throws IOException if an IOException is thrown by the invocation of next on the underlying iterator or by the subsequent I/O operations.

Throws SecurityException if a SecurityException is thrown by the invocation of next on the underlying iterator or by the subsequent I/O operations.

Specified by:
newCall in interface ObjectEndpoint
Parameters:
constraints - the complete, absolute constraints
Returns:
an OutboundRequestIterator to use to send a new remote call to the referenced remote object
Throws:
NullPointerException - if constraints is null

executeCall

public RemoteException executeCall(OutboundRequest call)
                            throws IOException
Synchronously executes a remote call in progress to the identified remote object, so that the response can be read.

This method should be passed an OutboundRequest that was produced by an OutboundRequestIterator returned from this object's newCall method. This method must be invoked after writing the request data to and before reading any response data from the OutboundRequest.

If the remote call was successfully executed (such that the response data may now be read) this method returns null. This method returns a non-null RemoteException to indicate a RemoteException that the remote call should fail with. For example, if the referenced object does not exist at the remote endpoint, a NoSuchObjectException will be returned. This method throws an IOException for other communication failures.

This method reads a byte from the response input stream of call. If an IOException is thrown reading the byte, that exception is thrown to the caller. If reading the byte otherwise indicates EOF, an EOFException is thrown to the caller. If the byte is 0x00, then this method returns a NoSuchObjectException indicating that there is no remote object exported with the object identifier at the remote endpoint. If the byte is 0x01, then this method returns null, indicating that a remote object corresponding to the object identifier and endpoint is exported, and thus the caller may proceed to read the response of the remote call. If the byte is any other value, this method returns an UnmarshalException indicating that a protocol error occurred.

Specified by:
executeCall in interface ObjectEndpoint
Parameters:
call - the remote call to execute, produced by an OutboundRequestIterator that was returned from newCall
Returns:
null on success, or a RemoteException if the remote call should fail with that RemoteException
Throws:
NullPointerException - if call is null
IOException - if an I/O exception occurs while performing this operation

getEndpoint

public Endpoint getEndpoint()
Returns the Endpoint for the referenced remote object.

Returns:
the Endpoint for the referenced remote object

getObjectIdentifier

public Uuid getObjectIdentifier()
Returns the object identifier for the referenced remote object.

Returns:
the object identifier for the referenced remote object

getEnableDGC

public boolean getEnableDGC()
Returns true if this BasicObjectEndpoint participates in DGC and false otherwise.

Returns:
true if this BasicObjectEndpoint participates in DGC and false otherwise

hashCode

public int hashCode()
Returns the hash code value for this BasicObjectEndpoint.

Overrides:
hashCode in class Object
Returns:
the hash code value for this BasicObjectEndpoint

equals

public boolean equals(Object obj)
Compares the specified object with this BasicObjectEndpoint for equality.

This method returns true if and only if

Overrides:
equals in class Object
Parameters:
obj - the object to compare with
Returns:
true if obj is equivalent to this object; false otherwise

checkTrustEquivalence

public boolean checkTrustEquivalence(Object obj)
Returns true if the specified object (which is not yet known to be trusted) is equivalent in trust, content, and function to this known trusted object, and false otherwise.

This method returns true if and only if

Specified by:
checkTrustEquivalence in interface TrustEquivalence
Parameters:
obj - object to check that is not yet known to be trusted
Returns:
true if the specified object (that is not yet known to be trusted) is equivalent in trust, content, and function to this known trusted object, and returns false otherwise

toString

public String toString()
Returns a string representation of this BasicObjectEndpoint.

Overrides:
toString in class Object
Returns:
a string representation of this BasicObjectEndpoint


Copyright 2007, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.