[jbosscache-commits] JBoss Cache SVN: r7701 - in core/branches/flat/src: main/java/org/horizon/config and 25 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Tue Feb 17 10:29:55 EST 2009


Author: manik.surtani at jboss.com
Date: 2009-02-17 10:29:55 -0500 (Tue, 17 Feb 2009)
New Revision: 7701

Added:
   core/branches/flat/src/main/java/org/horizon/interceptors/ActivationInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/PassivationInterceptor.java
   core/branches/flat/src/test/java/org/horizon/loader/PassivationFunctionalTest.java
   core/branches/flat/src/test/java/org/horizon/loader/decorators/ChainingCacheLoaderTest.java
Removed:
   core/branches/flat/src/main/java/org/horizon/annotations/
   core/branches/flat/src/main/java/org/horizon/notifications/Notifier.java
   core/branches/flat/src/test/java/org/horizon/notifications/CacheListenerPassivationTest.java
Modified:
   core/branches/flat/src/main/java/org/horizon/config/CacheLoaderManagerConfig.java
   core/branches/flat/src/main/java/org/horizon/config/Configuration.java
   core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java
   core/branches/flat/src/main/java/org/horizon/config/parsing/element/LoadersElementParser.java
   core/branches/flat/src/main/java/org/horizon/factories/InterceptorChainFactory.java
   core/branches/flat/src/main/java/org/horizon/interceptors/CacheLoaderInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/CacheMgmtInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/CacheStoreInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/InvalidationInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java
   core/branches/flat/src/main/java/org/horizon/interceptors/base/JmxStatsCommandInterceptor.java
   core/branches/flat/src/main/java/org/horizon/jmx/JmxStatisticsExposer.java
   core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheLoaderConfig.java
   core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheStore.java
   core/branches/flat/src/main/java/org/horizon/loader/CacheLoaderManagerImpl.java
   core/branches/flat/src/main/java/org/horizon/loader/CacheStore.java
   core/branches/flat/src/main/java/org/horizon/loader/StoredEntry.java
   core/branches/flat/src/main/java/org/horizon/loader/decorators/ChainingCacheLoader.java
   core/branches/flat/src/main/java/org/horizon/loader/jdbc/JDBCCacheLoader.java
   core/branches/flat/src/main/java/org/horizon/remoting/RPCManagerImpl.java
   core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java
   core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java
   core/branches/flat/src/test/java/org/horizon/api/tree/NodeReplicatedMoveTest.java
   core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java
   core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTxTest.java
   core/branches/flat/src/test/java/org/horizon/atomic/ClusteredAPITest.java
   core/branches/flat/src/test/java/org/horizon/config/parsing/ConfigurationParserTest.java
   core/branches/flat/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java
   core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java
   core/branches/flat/src/test/java/org/horizon/loader/BaseCacheLoaderTest.java
   core/branches/flat/src/test/java/org/horizon/loader/CacheLoaderFunctionalTest.java
   core/branches/flat/src/test/java/org/horizon/loader/decorators/SingletonStoreTest.java
   core/branches/flat/src/test/java/org/horizon/loader/dummy/DummyInMemoryCacheLoader.java
   core/branches/flat/src/test/java/org/horizon/marshall/MarshalledValueTest.java
   core/branches/flat/src/test/java/org/horizon/notifications/CacheListenerCacheLoaderTest.java
   core/branches/flat/src/test/java/org/horizon/replication/AsyncReplTest.java
   core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java
   core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java
   core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java
   core/branches/flat/src/test/java/org/horizon/replication/SyncReplTest.java
   core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java
Log:
Finished cache loaders, passivation, etc

Modified: core/branches/flat/src/main/java/org/horizon/config/CacheLoaderManagerConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/CacheLoaderManagerConfig.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/config/CacheLoaderManagerConfig.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -29,7 +29,7 @@
 
 /**
  * Holds the configuration of the cache loader chain.  ALL cache loaders should be defined using this class, adding
- * individual cache loaders to the chain by calling {@link CacheLoaderManagerConfig#addIndividualCacheLoaderConfig}
+ * individual cache loaders to the chain by calling {@link CacheLoaderManagerConfig#addCacheLoaderConfig}
  *
  * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  * @author Brian Stansberry
@@ -59,16 +59,16 @@
       return passivation;
    }
 
-   public void addIndividualCacheLoaderConfig(CacheLoaderConfig clc) {
+   public void addCacheLoaderConfig(CacheLoaderConfig clc) {
       testImmutability("cacheLoaderConfigs");
       cacheLoaderConfigs.add(clc);
    }
 
-   public List<CacheLoaderConfig> getIndividualCacheLoaderConfigs() {
+   public List<CacheLoaderConfig> getCacheLoaderConfigs() {
       return cacheLoaderConfigs;
    }
 
-   public void setIndividualCacheLoaderConfigs(List<CacheLoaderConfig> configs) {
+   public void setCacheLoaderConfigs(List<CacheLoaderConfig> configs) {
       testImmutability("cacheLoaderConfigs");
       this.cacheLoaderConfigs = configs == null ? new LinkedList<CacheLoaderConfig>() : configs;
    }
@@ -130,7 +130,7 @@
          for (CacheLoaderConfig clc : cacheLoaderConfigs) {
             clcs.add(clc.clone());
          }
-         clone.setIndividualCacheLoaderConfigs(clcs);
+         clone.setCacheLoaderConfigs(clcs);
       }
       return clone;
    }

Modified: core/branches/flat/src/main/java/org/horizon/config/Configuration.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/Configuration.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/config/Configuration.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -120,7 +120,7 @@
    private IsolationLevel isolationLevel = IsolationLevel.READ_COMMITTED;
    private EvictionConfig evictionConfig = null;
    private String transactionManagerLookupClass = null;
-   private CacheLoaderManagerConfig cacheLoaderConfig = null;
+   private CacheLoaderManagerConfig cacheLoaderManagerConfig = null;
    @Dynamic
    private boolean syncCommitPhase = false;
    @Dynamic
@@ -260,9 +260,9 @@
       this.transactionManagerLookupClass = transactionManagerLookupClass;
    }
 
-   public void setCacheLoaderConfig(CacheLoaderManagerConfig config) {
-      testImmutability("cacheLoaderConfig");
-      this.cacheLoaderConfig = config;
+   public void setCacheLoaderManagerConfig(CacheLoaderManagerConfig cacheLoaderManagerConfig) {
+      testImmutability("cacheLoaderManagerConfig");
+      this.cacheLoaderManagerConfig = cacheLoaderManagerConfig;
    }
 
    public void setSyncCommitPhase(boolean syncCommitPhase) {
@@ -367,8 +367,8 @@
       return transactionManagerLookupClass;
    }
 
-   public CacheLoaderManagerConfig getCacheLoaderConfig() {
-      return cacheLoaderConfig;
+   public CacheLoaderManagerConfig getCacheLoaderManagerConfig() {
+      return cacheLoaderManagerConfig;
    }
 
    public boolean isSyncCommitPhase() {
@@ -413,7 +413,7 @@
       if (syncRollbackPhase != that.syncRollbackPhase) return false;
       if (useLazyDeserialization != that.useLazyDeserialization) return false;
       if (useReplQueue != that.useReplQueue) return false;
-      if (cacheLoaderConfig != null ? !cacheLoaderConfig.equals(that.cacheLoaderConfig) : that.cacheLoaderConfig != null)
+      if (cacheLoaderManagerConfig != null ? !cacheLoaderManagerConfig.equals(that.cacheLoaderManagerConfig) : that.cacheLoaderManagerConfig != null)
          return false;
       if (cacheMode != that.cacheMode) return false;
       if (evictionConfig != null ? !evictionConfig.equals(that.evictionConfig) : that.evictionConfig != null)
@@ -440,7 +440,7 @@
       result = 31 * result + (isolationLevel != null ? isolationLevel.hashCode() : 0);
       result = 31 * result + (evictionConfig != null ? evictionConfig.hashCode() : 0);
       result = 31 * result + (transactionManagerLookupClass != null ? transactionManagerLookupClass.hashCode() : 0);
-      result = 31 * result + (cacheLoaderConfig != null ? cacheLoaderConfig.hashCode() : 0);
+      result = 31 * result + (cacheLoaderManagerConfig != null ? cacheLoaderManagerConfig.hashCode() : 0);
       result = 31 * result + (syncCommitPhase ? 1 : 0);
       result = 31 * result + (syncRollbackPhase ? 1 : 0);
       result = 31 * result + (useLazyDeserialization ? 1 : 0);
@@ -455,8 +455,8 @@
          if (evictionConfig != null) {
             c.setEvictionConfig(evictionConfig.clone());
          }
-         if (cacheLoaderConfig != null) {
-            c.setCacheLoaderConfig(cacheLoaderConfig.clone());
+         if (cacheLoaderManagerConfig != null) {
+            c.setCacheLoaderManagerConfig(cacheLoaderManagerConfig.clone());
          }
          return c;
       }
@@ -466,7 +466,7 @@
    }
 
    public boolean isUsingCacheLoaders() {
-      return getCacheLoaderConfig() != null && !getCacheLoaderConfig().getIndividualCacheLoaderConfigs().isEmpty();
+      return getCacheLoaderManagerConfig() != null && !getCacheLoaderManagerConfig().getCacheLoaderConfigs().isEmpty();
    }
 
    /**

Modified: core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/config/parsing/XmlConfigurationParserImpl.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -243,7 +243,7 @@
       if (element == null) return; //null cache loaders are allowed
       LoadersElementParser clElementParser = new LoadersElementParser();
       CacheLoaderManagerConfig cacheLoaderConfig = clElementParser.parseLoadersElement(element);
-      config.setCacheLoaderConfig(cacheLoaderConfig);
+      config.setCacheLoaderManagerConfig(cacheLoaderConfig);
    }
 
    void configureEviction(Element evictionElement, Configuration config) {

Modified: core/branches/flat/src/main/java/org/horizon/config/parsing/element/LoadersElementParser.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/config/parsing/element/LoadersElementParser.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/config/parsing/element/LoadersElementParser.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -57,7 +57,7 @@
       for (int i = 0; i < cacheLoaderNodes.getLength(); i++) {
          Element indivElement = (Element) cacheLoaderNodes.item(i);
          CacheLoaderConfig iclc = parseIndividualCacheLoaderConfig(indivElement);
-         cacheLoaderConfig.addIndividualCacheLoaderConfig(iclc);
+         cacheLoaderConfig.addCacheLoaderConfig(iclc);
       }
       return cacheLoaderConfig;
    }

Modified: core/branches/flat/src/main/java/org/horizon/factories/InterceptorChainFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/factories/InterceptorChainFactory.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/factories/InterceptorChainFactory.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -84,7 +84,6 @@
 
       interceptorChain.appendIntereceptor(createInterceptor(NotificationInterceptor.class));
 
-//       TODO: Uncomment once the Repl and Inval interceptors has been moved to Starobrno
       switch (configuration.getCacheMode()) {
          case REPL_SYNC:
          case REPL_ASYNC:
@@ -98,30 +97,22 @@
             //Nothing...
       }
 
-      // TODO: Uncomment once the CacheLoaderOld has been moved to Starobrno
       if (configuration.isUsingCacheLoaders()) {
-//         if (configuration.getCacheLoaderConfig().isPassivation())
-//         {
-//            interceptorChain.appendIntereceptor(createInterceptor(ActivationInterceptor.class));
-//         }
-//         else
-         {
+         if (configuration.getCacheLoaderManagerConfig().isPassivation()) {
+            interceptorChain.appendIntereceptor(createInterceptor(ActivationInterceptor.class));
+         } else {
             interceptorChain.appendIntereceptor(createInterceptor(CacheLoaderInterceptor.class));
          }
       }
       interceptorChain.appendIntereceptor(createInterceptor(LockingInterceptor.class));
 
-      // TODO: Uncomment once the CacheLoaderOld has been moved to Starobrno
       if (configuration.isUsingCacheLoaders()) {
-//         if (configuration.getCacheLoaderConfig().isPassivation())
-//         {
-//
-//            interceptorChain.appendIntereceptor(createInterceptor(PassivationInterceptor.class));
-//
-//         }
-//         else
-         {
+         if (configuration.getCacheLoaderManagerConfig().isPassivation()) {
 
+            interceptorChain.appendIntereceptor(createInterceptor(PassivationInterceptor.class));
+
+         } else {
+
             interceptorChain.appendIntereceptor(createInterceptor(CacheStoreInterceptor.class));
 
          }

Added: core/branches/flat/src/main/java/org/horizon/interceptors/ActivationInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/ActivationInterceptor.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/ActivationInterceptor.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -0,0 +1,89 @@
+package org.horizon.interceptors;
+
+import org.horizon.commands.read.GetKeyValueCommand;
+import org.horizon.commands.write.PutKeyValueCommand;
+import org.horizon.commands.write.PutMapCommand;
+import org.horizon.commands.write.RemoveCommand;
+import org.horizon.commands.write.ReplaceCommand;
+import org.horizon.config.ConfigurationException;
+import org.horizon.context.InvocationContext;
+import org.horizon.factories.annotations.Start;
+import org.horizon.jmx.annotations.ManagedAttribute;
+import org.horizon.jmx.annotations.ManagedOperation;
+import org.horizon.loader.CacheStore;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+public class ActivationInterceptor extends CacheLoaderInterceptor {
+
+   private AtomicLong activations = new AtomicLong(0);
+   private CacheStore store;
+
+   @Start(priority = 15)
+   public void setCacheStore() {
+      store = clm == null ? null : clm.getCacheStore();
+      if (store == null)
+         throw new ConfigurationException("passivation can only be used with a CacheLoader that implements CacheStore!");
+   }
+
+   @Override
+   public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
+      Object retval = super.visitPutKeyValueCommand(ctx, command);
+      removeFromStore(command.getKey());
+      return retval;
+   }
+
+   @Override
+   public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
+      Object retval = super.visitRemoveCommand(ctx, command);
+      removeFromStore(command.getKey());
+      return retval;
+   }
+
+   @Override
+   public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command) throws Throwable {
+      Object retval = super.visitReplaceCommand(ctx, command);
+      removeFromStore(command.getKey());
+      return retval;
+   }
+
+
+   @Override
+   public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable {
+      Object retval = super.visitPutMapCommand(ctx, command);
+      removeFromStore(command.getMap().keySet().toArray());
+      return retval;
+   }
+
+   // read commands
+
+   @Override
+   public Object visitGetKeyValueCommand(InvocationContext ctx, GetKeyValueCommand command) throws Throwable {
+      Object retval = super.visitGetKeyValueCommand(ctx, command);
+      removeFromStore(command.getKey());
+      return retval;
+   }
+
+   private void removeFromStore(Object... keys) {
+      for (Object k : keys) store.remove(k);
+   }
+
+   @Override
+   protected void sendNotification(Object key, boolean pre, InvocationContext ctx) {
+      super.sendNotification(key, pre, ctx);
+      notifier.notifyCacheEntryActivated(key, pre, ctx);
+   }
+
+   @ManagedAttribute(description = "number of activation events")
+   public long getActivations() {
+      return activations.get();
+   }
+
+   @ManagedOperation
+   public void resetStatistics() {
+      super.resetStatistics();
+      activations.set(0);
+   }
+}
+
+

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/CacheLoaderInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/CacheLoaderInterceptor.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/CacheLoaderInterceptor.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -21,8 +21,6 @@
  */
 package org.horizon.interceptors;
 
-import org.horizon.annotations.ManagedAttribute;
-import org.horizon.annotations.ManagedOperation;
 import org.horizon.commands.read.GetKeyValueCommand;
 import org.horizon.commands.write.InvalidateCommand;
 import org.horizon.commands.write.PutKeyValueCommand;
@@ -35,52 +33,36 @@
 import org.horizon.factories.annotations.Inject;
 import org.horizon.factories.annotations.Start;
 import org.horizon.interceptors.base.JmxStatsCommandInterceptor;
+import org.horizon.jmx.annotations.ManagedAttribute;
+import org.horizon.jmx.annotations.ManagedOperation;
 import org.horizon.loader.CacheLoader;
 import org.horizon.loader.CacheLoaderManager;
 import org.horizon.loader.StoredEntry;
 import org.horizon.notifications.cachelistener.CacheNotifier;
-import org.horizon.transaction.TransactionTable;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
 
-/**
- * Loads nodes that don't exist at the time of the call into memory from the CacheLoader
- *
- * @author Bela Ban
- * @since 1.0
- */
 public class CacheLoaderInterceptor extends JmxStatsCommandInterceptor {
-   private long cacheLoads = 0;
-   private long cacheMisses = 0;
-   private CacheLoaderManager clm;
+   private final AtomicLong cacheLoads = new AtomicLong(0);
+   private final AtomicLong cacheMisses = new AtomicLong(0);
 
-   protected TransactionTable txTable = null;
-   protected CacheLoader loader;
-   protected DataContainer dataContainer;
+   protected CacheLoaderManager clm;
    protected CacheNotifier notifier;
-   protected EntryFactory entryFactory;
+   protected CacheLoader loader;
+   private DataContainer dataContainer;
+   private EntryFactory entryFactory;
 
-   protected boolean isActivation = false;
-
-
-   /**
-    * True if CacheStoreInterceptor is in place. This allows us to skip loading keys for remove(Fqn, key) and put(Fqn,
-    * key). It also affects removal of node data and listing children.
-    */
-   protected boolean useCacheStore = true;
-
    @Inject
-   protected void injectDependencies(TransactionTable txTable, CacheLoaderManager clm,
-                                     DataContainer dataContainer, EntryFactory entryFactory, CacheNotifier notifier) {
-      this.txTable = txTable;
+   protected void injectDependencies(CacheLoaderManager clm, DataContainer dataContainer, EntryFactory entryFactory, CacheNotifier notifier) {
       this.clm = clm;
       this.dataContainer = dataContainer;
       this.notifier = notifier;
       this.entryFactory = entryFactory;
    }
 
-   @Start
+   @Start(priority = 15)
    protected void startInterceptor() {
       loader = clm.getCacheLoader();
    }
@@ -148,40 +130,43 @@
 
       if (getStatisticsEnabled()) {
          if (entryExists) {
-            cacheLoads++;
+            cacheLoads.incrementAndGet();
          } else {
-            cacheMisses++;
+            cacheMisses.incrementAndGet();
          }
       }
 
       if (entryExists) {
-         notifier.notifyCacheEntryLoaded(key, true, ctx);
-         if (isActivation) notifier.notifyCacheEntryActivated(key, true, ctx);
+         sendNotification(key, true, ctx);
          entry.setValue(storedEntry.getValue());
          entry.setLifespan(storedEntry.getLifespan());
          entry.setValid(true);
 
          notifier.notifyCacheEntryLoaded(key, false, ctx);
-         if (isActivation) notifier.notifyCacheEntryActivated(key, false, ctx);
+         sendNotification(key, false, ctx);
       }
 
       return entry;
    }
 
+   protected void sendNotification(Object key, boolean pre, InvocationContext ctx) {
+      notifier.notifyCacheEntryLoaded(key, pre, ctx);
+   }
+
    @ManagedAttribute(description = "number of cache loader node loads")
    public long getCacheLoaderLoads() {
-      return cacheLoads;
+      return cacheLoads.get();
    }
 
    @ManagedAttribute(description = "number of cache loader node misses")
    public long getCacheLoaderMisses() {
-      return cacheMisses;
+      return cacheMisses.get();
    }
 
    @ManagedOperation
    public void resetStatistics() {
-      cacheLoads = 0;
-      cacheMisses = 0;
+      cacheLoads.set(0);
+      cacheMisses.set(0);
    }
 
    @ManagedOperation

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/CacheMgmtInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/CacheMgmtInterceptor.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/CacheMgmtInterceptor.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -21,8 +21,6 @@
  */
 package org.horizon.interceptors;
 
-import org.horizon.annotations.ManagedAttribute;
-import org.horizon.annotations.ManagedOperation;
 import org.horizon.commands.read.GetKeyValueCommand;
 import org.horizon.commands.write.EvictCommand;
 import org.horizon.commands.write.PutKeyValueCommand;
@@ -31,9 +29,11 @@
 import org.horizon.context.InvocationContext;
 import org.horizon.factories.annotations.Inject;
 import org.horizon.interceptors.base.JmxStatsCommandInterceptor;
+import org.horizon.jmx.annotations.ManagedAttribute;
+import org.horizon.jmx.annotations.ManagedOperation;
 
-import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * Captures cache management statistics
@@ -42,15 +42,15 @@
  * @since 1.0
  */
 public class CacheMgmtInterceptor extends JmxStatsCommandInterceptor {
-   private long hitTimes = 0;
-   private long missTimes = 0;
-   private long storeTimes = 0;
-   private long hits = 0;
-   private long misses = 0;
-   private long stores = 0;
-   private long evictions = 0;
-   private long start = System.currentTimeMillis();
-   private long reset = start;
+   private AtomicLong hitTimes = new AtomicLong(0);
+   private AtomicLong missTimes = new AtomicLong(0);
+   private AtomicLong storeTimes = new AtomicLong(0);
+   private AtomicLong hits = new AtomicLong(0);
+   private AtomicLong misses = new AtomicLong(0);
+   private AtomicLong stores = new AtomicLong(0);
+   private AtomicLong evictions = new AtomicLong(0);
+   private AtomicLong start = new AtomicLong(System.currentTimeMillis());
+   private AtomicLong reset = new AtomicLong(start.get());
 
    private DataContainer dataContainer;
 
@@ -62,7 +62,7 @@
    @Override
    public Object visitEvictCommand(InvocationContext ctx, EvictCommand command) throws Throwable {
       Object returnValue = invokeNextInterceptor(ctx, command);
-      evictions++;
+      evictions.incrementAndGet();
       return returnValue;
    }
 
@@ -72,11 +72,11 @@
       Object retval = invokeNextInterceptor(ctx, command);
       long t2 = System.currentTimeMillis();
       if (retval == null) {
-         missTimes = missTimes + (t2 - t1);
-         misses++;
+         missTimes.getAndAdd(t2 - t1);
+         misses.incrementAndGet();
       } else {
-         hitTimes = hitTimes + (t2 - t1);
-         hits++;
+         hitTimes.getAndAdd(t2 - t1);
+         hits.incrementAndGet();
       }
       return retval;
    }
@@ -89,8 +89,8 @@
       long t2 = System.currentTimeMillis();
 
       if (data != null && data.size() > 0) {
-         storeTimes = storeTimes + (t2 - t1);
-         stores = stores + data.size();
+         storeTimes.getAndAdd(t2 - t1);
+         stores.getAndAdd(data.size());
       }
       return retval;
    }
@@ -100,59 +100,59 @@
       long t1 = System.currentTimeMillis();
       Object retval = invokeNextInterceptor(ctx, command);
       long t2 = System.currentTimeMillis();
-      storeTimes = storeTimes + (t2 - t1);
-      stores++;
+      storeTimes.getAndAdd(t2 - t1);
+      stores.incrementAndGet();
       return retval;
    }
 
    @ManagedAttribute(description = "number of cache attribute hits")
    public long getHits() {
-      return hits;
+      return hits.get();
    }
 
    @ManagedAttribute(description = "number of cache attribute misses")
    public long getMisses() {
-      return misses;
+      return misses.get();
    }
 
    @ManagedAttribute(description = "number of cache attribute put operations")
    public long getStores() {
-      return stores;
+      return stores.get();
    }
 
    @ManagedAttribute(description = "number of cache eviction operations")
    public long getEvictions() {
-      return evictions;
+      return evictions.get();
    }
 
    @ManagedAttribute(description = "hit/miss ratio for the cache")
    public double getHitMissRatio() {
-      double total = hits + misses;
+      double total = hits.get() + misses.get();
       if (total == 0)
          return 0;
-      return (hits / total);
+      return (hits.get() / total);
    }
 
    @ManagedAttribute(description = "read/writes ratio for the cache")
    public double getReadWriteRatio() {
-      if (stores == 0)
+      if (stores.get() == 0)
          return 0;
-      return (((double) (hits + misses) / (double) stores));
+      return (((double) (hits.get() + misses.get()) / (double) stores.get()));
    }
 
    @ManagedAttribute(description = "average number of milliseconds for a read operation")
    public long getAverageReadTime() {
-      long total = hits + misses;
+      long total = hits.get() + misses.get();
       if (total == 0)
          return 0;
-      return (hitTimes + missTimes) / total;
+      return (hitTimes.get() + missTimes.get()) / total;
    }
 
    @ManagedAttribute(description = "average number of milliseconds for a write operation")
    public long getAverageWriteTime() {
-      if (stores == 0)
+      if (stores.get() == 0)
          return 0;
-      return (storeTimes) / stores;
+      return (storeTimes.get()) / stores.get();
    }
 
    @ManagedAttribute(description = "number of entries in the cache")
@@ -162,41 +162,24 @@
 
    @ManagedAttribute(description = "seconds since cache started")
    public long getElapsedTime() {
-      return (System.currentTimeMillis() - start) / 1000;
+      return (System.currentTimeMillis() - start.get()) / 1000;
    }
 
    @ManagedAttribute(description = "number of seconds since the cache statistics were last reset")
    public long getTimeSinceReset() {
-      return (System.currentTimeMillis() - reset) / 1000;
+      return (System.currentTimeMillis() - reset.get()) / 1000;
    }
 
    @ManagedOperation
-   public Map<String, Object> dumpStatistics() {
-      Map<String, Object> retval = new HashMap<String, Object>();
-      retval.put("Hits", hits);
-      retval.put("Misses", misses);
-      retval.put("Stores", stores);
-      retval.put("Evictions", evictions);
-      retval.put("NumberOfEntries", dataContainer.size());
-      retval.put("ElapsedTime", getElapsedTime());
-      retval.put("TimeSinceReset", getTimeSinceReset());
-      retval.put("AverageReadTime", getAverageReadTime());
-      retval.put("AverageWriteTime", getAverageWriteTime());
-      retval.put("HitMissRatio", getHitMissRatio());
-      retval.put("ReadWriteRatio", getReadWriteRatio());
-      return retval;
-   }
-
-   @ManagedOperation
    public void resetStatistics() {
-      hits = 0;
-      misses = 0;
-      stores = 0;
-      evictions = 0;
-      hitTimes = 0;
-      missTimes = 0;
-      storeTimes = 0;
-      reset = System.currentTimeMillis();
+      hits.set(0);
+      misses.set(0);
+      stores.set(0);
+      evictions.set(0);
+      hitTimes.set(0);
+      missTimes.set(0);
+      storeTimes.set(0);
+      reset.set(System.currentTimeMillis());
    }
 }
 

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/CacheStoreInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/CacheStoreInterceptor.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/CacheStoreInterceptor.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -61,6 +61,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * Writes modifications back to the store on the way out: stores modifications back through the CacheLoader, either
@@ -74,7 +75,7 @@
    private TransactionManager txMgr = null;
    private HashMap<Transaction, Integer> txStores = new HashMap<Transaction, Integer>();
    private Map<Transaction, Set<Object>> preparingTxs = new ConcurrentHashMap<Transaction, Set<Object>>();
-   private long cacheStores = 0;
+   private final AtomicLong cacheStores = new AtomicLong(0);
    CacheStore store;
    private CacheLoaderManager loaderManager;
    private boolean statsEnabled;
@@ -90,11 +91,11 @@
       txMgr = txManager;
    }
 
-   @Start
+   @Start(priority = 15)
    protected void start() {
       store = loaderManager.getCacheStore();
       this.setStatisticsEnabled(configuration.isExposeManagementStatistics());
-      loaderConfig = configuration.getCacheLoaderConfig();
+      loaderConfig = configuration.getCacheLoaderManagerConfig();
    }
 
    /**
@@ -127,7 +128,7 @@
             if (getStatisticsEnabled()) {
                Integer puts = txStores.get(tx);
                if (puts != null) {
-                  cacheStores = cacheStores + puts;
+                  cacheStores.getAndAdd(puts);
                }
                txStores.remove(tx);
             }
@@ -196,7 +197,7 @@
       StoredEntry se = getStoredEntry(key, ctx);
       store.store(se);
       log.trace("Stored entry {0} under key {1}", se, key);
-      if (getStatisticsEnabled()) cacheStores++;
+      if (getStatisticsEnabled()) cacheStores.incrementAndGet();
 
       return returnValue;
    }
@@ -210,7 +211,7 @@
       StoredEntry se = getStoredEntry(key, ctx);
       store.store(se);
       log.trace("Stored entry {0} under key {1}", se, key);
-      if (getStatisticsEnabled()) cacheStores++;
+      if (getStatisticsEnabled()) cacheStores.incrementAndGet();
 
       return returnValue;
    }
@@ -226,7 +227,7 @@
          store.store(se);
          log.trace("Stored entry {0} under key {1}", se, key);
       }
-      if (getStatisticsEnabled()) cacheStores += map.size();
+      if (getStatisticsEnabled()) cacheStores.getAndAdd(map.size());
       return returnValue;
    }
 
@@ -311,16 +312,9 @@
 
    @ManagedOperation
    public void resetStatistics() {
-      cacheStores = 0;
+      cacheStores.set(0);
    }
 
-   @ManagedOperation
-   public Map<String, Object> dumpStatistics() {
-      Map<String, Object> retval = new HashMap<String, Object>();
-      retval.put("CacheLoaderStores", cacheStores);
-      return retval;
-   }
-
    @ManagedAttribute
    public boolean getStatisticsEnabled() {
       return statsEnabled;
@@ -333,7 +327,7 @@
 
    @ManagedAttribute(description = "number of cache loader stores")
    public long getCacheLoaderStores() {
-      return cacheStores;
+      return cacheStores.get();
    }
 
    private StoredEntry getStoredEntry(Object key, InvocationContext ctx) {

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/InvalidationInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/InvalidationInterceptor.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/InvalidationInterceptor.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -21,8 +21,6 @@
  */
 package org.horizon.interceptors;
 
-import org.horizon.annotations.ManagedAttribute;
-import org.horizon.annotations.ManagedOperation;
 import org.horizon.commands.AbstractVisitor;
 import org.horizon.commands.CommandsFactory;
 import org.horizon.commands.DataCommand;
@@ -41,6 +39,8 @@
 import org.horizon.factories.annotations.Inject;
 import org.horizon.factories.annotations.Start;
 import org.horizon.interceptors.base.BaseRpcInterceptor;
+import org.horizon.jmx.annotations.ManagedAttribute;
+import org.horizon.jmx.annotations.ManagedOperation;
 import org.horizon.transaction.GlobalTransaction;
 import org.horizon.transaction.TransactionTable;
 
@@ -52,6 +52,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
 
 
 /**
@@ -66,7 +67,7 @@
  * @since 1.0
  */
 public class InvalidationInterceptor extends BaseRpcInterceptor {
-   private long invalidations = 0;
+   private final AtomicLong invalidations = new AtomicLong(0);
    protected Map<GlobalTransaction, List<VisitableCommand>> txMods;
    private CommandsFactory commandsFactory;
    private boolean statsEnabled;
@@ -224,12 +225,12 @@
    }
 
    private void incrementInvalidations() {
-      if (getStatisticsEnabled()) invalidations++;
+      if (statsEnabled) invalidations.incrementAndGet();
    }
 
    @ManagedOperation
    public void resetStatistics() {
-      invalidations = 0;
+      invalidations.set(0);
    }
 
    @ManagedOperation
@@ -251,6 +252,6 @@
 
    @ManagedAttribute(description = "number of invalidations")
    public long getInvalidations() {
-      return invalidations;
+      return invalidations.get();
    }
 }
\ No newline at end of file

Added: core/branches/flat/src/main/java/org/horizon/interceptors/PassivationInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/PassivationInterceptor.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/PassivationInterceptor.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -0,0 +1,75 @@
+package org.horizon.interceptors;
+
+import org.horizon.commands.write.EvictCommand;
+import org.horizon.config.ConfigurationException;
+import org.horizon.container.DataContainer;
+import org.horizon.context.InvocationContext;
+import org.horizon.factories.annotations.Inject;
+import org.horizon.factories.annotations.Start;
+import org.horizon.interceptors.base.JmxStatsCommandInterceptor;
+import org.horizon.jmx.annotations.ManagedAttribute;
+import org.horizon.jmx.annotations.ManagedOperation;
+import org.horizon.loader.CacheLoaderManager;
+import org.horizon.loader.CacheStore;
+import org.horizon.notifications.cachelistener.CacheNotifier;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Writes evicted nodes back to the store on the way in through the CacheStore
+ *
+ * @since 1.0
+ */
+public class PassivationInterceptor extends JmxStatsCommandInterceptor {
+   private final AtomicLong passivations = new AtomicLong(0);
+
+   CacheStore cacheStore;
+   CacheNotifier notifier;
+   CacheLoaderManager cacheLoaderManager;
+   DataContainer dataContainer;
+
+   @Inject
+   public void setDependencies(CacheNotifier notifier, CacheLoaderManager cacheLoaderManager, DataContainer dataContainer) {
+      this.notifier = notifier;
+      this.cacheLoaderManager = cacheLoaderManager;
+      this.dataContainer = dataContainer;
+   }
+
+   @Start(priority = 15)
+   public void start() {
+      cacheStore = cacheLoaderManager == null ? null : cacheLoaderManager.getCacheStore();
+      if (cacheStore == null)
+         throw new ConfigurationException("passivation can only be used with a CacheLoader that implements CacheStore!");
+   }
+
+   @Override
+   public Object visitEvictCommand(InvocationContext ctx, EvictCommand command) throws Throwable {
+      // notify listeners that this node is about to be passivated
+      Object key = command.getKey();
+      notifier.notifyCacheEntryPassivated(key, true, ctx);
+      log.trace("Passivating entry {0}", key);
+      cacheStore.store(dataContainer.createEntryForStorage(key));
+      notifier.notifyCacheEntryPassivated(key, false, ctx);
+      if (getStatisticsEnabled()) passivations.getAndIncrement();
+      return invokeNextInterceptor(ctx, command);
+   }
+
+   @ManagedOperation
+   public void resetStatistics() {
+      passivations.set(0);
+   }
+
+   @ManagedOperation
+   public Map<String, Object> dumpStatistics() {
+      Map<String, Object> retval = new HashMap<String, Object>();
+      retval.put("Passivations", passivations.get());
+      return retval;
+   }
+
+   @ManagedAttribute(description = "Number of passivation events")
+   public long getPassivations() {
+      return passivations.get();
+   }
+}

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/TxInterceptor.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -22,8 +22,6 @@
 package org.horizon.interceptors;
 
 import org.horizon.CacheException;
-import org.horizon.annotations.ManagedAttribute;
-import org.horizon.annotations.ManagedOperation;
 import org.horizon.commands.CommandsFactory;
 import org.horizon.commands.ReplicableCommand;
 import org.horizon.commands.VisitableCommand;
@@ -37,6 +35,8 @@
 import org.horizon.factories.context.ContextFactory;
 import org.horizon.invocation.InvocationContextContainer;
 import org.horizon.invocation.Options;
+import org.horizon.jmx.annotations.ManagedAttribute;
+import org.horizon.jmx.annotations.ManagedOperation;
 import org.horizon.lock.LockManager;
 import org.horizon.manager.CacheManager;
 import org.horizon.notifications.cachelistener.CacheNotifier;
@@ -56,6 +56,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * This interceptor is the new default at the head of all interceptor chains, and makes transactional attributes
@@ -79,10 +80,9 @@
     */
    private final Set<Transaction> transactions = new ConcurrentHashSet<Transaction>();
    private final Map<Transaction, GlobalTransaction> rollbackTransactions = new ConcurrentHashMap<Transaction, GlobalTransaction>(16);
-   private long prepares = 0;
-   private long commits = 0;
-   private long rollbacks = 0;
-   protected boolean optimistic = false;
+   private final AtomicLong prepares = new AtomicLong(0);
+   private final AtomicLong commits = new AtomicLong(0);
+   private final AtomicLong rollbacks = new AtomicLong(0);
    private LockManager lockManager;
    private boolean statsEnabled;
 
@@ -109,7 +109,7 @@
       try {
          if (ctx.getGlobalTransaction().isRemote()) {
             result = handleRemotePrepare(ctx, command);
-            if (getStatisticsEnabled()) prepares++;
+            if (getStatisticsEnabled()) prepares.incrementAndGet();
          } else {
             if (trace) log.trace("received my own message (discarding it)");
             result = null;
@@ -152,7 +152,7 @@
             }
             if (log.isDebugEnabled()) log.debug(" executing commit() with local TX " + ltx + " under global tx " + gtx);
             txManager.commit();
-            if (getStatisticsEnabled()) commits++;
+            if (getStatisticsEnabled()) commits.incrementAndGet();
          }
          finally {
             //resume the old transaction if we suspended it
@@ -200,7 +200,7 @@
             }
             if (log.isDebugEnabled()) log.debug("executing with local TX " + ltx + " under global tx " + gtx);
             txManager.rollback();
-            if (getStatisticsEnabled()) rollbacks++;
+            if (getStatisticsEnabled()) rollbacks.incrementAndGet();
          }
          finally {
             //resume the old transaction if we suspended it
@@ -860,9 +860,9 @@
 
    @ManagedOperation
    public void resetStatistics() {
-      prepares = 0;
-      commits = 0;
-      rollbacks = 0;
+      prepares.set(0);
+      commits.set(0);
+      rollbacks.set(0);
    }
 
    @ManagedOperation
@@ -886,16 +886,16 @@
 
    @ManagedAttribute(description = "number of transaction prepares")
    public long getPrepares() {
-      return prepares;
+      return prepares.get();
    }
 
    @ManagedAttribute(description = "number of transaction commits")
    public long getCommits() {
-      return commits;
+      return commits.get();
    }
 
    @ManagedAttribute(description = "number of transaction rollbacks")
    public long getRollbacks() {
-      return rollbacks;
+      return rollbacks.get();
    }
 }
\ No newline at end of file

Modified: core/branches/flat/src/main/java/org/horizon/interceptors/base/JmxStatsCommandInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/interceptors/base/JmxStatsCommandInterceptor.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/interceptors/base/JmxStatsCommandInterceptor.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -21,13 +21,11 @@
  */
 package org.horizon.interceptors.base;
 
-import org.horizon.annotations.ManagedAttribute;
 import org.horizon.factories.annotations.Start;
 import org.horizon.jmx.JmxStatisticsExposer;
+import org.horizon.jmx.annotations.ManagedAttribute;
+import org.horizon.jmx.annotations.ManagedOperation;
 
-import java.util.Collections;
-import java.util.Map;
-
 /**
  * Base class for all the interceptors exposing management statistics.
  *
@@ -61,20 +59,9 @@
    }
 
    /**
-    * Returns a map of statistics.  This is a default implementation which returns an empty map and should be overridden
-    * if it is to be meaningful.
-    *
-    * @return an empty map
-    */
-   public Map<String, Object> dumpStatistics() {
-      return Collections.emptyMap();
-   }
-
-   /**
     * Resets statistics gathered.  Is a no-op, and should be overridden if it is to be meaningful.
     */
+   @ManagedOperation
    public void resetStatistics() {
    }
-
-
 }

Modified: core/branches/flat/src/main/java/org/horizon/jmx/JmxStatisticsExposer.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/jmx/JmxStatisticsExposer.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/jmx/JmxStatisticsExposer.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -21,8 +21,6 @@
  */
 package org.horizon.jmx;
 
-import java.util.Map;
-
 /**
  * Interface containing common cache management operations
  *
@@ -46,14 +44,6 @@
    void setStatisticsEnabled(boolean enabled);
 
    /**
-    * Returns a map of the cache interceptor's statistics Map is keyed on statistic names (which are Strings) and values
-    * are Objects.
-    *
-    * @return a map containing statistics
-    */
-   Map<String, Object> dumpStatistics();
-
-   /**
     * Resets an interceptor's cache statistics
     */
    void resetStatistics();

Modified: core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheLoaderConfig.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheLoaderConfig.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheLoaderConfig.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -95,12 +95,13 @@
 
    @Override
    public String toString() {
-      return new StringBuilder().append("IndividualCacheLoaderConfig{").append("className='").append(className).append('\'')
+      return new StringBuilder().append(getClass().getSimpleName()).append("{").append("className='").append(className).append('\'')
             .append(", ignoreModifications=").append(ignoreModifications)
             .append(", fetchPersistentState=").append(fetchPersistentState)
             .append(", properties=").append(properties)
             .append(", purgeOnStartup=").append(purgeOnStartup).append("},")
-            .append("SingletonStoreConfig{").append(singletonStoreConfig).append('}')
+            .append(", SingletonStoreConfig{").append(singletonStoreConfig).append('}')
+            .append(", AsyncStoreConfig{").append(asyncStoreConfig).append('}')
             .toString();
    }
 
@@ -113,7 +114,7 @@
          throw new RuntimeException("Should not happen!", e);
       }
       if (singletonStoreConfig != null) clone.setSingletonStoreConfig(singletonStoreConfig.clone());
-      if (asyncStoreConfig != null) clone.setAsyncStoreConfig((AsyncStoreConfig) asyncStoreConfig.clone());
+      if (asyncStoreConfig != null) clone.setAsyncStoreConfig(asyncStoreConfig.clone());
       return clone;
    }
 }

Modified: core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheStore.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheStore.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/loader/AbstractCacheStore.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -7,6 +7,7 @@
 import javax.transaction.Transaction;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -55,4 +56,10 @@
       List<? extends Modification> list = transactions.remove(tx);
       if (list != null && !list.isEmpty()) applyModifications(list);
    }
+
+   public void removeAll(Set<Object> keys) {
+      if (keys != null && !keys.isEmpty()) {
+         for (Object key : keys) remove(key);
+      }
+   }
 }

Modified: core/branches/flat/src/main/java/org/horizon/loader/CacheLoaderManagerImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/CacheLoaderManagerImpl.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/loader/CacheLoaderManagerImpl.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -82,9 +82,9 @@
       return clmConfig.isFetchPersistentState();
    }
 
-   @Start
+   @Start(priority = 10)
    public void start() {
-      clmConfig = configuration.getCacheLoaderConfig();
+      clmConfig = configuration.getCacheLoaderManagerConfig();
       if (clmConfig != null) {
          try {
             loader = createCacheLoader();
@@ -137,7 +137,7 @@
 
          // only one cache loader may have fetchPersistentState to true.
          int numLoadersWithFetchPersistentState = 0;
-         for (CacheLoaderConfig cfg : clmConfig.getIndividualCacheLoaderConfigs()) {
+         for (CacheLoaderConfig cfg : clmConfig.getCacheLoaderConfigs()) {
             if (cfg.isFetchPersistentState()) numLoadersWithFetchPersistentState++;
 
             if (numLoadersWithFetchPersistentState > 1)

Modified: core/branches/flat/src/main/java/org/horizon/loader/CacheStore.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/CacheStore.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/loader/CacheStore.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -7,6 +7,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.List;
+import java.util.Set;
 
 /**
  * A specialization of the {@link CacheLoader} interface that can be written to.
@@ -61,6 +62,13 @@
    boolean remove(Object key);
 
    /**
+    * Bulk remove operation
+    *
+    * @param keys to remove
+    */
+   void removeAll(Set<Object> keys);
+
+   /**
     * Purges expired entries from the store.
     */
    void purgeExpired();

Modified: core/branches/flat/src/main/java/org/horizon/loader/StoredEntry.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/StoredEntry.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/loader/StoredEntry.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -28,6 +28,12 @@
       this.key = key;
    }
 
+   public StoredEntry(Object key, Object value, long lifespan) {
+      super(value, System.currentTimeMillis());
+      this.key = key;
+      setLifespan(lifespan);
+   }
+
    public final Object getKey() {
       return key;
    }

Modified: core/branches/flat/src/main/java/org/horizon/loader/decorators/ChainingCacheLoader.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/decorators/ChainingCacheLoader.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/loader/decorators/ChainingCacheLoader.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -5,15 +5,17 @@
 import org.horizon.loader.CacheLoaderConfig;
 import org.horizon.loader.CacheStore;
 import org.horizon.loader.StoredEntry;
+import org.horizon.loader.modifications.Modification;
 import org.horizon.marshall.Marshaller;
 
 import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -28,68 +30,93 @@
  * @since 1.0
  */
 public class ChainingCacheLoader implements CacheStore {
+
+   // linked hash sets used since it provides fast (O(1)) iteration, maintains order and provides O(1) lookups to values as well.
+   LinkedHashMap<CacheLoader, CacheLoaderConfig> loaders = new LinkedHashMap<CacheLoader, CacheLoaderConfig>();
+   LinkedHashMap<CacheStore, CacheLoaderConfig> stores = new LinkedHashMap<CacheStore, CacheLoaderConfig>();
+
    public void store(StoredEntry ed) {
-      // TODO: Manik: Customise this generated block
+      for (CacheStore s : stores.keySet()) s.store(ed);
    }
 
-   public void storeAll(Collection ed) {
-      // TODO: Manik: Customise this generated block
+   public void store(InputStream inputStream) throws IOException, ClassNotFoundException {
+      // loading and storing state via streams is *only* supported on the *first* store that has fetchPersistentState set.
+      for (Map.Entry<CacheStore, CacheLoaderConfig> e : stores.entrySet()) {
+         if (e.getValue().isFetchPersistentState()) {
+            e.getKey().store(inputStream);
+            // do NOT continue this for other stores, since the stream will not be in an appropriate state anymore
+            break;
+         }
+      }
    }
 
-   public void store(InputStream inputStream) {
-      // TODO: Manik: Customise this generated block
-   }
-
    public void load(OutputStream outputStream) throws IOException {
-      // TODO: Manik: Customise this generated block
+      // loading and storing state via streams is *only* supported on the *first* store that has fetchPersistentState set.
+      for (Map.Entry<CacheStore, CacheLoaderConfig> e : stores.entrySet()) {
+         if (e.getValue().isFetchPersistentState()) {
+            e.getKey().load(outputStream);
+            // do NOT continue this for other stores, since the stream will not be in an appropriate state anymore
+            break;
+         }
+      }
    }
 
    public void clear() {
-      // TODO: Manik: Customise this generated block
+      for (CacheStore s : stores.keySet()) s.clear();
    }
 
    public boolean remove(Object key) {
-      return false;  // TODO: Manik: Customise this generated block
+      boolean r = false;
+      for (CacheStore s : stores.keySet()) r = s.remove(key) || r;
+      return r;
    }
 
+   public void removeAll(Set<Object> keys) {
+      for (CacheStore s : stores.keySet()) s.removeAll(keys);
+   }
+
    public void purgeExpired() {
-      // TODO: Manik: Customise this generated block
+      for (CacheStore s : stores.keySet()) s.purgeExpired();
    }
 
    public void commit(Transaction tx) {
-      // TODO: Manik: Customise this generated block
+      for (CacheStore s : stores.keySet()) s.commit(tx);
    }
 
    public void rollback(Transaction tx) {
-      // TODO: Manik: Customise this generated block
+      for (CacheStore s : stores.keySet()) s.rollback(tx);
    }
 
-   public void prepare(List list, Transaction tx, boolean isOnePhase) {
-      // TODO: Manik: Customise this generated block
+   public void prepare(List<? extends Modification> list, Transaction tx, boolean isOnePhase) {
+      for (CacheStore s : stores.keySet()) s.prepare(list, tx, isOnePhase);
    }
 
-   public void init(CacheLoaderConfig config, Cache cache, TransactionManager tm, Marshaller m) {
-      // TODO: Manik: Customise this generated block
-   }
-
    public void init(CacheLoaderConfig config, Cache cache, Marshaller m) {
-      // TODO: Manik: Customise this generated block
+      for (Map.Entry<CacheLoader, CacheLoaderConfig> e : loaders.entrySet()) {
+         e.getKey().init(e.getValue(), cache, m);
+      }
    }
 
    public StoredEntry load(Object key) {
-      return null;  // TODO: Manik: Customise this generated block
+      StoredEntry se = null;
+      for (CacheLoader l : loaders.keySet()) {
+         se = l.load(key);
+         if (se != null) break;
+      }
+      return se;
    }
 
-   public Set loadAll(Collection keys) {
-      return null;  // TODO: Manik: Customise this generated block
+   public Set<StoredEntry> loadAll() {
+      Set<StoredEntry> set = new HashSet<StoredEntry>();
+      for (CacheStore s : stores.keySet()) set.addAll(s.loadAll());
+      return set;
    }
 
-   public Set loadAll() {
-      return null;  // TODO: Manik: Customise this generated block
-   }
-
    public boolean containsKey(Object key) {
-      return false;  // TODO: Manik: Customise this generated block
+      for (CacheLoader l : loaders.keySet()) {
+         if (l.containsKey(key)) return true;
+      }
+      return false;
    }
 
    public Class<? extends CacheLoaderConfig> getConfigurationClass() {
@@ -97,18 +124,21 @@
    }
 
    public void start() {
-      // TODO: Manik: Customise this generated block
+      for (CacheLoader l : loaders.keySet()) l.start();
    }
 
    public void stop() {
-      // TODO: Manik: Customise this generated block
+      for (CacheLoader l : loaders.keySet()) l.stop();
    }
 
-   public void addCacheLoader(CacheLoader loader, CacheLoaderConfig cfg) {
-      // TODO: Manik: Customise this generated block      
+   public void addCacheLoader(CacheLoader loader, CacheLoaderConfig config) {
+      loaders.put(loader, config);
+      if (loader instanceof CacheStore) stores.put((CacheStore) loader, config);
    }
 
    public void purgeIfNecessary() {
-      // TODO: Manik: Customise this generated block
+      for (Map.Entry<CacheStore, CacheLoaderConfig> e : stores.entrySet()) {
+         if (e.getValue().isPurgeOnStartup()) e.getKey().clear();
+      }
    }
 }

Modified: core/branches/flat/src/main/java/org/horizon/loader/jdbc/JDBCCacheLoader.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/loader/jdbc/JDBCCacheLoader.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/loader/jdbc/JDBCCacheLoader.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -44,6 +44,10 @@
       return false;  // TODO: Manik: Customise this generated block
    }
 
+   public void removeAll(Set<Object> keys) {
+      // TODO: Manik: Customise this generated block
+   }
+
    public void purgeExpired() {
       // TODO: Manik: Customise this generated block
    }

Deleted: core/branches/flat/src/main/java/org/horizon/notifications/Notifier.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/notifications/Notifier.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/notifications/Notifier.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -1,11 +0,0 @@
-package org.horizon.notifications;
-
-/**
- * Common notifier methods
- *
- * @author Manik Surtani
- * @since 1.0
- */
-public interface Notifier {
-
-}

Modified: core/branches/flat/src/main/java/org/horizon/remoting/RPCManagerImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/horizon/remoting/RPCManagerImpl.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/main/java/org/horizon/remoting/RPCManagerImpl.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -1,8 +1,5 @@
 package org.horizon.remoting;
 
-import org.horizon.annotations.MBean;
-import org.horizon.annotations.ManagedAttribute;
-import org.horizon.annotations.ManagedOperation;
 import org.horizon.commands.RPCCommand;
 import org.horizon.config.GlobalConfiguration;
 import org.horizon.factories.KnownComponentNames;
@@ -10,6 +7,9 @@
 import org.horizon.factories.annotations.Inject;
 import org.horizon.factories.annotations.Start;
 import org.horizon.factories.annotations.Stop;
+import org.horizon.jmx.annotations.MBean;
+import org.horizon.jmx.annotations.ManagedAttribute;
+import org.horizon.jmx.annotations.ManagedOperation;
 import org.horizon.marshall.Marshaller;
 import org.horizon.notifications.cachemanagerlistener.CacheManagerNotifier;
 import org.horizon.remoting.transport.Address;
@@ -31,8 +31,8 @@
 public class RPCManagerImpl implements RPCManager {
 
    Transport t;
-   AtomicLong replicationCount = new AtomicLong(0);
-   AtomicLong replicationFailures = new AtomicLong(0);
+   private final AtomicLong replicationCount = new AtomicLong(0);
+   private final AtomicLong replicationFailures = new AtomicLong(0);
    boolean statisticsEnabled = false; // by default, don't gather statistics.
 
    @Inject

Modified: core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/api/MixedModeTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -14,7 +14,7 @@
    AdvancedCache invalSyncCache1, invalSyncCache2;
    AdvancedCache localCache1, localCache2;
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration replSync = new Configuration();
       replSync.setCacheMode(Configuration.CacheMode.REPL_SYNC);
 

Modified: core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/api/mvcc/PutForExternalReadTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -34,7 +34,7 @@
    TransactionManager tm1, tm2;
    ReplListener replListener1, replListener2;
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration c = new Configuration();
       c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
       c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());

Modified: core/branches/flat/src/test/java/org/horizon/api/tree/NodeReplicatedMoveTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/tree/NodeReplicatedMoveTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/api/tree/NodeReplicatedMoveTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -30,7 +30,7 @@
    TreeCache<Object, Object> cache1, cache2;
    TransactionManager tm1;
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration c = new Configuration();
       c.setInvocationBatchingEnabled(true);
       c.setCacheMode(Configuration.CacheMode.REPL_SYNC);

Modified: core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -28,7 +28,7 @@
 public class SyncReplTest extends MultipleCacheManagersTest {
    private TreeCache<Object, Object> cache1, cache2;
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration c = new Configuration();
       c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
       c.setInvocationBatchingEnabled(true);

Modified: core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTxTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTxTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/api/tree/SyncReplTxTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -33,7 +33,7 @@
 public class SyncReplTxTest extends MultipleCacheManagersTest {
    TreeCache<Object, Object> cache1, cache2;
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration c = new Configuration();
       c.setCacheMode(Configuration.CacheMode.REPL_SYNC);
       c.setFetchInMemoryState(false);

Modified: core/branches/flat/src/test/java/org/horizon/atomic/ClusteredAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/atomic/ClusteredAPITest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/atomic/ClusteredAPITest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -18,7 +18,7 @@
 public class ClusteredAPITest extends MultipleCacheManagersTest {
    AtomicMapCache cache1, cache2;
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration c = new Configuration();
       c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
       c.setCacheMode(Configuration.CacheMode.REPL_SYNC);

Modified: core/branches/flat/src/test/java/org/horizon/config/parsing/ConfigurationParserTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/config/parsing/ConfigurationParserTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/config/parsing/ConfigurationParserTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -172,7 +172,7 @@
       Configuration c = new Configuration();
       parser.configureCacheLoaders(e, c);
 
-      CacheLoaderManagerConfig clc = c.getCacheLoaderConfig();
+      CacheLoaderManagerConfig clc = c.getCacheLoaderManagerConfig();
       assert clc != null;
       assert clc.isFetchPersistentState();
       assert clc.isPassivation();
@@ -214,7 +214,7 @@
       Configuration c = new Configuration();
       parser.configureCacheLoaders(e, c);
 
-      CacheLoaderManagerConfig clc = c.getCacheLoaderConfig();
+      CacheLoaderManagerConfig clc = c.getCacheLoaderManagerConfig();
       assert clc != null;
       assert !clc.isFetchPersistentState();
       assert !clc.isPassivation();

Modified: core/branches/flat/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -13,7 +13,7 @@
 
    Cache c1, c2;
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration cfg = new Configuration();
       cfg.setCacheMode(Configuration.CacheMode.REPL_SYNC);
       List<Cache> caches = createClusteredCaches(2, "cache", cfg);

Modified: core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/invalidation/BaseInvalidationTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -31,7 +31,7 @@
    protected AdvancedCache cache1, cache2;
    protected boolean isSync;
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration c = new Configuration();
       c.setStateRetrievalTimeout(1000);
       c.setFetchInMemoryState(false);

Modified: core/branches/flat/src/test/java/org/horizon/loader/BaseCacheLoaderTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/loader/BaseCacheLoaderTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/loader/BaseCacheLoaderTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -6,8 +6,7 @@
 import org.horizon.loader.modifications.Remove;
 import org.horizon.loader.modifications.Store;
 import org.testng.annotations.AfterMethod;
-import org.testng.annotations.AfterTest;
-import org.testng.annotations.BeforeTest;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import javax.transaction.Transaction;
@@ -25,24 +24,22 @@
 
    protected abstract CacheStore createCacheStore();
 
-   CacheStore cs;
+   protected CacheStore cs;
 
-   @BeforeTest
+   @BeforeMethod
    public void setUp() {
       cs = createCacheStore();
    }
 
-   @AfterTest
+   @AfterMethod
    public void tearDown() {
-      if (cs != null) cs.clear();
+      if (cs != null) {
+         cs.clear();
+         cs.stop();
+      }
       cs = null;
    }
 
-   @AfterMethod
-   public void cleanCL() {
-      cs.clear();
-   }
-
    public void testLoadAndStore() throws InterruptedException {
       assert !cs.containsKey("k");
       StoredEntry se = new StoredEntry("k", "v", -1, -1);

Modified: core/branches/flat/src/test/java/org/horizon/loader/CacheLoaderFunctionalTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/loader/CacheLoaderFunctionalTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/loader/CacheLoaderFunctionalTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -39,8 +39,8 @@
       cfg = new Configuration();
       cfg.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
       CacheLoaderManagerConfig clmc = new CacheLoaderManagerConfig();
-      clmc.addIndividualCacheLoaderConfig(new DummyInMemoryCacheLoader.Cfg());
-      cfg.setCacheLoaderConfig(clmc);
+      clmc.addCacheLoaderConfig(new DummyInMemoryCacheLoader.Cfg());
+      cfg.setCacheLoaderManagerConfig(clmc);
       cm = new DefaultCacheManager(cfg);
       cache = cm.getCache();
       store = TestingUtil.extractComponent(cache, CacheLoaderManager.class).getCacheStore();
@@ -206,13 +206,13 @@
 
    public void testPreloading() {
       Configuration preloadingCfg = cfg.clone();
-      preloadingCfg.getCacheLoaderConfig().setPreload(true);
-      ((DummyInMemoryCacheLoader.Cfg) preloadingCfg.getCacheLoaderConfig().getFirstCacheLoaderConfig()).setStore("preloadingCache");
+      preloadingCfg.getCacheLoaderManagerConfig().setPreload(true);
+      ((DummyInMemoryCacheLoader.Cfg) preloadingCfg.getCacheLoaderManagerConfig().getFirstCacheLoaderConfig()).setStore("preloadingCache");
       cm.defineCache("preloadingCache", preloadingCfg);
       Cache preloadingCache = cm.getCache("preloadingCache");
       CacheStore preloadingStore = TestingUtil.extractComponent(preloadingCache, CacheLoaderManager.class).getCacheStore();
 
-      assert preloadingCache.getConfiguration().getCacheLoaderConfig().isPreload();
+      assert preloadingCache.getConfiguration().getCacheLoaderManagerConfig().isPreload();
 
       assertNotInCacheAndStore(preloadingCache, preloadingStore, "k1", "k2", "k3", "k4");
 
@@ -234,7 +234,7 @@
       assert c.size() == 0;
 
       preloadingCache.start();
-      assert preloadingCache.getConfiguration().getCacheLoaderConfig().isPreload();
+      assert preloadingCache.getConfiguration().getCacheLoaderManagerConfig().isPreload();
       c = preloadingCache.getAdvancedCache().getDataContainer();
       assert c.size() == 4;
 
@@ -248,8 +248,8 @@
 
    public void testPurgeOnStartup() {
       Configuration purgingCfg = cfg.clone();
-      purgingCfg.getCacheLoaderConfig().getFirstCacheLoaderConfig().setPurgeOnStartup(true);
-      ((DummyInMemoryCacheLoader.Cfg) purgingCfg.getCacheLoaderConfig().getFirstCacheLoaderConfig()).setStore("purgingCache");
+      purgingCfg.getCacheLoaderManagerConfig().getFirstCacheLoaderConfig().setPurgeOnStartup(true);
+      ((DummyInMemoryCacheLoader.Cfg) purgingCfg.getCacheLoaderManagerConfig().getFirstCacheLoaderConfig()).setStore("purgingCache");
       cm.defineCache("purgingCache", purgingCfg);
       Cache purgingCache = cm.getCache("purgingCache");
       CacheStore purgingStore = TestingUtil.extractComponent(purgingCache, CacheLoaderManager.class).getCacheStore();
@@ -337,4 +337,16 @@
       assertInCacheAndStore("k1", "v1");
       assertInCacheAndStore("k2", "v2", lifespan);
    }
+
+   public void testEvictAndRemove() {
+      assertNotInCacheAndStore("k1", "k2");
+      cache.put("k1", "v1");
+      cache.put("k2", "v2", lifespan, MILLISECONDS);
+
+      cache.evict("k1");
+      cache.evict("k2");
+
+      assert "v1".equals(cache.remove("k1"));
+      assert "v2".equals(cache.remove("k2"));
+   }
 }

Copied: core/branches/flat/src/test/java/org/horizon/loader/PassivationFunctionalTest.java (from rev 7697, core/branches/flat/src/test/java/org/horizon/loader/CacheLoaderFunctionalTest.java)
===================================================================
--- core/branches/flat/src/test/java/org/horizon/loader/PassivationFunctionalTest.java	                        (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/loader/PassivationFunctionalTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -0,0 +1,245 @@
+package org.horizon.loader;
+
+import org.horizon.Cache;
+import org.horizon.config.CacheLoaderManagerConfig;
+import org.horizon.config.Configuration;
+import org.horizon.loader.dummy.DummyInMemoryCacheLoader;
+import org.horizon.manager.CacheManager;
+import org.horizon.manager.DefaultCacheManager;
+import org.horizon.test.TestingUtil;
+import org.horizon.transaction.DummyTransactionManagerLookup;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.util.HashMap;
+import java.util.Map;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+/**
+ * Tests the interceptor chain and surrounding logic
+ *
+ * @author Manik Surtani
+ */
+ at Test(groups = "functional", sequential = true)
+public class PassivationFunctionalTest {
+   Cache cache;
+   CacheStore store;
+   TransactionManager tm;
+   Configuration cfg;
+   CacheManager cm;
+   long lifespan = 6000000; // very large lifespan so nothing actually expires
+
+   @BeforeTest
+   public void setUp() {
+      cfg = new Configuration();
+      cfg.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
+      CacheLoaderManagerConfig clmc = new CacheLoaderManagerConfig();
+      clmc.setPassivation(true);
+      clmc.addCacheLoaderConfig(new DummyInMemoryCacheLoader.Cfg());
+      cfg.setCacheLoaderManagerConfig(clmc);
+      cm = new DefaultCacheManager(cfg);
+      cache = cm.getCache();
+      store = TestingUtil.extractComponent(cache, CacheLoaderManager.class).getCacheStore();
+      tm = TestingUtil.getTransactionManager(cache);
+   }
+
+   @AfterTest
+   public void tearDown() {
+      TestingUtil.killCacheManagers(cm);
+   }
+
+   @AfterMethod
+   public void afterMethod() {
+      if (cache != null) cache.clear();
+      if (store != null) store.clear();
+   }
+
+   private void assertInCacheNotInStore(Object key, Object value) {
+      assertInCacheNotInStore(key, value, -1);
+   }
+
+   private void assertInCacheNotInStore(Object key, Object value, long lifespanMillis) {
+      StoredEntry se = cache.getAdvancedCache().getDataContainer().createEntryForStorage(key);
+      testStoredEntry(se, value, lifespanMillis, "Cache", key);
+      assert !store.containsKey(key) : "Key " + key + " should not be in store!";
+   }
+
+   private void assertInStoreNotInCache(Object key, Object value) {
+      assertInStoreNotInCache(key, value, -1);
+   }
+
+   private void assertInStoreNotInCache(Object key, Object value, long lifespanMillis) {
+      StoredEntry se = store.load(key);
+      testStoredEntry(se, value, lifespanMillis, "Store", key);
+      assert !cache.getAdvancedCache().getDataContainer().containsKey(key) : "Key " + key + " should not be in cache!";
+   }
+
+
+   private void testStoredEntry(StoredEntry entry, Object expectedValue, long expectedLifespan, String src, Object key) {
+      assert entry != null : src + " entry for key " + key + " should NOT be null";
+      assert entry.getValue().equals(expectedValue) : src + " should contain value " + expectedValue + " under key " + entry.getKey() + " but was " + entry.getValue() + ". Entry is " + entry;
+      assert entry.getLifespan() == expectedLifespan : src + " expected lifespan for key " + key + " to be " + expectedLifespan + " but was " + entry.getLifespan() + ". Entry is " + entry;
+   }
+
+   private void assertNotInCacheAndStore(Object... keys) {
+      for (Object key : keys) {
+         assert !cache.getAdvancedCache().getDataContainer().containsKey(key) : "Cache should not contain key " + key;
+         assert !store.containsKey(key) : "Store should not contain key " + key;
+      }
+   }
+
+   public void testPassivate() {
+      assertNotInCacheAndStore("k1", "k2");
+
+      cache.put("k1", "v1");
+      cache.put("k2", "v2", lifespan, MILLISECONDS);
+
+      assertInCacheNotInStore("k1", "v1");
+      assertInCacheNotInStore("k2", "v2", lifespan);
+
+      cache.evict("k1");
+      cache.evict("k2");
+
+      assertInStoreNotInCache("k1", "v1");
+      assertInStoreNotInCache("k2", "v2", lifespan);
+
+      // now activate
+
+      assert cache.get("k1").equals("v1");
+      assert cache.get("k2").equals("v2");
+
+      assertInCacheNotInStore("k1", "v1");
+      assertInCacheNotInStore("k2", "v2", lifespan);
+
+      cache.evict("k1");
+      cache.evict("k2");
+
+      assertInStoreNotInCache("k1", "v1");
+      assertInStoreNotInCache("k2", "v2", lifespan);
+   }
+
+   public void testRemoveAndReplace() {
+      assertNotInCacheAndStore("k1", "k2");
+
+      cache.put("k1", "v1");
+      cache.put("k2", "v2", lifespan, MILLISECONDS);
+
+      assertInCacheNotInStore("k1", "v1");
+      assertInCacheNotInStore("k2", "v2", lifespan);
+
+      cache.evict("k1");
+      cache.evict("k2");
+
+      assertInStoreNotInCache("k1", "v1");
+      assertInStoreNotInCache("k2", "v2", lifespan);
+
+      assert cache.remove("k1").equals("v1");
+      assertNotInCacheAndStore("k1");
+
+      assert cache.put("k2", "v2-NEW").equals("v2");
+      assertInCacheNotInStore("k2", "v2-NEW");
+
+      cache.evict("k2");
+      assertInStoreNotInCache("k2", "v2-NEW");
+      assert cache.replace("k2", "v2-REPLACED").equals("v2-NEW");
+      assertInCacheNotInStore("k2", "v2-REPLACED");
+
+      cache.evict("k2");
+      assertInStoreNotInCache("k2", "v2-REPLACED");
+
+      assert !cache.replace("k2", "some-rubbish", "v2-SHOULDNT-STORE"); // but should activate
+      assertInCacheNotInStore("k2", "v2-REPLACED");
+
+      cache.evict("k2");
+      assertInStoreNotInCache("k2", "v2-REPLACED");
+
+      assert cache.replace("k2", "v2-REPLACED", "v2-REPLACED-AGAIN");
+      assertInCacheNotInStore("k2", "v2-REPLACED-AGAIN");
+
+      cache.evict("k2");
+      assertInStoreNotInCache("k2", "v2-REPLACED-AGAIN");
+
+      assert cache.putIfAbsent("k2", "should-not-appear").equals("v2-REPLACED-AGAIN");
+      assertInCacheNotInStore("k2", "v2-REPLACED-AGAIN");
+
+      assert cache.putIfAbsent("k1", "v1-if-absent") == null;
+      assertInCacheNotInStore("k1", "v1-if-absent");
+   }
+
+   public void testTransactions() throws Exception {
+      assertNotInCacheAndStore("k1", "k2");
+
+      tm.begin();
+      cache.put("k1", "v1");
+      cache.put("k2", "v2", lifespan, MILLISECONDS);
+      Transaction t = tm.suspend();
+
+      assertNotInCacheAndStore("k1", "k2");
+
+      tm.resume(t);
+      tm.commit();
+
+      assertInCacheNotInStore("k1", "v1");
+      assertInCacheNotInStore("k2", "v2", lifespan);
+
+      tm.begin();
+      cache.clear();
+      t = tm.suspend();
+
+      assertInCacheNotInStore("k1", "v1");
+      assertInCacheNotInStore("k2", "v2", lifespan);
+      tm.resume(t);
+      tm.commit();
+
+      assertNotInCacheAndStore("k1", "k2");
+
+      tm.begin();
+      cache.put("k1", "v1");
+      cache.put("k2", "v2", lifespan, MILLISECONDS);
+      t = tm.suspend();
+
+      assertNotInCacheAndStore("k1", "k2");
+
+      tm.resume(t);
+      tm.rollback();
+
+      assertNotInCacheAndStore("k1", "k2");
+      cache.put("k1", "v1");
+      cache.put("k2", "v2", lifespan, MILLISECONDS);
+
+      assertInCacheNotInStore("k1", "v1");
+      assertInCacheNotInStore("k2", "v2", lifespan);
+
+      cache.evict("k1");
+      cache.evict("k2");
+
+      assertInStoreNotInCache("k1", "v1");
+      assertInStoreNotInCache("k2", "v2", lifespan);
+   }
+
+   public void testPutMap() {
+      assertNotInCacheAndStore("k1", "k2", "k3");
+      cache.put("k1", "v1");
+      cache.put("k2", "v2");
+
+      cache.evict("k2");
+
+      assertInCacheNotInStore("k1", "v1");
+      assertInStoreNotInCache("k2", "v2");
+
+      Map m = new HashMap();
+      m.put("k1", "v1-NEW");
+      m.put("k2", "v2-NEW");
+      m.put("k3", "v3-NEW");
+
+      cache.putAll(m);
+
+      assertInCacheNotInStore("k1", "v1-NEW");
+      assertInCacheNotInStore("k2", "v2-NEW");
+      assertInCacheNotInStore("k3", "v3-NEW");
+   }
+}
\ No newline at end of file

Added: core/branches/flat/src/test/java/org/horizon/loader/decorators/ChainingCacheLoaderTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/loader/decorators/ChainingCacheLoaderTest.java	                        (rev 0)
+++ core/branches/flat/src/test/java/org/horizon/loader/decorators/ChainingCacheLoaderTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -0,0 +1,271 @@
+package org.horizon.loader.decorators;
+
+import org.easymock.EasyMock;
+import org.horizon.loader.BaseCacheLoaderTest;
+import org.horizon.loader.CacheLoaderConfig;
+import org.horizon.loader.CacheStore;
+import org.horizon.loader.StoredEntry;
+import org.horizon.loader.dummy.DummyInMemoryCacheLoader;
+import org.horizon.loader.modifications.Clear;
+import org.horizon.loader.modifications.Modification;
+import org.horizon.loader.modifications.Remove;
+import org.horizon.loader.modifications.Store;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.Transaction;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+ at Test(groups = "unit", testName = "loader.decorators.ChainingCacheLoaderTest", sequential = true)
+public class ChainingCacheLoaderTest extends BaseCacheLoaderTest {
+
+   DummyInMemoryCacheLoader store1, store2;
+   DummyInMemoryCacheLoader[] stores;  // for convenient iteration   
+   private static final long lifespan = 6000000;
+
+   protected CacheStore createCacheStore() {
+      ChainingCacheLoader store = new ChainingCacheLoader();
+      CacheLoaderConfig cfg;
+      store1 = new DummyInMemoryCacheLoader();
+      store1.init((cfg = new DummyInMemoryCacheLoader.Cfg("instance1")), null, null);
+
+      store.addCacheLoader(store1, cfg);
+
+      store2 = new DummyInMemoryCacheLoader();
+      store2.init((cfg = new DummyInMemoryCacheLoader.Cfg("instance2")), null, null);
+      // set store2 up for streaming
+      cfg.setFetchPersistentState(true);
+      store.addCacheLoader(store2, cfg);
+
+      stores = new DummyInMemoryCacheLoader[]{store1, store2};
+
+      store.start();
+
+      return store;
+   }
+
+   @AfterMethod
+   public void afterMethod() {
+      if (store1 != null) store1.clear();
+      if (store2 != null) store2.clear();
+   }
+
+   public void testPropagatingWrites() throws Exception {
+      // put something in the store
+      cs.store(new StoredEntry("k1", "v1"));
+      cs.store(new StoredEntry("k2", "v2", lifespan));
+
+      int i = 1;
+      for (CacheStore s : stores) {
+         assert s.containsKey("k1") : "Key k1 missing on store " + i;
+         assert s.containsKey("k2") : "Key k2 missing on store " + i;
+         assert s.load("k1").getValue().equals("v1");
+         assert s.load("k2").getValue().equals("v2");
+         assert s.load("k1").getLifespan() == -1;
+         assert s.load("k2").getLifespan() == lifespan;
+         i++;
+      }
+
+      cs.remove("k1");
+
+      for (CacheStore s : stores) {
+         assert !s.containsKey("k1");
+         assert s.containsKey("k2");
+         assert s.load("k1") == null;
+         assert s.load("k2").getValue().equals("v2");
+         assert s.load("k2").getLifespan() == lifespan;
+      }
+
+      cs.clear();
+
+      for (CacheStore s : stores) {
+         assert !s.containsKey("k1");
+         assert !s.containsKey("k2");
+         assert s.load("k1") == null;
+         assert s.load("k2") == null;
+      }
+
+      cs.store(new StoredEntry("k1", "v1"));
+      cs.store(new StoredEntry("k2", "v2", lifespan));
+      cs.store(new StoredEntry("k3", "v3", 1000)); // short lifespan!
+
+      for (CacheStore s : stores) {
+         assert s.containsKey("k1");
+         assert s.containsKey("k2");
+         assert s.containsKey("k3");
+      }
+
+      Thread.sleep(1100);
+
+      cs.purgeExpired();
+
+      for (CacheStore s : stores) {
+         assert s.containsKey("k1");
+         assert s.containsKey("k2");
+         assert !s.containsKey("k3");
+      }
+   }
+
+   public void testGetsFromMultipleSrcs() throws Exception {
+
+      assert cs.load("k1") == null;
+      assert cs.load("k2") == null;
+      assert cs.load("k3") == null;
+      assert cs.load("k4") == null;
+
+      // k1 is on store1
+      store1.store(new StoredEntry("k1", "v1"));
+      // k2 is on store2
+      store2.store(new StoredEntry("k2", "v2"));
+
+      // k3 is on both
+      store1.store(new StoredEntry("k3", "v3"));
+      store2.store(new StoredEntry("k3", "v3"));
+
+      // k4 is on neither
+
+      assert cs.load("k1").getValue().equals("v1");
+      assert cs.load("k2").getValue().equals("v2");
+      assert cs.load("k3").getValue().equals("v3");
+      assert cs.load("k4") == null;
+
+      Set<StoredEntry> all = cs.loadAll();
+
+      assert all.size() == 3;
+      Set<Object> expectedKeys = new HashSet<Object>();
+      expectedKeys.add("k1");
+      expectedKeys.add("k2");
+      expectedKeys.add("k3");
+      for (StoredEntry a : all) assert expectedKeys.remove(a.getKey());
+
+      assert expectedKeys.isEmpty();
+
+      cs.remove("k3");
+
+      assert !store1.containsKey("k3");
+      assert !store2.containsKey("k3");
+   }
+
+   public void testPropagatingOnePhaseCommit() throws Exception {
+      List<Modification> list = new LinkedList<Modification>();
+      list.add(new Store(new StoredEntry("k1", "v1")));
+      list.add(new Store(new StoredEntry("k2", "v2", lifespan)));
+      list.add(new Store(new StoredEntry("k3", "v3")));
+      list.add(new Remove("k3"));
+      list.add(new Clear());
+      list.add(new Store(new StoredEntry("k4", "v4")));
+      list.add(new Store(new StoredEntry("k5", "v5", lifespan)));
+      list.add(new Store(new StoredEntry("k6", "v6")));
+      list.add(new Remove("k6"));
+      Transaction t = EasyMock.createNiceMock(Transaction.class);
+      cs.prepare(list, t, true);
+
+      CacheStore[] allStores = new CacheStore[]{cs, store1, store2}; // for iteration
+      for (int i = 1; i < 7; i++) {
+         if (i < 4 || i == 6) {
+            // these have been deleted
+            for (CacheStore s : allStores) assert !s.containsKey("k" + i) : "Failed on k" + i;
+         } else {
+            for (CacheStore s : allStores) {
+               assert s.containsKey("k" + i);
+               assert s.load("k" + i).getValue().equals("v" + i);
+               assert s.load("k" + i).getLifespan() == (i == 5 ? lifespan : -1);
+            }
+         }
+      }
+
+      cs.clear();
+
+      for (int i = 1; i < 7; i++) {
+         for (CacheStore s : allStores) assert !s.containsKey("k" + i);
+      }
+   }
+
+   public void testPropagatingTwoPhaseCommit() throws Exception {
+      List<Modification> list = new LinkedList<Modification>();
+      list.add(new Store(new StoredEntry("k1", "v1")));
+      list.add(new Store(new StoredEntry("k2", "v2", lifespan)));
+      list.add(new Store(new StoredEntry("k3", "v3")));
+      list.add(new Remove("k3"));
+      list.add(new Clear());
+      list.add(new Store(new StoredEntry("k4", "v4")));
+      list.add(new Store(new StoredEntry("k5", "v5", lifespan)));
+      list.add(new Store(new StoredEntry("k6", "v6")));
+      list.add(new Remove("k6"));
+      Transaction t = EasyMock.createNiceMock(Transaction.class);
+      cs.prepare(list, t, false);
+
+      CacheStore[] allStores = new CacheStore[]{cs, store1, store2}; // for iteration
+
+      for (int i = 1; i < 7; i++) {
+         for (CacheStore s : allStores) assert !s.containsKey("k" + i);
+      }
+
+      cs.commit(t);
+
+      for (int i = 1; i < 7; i++) {
+         if (i < 4 || i == 6) {
+            // these have been deleted
+            for (CacheStore s : allStores) assert !s.containsKey("k" + i);
+         } else {
+            for (CacheStore s : allStores) {
+               assert s.containsKey("k" + i);
+               assert s.load("k" + i).getValue().equals("v" + i);
+               assert s.load("k" + i).getLifespan() == (i == 5 ? lifespan : -1);
+            }
+         }
+      }
+   }
+
+
+   public void testPropagatingStreams() throws IOException, ClassNotFoundException {
+      store2.store(new StoredEntry("k1", "v1"));
+      store2.store(new StoredEntry("k2", "v2", lifespan));
+
+      assert cs.containsKey("k1");
+      assert cs.containsKey("k2");
+
+      ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+      ObjectOutputStream oos = new ObjectOutputStream(byteStream);
+      cs.load(oos);
+      oos.close();
+      byteStream.close();
+      cs.clear();
+
+      assert !cs.containsKey("k1");
+      assert !cs.containsKey("k2");
+      for (CacheStore s : stores) {
+         assert !s.containsKey("k1");
+         assert !s.containsKey("k2");
+      }
+
+      cs.store(new ObjectInputStream(new ByteArrayInputStream(byteStream.toByteArray())));
+
+      assert cs.containsKey("k1");
+      assert cs.containsKey("k2");
+      assert cs.load("k1").getValue().equals("v1");
+      assert cs.load("k2").getValue().equals("v2");
+      assert cs.load("k1").getLifespan() == -1;
+      assert cs.load("k2").getLifespan() == lifespan;
+
+      assert store2.containsKey("k1");
+      assert store2.containsKey("k2");
+      assert store2.load("k1").getValue().equals("v1");
+      assert store2.load("k2").getValue().equals("v2");
+      assert store2.load("k1").getLifespan() == -1;
+      assert store2.load("k2").getLifespan() == lifespan;
+
+      // store 1 has not been set up to support fetching state
+      assert !store1.containsKey("k1");
+      assert !store1.containsKey("k2");
+   }
+}
+

Modified: core/branches/flat/src/test/java/org/horizon/loader/decorators/SingletonStoreTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/loader/decorators/SingletonStoreTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/loader/decorators/SingletonStoreTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -10,12 +10,11 @@
 import org.horizon.loader.StoredEntry;
 import org.horizon.loader.dummy.DummyInMemoryCacheLoader;
 import org.horizon.manager.CacheManager;
+import org.horizon.test.MultipleCacheManagersTest;
 import org.horizon.test.TestingUtil;
 import org.horizon.test.ViewChangeListener;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.fail;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import java.util.HashMap;
@@ -30,35 +29,35 @@
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
 
- at Test(groups = "functional", testName = "loader.decorators.SingletonStoreTest")
-public class SingletonStoreTest {
+ at Test(groups = "functional", sequential = true)
+public class SingletonStoreTest extends MultipleCacheManagersTest {
    private static final Log log = LogFactory.getLog(SingletonStoreTest.class);
    private static final AtomicInteger storeCounter = new AtomicInteger(0);
    private CacheManager cm0, cm1, cm2;
 
-   @BeforeMethod
-   protected void setUp() throws Throwable {
-      cm0 = TestingUtil.createClusteredCacheManager();
-      cm1 = TestingUtil.createClusteredCacheManager();
-      cm2 = TestingUtil.createClusteredCacheManager();
 
+   protected void createCacheManagers() {
+      cm0 = addClusterEnabledCacheManager();
+      cm1 = addClusterEnabledCacheManager();
+      cm2 = addClusterEnabledCacheManager();
+
       Configuration conf = new Configuration();
       conf.setCacheMode(Configuration.CacheMode.REPL_SYNC);
       DummyInMemoryCacheLoader.Cfg cfg = new DummyInMemoryCacheLoader.Cfg();
       cfg.setStore("Store-" + storeCounter.getAndIncrement());
       CacheLoaderManagerConfig pushingCfg = new CacheLoaderManagerConfig();
-      pushingCfg.addIndividualCacheLoaderConfig(cfg);
+      pushingCfg.addCacheLoaderConfig(cfg);
       SingletonStoreConfig ssc = new SingletonStoreConfig();
       ssc.setPushStateWhenCoordinator(true);
       ssc.setSingletonStoreEnabled(true);
       cfg.setSingletonStoreConfig(ssc);
-      conf.setCacheLoaderConfig(pushingCfg);
+      conf.setCacheLoaderManagerConfig(pushingCfg);
 
       // cannot define on ALL cache managers since the same dummy in memory CL bin will be used!
       cm0.defineCache("pushing", conf);
-      ((DummyInMemoryCacheLoader.Cfg) conf.getCacheLoaderConfig().getFirstCacheLoaderConfig()).setStore("Store-" + storeCounter.getAndIncrement());
+      ((DummyInMemoryCacheLoader.Cfg) conf.getCacheLoaderManagerConfig().getFirstCacheLoaderConfig()).setStore("Store-" + storeCounter.getAndIncrement());
       cm1.defineCache("pushing", conf);
-      ((DummyInMemoryCacheLoader.Cfg) conf.getCacheLoaderConfig().getFirstCacheLoaderConfig()).setStore("Store-" + storeCounter.getAndIncrement());
+      ((DummyInMemoryCacheLoader.Cfg) conf.getCacheLoaderManagerConfig().getFirstCacheLoaderConfig()).setStore("Store-" + storeCounter.getAndIncrement());
       cm2.defineCache("pushing", conf);
 
       conf = new Configuration();
@@ -66,33 +65,24 @@
       cfg = new DummyInMemoryCacheLoader.Cfg();
       cfg.setStore("Store-" + storeCounter.getAndIncrement());
       CacheLoaderManagerConfig nonPushingCfg = new CacheLoaderManagerConfig();
-      nonPushingCfg.addIndividualCacheLoaderConfig(cfg);
+      nonPushingCfg.addCacheLoaderConfig(cfg);
       ssc = new SingletonStoreConfig();
       ssc.setPushStateWhenCoordinator(false);
       ssc.setSingletonStoreEnabled(true);
       cfg.setSingletonStoreConfig(ssc);
-      conf.setCacheLoaderConfig(nonPushingCfg);
+      conf.setCacheLoaderManagerConfig(nonPushingCfg);
 
       // cannot define on ALL cache managers since the same dummy in memory CL bin will be used!
       cm0.defineCache("nonPushing", conf);
-      ((DummyInMemoryCacheLoader.Cfg) conf.getCacheLoaderConfig().getFirstCacheLoaderConfig()).setStore("Store-" + storeCounter.getAndIncrement());
+      ((DummyInMemoryCacheLoader.Cfg) conf.getCacheLoaderManagerConfig().getFirstCacheLoaderConfig()).setStore("Store-" + storeCounter.getAndIncrement());
       cm1.defineCache("nonPushing", conf);
-      ((DummyInMemoryCacheLoader.Cfg) conf.getCacheLoaderConfig().getFirstCacheLoaderConfig()).setStore("Store-" + storeCounter.getAndIncrement());
+      ((DummyInMemoryCacheLoader.Cfg) conf.getCacheLoaderManagerConfig().getFirstCacheLoaderConfig()).setStore("Store-" + storeCounter.getAndIncrement());
       cm2.defineCache("nonPushing", conf);
    }
 
-   @AfterMethod
-   public void tearDown() {
-      TestingUtil.killCacheManagers(cm0, cm1, cm2);
-   }
-
    private Cache[] getCaches(String name) {
-      Cache cache = cm0.getCache(name);
-      Cache cache1 = cm1.getCache(name);
-      Cache cache2 = cm2.getCache(name);
-      TestingUtil.blockUntilViewsReceived(10000, cm0, cm1, cm2);
       return new Cache[]{
-            cache, cache1, cache2
+            cm0.getCache(name), cm1.getCache(name), cm2.getCache(name)
       };
    }
 
@@ -136,7 +126,7 @@
       }
 
       cm0.stop();
-      TestingUtil.blockForMemberToFail(60000, cm1, cm2);
+      TestingUtil.blockUntilViewsReceived(60000, false, cm1, cm2);
 
       caches[1].put("key4", "value4");
       caches[2].put("key5", "value5");
@@ -148,7 +138,7 @@
       assert load(stores[2], "key5") == null;
 
       cm1.stop();
-      TestingUtil.blockForMemberToFail(10000, cm2);
+      TestingUtil.blockUntilViewsReceived(60000, false, cm2);
 
       caches[2].put("key6", "value6");
       assert load(stores[2], "key6").equals("value6");

Modified: core/branches/flat/src/test/java/org/horizon/loader/dummy/DummyInMemoryCacheLoader.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/loader/dummy/DummyInMemoryCacheLoader.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/loader/dummy/DummyInMemoryCacheLoader.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -123,6 +123,11 @@
          setClassName(DummyInMemoryCacheLoader.class.getName());
       }
 
+      public Cfg(String name) {
+         this();
+         setStore(name);
+      }
+
       public boolean isDebug() {
          return debug;
       }

Modified: core/branches/flat/src/test/java/org/horizon/marshall/MarshalledValueTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/marshall/MarshalledValueTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/marshall/MarshalledValueTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -1,8 +1,8 @@
 package org.horizon.marshall;
 
+import org.horizon.AdvancedCache;
 import org.horizon.Cache;
 import org.horizon.CacheException;
-import org.horizon.AdvancedCache;
 import org.horizon.commands.write.PutKeyValueCommand;
 import org.horizon.config.CacheLoaderManagerConfig;
 import org.horizon.config.Configuration;
@@ -45,7 +45,7 @@
    private MarshalledValueListenerInterceptor mvli;
    String k = "key", v = "value";
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration replSync = new Configuration();
       replSync.setCacheMode(Configuration.CacheMode.REPL_SYNC);
       replSync.setUseLazyDeserialization(true);
@@ -67,7 +67,7 @@
    @BeforeMethod
    public void addMarshalledValueInterceptor() {
       mvli = new MarshalledValueListenerInterceptor();
-      ((AdvancedCache)cache1).addInterceptorAfter(mvli, MarshalledValueInterceptor.class);
+      ((AdvancedCache) cache1).addInterceptorAfter(mvli, MarshalledValueInterceptor.class);
    }
 
    @AfterMethod
@@ -257,8 +257,8 @@
       CacheLoaderManagerConfig clmc = new CacheLoaderManagerConfig();
       DummyInMemoryCacheLoader.Cfg clc = new DummyInMemoryCacheLoader.Cfg();
       clc.setStore(getClass().getSimpleName());
-      clmc.setIndividualCacheLoaderConfigs(Collections.singletonList((CacheLoaderConfig)clc));
-      cacheCofig.setCacheLoaderConfig(clmc);
+      clmc.setCacheLoaderConfigs(Collections.singletonList((CacheLoaderConfig) clc));
+      cacheCofig.setCacheLoaderManagerConfig(clmc);
 
       defineCacheOnAllManagers("replSync2", cacheCofig);
       cache1 = cache(0, "replSync2");
@@ -314,6 +314,7 @@
 
    class MarshalledValueListenerInterceptor extends CommandInterceptor {
       int invocationCount = 0;
+
       public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
          invocationCount++;
          if (command.getKey() instanceof MarshalledValue)

Modified: core/branches/flat/src/test/java/org/horizon/notifications/CacheListenerCacheLoaderTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/notifications/CacheListenerCacheLoaderTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/notifications/CacheListenerCacheLoaderTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -1,184 +1,167 @@
 package org.horizon.notifications;
 
+import org.horizon.Cache;
+import org.horizon.config.CacheLoaderManagerConfig;
+import org.horizon.config.Configuration;
+import org.horizon.loader.dummy.DummyInMemoryCacheLoader;
+import org.horizon.manager.CacheManager;
+import org.horizon.manager.DefaultCacheManager;
+import org.horizon.notifications.cachelistener.annotation.CacheEntryActivated;
+import org.horizon.notifications.cachelistener.annotation.CacheEntryLoaded;
+import org.horizon.notifications.cachelistener.annotation.CacheEntryPassivated;
+import org.horizon.notifications.cachelistener.event.CacheEntryEvent;
+import org.horizon.test.TestingUtil;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
- at Test(groups = "functional", testName = "notifications.CacheListenerCacheLoaderTest")
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+ at Test(groups = "functional", sequential = true)
 public class CacheListenerCacheLoaderTest {
-   // TODO implement me!
-//   private Cache<Object, Object> cache;
-//   private EventLog eventLog = new EventLog();
-//   private TransactionManager tm;
-//   private Fqn fqn = Fqn.fromString("/test");
-//
-//   @BeforeMethod(alwaysRun = true)
-//   public void setUp() throws Exception
-//   {
-//      Configuration c = new Configuration();
-//      c.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
-//      c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
-//
-//      CacheLoaderManagerConfig clc = new CacheLoaderManagerConfig();
-//      IndividualCacheLoaderConfig iclc = new IndividualCacheLoaderConfig();
-//      iclc.setClassName(DummyInMemoryCacheLoader.class.getName());
-//      clc.addIndividualCacheLoaderConfig(iclc);
-//      clc.setPassivation(true);
-//
-//      c.setCacheLoaderConfig(clc);
-//      cache = new UnitTestCacheFactory<Object, Object>().createCacheManager(c, getClass());
-//      eventLog.events.clear();
-//      cache.addCacheListener(eventLog);
-//      tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
-//   }
-//
-//   @AfterMethod(alwaysRun = true)
-//   public void tearDown() throws Exception
-//   {
-//      TestingUtil.killCaches(cache);
-//      cache = null;
-//   }
-//
-//   public void testActivationAndPassivation() throws Exception
-//   {
-//      assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
-//      cache.put(fqn, "key", "value");
-//      Map<Object, Object> data = new HashMap<Object, Object>();
-//      data.put("key", "value");
-//
-//      List<Event> expected = new ArrayList<Event>();
-//
-//      // now evict the node - which should cause a passivation
-//      eventLog.events.clear();
-//      cache.evict(fqn);
-//      expected.add(new EventImpl(true, cache, null, data, fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(false, cache, null, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      assertEquals(expected, eventLog.events);
-//
-//      // now load the node.
-//      expected.clear();
-//      eventLog.events.clear();
-//      cache.get(fqn, "DOES_NOT_EXIST");
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(true, cache, null, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(false, cache, null, data, fqn, null, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_VISITED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_VISITED));
-//
-//      assertEquals(expected, eventLog.events);
-//   }
-//
-//   public void testActivationAndPassivationTxNoMods() throws Exception
-//   {
-//      assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
-//      cache.put(fqn, "key", "value");
-//      Map<Object, Object> data = new HashMap<Object, Object>();
-//      data.put("key", "value");
-//
-//      List<Event> expected = new ArrayList<Event>();
-//
-//      // now evict the node - which should cause a passivation
-//      eventLog.events.clear();
-//      cache.evict(fqn);
-//      expected.add(new EventImpl(true, cache, null, data, fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(false, cache, null, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      assertEquals(expected, eventLog.events);
-//
-//      // now load the node.
-//      expected.clear();
-//      eventLog.events.clear();
-//      tm.begin();
-//      Transaction tx = tm.getTransaction();
-//      cache.get(fqn, "DOES_NOT_EXIST");
-//      tm.commit();
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(true, cache, null, Collections.emptyMap(), fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(false, cache, null, data, fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, tx, true, null, false, null, NODE_VISITED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, tx, true, null, false, null, NODE_VISITED));
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, true, null, TRANSACTION_COMPLETED));
-//      assertEquals(expected, eventLog.events);
-//   }
-//
-//   public void testActivationAndPassivationTxMods() throws Exception
-//   {
-//      assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
-//      cache.put(fqn, "key", "value");
-//      Map<Object, Object> data = new HashMap<Object, Object>();
-//      data.put("key", "value");
-//
-//      List<Event> expected = new ArrayList<Event>();
-//
-//      // now evict the node - which should cause a passivation
-//      eventLog.events.clear();
-//      cache.evict(fqn);
-//      expected.add(new EventImpl(true, cache, null, data, fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(false, cache, null, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      assertEquals(expected, eventLog.events);
-//
-//      // now load the node.
-//      expected.clear();
-//      eventLog.events.clear();
-//      tm.begin();
-//      Transaction tx = tm.getTransaction();
-//      cache.put(fqn, "key2", "value2");
-//      tm.commit();
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(true, cache, null, Collections.emptyMap(), fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(false, cache, null, data, fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(true, cache, PUT_DATA, data, fqn, tx, true, null, false, null, NODE_MODIFIED));
-//      expected.add(new EventImpl(false, cache, PUT_DATA, Collections.singletonMap("key2", "value2"), fqn, tx, true, null, false, null, NODE_MODIFIED));
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, true, null, TRANSACTION_COMPLETED));
-//      assertEquals(expected, eventLog.events);
-//
-//      assert cache.get(fqn, "key").equals("value");
-//      assert cache.get(fqn, "key2").equals("value2");
-//   }
-//
-//   public void testActivationAndPassivationTxModsWithChildren() throws Exception
-//   {
-//      assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
-//      cache.put(fqn, "key", "value");
-//      cache.put(Fqn.fromRelativeElements(fqn, "child"), "key3", "value3");
-//      Map<Object, Object> data = new HashMap<Object, Object>();
-//      data.put("key", "value");
-//
-//      List<Event> expected = new ArrayList<Event>();
-//
-//      // now evict the node - which should cause a passivation
-//      eventLog.events.clear();
-//      cache.evict(fqn);
-//      expected.add(new EventImpl(true, cache, null, data, fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(false, cache, null, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      assertEquals(expected, eventLog.events);
-//
-//      // now load the node.
-//      expected.clear();
-//      eventLog.events.clear();
-//      tm.begin();
-//      Transaction tx = tm.getTransaction();
-//      cache.put(fqn, "key2", "value2");
-//      tm.commit();
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
-//      expected.add(new EventImpl(true, cache, null, Collections.emptyMap(), fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(false, cache, null, data, fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(true, cache, PUT_DATA, data, fqn, tx, true, null, false, null, NODE_MODIFIED));
-//      expected.add(new EventImpl(false, cache, PUT_DATA, Collections.singletonMap("key2", "value2"), fqn, tx, true, null, false, null, NODE_MODIFIED));
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, true, null, TRANSACTION_COMPLETED));
-//      assertEquals(expected, eventLog.events);
-//
-//      assert cache.get(fqn, "key").equals("value");
-//      assert cache.get(fqn, "key2").equals("value2");
-//   }
-}
+
+   CacheManager cm;
+
+   @BeforeMethod
+   public void setUp() {
+      cm = new DefaultCacheManager();
+      Configuration c = new Configuration();
+      CacheLoaderManagerConfig clmc = new CacheLoaderManagerConfig();
+      DummyInMemoryCacheLoader.Cfg clc = new DummyInMemoryCacheLoader.Cfg("no_passivation");
+      clmc.addCacheLoaderConfig(clc);
+      c.setCacheLoaderManagerConfig(clmc);
+      cm.defineCache("no_passivation", c);
+
+      c = c.clone();
+      ((DummyInMemoryCacheLoader.Cfg) c.getCacheLoaderManagerConfig().getFirstCacheLoaderConfig()).setStore("passivation");
+      c.getCacheLoaderManagerConfig().setPassivation(true);
+      cm.defineCache("passivation", c);
+   }
+
+   @AfterMethod
+   public void tearDown() {
+      TestingUtil.killCacheManagers(cm);
+   }
+
+   public void testLoadingAndStoring() {
+      Cache c = cm.getCache("no_passivation");
+      TestListener l = new TestListener();
+      c.addListener(l);
+
+      assert l.loaded.isEmpty();
+      assert l.activated.isEmpty();
+      assert l.passivated.isEmpty();
+
+      c.put("k", "v");
+
+      assert l.loaded.isEmpty();
+      assert l.activated.isEmpty();
+      assert l.passivated.isEmpty();
+
+      c.evict("k");
+
+      assert l.loaded.isEmpty();
+      assert l.activated.isEmpty();
+      assert l.passivated.isEmpty();
+
+      c.remove("k");
+
+      assert l.loaded.contains("k");
+      assert l.loaded.size() == 1;
+      assert l.activated.isEmpty();
+      assert l.passivated.isEmpty();
+
+      c.put("k", "v");
+      c.evict("k");
+
+      assert l.loaded.size() == 1;
+      assert l.activated.isEmpty();
+      assert l.passivated.isEmpty();
+
+      c.putAll(Collections.singletonMap("k2", "v2"));
+      assert l.loaded.size() == 1;
+      assert l.activated.isEmpty();
+      assert l.passivated.isEmpty();
+
+      c.putAll(Collections.singletonMap("k", "v-new"));
+      assert l.passivated.isEmpty();
+      assert l.loaded.size() == 1;
+      assert l.activated.isEmpty();
+
+      c.clear();
+      assert l.passivated.isEmpty();
+      assert l.loaded.size() == 1;
+      assert l.activated.isEmpty();
+
+      c.putAll(Collections.singletonMap("k2", "v-new"));
+      c.evict("k2");
+      assert l.passivated.isEmpty();
+      assert l.loaded.size() == 1;
+      assert l.activated.isEmpty();
+
+      c.replace("k2", "something");
+      assert l.passivated.isEmpty();
+      assert l.loaded.size() == 2;
+      assert l.loaded.contains("k2");
+      assert l.activated.isEmpty();
+   }
+
+   public void testActivatingAndPassivating() {
+      Cache c = cm.getCache("passivation");
+      TestListener l = new TestListener();
+      c.addListener(l);
+
+      assert l.loaded.isEmpty();
+      assert l.activated.isEmpty();
+      assert l.passivated.isEmpty();
+
+      c.put("k", "v");
+
+      assert l.loaded.isEmpty();
+      assert l.activated.isEmpty();
+      assert l.passivated.isEmpty();
+
+      c.evict("k");
+
+      assert l.loaded.isEmpty();
+      assert l.activated.isEmpty();
+      assert l.passivated.contains("k");
+
+      c.remove("k");
+
+      assert l.loaded.contains("k");
+      assert l.activated.contains("k");
+      assert l.passivated.contains("k");
+   }
+
+
+   @Listener
+   public class TestListener {
+      List<Object> loaded = new LinkedList<Object>();
+      List<Object> activated = new LinkedList<Object>();
+      List<Object> passivated = new LinkedList<Object>();
+
+      @CacheEntryLoaded
+      public void handleLoaded(CacheEntryEvent e) {
+         if (e.isPre()) loaded.add(e.getKey());
+      }
+
+      @CacheEntryActivated
+      public void handleActivated(CacheEntryEvent e) {
+         if (e.isPre()) activated.add(e.getKey());
+      }
+
+      @CacheEntryPassivated
+      public void handlePassivated(CacheEntryEvent e) {
+         if (e.isPre()) passivated.add(e.getKey());
+      }
+
+      void reset() {
+         loaded.clear();
+         activated.clear();
+         passivated.clear();
+      }
+   }
+}
\ No newline at end of file

Deleted: core/branches/flat/src/test/java/org/horizon/notifications/CacheListenerPassivationTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/notifications/CacheListenerPassivationTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/notifications/CacheListenerPassivationTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -1,184 +0,0 @@
-package org.horizon.notifications;
-
-import org.testng.annotations.Test;
-
- at Test(groups = "functional", testName = "notifications.CacheListenerPassivationTest")
-public class CacheListenerPassivationTest {
-   // TODO implement me!
-//   private Cache<Object, Object> cache;
-//   private EventLog eventLog = new EventLog();
-//   private TransactionManager tm;
-//   private Fqn fqn = Fqn.fromString("/test");
-//
-//   @BeforeMethod(alwaysRun = true)
-//   public void setUp() throws Exception
-//   {
-//      Configuration c = new Configuration();
-//      c.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
-//      c.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
-//
-//      CacheLoaderManagerConfig clc = new CacheLoaderManagerConfig();
-//      IndividualCacheLoaderConfig iclc = new IndividualCacheLoaderConfig();
-//      iclc.setClassName(DummyInMemoryCacheLoader.class.getName());
-//      clc.addIndividualCacheLoaderConfig(iclc);
-//      clc.setPassivation(true);
-//
-//      c.setCacheLoaderConfig(clc);
-//      cache = new UnitTestCacheFactory<Object, Object>().createCacheManager(c, getClass());
-//      eventLog.events.clear();
-//      cache.addCacheListener(eventLog);
-//      tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
-//   }
-//
-//   @AfterMethod(alwaysRun = true)
-//   public void tearDown() throws Exception
-//   {
-//      TestingUtil.killCaches(cache);
-//      cache = null;
-//   }
-//
-//   public void testActivationAndPassivation() throws Exception
-//   {
-//      assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
-//      cache.put(fqn, "key", "value");
-//      Map<Object, Object> data = new HashMap<Object, Object>();
-//      data.put("key", "value");
-//
-//      List<Event> expected = new ArrayList<Event>();
-//
-//      // now evict the node - which should cause a passivation
-//      eventLog.events.clear();
-//      cache.evict(fqn);
-//      expected.add(new EventImpl(true, cache, null, data, fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(false, cache, null, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      assertEquals(expected, eventLog.events);
-//
-//      // now load the node.
-//      expected.clear();
-//      eventLog.events.clear();
-//      cache.get(fqn, "DOES_NOT_EXIST");
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(true, cache, null, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(false, cache, null, data, fqn, null, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_VISITED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_VISITED));
-//
-//      assertEquals(expected, eventLog.events);
-//   }
-//
-//   public void testActivationAndPassivationTxNoMods() throws Exception
-//   {
-//      assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
-//      cache.put(fqn, "key", "value");
-//      Map<Object, Object> data = new HashMap<Object, Object>();
-//      data.put("key", "value");
-//
-//      List<Event> expected = new ArrayList<Event>();
-//
-//      // now evict the node - which should cause a passivation
-//      eventLog.events.clear();
-//      cache.evict(fqn);
-//      expected.add(new EventImpl(true, cache, null, data, fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(false, cache, null, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      assertEquals(expected, eventLog.events);
-//
-//      // now load the node.
-//      expected.clear();
-//      eventLog.events.clear();
-//      tm.begin();
-//      Transaction tx = tm.getTransaction();
-//      cache.get(fqn, "DOES_NOT_EXIST");
-//      tm.commit();
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(true, cache, null, Collections.emptyMap(), fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(false, cache, null, data, fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, tx, true, null, false, null, NODE_VISITED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, tx, true, null, false, null, NODE_VISITED));
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, true, null, TRANSACTION_COMPLETED));
-//      assertEquals(expected, eventLog.events);
-//   }
-//
-//   public void testActivationAndPassivationTxMods() throws Exception
-//   {
-//      assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
-//      cache.put(fqn, "key", "value");
-//      Map<Object, Object> data = new HashMap<Object, Object>();
-//      data.put("key", "value");
-//
-//      List<Event> expected = new ArrayList<Event>();
-//
-//      // now evict the node - which should cause a passivation
-//      eventLog.events.clear();
-//      cache.evict(fqn);
-//      expected.add(new EventImpl(true, cache, null, data, fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(false, cache, null, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      assertEquals(expected, eventLog.events);
-//
-//      // now load the node.
-//      expected.clear();
-//      eventLog.events.clear();
-//      tm.begin();
-//      Transaction tx = tm.getTransaction();
-//      cache.put(fqn, "key2", "value2");
-//      tm.commit();
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
-//      expected.add(new EventImpl(true, cache, null, Collections.emptyMap(), fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(false, cache, null, data, fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(true, cache, PUT_DATA, data, fqn, tx, true, null, false, null, NODE_MODIFIED));
-//      expected.add(new EventImpl(false, cache, PUT_DATA, Collections.singletonMap("key2", "value2"), fqn, tx, true, null, false, null, NODE_MODIFIED));
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, true, null, TRANSACTION_COMPLETED));
-//      assertEquals(expected, eventLog.events);
-//
-//      assert cache.get(fqn, "key").equals("value");
-//      assert cache.get(fqn, "key2").equals("value2");
-//   }
-//
-//   public void testActivationAndPassivationTxModsWithChildren() throws Exception
-//   {
-//      assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
-//      cache.put(fqn, "key", "value");
-//      cache.put(Fqn.fromRelativeElements(fqn, "child"), "key3", "value3");
-//      Map<Object, Object> data = new HashMap<Object, Object>();
-//      data.put("key", "value");
-//
-//      List<Event> expected = new ArrayList<Event>();
-//
-//      // now evict the node - which should cause a passivation
-//      eventLog.events.clear();
-//      cache.evict(fqn);
-//      expected.add(new EventImpl(true, cache, null, data, fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(false, cache, null, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_PASSIVATED));
-//      expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_EVICTED));
-//      assertEquals(expected, eventLog.events);
-//
-//      // now load the node.
-//      expected.clear();
-//      eventLog.events.clear();
-//      tm.begin();
-//      Transaction tx = tm.getTransaction();
-//      cache.put(fqn, "key2", "value2");
-//      tm.commit();
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
-//      expected.add(new EventImpl(true, cache, null, Collections.emptyMap(), fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(false, cache, null, data, fqn, tx, true, null, false, null, NODE_ACTIVATED));
-//      expected.add(new EventImpl(true, cache, PUT_DATA, data, fqn, tx, true, null, false, null, NODE_MODIFIED));
-//      expected.add(new EventImpl(false, cache, PUT_DATA, Collections.singletonMap("key2", "value2"), fqn, tx, true, null, false, null, NODE_MODIFIED));
-//      expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, true, null, TRANSACTION_COMPLETED));
-//      assertEquals(expected, eventLog.events);
-//
-//      assert cache.get(fqn, "key").equals("value");
-//      assert cache.get(fqn, "key2").equals("value2");
-//   }
-}

Modified: core/branches/flat/src/test/java/org/horizon/replication/AsyncReplTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/AsyncReplTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/replication/AsyncReplTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -28,7 +28,7 @@
 
    Cache cache1, cache2;
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration asyncConfiguration = new Configuration();
       asyncConfiguration.setCacheMode(Configuration.CacheMode.REPL_ASYNC);
       asyncConfiguration.setSyncCommitPhase(true);

Modified: core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/replication/BaseReplicatedAPITest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -21,7 +21,7 @@
    AdvancedCache cache1, cache2;
    protected boolean isSync;
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration c = new Configuration();
       c.setStateRetrievalTimeout(1000);
       c.setFetchInMemoryState(false);

Modified: core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/replication/ReplicationExceptionTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -34,7 +34,7 @@
 public class ReplicationExceptionTest extends MultipleCacheManagersTest {
    private AdvancedCache cache1, cache2;
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration configuration = new Configuration();
 
       configuration.setCacheMode(Configuration.CacheMode.REPL_SYNC);

Modified: core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/replication/SyncCacheListenerTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -37,7 +37,7 @@
    private Cache<Object, Object> cache1, cache2;
    private final static Log log = LogFactory.getLog(SyncCacheListenerTest.class);
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration conf = new Configuration();
       conf.setSyncCommitPhase(true);
       conf.setCacheMode(Configuration.CacheMode.REPL_SYNC);

Modified: core/branches/flat/src/test/java/org/horizon/replication/SyncReplTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/replication/SyncReplTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/replication/SyncReplTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -34,7 +34,7 @@
    Cache cache1, cache2;
    String k = "key", v = "value";
 
-   protected void createCaches() throws Throwable {
+   protected void createCacheManagers() throws Throwable {
       Configuration replSync = new Configuration();
       replSync.setCacheMode(Configuration.CacheMode.REPL_SYNC);
       createClusteredCaches(2, "replSync", replSync);

Modified: core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java
===================================================================
--- core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java	2009-02-17 15:24:59 UTC (rev 7700)
+++ core/branches/flat/src/test/java/org/horizon/test/MultipleCacheManagersTest.java	2009-02-17 15:29:55 UTC (rev 7701)
@@ -17,7 +17,7 @@
  * Base class for tests that operates on clusters of caches. The way tests extending this class operates is:
  * <pre>
  *    1) created cache managers before tests start. The cache managers are only created once
- *    2) after each test method runs, the cache managers are being cleared
+ *    2) after each test method runs, the cache instances are being cleared
  *    3) next test method will run on same cacheManager instance. This way the test is much faster, as CacheManagers
  *       are expensive to create.
  * </pre>
@@ -33,7 +33,7 @@
 
    @BeforeClass
    public void create() throws Throwable {
-      createCaches();
+      createCacheManagers();
    }
 
    @AfterClass
@@ -113,5 +113,9 @@
       }
    }
 
-   protected abstract void createCaches() throws Throwable;
+   /**
+    * Create the cache managers you need for your test.  Note that the cache managers you create *must* be created using
+    * {@link #addClusterEnabledCacheManager()}
+    */
+   protected abstract void createCacheManagers() throws Throwable;
 }




More information about the jbosscache-commits mailing list