Class RMICacheManagerPeerListener

  • All Implemented Interfaces:
    CacheManagerPeerListener, CacheManagerEventListener

    public class RMICacheManagerPeerListener
    extends java.lang.Object
    implements CacheManagerPeerListener
    A cache server which exposes available cache operations remotely through RMI.

    It acts as a Decorator to a Cache. It holds an instance of cache, which is a local cache it talks to.

    This class could specify a security manager with code like:

     if (System.getSecurityManager() == null) {
         System.setSecurityManager(new RMISecurityManager());
     }
     
    Doing so would require the addition of grant statements in the java.policy file.

    If no security manager is specified no class loading, by RMI clients or servers, is allowed, aside from what can be found in the local CLASSPATH. The classpath of each instance of this class should have all required classes to enable distribution, so no remote classloading is required or desirable. Accordingly, no security manager is set and there are no special JVM configuration requirements.

    This class opens a ServerSocket. The dispose method should be called for orderly closure of that socket. This class has a shutdown hook which calls dispose() as a convenience feature for developers.

    Version:
    $Id$
    Author:
    Greg Luck
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected java.util.Map cachePeers
      The cache peers.
      protected java.lang.Integer port
      The RMI listener port
      protected Status status
      status.
    • Constructor Summary

      Constructors 
      Constructor Description
      RMICacheManagerPeerListener​(java.lang.String hostName, java.lang.Integer port, java.lang.Integer remoteObjectPort, CacheManager cacheManager, java.lang.Integer socketTimeoutMillis)
      Constructor with full arguments.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      protected void assignFreePort​(boolean forced)
      Assigns a free port to be the listener port.
      void attemptResolutionOfUniqueResourceConflict()
      If a conflict is detected in unique resource use, this method signals the listener to attempt automatic resolution of the resource conflict.
      protected void bind​(java.lang.String peerName, RMICachePeer rmiCachePeer)
      Bind a cache peer
      protected java.lang.String calculateHostAddress()
      Calculates the host address as the default NICs IP address
      void dispose()
      Stop the listener.
      protected void disposeRMICachePeer​(RMICachePeer rmiCachePeer)
      A template method to dispose an individual RMICachePeer.
      java.util.List getBoundCachePeers()
      All of the caches which are listening for remote changes.
      protected int getFreePort()
      Gets a free server socket port.
      java.lang.String getScheme()
      The replication scheme this listener interacts with.
      Status getStatus()
      Returns the listener status.
      java.lang.String getUniqueResourceIdentifier()
      A listener will normally have a resource that only one instance can use at the same time, such as a port.
      void init()
      Call to start the listeners and do any other required initialisation.
      protected boolean isDistributed​(Ehcache cache)
      Determine if the given cache is distributed.
      protected java.lang.String[] listBoundRMICachePeers()
      Returns a list of bound objects.
      protected java.rmi.Remote lookupPeer​(java.lang.String name)
      Returns a reference to the remote object.
      void notifyCacheAdded​(java.lang.String cacheName)
      Called immediately after a cache has been added and activated.
      void notifyCacheRemoved​(java.lang.String cacheName)
      Called immediately after a cache has been disposed and removed.
      protected void populateListOfRemoteCachePeers()
      Should be called on init because this is one of the last things that should happen on CacheManager startup.
      protected void startRegistry()
      Start the rmiregistry.
      protected void stopRegistry()
      Stop the rmiregistry if it was started by this class.
      protected void unbind​(RMICachePeer rmiCachePeer)
      Unbinds an RMICachePeer and unexports it.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • cachePeers

        protected final java.util.Map cachePeers
        The cache peers. The value is an RMICachePeer.
      • status

        protected Status status
        status.
      • port

        protected java.lang.Integer port
        The RMI listener port
    • Constructor Detail

      • RMICacheManagerPeerListener

        public RMICacheManagerPeerListener​(java.lang.String hostName,
                                           java.lang.Integer port,
                                           java.lang.Integer remoteObjectPort,
                                           CacheManager cacheManager,
                                           java.lang.Integer socketTimeoutMillis)
                                    throws java.net.UnknownHostException
        Constructor with full arguments.
        Parameters:
        hostName - may be null, in which case the hostName will be looked up. Machines with multiple interfaces should specify this if they do not want it to be the default NIC.
        port - a port in the range 1025 - 65536
        remoteObjectPort - the port number on which the remote objects bound in the registry receive calls. This defaults to a free port if not specified.
        cacheManager - the CacheManager this listener belongs to
        socketTimeoutMillis - TCP/IP Socket timeout when waiting on response
        Throws:
        java.net.UnknownHostException
    • Method Detail

      • assignFreePort

        protected void assignFreePort​(boolean forced)
                               throws java.lang.IllegalStateException
        Assigns a free port to be the listener port.
        Throws:
        java.lang.IllegalStateException - if the statis of the listener is not Status.STATUS_UNINITIALISED
      • calculateHostAddress

        protected java.lang.String calculateHostAddress()
                                                 throws java.net.UnknownHostException
        Calculates the host address as the default NICs IP address
        Throws:
        java.net.UnknownHostException
      • getFreePort

        protected int getFreePort()
                           throws java.lang.IllegalArgumentException
        Gets a free server socket port.
        Returns:
        a number in the range 1025 - 65536 that was free at the time this method was executed
        Throws:
        java.lang.IllegalArgumentException
      • init

        public void init()
                  throws CacheException
        Call to start the listeners and do any other required initialisation. init should also handle any work to do with the caches that are part of the initial configuration.
        Specified by:
        init in interface CacheManagerEventListener
        Throws:
        CacheException - - all exceptions are wrapped in CacheException
      • bind

        protected void bind​(java.lang.String peerName,
                            RMICachePeer rmiCachePeer)
                     throws java.lang.Exception
        Bind a cache peer
        Parameters:
        rmiCachePeer -
        Throws:
        java.lang.Exception
      • listBoundRMICachePeers

        protected java.lang.String[] listBoundRMICachePeers()
                                                     throws CacheException
        Returns a list of bound objects.

        This should match the list of cachePeers i.e. they should always be bound

        Returns:
        a list of String representations of RMICachePeer objects
        Throws:
        CacheException
      • lookupPeer

        protected java.rmi.Remote lookupPeer​(java.lang.String name)
                                      throws CacheException
        Returns a reference to the remote object.
        Parameters:
        name - the name of the cache e.g. sampleCache1
        Throws:
        CacheException
      • populateListOfRemoteCachePeers

        protected void populateListOfRemoteCachePeers()
                                               throws java.rmi.RemoteException
        Should be called on init because this is one of the last things that should happen on CacheManager startup.
        Throws:
        java.rmi.RemoteException
      • isDistributed

        protected boolean isDistributed​(Ehcache cache)
        Determine if the given cache is distributed.
        Parameters:
        cache - the cache to check
        Returns:
        true if a CacheReplicator is found in the listeners
      • startRegistry

        protected void startRegistry()
                              throws java.rmi.RemoteException
        Start the rmiregistry.

        The alternative is to use the rmiregistry binary, in which case:

        1. rmiregistry running
        2. -Djava.rmi.server.codebase="file:///Users/gluck/work/ehcache/build/classes/ file:///Users/gluck/work/ehcache/lib/commons-logging-1.0.4.jar"
        Throws:
        java.rmi.RemoteException
      • stopRegistry

        protected void stopRegistry()
                             throws java.rmi.RemoteException
        Stop the rmiregistry if it was started by this class.
        Throws:
        java.rmi.RemoteException
      • disposeRMICachePeer

        protected void disposeRMICachePeer​(RMICachePeer rmiCachePeer)
                                    throws java.lang.Exception
        A template method to dispose an individual RMICachePeer. This consists of:
        1. Unbinding the peer from the naming service
        2. Unexporting the peer
        Override to specialise behaviour
        Parameters:
        rmiCachePeer - the cache peer to dispose of
        Throws:
        java.lang.Exception - thrown if something goes wrong
      • unbind

        protected void unbind​(RMICachePeer rmiCachePeer)
                       throws java.lang.Exception
        Unbinds an RMICachePeer and unexports it.

        We unbind from the registry first before unexporting. Unbinding first removes the very small possibility of a client getting the object from the registry while we are trying to unexport it.

        This method may take up to 4 seconds to complete, if we are having trouble unexporting the peer.

        Parameters:
        rmiCachePeer - the bound and exported cache peer
        Throws:
        java.lang.Exception
      • getBoundCachePeers

        public java.util.List getBoundCachePeers()
        All of the caches which are listening for remote changes.
        Specified by:
        getBoundCachePeers in interface CacheManagerPeerListener
        Returns:
        a list of RMICachePeer objects. The list if not live
      • getUniqueResourceIdentifier

        public java.lang.String getUniqueResourceIdentifier()
        A listener will normally have a resource that only one instance can use at the same time, such as a port. This identifier is used to tell if it is unique and will not conflict with an existing instance using the resource.
        Specified by:
        getUniqueResourceIdentifier in interface CacheManagerPeerListener
        Returns:
        a String identifier for the resource
      • getScheme

        public java.lang.String getScheme()
        The replication scheme this listener interacts with. Each peer provider has a scheme name, which can be used by caches to specify for replication and bootstrap purposes.
        Specified by:
        getScheme in interface CacheManagerPeerListener
        Returns:
        the well-known scheme name, which is determined by the replication provider author.
      • notifyCacheAdded

        public void notifyCacheAdded​(java.lang.String cacheName)
                              throws CacheException
        Called immediately after a cache has been added and activated.

        Note that the CacheManager calls this method from a synchronized method. Any attempt to call a synchronized method on CacheManager from this method will cause a deadlock.

        Note that activation will also cause a CacheEventListener status change notification from Status.STATUS_UNINITIALISED to Status.STATUS_ALIVE. Care should be taken on processing that notification because:

        • the cache will not yet be accessible from the CacheManager.
        • the addCaches methods whih cause this notification are synchronized on the CacheManager. An attempt to call CacheManager.getCache(String) will cause a deadlock.
        The calling method will block until this method returns.

        Repopulates the list of cache peers and rebinds the list. This method should be called if a cache is dynamically added

        Specified by:
        notifyCacheAdded in interface CacheManagerEventListener
        Parameters:
        cacheName - the name of the Cache the operation relates to
        Throws:
        CacheException
        See Also:
        CacheEventListener
      • notifyCacheRemoved

        public void notifyCacheRemoved​(java.lang.String cacheName)
        Called immediately after a cache has been disposed and removed. The calling method will block until this method returns.

        Note that the CacheManager calls this method from a synchronized method. Any attempt to call a synchronized method on CacheManager from this method will cause a deadlock.

        Note that a CacheEventListener status changed will also be triggered. Any attempt from that notification to access CacheManager will also result in a deadlock.

        Specified by:
        notifyCacheRemoved in interface CacheManagerEventListener
        Parameters:
        cacheName - the name of the Cache the operation relates to