You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2010/12/04 12:21:18 UTC

svn commit: r1042145 - in /directory/apacheds/branches/apacheds-kerberos-codec-2.0: core-api/src/main/resources/ kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/ kerberos-shared/src/test/java/org/apache/directory/server...

Author: kayyagari
Date: Sat Dec  4 11:21:18 2010
New Revision: 1042145

URL: http://svn.apache.org/viewvc?rev=1042145&view=rev
Log:
o used ehcache as store for replay cache implementation and renamed InMemoryReplayCache to ReplayCacheImpl
o moved the instantiation of replay cache to KDC and ChangePassword server classes
o removed the static replay cache instances from ChangePasswordService and TicketGrantingService
o added cache configuration to the irectory-cacheservice.xml
o removed set/get methods for replay cache from TicketGrantingContext and ChangePasswordContext


Added:
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/ReplayCacheImpl.java
      - copied, changed from r1042117, directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/InMemoryReplayCache.java
Removed:
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/InMemoryReplayCache.java
Modified:
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/core-api/src/main/resources/directory-cacheservice.xml
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/ReplayCache.java
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/replay/InMemoryReplayCacheTest.java
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/ChangePasswordServer.java
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/service/ChangePasswordContext.java
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/service/ChangePasswordService.java
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/KdcServer.java
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/authentication/AuthenticationContext.java
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/authentication/AuthenticationService.java
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingContext.java
    directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingService.java

Modified: directory/apacheds/branches/apacheds-kerberos-codec-2.0/core-api/src/main/resources/directory-cacheservice.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/core-api/src/main/resources/directory-cacheservice.xml?rev=1042145&r1=1042144&r2=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/core-api/src/main/resources/directory-cacheservice.xml (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/core-api/src/main/resources/directory-cacheservice.xml Sat Dec  4 11:21:18 2010
@@ -93,7 +93,6 @@
 		on disk is needed to swap the data if it is too much to hold in memory -->
 	<cache name="groupCache" 
 	       maxElementsInMemory="10000"
-		   maxElementsOnDisk="1000"
 		   eternal="false" 
 		   overflowToDisk="true"
 		   diskSpoolBufferSizeMB="20"
@@ -104,7 +103,6 @@
     
     <cache name="dnCache" 
 	       maxElementsInMemory="10000"
-		   maxElementsOnDisk="1000"
 		   eternal="false" 
 		   overflowToDisk="false"
 		   diskSpoolBufferSizeMB="20"
@@ -112,5 +110,38 @@
 		   timeToLiveSeconds="600"
 		   memoryStoreEvictionPolicy="LFU" 
 		   diskPersistent="false" />
+
+   <!-- Kerberos replay cache
+      NOTE1: keep the maxElementsInMemory as low as possible to avoid wasting memory
+      Cause the elements present in the cache won't be removed dynamically even after their TTL
+      expires. For a good explanation see http://forums.terracotta.org/forums/posts/list/4126.page
+      
+      NOTE2: We don't use the standard eviction policies like LFU or LRU rather we use a custom eviction
+             policy based on the value of clockskew setting. The default value of clokcskew is 5 minutes,
+             which is also set for the TTL and TTI values of cache config
+             
+      So what we do here is enable the overflowToDisk flag and then let the disk store be cleaned
+      periodically based on diskExpiryThreadIntervalSeconds
+   -->
+    <cache name="kdcReplayCache" 
+	       maxElementsInMemory="100"
+		   eternal="false" 
+		   overflowToDisk="true"
+		   diskSpoolBufferSizeMB="20"
+		   diskExpiryThreadIntervalSeconds="300"
+		   timeToLiveSeconds="300"
+		   timeToIdleSeconds="300"
+		   diskPersistent="false" />
+
+   <!-- ChangePassword replay cache, this has the same settings as the Kerberos replay cache -->
+    <cache name="changePwdReplayCache" 
+	       maxElementsInMemory="100"
+		   eternal="false" 
+		   overflowToDisk="true"
+		   diskSpoolBufferSizeMB="20"
+		   diskExpiryThreadIntervalSeconds="300"
+		   timeToLiveSeconds="300"
+		   timeToIdleSeconds="300"
+		   diskPersistent="false" />
 		   
 </ehcache>
\ No newline at end of file

Modified: directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/ReplayCache.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/ReplayCache.java?rev=1042145&r1=1042144&r2=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/ReplayCache.java (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/ReplayCache.java Sat Dec  4 11:21:18 2010
@@ -59,4 +59,9 @@ public interface ReplayCache
      */
     void save( KerberosPrincipal serverPrincipal, KerberosPrincipal clientPrincipal, KerberosTime clientTime,
         int clientMicroSeconds );
+    
+    /**
+     * removes all the elements present in the cache
+     */
+    void clear();
 }

Copied: directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/ReplayCacheImpl.java (from r1042117, directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/InMemoryReplayCache.java)
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/ReplayCacheImpl.java?p2=directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/ReplayCacheImpl.java&p1=directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/InMemoryReplayCache.java&r1=1042117&r2=1042145&rev=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/InMemoryReplayCache.java (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/main/java/org/apache/directory/server/kerberos/shared/replay/ReplayCacheImpl.java Sat Dec  4 11:21:18 2010
@@ -20,16 +20,17 @@
 package org.apache.directory.server.kerberos.shared.replay;
 
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.io.Serializable;
 
 import javax.security.auth.kerberos.KerberosPrincipal;
 
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.store.AbstractPolicy;
+
 import org.apache.directory.shared.kerberos.KerberosTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
@@ -37,20 +38,17 @@ import org.apache.directory.shared.kerbe
  * time, and microsecond fields from the recently-seen authenticators, and if a
  * matching tuple is found, the KRB_AP_ERR_REPEAT error is returned."
  * 
- * We will store the entries using an HashMap which key will be the client
- * principal, and we will store a list of entries for each client principal.
- * 
- * A thread will run every N seconds to clean the cache from entries out of the 
- * clockSkew.
+ * We will store the entries in Ehacache instance
  * 
- * TODO: check if we really want an active thread for each cache instance (DIRKRB-80).
- *    
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-public class InMemoryReplayCache extends Thread implements ReplayCache
+public class ReplayCacheImpl implements ReplayCache
 {
-    /** Stores the entries in memory */
-    private Map<KerberosPrincipal, List<ReplayCacheEntry>> cache = new HashMap<KerberosPrincipal, List<ReplayCacheEntry>>();
+    
+    private static final Logger LOG = LoggerFactory.getLogger( ReplayCacheImpl.class );
+    
+    /** ehcache based storage to store the entries */
+    private Cache cache;
 
     /** default clock skew */
     private static final long DEFAULT_CLOCK_SKEW = 5 * KerberosTime.MINUTE;
@@ -58,17 +56,13 @@ public class InMemoryReplayCache extends
     /** The clock skew */
     private long clockSkew = DEFAULT_CLOCK_SKEW;
 
-    /** The default delay between each run of the cleaning process : 5 s */
-    private static long DEFAULT_DELAY = 5 * 1000;  
-
-    /** The delay to wait between each cache cleaning */
-    private long delay;
-
     /**
      * A structure to hold an entry
      */
-    public class ReplayCacheEntry
+    public class ReplayCacheEntry implements Serializable
     {
+        private static final long serialVersionUID = 1L;
+
         private KerberosPrincipal serverPrincipal;
         private KerberosPrincipal clientPrincipal;
         private KerberosTime clientTime;
@@ -118,71 +112,85 @@ public class InMemoryReplayCache extends
         {
             return !clientTime.isInClockSkew( clockSkew );
         }
+
+
+        /**
+         * @return create a key to be used while storing in the cache
+         */
+        private String createKey()
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.append( ( clientPrincipal == null ) ? "null" : clientPrincipal.getName() );
+            sb.append( '#' );
+            sb.append( ( serverPrincipal == null ) ? "null" : serverPrincipal.getName() );
+            sb.append( '#' );
+            sb.append( ( clientTime == null ) ? "null" : clientTime.getDate() );
+            sb.append( '#' );
+            sb.append( clientMicroSeconds );
+
+            return sb.toString();
+        }
     }
 
-    
     /**
-     * Creates a new instance of InMemoryReplayCache. Sets the
-     * delay between each cleaning run to 5 seconds.
+     * an expiration policy based on the clockskew
      */
-    public InMemoryReplayCache()
+    private class ClockskewExpirationPolicy extends AbstractPolicy
     {
-        cache = new HashMap<KerberosPrincipal, List<ReplayCacheEntry>>();
-        delay = DEFAULT_DELAY;
-        this.start();
+
+        /**
+         * {@inheritDoc}
+         */
+        public String getName()
+        {
+            System.out.println( "getName" );
+            return "CLOCK-SKEW";
+        }
+
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean compare( Element element1, Element element2 )
+        {
+            ReplayCacheEntry entry = ( ReplayCacheEntry ) element2.getValue();
+
+            if ( entry.isOutsideClockSkew( clockSkew ) )
+            {
+                return true;
+            }
+
+            return false;
+        }
     }
-    
-    
+
+
     /**
      * Creates a new instance of InMemoryReplayCache. Sets the
-     * delay between each cleaning run to 5 seconds. Sets the
-     * clockSkew to the given value
-     * 
-     * @param clockSkew the allowed skew (milliseconds)
+     * delay between each cleaning run to 5 seconds.
      */
-    public InMemoryReplayCache( long clockSkew )
+    public ReplayCacheImpl( Cache cache )
     {
-        cache = new HashMap<KerberosPrincipal, List<ReplayCacheEntry>>();
-        delay = DEFAULT_DELAY;
-        this.clockSkew = clockSkew;
-        this.start();
+        this.cache = cache;
+        this.cache.setMemoryStoreEvictionPolicy( new ClockskewExpirationPolicy() );
     }
-    
-    
+
+
     /**
      * Creates a new instance of InMemoryReplayCache. Sets the
-     * clockSkew to the given value, and set the cleaning thread 
-     * kick off delay
+     * delay between each cleaning run to 5 seconds. Sets the
+     * clockSkew to the given value
      * 
      * @param clockSkew the allowed skew (milliseconds)
-     * @param delay the interval between each run of the cache 
-     * cleaning thread (milliseconds)
      */
-    public InMemoryReplayCache( long clockSkew, int delay  )
+    public ReplayCacheImpl( Cache cache, long clockSkew )
     {
-        cache = new HashMap<KerberosPrincipal, List<ReplayCacheEntry>>();
-        this.delay = (long)delay;
+        this.cache = cache;
         this.clockSkew = clockSkew;
-        this.start();
+        this.cache.setMemoryStoreEvictionPolicy( new ClockskewExpirationPolicy() );
     }
-    
-    
-    /**
-     * Creates a new instance of InMemoryReplayCache. Sets the
-     * delay between each cleaning run to 5 seconds. Sets the 
-     * cleaning thread kick off delay
-     * 
-     * @param delay the interval between each run of the cache 
-     * cleaning thread (milliseconds).
-     */
-    public InMemoryReplayCache( int delay )
-    {
-        cache = new HashMap<KerberosPrincipal, List<ReplayCacheEntry>>();
-        this.delay = (long)delay;
-        this.clockSkew = DEFAULT_CLOCK_SKEW;
-    }
-    
-    
+
+
     /**
      * Sets the clock skew.
      *
@@ -193,16 +201,6 @@ public class InMemoryReplayCache extends
         this.clockSkew = clockSkew;
     }
 
-    
-    /**
-     * Set the delay between each cleaning thread run.
-     *
-     * @param delay delay in milliseconds
-     */
-    public void setDelay( long delay )
-    {
-        this.delay = delay;
-    }
 
     /**
      * Check if an entry is a replay or not.
@@ -210,21 +208,23 @@ public class InMemoryReplayCache extends
     public synchronized boolean isReplay( KerberosPrincipal serverPrincipal, KerberosPrincipal clientPrincipal,
         KerberosTime clientTime, int clientMicroSeconds )
     {
-        List<ReplayCacheEntry> entries = cache.get( clientPrincipal );
-        
-        if ( ( entries == null ) || ( entries.size() == 0 ) )
+
+        ReplayCacheEntry entry = new ReplayCacheEntry( serverPrincipal, clientPrincipal, clientTime, clientMicroSeconds );
+
+        Element element = cache.get( entry.createKey() );
+
+        if ( element == null )
         {
             return false;
         }
-        
-        for ( ReplayCacheEntry entry:entries )
+
+        entry = ( ReplayCacheEntry ) element.getValue();
+
+        if ( serverPrincipal.equals( entry.serverPrincipal ) &&
+            clientTime.equals( entry.clientTime ) &&
+            ( clientMicroSeconds == entry.clientMicroSeconds ) )
         {
-            if ( serverPrincipal.equals( entry.serverPrincipal ) && 
-                 clientTime.equals( entry.clientTime ) && 
-                 (clientMicroSeconds == entry.clientMicroSeconds ) )
-            {
-                return true;
-            }
+            return true;
         }
 
         return false;
@@ -238,80 +238,19 @@ public class InMemoryReplayCache extends
     public synchronized void save( KerberosPrincipal serverPrincipal, KerberosPrincipal clientPrincipal,
         KerberosTime clientTime, int clientMicroSeconds )
     {
-        List<ReplayCacheEntry> entries = cache.get( clientPrincipal );
-        
-        if ( entries == null )
-        {
-            entries = new ArrayList<ReplayCacheEntry>();
-        }
-        
-        entries.add( new ReplayCacheEntry( serverPrincipal, clientPrincipal, clientTime, clientMicroSeconds ) );
-        
-        cache.put( clientPrincipal, entries );
-    }
+        ReplayCacheEntry entry = new ReplayCacheEntry( serverPrincipal, clientPrincipal, clientTime, clientMicroSeconds );
 
-    
-    public Map<KerberosPrincipal, List<ReplayCacheEntry>> getCache()
-    {
-        return cache;
-    }
-    
-    /**
-     * A method to remove all the expired entries from the cache.
-     */
-    synchronized void cleanCache()
-    {
-        Collection<List<ReplayCacheEntry>> entryList = cache.values();
-        
-        if ( ( entryList == null ) || ( entryList.size() == 0 ) )
-        {
-            return;
-        }
-        
-        for ( List<ReplayCacheEntry> entries:entryList )
-        {
-            if ( ( entries == null ) || ( entries.size() == 0 ) )
-            {
-                continue;
-            }
-            
-            Iterator<ReplayCacheEntry> iterator = entries.iterator();
-            
-            while ( iterator.hasNext() )
-            {
-                ReplayCacheEntry entry = iterator.next();
-                
-                if ( entry.isOutsideClockSkew( clockSkew ) )
-                {
-                    iterator.remove();
-                }
-                else
-                {
-                    break;
-                }
-            }
-        }
+        Element element = new Element( entry.createKey(), entry );
+        cache.put( element );
     }
     
     
-    /** 
-     * The cleaning thread. It runs every N seconds.
+    /**
+     * {@inheritDoc}
      */
-    public void run()
+    public void clear()
     {
-        while ( true )
-        {
-            try
-            {
-                Thread.sleep( delay );
-                
-                cleanCache();
-            }
-            catch ( InterruptedException ie )
-            {
-                cache.clear();
-                return;
-            }
-        }
+        LOG.debug( "removing all the elements from cache" );
+        cache.removeAll();
     }
 }

Modified: directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/replay/InMemoryReplayCacheTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/replay/InMemoryReplayCacheTest.java?rev=1042145&r1=1042144&r2=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/replay/InMemoryReplayCacheTest.java (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/kerberos-shared/src/test/java/org/apache/directory/server/kerberos/shared/replay/InMemoryReplayCacheTest.java Sat Dec  4 11:21:18 2010
@@ -19,27 +19,27 @@
  */
 package org.apache.directory.server.kerberos.shared.replay;
 
+
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNull;
 
-import java.util.Collection;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
 import javax.security.auth.kerberos.KerberosPrincipal;
 
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+
 import org.apache.directory.junit.tools.Concurrent;
 import org.apache.directory.junit.tools.ConcurrentJunitRunner;
 import org.apache.directory.junit.tools.MultiThreadedMultiInvoker;
-import org.apache.directory.server.kerberos.shared.replay.InMemoryReplayCache.ReplayCacheEntry;
 import org.apache.directory.shared.kerberos.KerberosTime;
 import org.apache.directory.shared.kerberos.codec.types.PrincipalNameType;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+
 /**
  * Test the InMemory replay cache
  * 
@@ -52,96 +52,58 @@ public class InMemoryReplayCacheTest
     @Rule
     public MultiThreadedMultiInvoker i = new MultiThreadedMultiInvoker( MultiThreadedMultiInvoker.THREADSAFE );
 
+
     /**
      * Test that the cache is working well. We will create a new entry
-     * every 20 ms, with 10 different serverPrincipals.
+     * every 500 ms, with 4 different serverPrincipals.
      * 
-     * After this period of time, we should only have 25 entries in the cache
+     * After this period of time, we should only have 2 entries in the cache
      */
     @Test
     public void testCacheSetting() throws Exception
     {
-        int delay = 500;
-        long clockSkew = 100;
-        
-        // Set a delay of 500 ms and a clock skew of 100 ms
-        InMemoryReplayCache cache = new InMemoryReplayCache( clockSkew, delay );
-        
-        // Loop for 2 seconds, then check that the cache is clean
+        long clockSkew = 1000; // 1 sec
+
+        CacheManager cacheManager = new CacheManager( InMemoryReplayCacheTest.class.getClassLoader().getResource(
+            "directory-cacheservice.xml" ) );
+
+        Cache ehCache = cacheManager.getCache( "kdcReplayCache" );
+        ehCache.getCacheConfiguration().setMaxElementsInMemory( 2 );
+        ehCache.getCacheConfiguration().setTimeToLiveSeconds( 1 );
+        ehCache.getCacheConfiguration().setTimeToIdleSeconds( 1 );
+        ehCache.getCacheConfiguration().setDiskExpiryThreadIntervalSeconds( 1 );
+
+        ReplayCacheImpl cache = new ReplayCacheImpl( ehCache, clockSkew );
+
         int i = 0;
-        int nbClient = 20;
-        int nbServer = 10;
-        
-        // Inject 100 entries, one every 20 ms
-        while ( i < 100 )
+
+        // Inject 4 entries one every second 
+        while ( i < 4 )
         {
-            KerberosPrincipal serverPrincipal = new KerberosPrincipal( "server" + i%nbServer + "@APACHE.ORG", PrincipalNameType.KRB_NT_PRINCIPAL.getValue() );
-            KerberosPrincipal clientPrincipal = new KerberosPrincipal( "client" + i%nbClient + "@APACHE.ORG", PrincipalNameType.KRB_NT_PRINCIPAL.getValue() );
-            
+            KerberosPrincipal serverPrincipal = new KerberosPrincipal( "server" + i + "@APACHE.ORG",
+                PrincipalNameType.KRB_NT_PRINCIPAL.getValue() );
+            KerberosPrincipal clientPrincipal = new KerberosPrincipal( "client" + i + "@APACHE.ORG",
+                PrincipalNameType.KRB_NT_PRINCIPAL.getValue() );
+
             cache.save( serverPrincipal, clientPrincipal, new KerberosTime( System.currentTimeMillis() ), 0 );
-            
-            Thread.sleep( 20 );
+
             i++;
         }
-        
-        Map<KerberosPrincipal, List<ReplayCacheEntry>> map = cache.getCache();
 
-        // We should have 20 List of entries, as we have injected 20 different
-        // clientPrincipals
-        assertEquals( nbClient, map.size() );
-        
-        int nbEntries = 0;
-        
-        // Loop into the cache to see how many entries we have
-        Collection<List<ReplayCacheEntry>> entryList = map.values();
-        
-        for ( List<ReplayCacheEntry> entries:entryList )
-        {
-            if ( ( entries == null ) || ( entries.size() == 0 ) )
-            {
-                continue;
-            }
-            
-            Iterator<ReplayCacheEntry> iterator = entries.iterator();
-            
-            while ( iterator.hasNext() )
-            {
-                iterator.next();
-                nbEntries ++;
-            }
-        }
+        List keys = ehCache.getKeys();
+
+        // We should have 4 entries
+        assertEquals( 4, keys.size() );
 
-        // We should have some
-        assertNotNull( nbEntries );
-        assertTrue(nbEntries > 0);
-        
-        // Wait another delay, so that the cleaning thread will be kicked off
-        Thread.sleep( delay + 50 );
-        // It's not guaranteed that the thread run, so invoke the method manually
-        cache.cleanCache();
-        
-        nbEntries = 0;
-        
-        for ( List<ReplayCacheEntry> entries:entryList )
+        // Wait till the timetolive time exceeds 
+        Thread.sleep( 1000 );
+
+        // then access the cache so that the objects present in the cache will be expired
+        for ( Object k : keys )
         {
-            if ( ( entries == null ) || ( entries.size() == 0 ) )
-            {
-                continue;
-            }
-            
-            Iterator<ReplayCacheEntry> iterator = entries.iterator();
-            
-            while ( iterator.hasNext() )
-            {
-                iterator.next();
-                nbEntries ++;
-            }
+            assertNull( ehCache.get( k ) );
         }
 
-        // We should not have anymore entry in the cache
-        assertEquals( 0, nbEntries );
-
-        // Stop background thread
-        cache.interrupt();
+        assertEquals( 0, ehCache.getKeys().size() );
     }
 }

Modified: directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/ChangePasswordServer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/ChangePasswordServer.java?rev=1042145&r1=1042144&r2=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/ChangePasswordServer.java (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/ChangePasswordServer.java Sat Dec  4 11:21:18 2010
@@ -26,8 +26,12 @@ import java.util.List;
 
 import javax.security.auth.kerberos.KerberosPrincipal;
 
+import net.sf.ehcache.Cache;
+
 import org.apache.directory.server.changepw.protocol.ChangePasswordProtocolHandler;
 import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.kerberos.shared.replay.ReplayCacheImpl;
+import org.apache.directory.server.kerberos.shared.replay.ReplayCache;
 import org.apache.directory.server.kerberos.shared.store.DirectoryPrincipalStore;
 import org.apache.directory.server.kerberos.shared.store.PrincipalStore;
 import org.apache.directory.server.protocol.shared.DirectoryBackedService;
@@ -114,6 +118,8 @@ public class ChangePasswordServer extend
     /** The policy for token size. */
     private int policyTokenSize;
 
+    /** the cache used for storing change password requests */
+    private ReplayCache replayCache;
 
     /**
      * Creates a new instance of ChangePasswordConfiguration.
@@ -268,6 +274,11 @@ public class ChangePasswordServer extend
     {
         PrincipalStore store = new DirectoryPrincipalStore( getDirectoryService(), new DN(this.getSearchBaseDn())  );
         
+        LOG.debug( "initializing the changepassword replay cache" );
+
+        Cache cache = getDirectoryService().getCacheService().getCache( "changePwdReplayCache" );
+        replayCache = new ReplayCacheImpl( cache );
+
         if ( ( transports == null ) || ( transports.size() == 0 ) )
         {
             // Default to UDP with port 464
@@ -334,6 +345,8 @@ public class ChangePasswordServer extend
             }
         }
 
+        replayCache.clear();
+        
         LOG.info( "ChangePassword service stopped." );
         //System.out.println( "ChangePassword service stopped." );
     }
@@ -393,6 +406,15 @@ public class ChangePasswordServer extend
     
     
     /**
+     * @return the replayCache
+     */
+    public ReplayCache getReplayCache()
+    {
+        return replayCache;
+    }
+
+
+    /**
      * @see Object#toString()
      */
     public String toString()

Modified: directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/service/ChangePasswordContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/service/ChangePasswordContext.java?rev=1042145&r1=1042144&r2=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/service/ChangePasswordContext.java (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/service/ChangePasswordContext.java Sat Dec  4 11:21:18 2010
@@ -50,30 +50,11 @@ public class ChangePasswordContext
     private Ticket ticket;
     private Authenticator authenticator;
     private PrincipalStoreEntry serverEntry;
-    private ReplayCache replayCache;
     private CipherTextHandler cipherTextHandler;
     private String password;
 
 
     /**
-     * @return Returns the replayCache.
-     */
-    public ReplayCache getReplayCache()
-    {
-        return replayCache;
-    }
-
-
-    /**
-     * @param replayCache The replayCache to set.
-     */
-    public void setReplayCache( ReplayCache replayCache )
-    {
-        this.replayCache = replayCache;
-    }
-
-
-    /**
      * @return Returns the serverEntry.
      */
     public PrincipalStoreEntry getServerEntry()

Modified: directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/service/ChangePasswordService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/service/ChangePasswordService.java?rev=1042145&r1=1042144&r2=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/service/ChangePasswordService.java (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-changepw/src/main/java/org/apache/directory/server/changepw/service/ChangePasswordService.java Sat Dec  4 11:21:18 2010
@@ -43,7 +43,6 @@ import org.apache.directory.server.kerbe
 import org.apache.directory.server.kerberos.shared.messages.ApplicationRequest;
 import org.apache.directory.server.kerberos.shared.messages.application.ApplicationReply;
 import org.apache.directory.server.kerberos.shared.messages.application.PrivateMessage;
-import org.apache.directory.server.kerberos.shared.replay.InMemoryReplayCache;
 import org.apache.directory.server.kerberos.shared.replay.ReplayCache;
 import org.apache.directory.server.kerberos.shared.store.PrincipalStore;
 import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntry;
@@ -66,11 +65,8 @@ public class ChangePasswordService
     /** the logger for this class */
     private static final Logger LOG = LoggerFactory.getLogger( ChangePasswordService.class );
 
-    private static final ReplayCache replayCache = new InMemoryReplayCache();
-    
     private static final CipherTextHandler cipherTextHandler = new CipherTextHandler();
 
-    
     public static void execute( IoSession session, ChangePasswordContext changepwContext ) throws KerberosException, IOException
     {
         if ( LOG.isDebugEnabled() )
@@ -152,7 +148,6 @@ public class ChangePasswordService
     
     private static void configureChangePassword( ChangePasswordContext changepwContext )
     {
-        changepwContext.setReplayCache( replayCache );
         changepwContext.setCipherTextHandler( cipherTextHandler );
     }
     
@@ -212,7 +207,7 @@ public class ChangePasswordService
         EncryptionKey serverKey = changepwContext.getServerEntry().getKeyMap().get( encryptionType );
 
         long clockSkew = changepwContext.getConfig().getAllowableClockSkew();
-        ReplayCache replayCache = changepwContext.getReplayCache();
+        ReplayCache replayCache = changepwContext.getConfig().getReplayCache();
         boolean emptyAddressesAllowed = changepwContext.getConfig().isEmptyAddressesAllowed();
         InetAddress clientAddress = changepwContext.getClientAddress();
         CipherTextHandler cipherTextHandler = changepwContext.getCipherTextHandler();
@@ -294,7 +289,7 @@ public class ChangePasswordService
             PrincipalStore store = changepwContext.getStore();
             ApplicationRequest authHeader = changepwContext.getAuthHeader();
             Ticket ticket = changepwContext.getTicket();
-            ReplayCache replayCache = changepwContext.getReplayCache();
+            ReplayCache replayCache = changepwContext.getConfig().getReplayCache();
             long clockSkew = changepwContext.getConfig().getAllowableClockSkew();
 
             Authenticator authenticator = changepwContext.getAuthenticator();

Modified: directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/KdcServer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/KdcServer.java?rev=1042145&r1=1042144&r2=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/KdcServer.java (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/KdcServer.java Sat Dec  4 11:21:18 2010
@@ -26,9 +26,13 @@ import java.util.Set;
 
 import javax.security.auth.kerberos.KerberosPrincipal;
 
+import net.sf.ehcache.Cache;
+
 import org.apache.directory.server.constants.ServerDNConstants;
 import org.apache.directory.server.kerberos.protocol.KerberosProtocolHandler;
 import org.apache.directory.server.kerberos.protocol.KerberosUdpProtocolCodecFactory;
+import org.apache.directory.server.kerberos.shared.replay.ReplayCacheImpl;
+import org.apache.directory.server.kerberos.shared.replay.ReplayCache;
 import org.apache.directory.server.kerberos.shared.store.DirectoryPrincipalStore;
 import org.apache.directory.server.kerberos.shared.store.PrincipalStore;
 import org.apache.directory.server.protocol.shared.DirectoryBackedService;
@@ -149,6 +153,8 @@ public class KdcServer extends Directory
     /** Whether to verify the body checksum. */
     private boolean isBodyChecksumVerified = DEFAULT_VERIFY_BODY_CHECKSUM;
 
+    /** the cache used for storing AS and TGS requests */
+    private ReplayCache replayCache;
 
     /**
      * Creates a new instance of KdcConfiguration.
@@ -429,6 +435,15 @@ public class KdcServer extends Directory
 
 
     /**
+     * @return the replayCache
+     */
+    public ReplayCache getReplayCache()
+    {
+        return replayCache;
+    }
+
+
+    /**
      * @throws IOException if we cannot bind to the sockets
      */
     public void start() throws IOException, LdapInvalidDnException
@@ -438,6 +453,11 @@ public class KdcServer extends Directory
         // TODO - for now ignoring this catalog crap
         store = new DirectoryPrincipalStore( getDirectoryService(), new DN(this.getSearchBaseDn())  );
         
+        LOG.debug( "initializing the kerberos replay cache" );
+
+        Cache cache = getDirectoryService().getCacheService().getCache( "kdcReplayCache" );
+        replayCache = new ReplayCacheImpl( cache, allowableClockSkew );
+        
         if ( ( transports == null ) || ( transports.size() == 0 ) )
         {
             // Default to UDP with port 88
@@ -517,6 +537,8 @@ public class KdcServer extends Directory
             }
         }
         
+        replayCache.clear();
+        
         LOG.info( "Kerberos service stopped." );
     }
 

Modified: directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/authentication/AuthenticationContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/authentication/AuthenticationContext.java?rev=1042145&r1=1042144&r2=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/authentication/AuthenticationContext.java (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/authentication/AuthenticationContext.java Sat Dec  4 11:21:18 2010
@@ -102,24 +102,6 @@ public class AuthenticationContext exten
 
 
     /**
-     * @return Returns the replayCache.
-     */
-    public ReplayCache getReplayCache()
-    {
-        return replayCache;
-    }
-
-
-    /**
-     * @param replayCache The replayCache to set.
-     */
-    public void setReplayCache( ReplayCache replayCache )
-    {
-        this.replayCache = replayCache;
-    }
-
-
-    /**
      * @return Returns the clientKey.
      */
     public EncryptionKey getClientKey()

Modified: directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/authentication/AuthenticationService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/authentication/AuthenticationService.java?rev=1042145&r1=1042144&r2=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/authentication/AuthenticationService.java (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/authentication/AuthenticationService.java Sat Dec  4 11:21:18 2010
@@ -43,8 +43,6 @@ import org.apache.directory.server.kerbe
 import org.apache.directory.server.kerberos.shared.io.decoder.EncryptedDataDecoder;
 import org.apache.directory.server.kerberos.shared.messages.AuthenticationReply;
 import org.apache.directory.server.kerberos.shared.messages.KdcReply;
-import org.apache.directory.server.kerberos.shared.replay.InMemoryReplayCache;
-import org.apache.directory.server.kerberos.shared.replay.ReplayCache;
 import org.apache.directory.server.kerberos.shared.store.PrincipalStore;
 import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntry;
 import org.apache.directory.shared.asn1.codec.EncoderException;
@@ -83,7 +81,6 @@ public class AuthenticationService
     /** The log for this class. */
     private static final Logger LOG = LoggerFactory.getLogger( AuthenticationService.class );
 
-    private static final ReplayCache replayCache = new InMemoryReplayCache();
     private static final CipherTextHandler cipherTextHandler = new CipherTextHandler();
 
     private static final String SERVICE_NAME = "Authentication Service (AS)";
@@ -96,7 +93,6 @@ public class AuthenticationService
             monitorRequest( authContext );
         }
         
-        authContext.setReplayCache( replayCache );
         authContext.setCipherTextHandler( cipherTextHandler );
 
         if ( authContext.getRequest().getProtocolVersionNumber() != KerberosConstants.KERBEROS_V5 )

Modified: directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingContext.java?rev=1042145&r1=1042144&r2=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingContext.java (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingContext.java Sat Dec  4 11:21:18 2010
@@ -39,7 +39,6 @@ public class TicketGrantingContext exten
     private Ticket tgt;
     private Ticket newTicket;
     private Authenticator authenticator;
-    private ReplayCache replayCache;
 
     private PrincipalStoreEntry ticketPrincipalEntry;
     private PrincipalStoreEntry requestPrincipalEntry;
@@ -82,24 +81,6 @@ public class TicketGrantingContext exten
 
 
     /**
-     * @return Returns the replayCache.
-     */
-    public ReplayCache getReplayCache()
-    {
-        return replayCache;
-    }
-
-
-    /**
-     * @param replayCache The replayCache to set.
-     */
-    public void setReplayCache( ReplayCache replayCache )
-    {
-        this.replayCache = replayCache;
-    }
-
-
-    /**
      * @return Returns the authenticator.
      */
     public Authenticator getAuthenticator()

Modified: directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingService.java?rev=1042145&r1=1042144&r2=1042145&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingService.java (original)
+++ directory/apacheds/branches/apacheds-kerberos-codec-2.0/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/kdc/ticketgrant/TicketGrantingService.java Sat Dec  4 11:21:18 2010
@@ -42,7 +42,7 @@ import org.apache.directory.server.kerbe
 import org.apache.directory.server.kerberos.shared.messages.KdcReply;
 import org.apache.directory.server.kerberos.shared.messages.TicketGrantReply;
 import org.apache.directory.server.kerberos.shared.messages.components.EncTicketPartModifier;
-import org.apache.directory.server.kerberos.shared.replay.InMemoryReplayCache;
+import org.apache.directory.server.kerberos.shared.replay.ReplayCacheImpl;
 import org.apache.directory.server.kerberos.shared.replay.ReplayCache;
 import org.apache.directory.server.kerberos.shared.store.PrincipalStore;
 import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntry;
@@ -79,7 +79,6 @@ public class TicketGrantingService
     /** the log for this class */
     private static final Logger LOG = LoggerFactory.getLogger( TicketGrantingService.class );
     
-    private static final InMemoryReplayCache replayCache = new InMemoryReplayCache();
     private static final CipherTextHandler cipherTextHandler = new CipherTextHandler();
 
     private static final String SERVICE_NAME = "Ticket-Granting Service (TGS)";
@@ -116,11 +115,6 @@ public class TicketGrantingService
     
     private static void configureTicketGranting( TicketGrantingContext tgsContext ) throws KerberosException
     {
-        KdcServer config = tgsContext.getConfig();
-        long clockSkew = config.getAllowableClockSkew();
-        replayCache.setClockSkew( clockSkew );
-        tgsContext.setReplayCache( replayCache );
-
         tgsContext.setCipherTextHandler( cipherTextHandler );
 
         if ( tgsContext.getRequest().getProtocolVersionNumber() != KerberosConstants.KERBEROS_V5 )
@@ -266,7 +260,7 @@ public class TicketGrantingService
         EncryptionKey serverKey = tgsContext.getTicketPrincipalEntry().getKeyMap().get( encryptionType );
 
         long clockSkew = tgsContext.getConfig().getAllowableClockSkew();
-        ReplayCache replayCache = tgsContext.getReplayCache();
+        ReplayCache replayCache = tgsContext.getConfig().getReplayCache();
         boolean emptyAddressesAllowed = tgsContext.getConfig().isEmptyAddressesAllowed();
         InetAddress clientAddress = tgsContext.getClientAddress();
         CipherTextHandler cipherTextHandler = tgsContext.getCipherTextHandler();