Implemented Memory Handle Repository handle cleanup thread.
authorwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Wed, 5 Feb 2003 05:56:50 +0000 (05:56 +0000)
committerwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Wed, 5 Feb 2003 05:56:50 +0000 (05:56 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@452 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/edu/internet2/middleware/shibboleth/hs/provider/MemoryHandleRepository.java

index 70a5ede..52d88c2 100644 (file)
@@ -51,15 +51,19 @@ package edu.internet2.middleware.shibboleth.hs.provider;
 
 import java.security.Principal;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
+import java.util.Map.Entry;
 
 import org.apache.log4j.Logger;
 import org.doomdark.uuid.UUIDGenerator;
 
 import edu.internet2.middleware.shibboleth.hs.HandleRepository;
 import edu.internet2.middleware.shibboleth.hs.HandleRepositoryException;
-import edu.internet2.middleware.shibboleth.hs.HandleServlet;
+import edu.internet2.middleware.shibboleth.hs.provider.BaseHandleRepository.HandleEntry;
 
 /**
  * <code>HandleRepository</code> implementation that uses a static cache.  This requires
@@ -69,10 +73,8 @@ import edu.internet2.middleware.shibboleth.hs.HandleServlet;
  */
 public class MemoryHandleRepository extends BaseHandleRepository implements HandleRepository {
 
-       protected static Map handleEntries = new HashMap();
-               private static Logger log = Logger.getLogger(MemoryHandleRepository.class.getName());
-
-
+       protected HandleCache cache = HandleCache.instance();
+       private static Logger log = Logger.getLogger(MemoryHandleRepository.class.getName());
 
        public MemoryHandleRepository(Properties properties) throws HandleRepositoryException {
                super(properties);
@@ -84,8 +86,8 @@ public class MemoryHandleRepository extends BaseHandleRepository implements Hand
        public String getHandle(Principal principal) {
                String handle = UUIDGenerator.getInstance().generateRandomBasedUUID().toString();
                log.debug("Assigning handle (" + handle + ") to principal (" + principal.getName() + ").");
-               synchronized (handleEntries) {
-                       handleEntries.put(handle, new HandleEntry(principal));
+               synchronized (cache.handleEntries) {
+                       cache.handleEntries.put(handle, new HandleEntry(principal));
                }
                return handle;
        }
@@ -94,20 +96,20 @@ public class MemoryHandleRepository extends BaseHandleRepository implements Hand
         * @see edu.internet2.middleware.shibboleth.hs.HandleRepository#getPrincipal(String)
         */
        public Principal getPrincipal(String handle) {
-               synchronized (handleEntries) {
-                       if (!handleEntries.containsKey(handle)) {
+               synchronized (cache.handleEntries) {
+                       if (!cache.handleEntries.containsKey(handle)) {
                                log.debug("Repository does not contain an entry for this Attribute Query Handle.");
                                return null;
                        }
                }
                HandleEntry handleEntry;
-               synchronized (handleEntries) {
-                       handleEntry = (HandleEntry) handleEntries.get(handle);
+               synchronized (cache.handleEntries) {
+                       handleEntry = (HandleEntry) cache.handleEntries.get(handle);
                }
                if (handleEntry.isExpired()) {
                        log.debug("Attribute Query Handle is expired.");
-                       synchronized (handleEntries) {
-                               handleEntries.remove(handle);
+                       synchronized (cache.handleEntries) {
+                               cache.handleEntries.remove(handle);
                        }
                        return null;
                } else {
@@ -115,5 +117,83 @@ public class MemoryHandleRepository extends BaseHandleRepository implements Hand
                        return handleEntry.principal;
                }
        }
-
 }
+       class HandleCache {
+
+               protected Map handleEntries = new HashMap();
+               private static HandleCache instance;
+               protected MemoryRepositoryCleaner cleaner = new MemoryRepositoryCleaner();
+               private static Logger log = Logger.getLogger(HandleCache.class.getName());
+
+               protected HandleCache() {
+               }
+               
+               public static synchronized HandleCache instance() {
+                       if (instance == null) {
+                               instance = new HandleCache();
+                               return instance;
+                       }
+                       return instance;
+               }
+               /**
+               * @see java.lang.Object#finalize()
+               */
+               protected void finalize() throws Throwable {
+                       super.finalize();
+                       synchronized (cleaner) {
+                               cleaner.shutdown = true;
+                               cleaner.interrupt();
+                       }
+               }
+
+               private class MemoryRepositoryCleaner extends Thread {
+
+                       private boolean shutdown = false;
+
+                       public MemoryRepositoryCleaner() {
+                               super();
+                               log.debug("Starting Memory Repository Cleanup Thread.");
+                               start();
+                       }
+
+                       public void run() {
+                               try {
+                                       sleep(1 * 60 * 1000);
+                               } catch (InterruptedException e) {
+                                       log.debug("Memory Repository Cleanup interrupted.");
+                               }
+                               while (true) {
+                                       try {
+                                               if (shutdown) {
+                                                       log.debug("Stopping Memory Repository Cleanup Thread.");
+                                                       return;
+                                               }
+                                               Set needsDeleting = new HashSet();
+                                               synchronized (handleEntries) {
+                                                       Iterator iterator = handleEntries.entrySet().iterator();
+                                                       while (iterator.hasNext()) {
+                                                               Entry entry = (Entry) iterator.next();
+                                                               HandleEntry handleEntry = (HandleEntry) entry.getValue();
+                                                               if (handleEntry.isExpired()) {
+                                                                       needsDeleting.add(entry.getKey());
+                                                               }
+                                                       }
+                                                       //release the lock to be friendly
+                                                       Iterator deleteIterator = needsDeleting.iterator();
+                                                       while (deleteIterator.hasNext()) {
+                                                               synchronized (handleEntries) {
+                                                                       log.debug(
+                                                                               "Expiring an Attribute Query Handle from the Memory Repository.");
+                                                                       handleEntries.remove(deleteIterator.next());
+                                                               }
+                                                       }
+                                               }
+                                               sleep(1 * 60 * 1000);
+                                       } catch (InterruptedException e) {
+                                               log.debug("Memory Repository Cleanup interrupted.");
+                                       }
+                               }
+                       }
+               }
+
+       }