[prev in list] [next in list] [prev in thread] [next in thread] 

List:       jboss-cvs-commits
Subject:    [jboss-cvs] jboss-tomcat/src/main/org/jboss/web/tomcat/tc5/sso TreeCacheSSOClusterManager.java
From:       Brian Stansberry <bstansberry () users ! sourceforge ! net>
Date:       2004-05-30 23:58:05
Message-ID: E1BUaBp-000140-Ig () sc8-pr-cvs1 ! sourceforge ! net
[Download RAW message or body]

  User: bstansberry
  Date: 04/05/30 16:58:05

  Modified:    src/main/org/jboss/web/tomcat/tc5/sso Tag: Branch_3_2
                        TreeCacheSSOClusterManager.java
  Log:
  1) Remove our own creation of a TreeCache -- rely on external TreeCaches identified \
via property cacheName  2) Rename tree cache nodes to help prevent conflicts in a \
shared cache  3) Fix CredentialUpdater to prevent unintended InterruptedExceptions \
while it is waiting for a lock on a TreeCache object  
  Note that there is still a lot of dead code in here related to creating a \
TreeCache.  This will be removed once there is no chance we will want this class to \
manage the lifecycle of its ache.  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.3   +404 -113  \
jboss-tomcat/src/main/org/jboss/web/tomcat/tc5/sso/TreeCacheSSOClusterManager.java  
  Index: TreeCacheSSOClusterManager.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-tomcat/src/main/org/jboss/web/tomcat/tc5/sso/TreeCacheSSOClusterManager.java,v
  retrieving revision 1.1.2.2
  retrieving revision 1.1.2.3
  diff -u -r1.1.2.2 -r1.1.2.3
  --- TreeCacheSSOClusterManager.java	23 May 2004 04:41:59 -0000	1.1.2.2
  +++ TreeCacheSSOClusterManager.java	30 May 2004 23:58:03 -0000	1.1.2.3
  @@ -7,16 +7,18 @@
   package org.jboss.web.tomcat.tc5.sso;
   
   import java.io.Serializable;
  +import java.security.Principal;
   import java.util.HashSet;
  -import java.util.Set;
   import java.util.LinkedList;
  -import java.security.Principal;
  +import java.util.Set;
   
  +import javax.management.Attribute;
  +import javax.management.MBeanServer;
  +import javax.management.ObjectName;
   import javax.naming.InitialContext;
   import javax.naming.NamingException;
   import javax.transaction.UserTransaction;
   
  -import org.apache.catalina.Host;
   import org.apache.catalina.LifecycleException;
   import org.apache.catalina.LifecycleListener;
   import org.apache.catalina.Session;
  @@ -24,10 +26,8 @@
   import org.jboss.cache.Fqn;
   import org.jboss.cache.TreeCache;
   import org.jboss.cache.TreeCacheListener;
  -import org.jboss.cache.lock.IsolationLevel;
  -import org.jboss.cache.lock.LockingException;
  -import org.jboss.cache.lock.TimeoutException;
   import org.jboss.logging.Logger;
  +import org.jboss.mx.util.MBeanServerLocator;
   import org.jgroups.View;
   
   /**
  @@ -46,13 +46,13 @@
       * Final segment of any FQN that names a TreeCache node storing
       * SSO credential information.
       */
  -   private static final String CREDENTIALS = "credentials";
  +   private static final String CREDENTIALS = "sso-credentials";
   
      /**
       * Final segment of any FQN that names a TreeCache node storing
       * the set of Sessions associated with an SSO.
       */
  -   private static final String SESSIONS = "sessions";
  +   private static final String SESSIONS = "sso-sessions";
   
      /**
       * Key under which data is stored to the TreeCache.
  @@ -63,8 +63,42 @@
       * Maximum time between cycles of the CredentialUpdater thread.
       */
      private static final int UPDATE_THREAD_INTERVAL = 30000;
  +   
  +   /**
  +    * Default global value for the cacheName property
  +    */ 
  +   public static final String DEFAULT_GLOBAL_CACHE_NAME = 
  +         "jboss.cache:service=TreeCache";
  +   
  +   /**
  +    * Default base value for the cacheName property, to which a 
  +    * cluster name can be added
  +    */ 
  +   public static final String SSO_ONLY_CACHE_NAME_BASE = 
  +         "jboss.web:service=TreeCache,partition=";
  +   
  +   /**
  +    * Default value for the clusterName property
  +    */ 
  +   public static final String DEFAULT_CLUSTER_NAME = "sso-partition";
  +   
  +   /**
  +    * Default sso-only value for the cacheName property
  +    */ 
  +   public static final String DEFAULT_SSO_ONLY_CACHE_NAME = 
  +         SSO_ONLY_CACHE_NAME_BASE + DEFAULT_CLUSTER_NAME;
   
  -
  +   /** Parameter signature used for TreeCache.get calls over JMX */
  +   private static final String[] GET_SIGNATURE = 
  +         {Fqn.class.getName(), Object.class.getName()};
  +   
  +   /** Parameter signature used for TreeCache.put calls over JMX */
  +   private static final String[] PUT_SIGNATURE = 
  +      {Fqn.class.getName(), Object.class.getName(), Object.class.getName()};
  +   
  +   /** Parameter signature used for TreeCache.remove calls over JMX */
  +   private static final String[] REMOVE_SIGNATURE = {Fqn.class.getName()};
  +   
      // -------------------------------------------------------  Instance Fields
      
      /**
  @@ -82,6 +116,16 @@
       * node
       */
      private LinkedList beingRemotelyRemoved = new LinkedList();
  +   
  +   /**
  +    * ObjectName of the TreeCache
  +    */ 
  +   private ObjectName cacheObjectName = null;
  +   
  +   /**
  +    * String version of the object name to use to access the TreeCache
  +    */ 
  +   private String cacheName = null;
   
      /**
       * Name of the channel used for intra-cluster communications.
  @@ -110,6 +154,16 @@
      private Logger log = Logger.getLogger(getClass().getName());;
   
      /**
  +    * Whether we are registered as a TreeCacheListener anywhere 
  +    */
  +   private boolean registeredAsListener = false;
  +   
  +   /**
  +    * The MBean server we use to access our TreeCache 
  +    */
  +   private MBeanServer server = null;
  +   
  +   /**
       * The SingleSignOn for which we are providing cluster support
       */ 
      private ClusteredSingleSignOn ssoValve = null;
  @@ -118,17 +172,15 @@
       * Whether we have been started
       */
      private boolean started = false;
  +   
  +   private Boolean treeCacheAvailable = null;
   
      /**
       * The TreeCache in which sso data is stored.
       */
  -   private TreeCache treeCache;
  -   
  -   /**
  -    * Whether the TreeCache instance we're using was created by this object.
  -    */ 
  -   private boolean treeCacheLocallyManaged = false;
  +   //private TreeCache localTreeCache;
   
  +   private boolean createdLocalTreeCache = false;
      
      // ----------------------------------------------------------  Constructors
   
  @@ -136,35 +188,102 @@
      /**
       * Creates a new TreeCacheSSOClusterManager
       */
  -   public TreeCacheSSOClusterManager() {}
  +   public TreeCacheSSOClusterManager() 
  +   {
  +      // Find our MBeanServer
  +      server = MBeanServerLocator.locate();
  +   }
      
      
      // ------------------------------------------------------------  Properties
     
  -
  -   public TreeCache getTreeCache()
  +   public String getCacheName()
      {
  -      return this.treeCache;
  +      return cacheName;
      }
  -   
  -   public void setTreeCache(TreeCache cache)
  +
  +   public void setCacheName(String objectName) 
  +         throws Exception
      {
  -      this.treeCache = cache;
  -      if (cache != null) 
  +      if (objectName == null)
         {
  -         setPartitionName(cache.getClusterName());         
  +         setCacheObjectName(null);
  +      }
  +      else if (objectName.equals(cacheName) == false)
  +      {
  +         setCacheObjectName(new ObjectName(objectName));
         }
  -      treeCacheLocallyManaged = false;
      }
  -   
  -   public boolean isTreeCacheLocallyManaged()
  +
  +   public ObjectName getCacheObjectName()
      {
  -      return treeCacheLocallyManaged;
  +      return cacheObjectName;
      }
   
  -   public void setTreeCacheLocallyManaged(boolean treeCacheLocallyManaged)
  +   public void setCacheObjectName(ObjectName objectName)
  +         throws Exception
      {
  -      this.treeCacheLocallyManaged = treeCacheLocallyManaged;
  +      /*
  +      if (started)
  +      {
  +         boolean validName = findTreeCache(objectName);
  +         if (validName)
  +         {
  +            // Stop listening to the old cache
  +            removeAsTreeCacheListener(cacheObjectName);
  +            
  +            // If we created the existing tree cache, stop it
  +            if (createdLocalTreeCache)
  +            {
  +               //localTreeCache.stop();
  +               //localTreeCache = null;
  +               server.invoke(cacheObjectName, "stop", 
  +                             new Object[]{}, new String[]{});
  +               server.invoke(cacheObjectName, "destroy", 
  +                             new Object[]{}, new String[]{});
  +               //server.unregisterMBean(cacheObjectName);
  +               createdLocalTreeCache = false;
  +            }
  +            
  +            cacheObjectName = objectName;
  +            cacheName = cacheObjectName.getCanonicalName();
  +            
  +            // Start listening to the new TreeCache
  +            registerAsTreeCacheListener(cacheObjectName);
  +         }
  +         else
  +         {
  +            throw new IllegalStateException("No TreeCache found registered " +
  +                                            "under " + objectName);            
  +         }         
  +      }
  +      else
  +      {
  +         // We're not started yet, so just set the values
  +         */
  +         removeAsTreeCacheListener(cacheObjectName);
  +         this.cacheObjectName = objectName;      
  +         this.cacheName = (objectName == null 
  +                                       ? null 
  +                                       : objectName.getCanonicalName());
  +         treeCacheAvailable = null;
  +         if (isTreeCacheAvailable())
  +         {
  +            registerAsTreeCacheListener(cacheObjectName);
  +         }
  +         else if (started)
  +         {
  +            log.error("Cannot find TreeCache using " + cacheName +
  +                     " -- TreeCache must be started before " +
  +                      "ClusteredSingleSignOn can handle requests");
  +         }
  +         else
  +         {
  +            log.info("Cannot find TreeCache using " + cacheName + " -- tree" +
  +                     "CacheName must be set to point to a running TreeCache " +
  +                     "before ClusteredSingleSignOn can handle requests");
  +         }
  +      //}
      }
      
      // -----------------------------------------------------  SSOClusterManager
  @@ -196,7 +315,7 @@
            tx.begin();
            Set sessions = getSessionSet(fqn, true);
            sessions.add(session.getId());
  -         treeCache.put(fqn, KEY, sessions);         
  +         putInTreeCache(fqn, sessions);
            tx.commit();
         }
         catch (Exception e)
  @@ -229,9 +348,7 @@
      {
         if (clusterName == null) 
         {
  -         Host host = (Host) ssoValve.getContainer();
  -         String hostName = host.getName();
  -         clusterName = "sso-partition/" + hostName;         
  +         clusterName = DEFAULT_CLUSTER_NAME;         
         }
         return clusterName;
      }
  @@ -245,6 +362,7 @@
       * </p>
       * 
       * @param partitionName   the name of the cluster partition
  +    * 
       */ 
      public void setPartitionName(String partitionName)
      {
  @@ -316,7 +434,7 @@
         {
            tx = getNewTransaction();
            tx.begin();
  -         treeCache.remove(fqn);
  +         removeFromTreeCache(fqn);
            tx.commit();
         }
         catch (Exception e)
  @@ -341,7 +459,7 @@
         }
      }
   
  -   
  +
      /**
       * Queries the cluster for the existence of an SSO session with the given
       * id, returning a <code>SingleSignOnEntry</code> if one is found.
  @@ -362,7 +480,7 @@
         {
            tx = getNewTransaction();
            tx.begin();
  -         SSOCredentials data = (SSOCredentials) treeCache.get(fqn, KEY);
  +         SSOCredentials data = (SSOCredentials) getFromTreeCache(fqn);
            if (data != null)
            {
               entry = new SingleSignOnEntry(null,
  @@ -388,7 +506,7 @@
         return entry;
      }
   
  -   
  +
      /**
       * Notifies the cluster of the creation of a new SSO entry.
       *
  @@ -456,11 +574,11 @@
                  }
                  removing = true;
                  // No sessions left; remove node
  -               treeCache.remove(new Fqn(ssoId));
  +               removeFromTreeCache(new Fqn(ssoId));
               }
               else
               {
  -               treeCache.put(fqn, KEY, sessions);
  +               putInTreeCache(fqn, sessions);
               }
            }
            tx.commit();
  @@ -580,10 +698,6 @@
            beingRemotelyRemoved.add(ssoId);
         }     
   
  -      // Handle the logout in a separate thread so that if it starts
  -      // invalidating sessions, etc, we avoid deadlocks
  -      //logoutHandler.enqueue(ssoId);
  -      
         try
         {
            if (log.isTraceEnabled())
  @@ -727,21 +841,16 @@
                  ("TreeCacheSSOClusterManager already Started");
         }
         
  +      /*
         try
         {
  -         if (treeCache == null)
  -         {
  -            createTreeCache();
  -         }
  -         
  -         treeCache.addTreeCacheListener(this);
  -
  -         treeCache.start();
  +         accessTreeCache();
         }
         catch (Exception e)
         {
            throw new LifecycleException("cannot start TreeCache", e);
         }
  +      */
   
         // Start the thread we use to clear nodeModified events
         credentialUpdater = new CredentialUpdater();
  @@ -771,12 +880,27 @@
                  ("TreeCacheSSOClusterManager not Started");
         }
         
  -      // If we are managing our own tree cache, stop it 
  -      if (isTreeCacheLocallyManaged())
  +      /*
  +      // If we are managing our own tree cache, stop and unregister it 
  +      //if (localTreeCache != null)
  +      if (createdLocalTreeCache)
         {
  -         treeCache.stop();
  +         //localTreeCache.stop();         
  +         try
  +         {
  +            server.invoke(cacheObjectName, "stop", 
  +                          new Object[]{}, new String[]{});
  +            server.invoke(cacheObjectName, "destroy", 
  +                          new Object[]{}, new String[]{});
  +            server.unregisterMBean(cacheObjectName);
  +         }
  +         catch (Exception e)
  +         {
  +            throw new LifecycleException("exception unregistering TreeCache "
  +                                          + cacheObjectName, e);
  +         }
         }
  -      
  +      */
         credentialUpdater.stop();
   
         started = false;
  @@ -789,51 +913,144 @@
      // -------------------------------------------------------  Private Methods
   
      /**
  -    * Configures and starts the TreeCache used to share SSOCredentials objects
  -    * between cluster members.
  -    *
  -    * @throws Exception if TreeCache does
  +    * Attempts to find a TreeCache in the MBean server.  If unsuccessful,
  +    * creates a new one and registers it with the server.
  +    * <p>
  +    * Looks for the TreeCache in the following places:
  +    * <ol>
  +    * <li>Under the object name stored in property <code>cacheName</code>.
  +    * If this property is not <code>null</code>, and no TreeCache is found,
  +    * an exception will be thrown.</li>
  +    * <li>Under the object name "jboss.cache:service=TreeCache".  This is the
  +    * default location for a global TreeCache</li>
  +    * <li>Under the object name 
  +    * "jboss.web:service=TreeCache,type=ClusteredSingleSignOn".  This is the
  +    * name under which we register any TreeCache we create.</li>
       */
  -   private void createTreeCache()
  -         throws Exception
  +   private void accessTreeCache() throws Exception
      {
  -      if (treeCache != null)
  +      boolean cacheFound = false;      
  +      
  +      ObjectName testName = null;
  +      // Try to find a TreeCache registered under the value of cacheName
  +      if (cacheName != null)
  +      {
  +         testName = new ObjectName(cacheName);
  +         cacheFound = findTreeCache(testName);
  +         if (!cacheFound)
  +         {
  +            // We were passed in an invalid object name; throw exception
  +            throw new Exception("cannot find a TreeCache registered under " +
  +                                cacheName + "; be sure it is deployed " +
  +                                "before Tomcat");            
  +         }
  +      }      
  +      
  +      if (!cacheFound)
         {
  -         return;
  +         // Try the default global name
  +         testName = new ObjectName(DEFAULT_GLOBAL_CACHE_NAME);
  +         cacheFound = findTreeCache(testName);
         }
         
  +      if (!cacheFound)
  +      {
  +         // Try the default name we use to register caches we create, in
  +         // case another Host has already created one
  +         String ssoOnly = SSO_ONLY_CACHE_NAME_BASE + getPartitionName();
  +         testName = new ObjectName(ssoOnly);
  +         cacheFound = findTreeCache(testName);
  +      }
  +      
  +      if (!cacheFound)
  +      {
  +         testName = new ObjectName(SSO_ONLY_CACHE_NAME_BASE + 
  +                                   getPartitionName());;
  +         createTreeCache(testName);
  +      }          
  +      
  +      cacheObjectName = testName;
  +      cacheName = testName.getCanonicalName();      
  +      
  +      // Register ourselves as a listener with the TreeCache
  +      registerAsTreeCacheListener(cacheObjectName);
  +   }
  +   
  +   
  +   /**
  +    * Configures and starts a TreeCache used to share SSOCredentials objects
  +    * between cluster members, and registers it with the JMX server.
  +    *
  +    * @throws Exception if TreeCache does
  +    */
  +   private void createTreeCache(ObjectName objName)
  +         throws Exception
  +   {      
         try
         {
  -         TreeCache cache = new TreeCache();
  +         //TreeCache cache = new TreeCache();
  +         server.createMBean(TreeCache.class.getName(), objName);
   
  -         cache.setClusterName(getPartitionName());
  +         //cache.setClusterName(getPartitionName());
  +         server.setAttribute(objName, 
  +                             new Attribute("ClusterName", getPartitionName()));
            if (log.isDebugEnabled())
            {
               log.debug("clusterName set to " + getPartitionName());
            }
   
  -         cache.setClusterProperties("sso-channel.xml");
  -
  -         cache.setCacheMode(TreeCache.REPL_SYNC);
  -
  -         // 2004/02/09 we tried this with READ_COMMITTED, but kept
  -         // getting inexplicable locking problems.  May have been due to issues
  -         // in Branch_3_2 TreeCache???  Should try again w/ HEAD
  -         // 2004/05/18 Tried again w/ READ_COMMITTED; looks OK
  -         //cache.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
  -         cache.setIsolationLevel(IsolationLevel.READ_COMMITTED);
  -
  -         cache.setTransactionManagerLookupClass("org.jboss.cache.JBossTransactionManagerLookup");
                
  -         
  -         treeCache = cache;
  -         
  -         setTreeCacheLocallyManaged(true);
  +         //cache.setClusterProperties("sso-channel.xml");
  +         server.setAttribute(objName, 
  +                             new Attribute("ClusterProperties", 
  +                                           "sso-channel.xml"));
  +         //cache.setCacheMode(TreeCache.REPL_SYNC);
  +         server.setAttribute(objName, 
  +                             new Attribute("CacheMode", "REPL_SYNC"));
  +         //cache.setIsolationLevel(IsolationLevel.READ_COMMITTED);
  +         server.setAttribute(objName, 
  +                             new Attribute("IsolationLevel", "READ_COMMITTED"));
  +         //cache.setTransactionManagerLookupClass("org.jboss.cache.JBossTransactionManagerLookup");
  +         server.setAttribute(objName, 
  +                             new Attribute("TransactionManagerLookupClass", 
  +                                           \
"org.jboss.cache.JBossTransactionManagerLookup"));  +         server.invoke(objName, \
"create", new Object[]{}, new String[]{});  +         server.invoke(objName, "start", \
new Object[]{}, new String[]{});  +         //localTreeCache = cache;
  +         createdLocalTreeCache = true;
         }
         catch (Exception e)
         {
  +         cacheName = null;
  +         cacheObjectName = null;
            log.error("Exception creating TreeCache", e);
            throw e;
         }
  +      
  +      //localTreeCache.start(); 
  +   }
  +   
  +   
  +   /**
  +    * Attempts to find a TreeCache registered under the given ObjectName.
  +    * If successful, records it as this object's TreeCache.
  +    * 
  +    * @param objectName
  +    * @return  <code>true</code> if a TreeCache was found
  +    */ 
  +   private boolean findTreeCache(ObjectName objectName)
  +   {
  +      boolean cacheFound = false;
  +      if (objectName != null)
  +      {
  +         cacheFound = server.queryMBeans(objectName, null).size() > 0;
  +      }      
  +      return cacheFound;
  +   }
  +
  +   private Object getFromTreeCache(Fqn fqn) throws Exception
  +   {
  +      Object[] args = new Object[] {fqn, KEY};
  +      return server.invoke(getCacheObjectName(), "get", args, GET_SIGNATURE);
      }
   
      /**
  @@ -856,9 +1073,9 @@
      }
   
      private Set getSessionSet(Fqn fqn, boolean create) 
  -         throws LockingException, TimeoutException
  +         throws Exception 
      {
  -      Set sessions = (Set) treeCache.get(fqn, KEY);
  +      Set sessions = (Set) getFromTreeCache(fqn);
         if (create && sessions == null)
         {
            sessions = new HashSet();
  @@ -891,9 +1108,84 @@
            initialContext = null;
            throw n;
         }
  +   }  
  +   
  +   /**
  +    * Checks whether an MBean is registered under the value of property
  +    * "cacheName".
  +    * <p>
  +    * This check is only performed once; thereafter the same result is 
  +    * returned.
  +    * 
  +    * TODO should we check further -- ensure the MBean is a TreeCache,
  +    * is started, is configured correctly, etc? 
  +    * 
  +    * @return <code>true</code> if property <code>cacheName</code> has been
  +    *         set and points to a registered MBean.
  +    */ 
  +   private boolean isTreeCacheAvailable()
  +   {
  +      if (treeCacheAvailable == null)
  +      {
  +         boolean available = (cacheObjectName != null);
  +         if (available)
  +         {
  +            Set s = server.queryMBeans(cacheObjectName, null);
  +            available = s.size() > 0;
  +         }
  +         treeCacheAvailable = Boolean.valueOf(available);
  +      }
  +      return treeCacheAvailable.booleanValue();
  +   }
  +
  +   private void putInTreeCache(Fqn fqn, Object data) throws Exception
  +   {
  +      Object[] args = new Object[] {fqn, KEY, data};
  +      server.invoke(getCacheObjectName(), "put", args, PUT_SIGNATURE);
      }
   
      /**
  +    * Invokes an operation on the JMX server to register ourself as a
  +    * listener on the TreeCache service.
  +    * 
  +    * @throws Exception
  +    */ 
  +   private void registerAsTreeCacheListener(ObjectName listenTo)
  +      throws Exception
  +   {
  +      server.invoke(listenTo, "addTreeCacheListener", 
  +                    new Object[] { this }, 
  +                    new String[] { TreeCacheListener.class.getName() } );
  +      registeredAsListener = true;
  +   }
  +   
  +   
  +
  +   /**
  +    * Invokes an operation on the JMX server to register ourself as a
  +    * listener on the TreeCache service.
  +    * 
  +    * @throws Exception
  +    */ 
  +   private void removeAsTreeCacheListener(ObjectName removeFrom)
  +      throws Exception
  +   {
  +      if (registeredAsListener && removeFrom != null)
  +      {
  +         server.invoke(removeFrom, "removeTreeCacheListener", 
  +                       new Object[] { this }, 
  +                       new String[] { TreeCacheListener.class.getName() } );
  +      }
  +   }
  +
  +   private void removeFromTreeCache(Fqn fqn) throws Exception
  +   {     
  +      server.invoke(getCacheObjectName(), "remove", 
  +                    new Object[] {fqn}, 
  +                    REMOVE_SIGNATURE);
  +   }
  +   
  +   /**
       * Stores the given data to the clustered cache in a tree branch whose FQN
       * is the given SSO id.  Stores the given credential data in a child node
       * named "credentials".  If parameter <code>storeSessions</code> is
  @@ -924,8 +1216,7 @@
         {
            tx = getNewTransaction();
            tx.begin();
  -         treeCache.put(new Fqn(new Object[]{ssoId, CREDENTIALS}),
  -                       KEY, data);
  +         putInTreeCache(new Fqn(new Object[]{ssoId, CREDENTIALS}), data);
            tx.commit();
         }
         catch (Exception e)
  @@ -960,12 +1251,14 @@
      {
         private HashSet awaitingUpdate = new HashSet();
         private Thread updateThread;
  +      private boolean updateThreadSleeping = false;
  +      private boolean queueEmpty = true;
         private boolean stopped = false;
   
         private CredentialUpdater()
         {
            updateThread = 
  -               new Thread(this,"SSOClusterManager.CredentialUpdater");         
  +               new Thread(this, "SSOClusterManager.CredentialUpdater");         
            updateThread.setDaemon(true);
            updateThread.start();
         }
  @@ -973,12 +1266,13 @@
         // ------------------------------------------------------  Runnable
   
         public void run()
  -      {         
  +      {
            while (!stopped)
            {
  -            // Ensure that no runtime exceptions kill this thread         
  +            // Ensure that no runtime exceptions kill this thread
               try
               {
  +               updateThreadSleeping = false;
                  // Get the current list of ids awaiting processing
                  SSOWrapper[] ssos = null;
                  synchronized (awaitingUpdate)
  @@ -986,6 +1280,7 @@
                     ssos = new SSOWrapper[awaitingUpdate.size()];
                     ssos = (SSOWrapper[]) awaitingUpdate.toArray(ssos);
                     awaitingUpdate.clear();
  +                  queueEmpty = true;
                  }
   
                  // Handle the credential update
  @@ -997,10 +1292,11 @@
                  // Wait for another invocation of enqueue().  But,
                  // first have to check in case it was invoked while we
                  // were processing the previous bunch
  -               if (!Thread.interrupted())
  +               if (!queueEmpty)
                  {
                     try
                     {
  +                     updateThreadSleeping = true; // TODO fix possible race cond
                        updateThread.sleep(UPDATE_THREAD_INTERVAL);
                     }
                     catch (InterruptedException e)
  @@ -1009,14 +1305,14 @@
                        {
                           log.trace("CredentialUpdater: interrupted");
                        }
  -                     ; // process the next bunch
  +                     // process the next bunch
                     }
                  }
                  else if (log.isTraceEnabled())
                  {
                     log.trace("CredentialUpdater: interrupted while handling " +
                               "updates");
  -               }
  +               }            
               }
               catch (Exception e)
               {
  @@ -1039,8 +1335,12 @@
            synchronized(awaitingUpdate)
            {
               awaitingUpdate.add(new SSOWrapper(sso, ssoId));
  +            queueEmpty = false;
  +         }
  +         if (updateThreadSleeping)
  +         {
  +            updateThread.interrupt();
            }
  -         updateThread.interrupt();
         }
   
         private void processUpdate(SSOWrapper wrapper)
  @@ -1057,7 +1357,7 @@
            {
               tx = getNewTransaction();
               tx.begin();
  -            SSOCredentials data = (SSOCredentials) treeCache.get(fqn, KEY);
  +            SSOCredentials data = (SSOCredentials) getFromTreeCache(fqn);
               if (data != null)
               {
                  // We want to release our read lock quickly, so get the needed
  @@ -1072,16 +1372,7 @@
                     log.trace("CredentialUpdater: Updating credentials for SSO " +
                               wrapper.sso);
                  }
  -               /*
  -               SingleSignOnEntry entry = ssoValve.localLookup(ssoId);
  -               // Only update if the local entry needs it
  -               if (entry != null && !entry.getCanReauthenticate())
  -               {
  -                  Principal p = entry.getPrincipal();
  -                  entry.updateCredentials(p, authType, username, password);
  -               }
  -               */               
  -               //ssoValve.remoteUpdate(ssoId, authType, username, password);
  +               
                  synchronized (wrapper.sso)
                  {
                     // Use the existing principal
  @@ -1119,13 +1410,16 @@
   
      }  // end CredentialUpdater
   
  -
  +   
  +   /**
  +    * Wrapper class that holds a SingleSignOnEntry and its id
  +    */ 
      private class SSOWrapper
      {
  -      SingleSignOnEntry sso = null;
  -      String id = null;
  +      private SingleSignOnEntry sso = null;
  +      private String id = null;
         
  -      SSOWrapper(SingleSignOnEntry entry, String ssoId)
  +      private SSOWrapper(SingleSignOnEntry entry, String ssoId)
         {
            this.sso = entry;
            this.id = ssoId;
  @@ -1137,16 +1431,13 @@
      /**
       * Private class used to store authentication credentials in the TreeCache.
       * <p>
  -    * For security, all methods are private.
  +    * For security, password accessor is private.
       */
      public static class SSOCredentials 
            implements Serializable
  -   {
  -      
  +   {      
         private String authType = null;
  -
         private String password = null;
  -
         private String username = null;
   
         /**
  
  
  


-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g. 
Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click
_______________________________________________
jboss-cvs-commits mailing list
jboss-cvs-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jboss-cvs-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic