[jboss-cvs] JBossAS SVN: r107322 - in projects/cluster/ha-server-cache-ispn/trunk/src: main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn and 20 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Aug 2 15:56:11 EDT 2010


Author: pferraro
Date: 2010-08-02 15:56:09 -0400 (Mon, 02 Aug 2010)
New Revision: 107322

Added:
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntry.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorage.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManager.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactory.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorage.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorage.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactory.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryImpl.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/sso/
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/sso/ispn/
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/sso/ispn/CacheKey.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/sso/ispn/SSOClusterManager.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntryTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorageTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactoryTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorageTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/sso/
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/sso/ispn/
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/sso/ispn/SSOClusterManagerTest.java
Removed:
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntry.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorage.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManager.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactory.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorage.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorage.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactory.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryImpl.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/CacheKey.java
   projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/SSOClusterManager.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntryTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorageTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactoryTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorageTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryTest.java
   projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/SSOClusterManagerTest.java
Log:
Ooops.  Refactor org.jboss.ha.web.tomcat.service -> org.jboss.web.tomcat.service

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntry.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntry.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntry.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,83 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import org.infinispan.atomic.AtomicMap;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
-
-/**
- * Enumerates the properties of a session to be stored in a cache entry.
- * Provides get/put methods which encapsulate away the details of the map key.
- * @author Paul Ferraro
- */
-public enum AtomicMapEntry
-{
-   VERSION(Integer.class), TIMESTAMP(Long.class), METADATA(DistributableSessionMetadata.class), ATTRIBUTES(Object.class);
-   
-   private Class<?> targetClass;
-   
-   private AtomicMapEntry(Class<?> targetClass)
-   {
-      this.targetClass = targetClass;
-   }
-   
-   /**
-    * Returns the value associated with this atomic map entry.
-    * @param <T> the value type
-    * @param data an atomic map
-    * @return the entry value
-    */
-   public <T> T get(AtomicMap<Object, Object> data)
-   {
-      return this.cast(data.get(this.key()));
-   }
-
-   /**
-    * Add this entry to the specified map if the specified value is non-null.
-    * @param <T> the value type
-    * @param data an atomic map
-    * @param value the entry value
-    * @return the old entry value, or null if no previous entry existed
-    */
-   public <T> T put(AtomicMap<Object, Object> data, Object value)
-   {
-      if (value == null) return null;
-      
-      if (!this.targetClass.isInstance(value))
-      {
-         throw new IllegalArgumentException(String.format("Attempt to put value of type %s into %s entry", value.getClass().getName(), this));
-      }
-      
-      return this.cast(data.put(this.key(), value));
-   }
-   
-   @SuppressWarnings("unchecked")
-   private <T> T cast(Object value)
-   {
-      return (value != null) ? (T) this.targetClass.cast(value) : null;
-   }
-   
-   private Byte key()
-   {
-      return Byte.valueOf((byte) this.ordinal());
-   }
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorage.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorage.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorage.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,69 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import java.util.Map;
-
-import org.infinispan.atomic.AtomicMap;
-import org.jboss.metadata.web.jboss.ReplicationGranularity;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingSessionGranularitySessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
-
-/**
- * Handles session attribute load/store operations for {@link ReplicationGranularity#SESSION} distributed session managers.
- * @author Paul Ferraro
- */
-public class CoarseSessionAttributeStorage implements SessionAttributeStorage<OutgoingSessionGranularitySessionData>
-{
-   private final SessionAttributeMarshaller marshaller;
-   
-   public CoarseSessionAttributeStorage(SessionAttributeMarshaller marshaller)
-   {
-      this.marshaller = marshaller;
-   }
-   
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage#store(org.infinispan.atomic.AtomicMap, org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData)
-    */
-   @Override
-   public void store(AtomicMap<Object, Object> data, OutgoingSessionGranularitySessionData sessionData)
-   {
-      Map<String, Object> attributes = sessionData.getSessionAttributes();
-      
-      if (attributes != null)
-      {
-         AtomicMapEntry.ATTRIBUTES.put(data, this.marshaller.marshal(attributes));
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage#load(org.infinispan.atomic.AtomicMap)
-    */
-   @SuppressWarnings("unchecked")
-   @Override
-   public Map<String, Object> load(AtomicMap<Object, Object> data) throws Exception
-   {
-      return (Map<String, Object>) this.marshaller.unmarshal(AtomicMapEntry.ATTRIBUTES.get(data));
-   }
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManager.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManager.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManager.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,491 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.transaction.TransactionManager;
-
-import org.infinispan.Cache;
-import org.infinispan.atomic.AtomicMap;
-import org.infinispan.config.CacheLoaderManagerConfig;
-import org.infinispan.config.Configuration;
-import org.infinispan.context.Flag;
-import org.infinispan.distribution.DistributionManager;
-import org.infinispan.lifecycle.ComponentStatus;
-import org.infinispan.manager.CacheContainer;
-import org.infinispan.manager.EmbeddedCacheManager;
-import org.infinispan.notifications.Listener;
-import org.infinispan.notifications.cachelistener.annotation.CacheEntryActivated;
-import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
-import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
-import org.infinispan.notifications.cachelistener.event.CacheEntryActivatedEvent;
-import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
-import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
-import org.infinispan.transaction.tm.BatchModeTransactionManager;
-import org.jboss.ha.ispn.CacheContainerRegistry;
-import org.jboss.ha.ispn.atomic.AtomicMapFactory;
-import org.jboss.ha.ispn.invoker.CacheInvoker;
-import org.jboss.logging.Logger;
-import org.jboss.web.tomcat.service.session.distributedcache.impl.BatchingManagerImpl;
-import org.jboss.web.tomcat.service.session.distributedcache.impl.IncomingDistributableSessionDataImpl;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.BatchingManager;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.IncomingDistributableSessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionOwnershipSupport;
-
-/**
- * Distributed cache manager implementation using Infinispan.
- * @author Paul Ferraro
- */
- at Listener
-public class DistributedCacheManager<T extends OutgoingDistributableSessionData> implements org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager<T>
-{
-   static String mask(String sessionId)
-   {
-      if (sessionId == null) return null;
-      
-      int length = sessionId.length();
-      
-      if (length <= 8) return sessionId;
-
-      return sessionId.substring(0, 2) + "****" + sessionId.substring(length - 6, length);
-   }
-
-   static RuntimeException getRuntimeException(String message, Exception e)
-   {   
-      if (e instanceof RuntimeException) return (RuntimeException) e;
-      
-      return new RuntimeException(message != null ? message : e.toString(), e);
-   }
-   
-   private static final Logger log = Logger.getLogger(DistributedCacheManager.class);
-   
-   private final LocalDistributableSessionManager manager;
-   private final SessionAttributeStorage<T> attributeStorage;
-   private final CacheInvoker invoker;
-   private final CacheContainerRegistry registry;
-   final AtomicMapFactory atomicMapFactory;
-   
-   private Cache<String, AtomicMap<Object, Object>> cache;
-   private BatchingManagerImpl batchingManager;
-   private boolean passivationEnabled = false;
-   
-   public DistributedCacheManager(LocalDistributableSessionManager manager, CacheContainerRegistry registry, SessionAttributeStorage<T> attributeStorage, CacheInvoker invoker, AtomicMapFactory atomicMapFactory)
-   {
-      this.manager = manager;
-      this.registry = registry;
-      this.attributeStorage = attributeStorage;
-      this.invoker = invoker;
-      this.atomicMapFactory = atomicMapFactory;
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#start()
-    */
-   @Override
-   public void start()
-   {
-      String templateCacheName = this.manager.getReplicationConfig().getCacheName();
-      
-      String containerName = null;
-      
-      if (templateCacheName != null)
-      {
-         String[] parts = templateCacheName.split(":");
-         
-         if (parts.length == 2)
-         {
-            containerName = parts[0];
-            templateCacheName = parts[1];
-         }
-      }
-      
-      CacheContainer container = this.registry.getCacheContainer(containerName);
-      
-      String hostName = this.manager.getHostName();
-      String host = (hostName == null) || hostName.isEmpty() ? "localhost" : hostName;
-      
-      String context = this.manager.getContextName();
-      String path = context.isEmpty() || context.equals("/") ? "ROOT" : context.startsWith("/") ? context.substring(1) : context;
-
-      String cacheName = host + "/" + path;
-      
-      EmbeddedCacheManager manager = (EmbeddedCacheManager) container.getCache().getCacheManager();
-      manager.defineConfiguration(cacheName, templateCacheName, new Configuration());
-      
-      this.cache = manager.getCache(cacheName);
-      
-      if (this.cache.getStatus() != ComponentStatus.RUNNING)
-      {
-         this.cache.start();
-      }
-      
-      TransactionManager tm = this.cache.getAdvancedCache().getTransactionManager();
-      
-      if (!(tm instanceof BatchModeTransactionManager))
-      {
-         throw new IllegalStateException("Unexpected transaction manager type: " + ((tm != null) ? tm.getClass().getName() : "null"));
-      }
-      
-      this.batchingManager = new BatchingManagerImpl(tm);
-      
-      this.cache.addListener(this);
-      
-      CacheLoaderManagerConfig loaderManagerConfig = this.cache.getConfiguration().getCacheLoaderManagerConfig();
-      
-      this.passivationEnabled = (loaderManagerConfig != null) ? loaderManagerConfig.isPassivation().booleanValue() && !loaderManagerConfig.isShared().booleanValue() : false;
-   }
-   
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#stop()
-    */
-   @Override
-   public void stop()
-   {
-      this.cache.removeListener(this);
-      
-      this.cache.stop();
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#getBatchingManager()
-    */
-   @Override
-   public BatchingManager getBatchingManager()
-   {
-      return this.batchingManager;
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#sessionCreated(java.lang.String)
-    */
-   @Override
-   public void sessionCreated(String sessionId)
-   {
-      // Do nothing
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#storeSessionData(org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData)
-    */
-   @Override
-   public void storeSessionData(T sessionData)
-   {
-      final String sessionId = sessionData.getRealId();
-      
-      if (log.isTraceEnabled())
-      {
-         log.trace("putSession(): putting session " + mask(sessionId));
-      }     
-      
-      Operation<AtomicMap<Object, Object>> operation = new Operation<AtomicMap<Object, Object>>()
-      {
-         @Override
-         public AtomicMap<Object, Object> invoke(Cache<String, AtomicMap<Object, Object>> cache)
-         {
-            return DistributedCacheManager.this.atomicMapFactory.getAtomicMap(cache, sessionId, true);
-         }
-      };
-      
-      AtomicMap<Object, Object> data = this.invoker.invoke(this.cache, operation);
-      
-      AtomicMapEntry.VERSION.put(data, Integer.valueOf(sessionData.getVersion()));
-      AtomicMapEntry.METADATA.put(data, sessionData.getMetadata());
-      AtomicMapEntry.TIMESTAMP.put(data, sessionData.getTimestamp());
-      
-      this.attributeStorage.store(data, sessionData);
-   }
-   
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#getSessionData(java.lang.String, boolean)
-    */
-   @Override
-   public IncomingDistributableSessionData getSessionData(String sessionId, boolean initialLoad)
-   {
-      return this.getData(sessionId, true);
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#getSessionData(java.lang.String, java.lang.String, boolean)
-    */
-   @Override
-   public IncomingDistributableSessionData getSessionData(final String sessionId, String dataOwner, boolean includeAttributes)
-   {
-      return (dataOwner == null) ? this.getData(sessionId, includeAttributes) : null;
-   }
-   
-   private IncomingDistributableSessionData getData(final String sessionId, boolean includeAttributes)
-   {
-      Operation<AtomicMap<Object, Object>> operation = new Operation<AtomicMap<Object, Object>>()
-      {
-         @Override
-         public AtomicMap<Object, Object> invoke(Cache<String, AtomicMap<Object, Object>> cache)
-         {
-            return DistributedCacheManager.this.atomicMapFactory.getAtomicMap(cache, sessionId, false);
-         }
-      };
-      
-      AtomicMap<Object, Object> data = this.invoker.invoke(this.cache, operation);
-      
-      // If requested session is no longer in the cache; return null
-      if (data == null) return null;
-      
-      try
-      {
-         Integer version = AtomicMapEntry.VERSION.get(data);
-         Long timestamp = AtomicMapEntry.TIMESTAMP.get(data);
-         DistributableSessionMetadata metadata = AtomicMapEntry.METADATA.get(data);
-         IncomingDistributableSessionDataImpl result = new IncomingDistributableSessionDataImpl(version, timestamp, metadata);
-         
-         if (includeAttributes)
-         {
-            try
-            {
-               result.setSessionAttributes(this.attributeStorage.load(data));
-            }
-            catch (Exception e)
-            {
-               throw getRuntimeException("Failed to load session attributes for session: " + mask(sessionId), e);
-            }
-         }
-
-         return result;
-      }
-      catch (Exception e)
-      {
-         String message = String.format("Problem accessing session [%s]: %s", mask(sessionId), e.toString());
-         log.warn(message);
-         log.debug(message, e);
-         
-         // Clean up
-         this.removeSessionLocal(sessionId);
-         
-         return null;
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#removeSession(java.lang.String)
-    */
-   @Override
-   public void removeSession(final String sessionId)
-   {
-      this.removeSession(sessionId, false);
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#removeSessionLocal(java.lang.String)
-    */
-   @Override
-   public void removeSessionLocal(final String sessionId)
-   {
-      this.removeSession(sessionId, true);
-   }
-
-   private void removeSession(final String sessionId, final boolean local)
-   {
-      Operation<AtomicMap<Object, Object>> operation = new Operation<AtomicMap<Object, Object>>()
-      {
-         @Override
-         public AtomicMap<Object, Object> invoke(Cache<String, AtomicMap<Object, Object>> cache)
-         {
-            if (local)
-            {
-               cache.getAdvancedCache().withFlags(Flag.CACHE_MODE_LOCAL);
-            }
-            
-            return cache.remove(sessionId);
-         }
-      };
-      
-      this.invoker.invoke(this.cache, operation);
-   }
-   
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#removeSessionLocal(java.lang.String, java.lang.String)
-    */
-   @Override
-   public void removeSessionLocal(String sessionId, String dataOwner)
-   {
-      if (dataOwner == null)
-      {
-         this.removeSession(sessionId, true);
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#evictSession(java.lang.String)
-    */
-   @Override
-   public void evictSession(final String sessionId)
-   {
-      Operation<Void> operation = new Operation<Void>()
-      {
-         @Override
-         public Void invoke(Cache<String, AtomicMap<Object, Object>> cache)
-         {
-            cache.evict(sessionId);
-            return null;
-         }
-      };
-      
-      this.invoker.invoke(this.cache, operation);
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#evictSession(java.lang.String, java.lang.String)
-    */
-   @Override
-   public void evictSession(String sessionId, String dataOwner)
-   {
-      if (dataOwner == null)
-      {
-         this.evictSession(sessionId);
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#getSessionIds()
-    */
-   @Override
-   public Map<String, String> getSessionIds()
-   {
-      Map<String, String> result = new HashMap<String, String>();
-
-      for (String sessionId: this.cache.keySet())
-      {
-         result.put(sessionId, null);
-      }
-      
-      return result;
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#isPassivationEnabled()
-    */
-   @Override
-   public boolean isPassivationEnabled()
-   {
-      return this.passivationEnabled;
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#setForceSynchronous(boolean)
-    */
-   @Override
-   public void setForceSynchronous(boolean forceSynchronous)
-   {
-      this.invoker.setForceSynchronous(forceSynchronous);
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#getSessionOwnershipSupport()
-    */
-   @Override
-   public SessionOwnershipSupport getSessionOwnershipSupport()
-   {
-      return null;
-   }
-   
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#isLocal(java.lang.String)
-    */
-   @Override
-   public boolean isLocal(String realId)
-   {
-      DistributionManager manager = this.cache.getAdvancedCache().getDistributionManager();
-      
-      return (manager != null) ? manager.isLocal(realId) : true;
-   }
-
-   @CacheEntryRemoved
-   public void removed(CacheEntryRemovedEvent event)
-   {
-      if (event.isPre() || event.isOriginLocal()) return;
-      
-      this.manager.notifyRemoteInvalidation((String) event.getKey());
-   }
-   
-   @CacheEntryModified
-   public void modified(CacheEntryModifiedEvent event)
-   {
-      if (event.isPre() || event.isOriginLocal()) return;
-      
-      String sessionId = (String) event.getKey();
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> data = (AtomicMap<Object, Object>) event.getValue();
-      
-      Integer version = AtomicMapEntry.VERSION.get(data);
-      Long timestamp = AtomicMapEntry.TIMESTAMP.get(data);
-      DistributableSessionMetadata metadata = AtomicMapEntry.METADATA.get(data);
-      
-      if (timestamp == null)
-      {
-         log.warn(String.format("No timestamp attribute found in node modification event for session %s", mask(sessionId)));
-         return;
-      }
-      
-      boolean updated = this.manager.sessionChangedInDistributedCache(sessionId, null, version.intValue(), timestamp.longValue(), metadata);
-      
-      if (!updated)
-      {
-         log.warn(String.format("Possible concurrency problem: Replicated version id %d is less than or equal to in-memory version for session %s", version, mask(sessionId))); 
-      }
-   }
-   
-   @CacheEntryActivated
-   public void activated(CacheEntryActivatedEvent event)
-   {
-      if (event.isPre()) return;
-      
-      if (this.manager.isPassivationEnabled())
-      {
-         this.manager.sessionActivated();
-      }
-   }
-   
-   // Simplified CacheInvoker.Operation using assigned key/value types
-   static interface Operation<R> extends CacheInvoker.Operation<String, AtomicMap<Object, Object>, R>
-   {      
-   }
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactory.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactory.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactory.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,81 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import org.jboss.ha.ispn.CacheContainerRegistry;
-import org.jboss.ha.ispn.DefaultCacheContainerRegistry;
-import org.jboss.ha.ispn.atomic.AtomicMapFactory;
-import org.jboss.ha.ispn.atomic.DefaultAtomicMapFactory;
-import org.jboss.ha.ispn.invoker.CacheInvoker;
-import org.jboss.ha.ispn.invoker.RetryingCacheInvoker;
-import org.jboss.web.tomcat.service.session.distributedcache.impl.SessionAttributeMarshallerFactoryImpl;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshallerFactory;
-
-/**
- * Factory for creating an Infinispan-backed distributed cache manager.
- * @author Paul Ferraro
- */
-public class DistributedCacheManagerFactory implements org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManagerFactory
-{
-   private CacheContainerRegistry registry = DefaultCacheContainerRegistry.getInstance();
-   private SessionAttributeStorageFactory storageFactory = new SessionAttributeStorageFactoryImpl();
-   private SessionAttributeMarshallerFactory marshallerFactory = new SessionAttributeMarshallerFactoryImpl();
-   private CacheInvoker invoker = new RetryingCacheInvoker(10, 100);
-   private AtomicMapFactory atomicMapFactory = new DefaultAtomicMapFactory();
-   
-   @Override
-   public <T extends OutgoingDistributableSessionData> org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager<T> getDistributedCacheManager(LocalDistributableSessionManager manager)
-   {
-      SessionAttributeMarshaller marshaller = this.marshallerFactory.createMarshaller(manager);
-      SessionAttributeStorage<T> storage = this.storageFactory.createStorage(manager.getReplicationConfig().getReplicationGranularity(), marshaller);
-      
-      return new DistributedCacheManager<T>(manager, this.registry, storage, this.invoker, this.atomicMapFactory);
-   }
-   
-   public void setCacheContainerRegistry(CacheContainerRegistry registry)
-   {
-      this.registry = registry;
-   }
-   
-   public void setSessionAttributeStorageFactory(SessionAttributeStorageFactory storageFactory)
-   {
-      this.storageFactory = storageFactory;
-   }
-   
-   public void setSessionAttributeMarshallerFactory(SessionAttributeMarshallerFactory marshallerFactory)
-   {
-      this.marshallerFactory = marshallerFactory;
-   }
-   
-   public void setCacheInvoker(CacheInvoker invoker)
-   {
-      this.invoker = invoker;
-   }
-   
-   public void setAtomicMapFactory(AtomicMapFactory atomicMapFactory)
-   {
-      this.atomicMapFactory = atomicMapFactory;
-   }
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorage.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorage.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorage.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,109 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import org.infinispan.atomic.AtomicMap;
-import org.jboss.metadata.web.jboss.ReplicationGranularity;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingAttributeGranularitySessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
-
-/**
- * Handles session attribute load/store operations for {@link ReplicationGranularity#ATTRIBUTE} distributed session managers.
- * @author Paul Ferraro
- */
-public class FineSessionAttributeStorage implements SessionAttributeStorage<OutgoingAttributeGranularitySessionData>
-{
-   private final SessionAttributeMarshaller marshaller;
-   
-   public FineSessionAttributeStorage(SessionAttributeMarshaller marshaller)
-   {
-      this.marshaller = marshaller;
-   }
-   
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage#store(org.infinispan.atomic.AtomicMap, org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData)
-    */
-   @Override
-   public void store(AtomicMap<Object, Object> data, OutgoingAttributeGranularitySessionData sessionData)
-   {
-      Map<String, Object> modified = sessionData.getModifiedSessionAttributes();
-      
-      if (modified != null)
-      {
-         for (Map.Entry<String, Object> entry: modified.entrySet())
-         {
-            data.put(entry.getKey(), this.marshaller.marshal(entry.getValue()));
-         }
-      }
-      
-      Set<String> removed = sessionData.getRemovedSessionAttributes();
-      
-      if (removed != null)
-      {
-         for (String attribute: removed)
-         {
-            data.remove(attribute);
-         }
-      }
-   }
-
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage#load(org.infinispan.atomic.AtomicMap)
-    */
-   @Override
-   public Map<String, Object> load(AtomicMap<Object, Object> data) throws Exception
-   {
-      Map<String, Object> map = new HashMap<String, Object>();
-      
-      for (Map.Entry<Object, Object> entry: data.entrySet())
-      {
-         Object key = entry.getKey();
-         
-         if (key instanceof String)
-         {
-            String attribute = (String) key;
-            
-            try
-            {
-               map.put(attribute, this.marshaller.unmarshal(entry.getValue()));
-            }
-            catch (RuntimeException e)
-            {
-               throw e;
-            }
-            catch (Exception e)
-            {
-               throw new Exception("Failed to unmarshal session attribute: " + attribute, e);
-            }
-         }
-      }
-      
-      return map;
-   }
-
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorage.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorage.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorage.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,38 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import java.util.Map;
-
-import org.infinispan.atomic.AtomicMap;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
-
-/**
- * Strategy for 
- * @author Paul Ferraro
- */
-public interface SessionAttributeStorage<T extends OutgoingDistributableSessionData>
-{
-   void store(AtomicMap<Object, Object> data, T sessionData);
-   
-   Map<String, Object> load(AtomicMap<Object, Object> data) throws Exception;
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactory.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactory.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactory.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,42 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import org.jboss.metadata.web.jboss.ReplicationGranularity;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
-
-/**
- * Factory for creating strategies for storing session attributes.
- * @author Paul Ferraro
- */
-public interface SessionAttributeStorageFactory
-{
-   /**
-    * Creates a session attribute storage strategy.
-    * @param <T> the type of session data appropriate for the specified granularity
-    * @param granularity the replication granularity
-    * @param marshaller a session attribute marshaller
-    * @return a strategy for storing session attributes.
-    */
-   <T extends OutgoingDistributableSessionData> SessionAttributeStorage<T> createStorage(ReplicationGranularity granularity, SessionAttributeMarshaller marshaller);
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryImpl.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryImpl.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryImpl.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,62 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import org.jboss.metadata.web.jboss.ReplicationGranularity;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
-
-/**
- * Default factory for creating strategies for storing session attributes.
- * @author Paul Ferraro
- */
-public class SessionAttributeStorageFactoryImpl implements SessionAttributeStorageFactory
-{
-   /**
-    * {@inheritDoc}
-    * @see org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorageFactory#createStorage(org.jboss.metadata.web.jboss.ReplicationGranularity, org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller)
-    */
-   @SuppressWarnings("unchecked")
-   @Override
-   public <T extends OutgoingDistributableSessionData> SessionAttributeStorage<T> createStorage(ReplicationGranularity granularity, SessionAttributeMarshaller marshaller)
-   {
-      switch (granularity)
-      {
-         case SESSION:
-         {
-            return (SessionAttributeStorage<T>) new CoarseSessionAttributeStorage(marshaller);
-         }
-         case ATTRIBUTE:
-         {
-            return (SessionAttributeStorage<T>) new FineSessionAttributeStorage(marshaller);
-         }
-         case FIELD:
-         {
-            throw new IllegalArgumentException("FIELD replication granularity is no longer supported, use SESSION or ATTRIBUTE instead.");
-         }
-         default:
-         {
-            throw new IllegalArgumentException("Unknown replication granularity: " + granularity);
-         }
-      }
-   }
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/CacheKey.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/CacheKey.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/CacheKey.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,73 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2010, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-
-package org.jboss.ha.web.tomcat.service.session.sso.ispn;
-
-/**
- * Used to represent the different types of entries in the cache store.
- *
- * Note that we purposely do not implement equals, which allows many different
- * entries with the same key to be added.
- *
- */
-public class CacheKey
-{
-   public static enum Type { SESSION, CREDENTIAL }
-
-   private final String ssoId;
-   private final Type type;
-
-   public CacheKey(String ssoId, Type type)
-   {
-      this.ssoId = ssoId;
-      this.type = type;
-   }
-
-   public String getSSOID()
-   {
-      return this.ssoId;
-   }
-
-   public Type getType()
-   {
-      return this.type;
-   }
-
-   @Override
-   public int hashCode()
-   {
-      int result = 17;
-      result = 37*result + this.ssoId.hashCode();
-      result = 37*result + this.type.ordinal();
-      return result;
-   }
-   
-   @Override
-   public boolean equals(Object object)
-   {
-      if ((object == null) || !(object instanceof CacheKey)) return false;
-      
-      CacheKey key = (CacheKey) object;
-      
-      return (this.type == key.type) && this.ssoId.equals(key.ssoId);
-   }
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/SSOClusterManager.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/SSOClusterManager.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/SSOClusterManager.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,1150 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2010, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-
-package org.jboss.ha.web.tomcat.service.session.sso.ispn;
-
-import org.infinispan.atomic.AtomicMap;
-import org.infinispan.atomic.AtomicMapLookup;
-import org.infinispan.config.Configuration;
-import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
-import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
-import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
-import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
-import org.infinispan.notifications.cachemanagerlistener.annotation.ViewChanged;
-import org.infinispan.notifications.cachemanagerlistener.event.ViewChangedEvent;
-import org.infinispan.Cache;
-import org.infinispan.remoting.transport.Address;
-import org.jboss.ha.framework.server.ispn.InfinispanHAPartitionCacheHandler;
-import org.jboss.logging.Logger;
-import org.jboss.util.threadpool.ThreadPool;
-import org.jboss.web.tomcat.service.sso.spi.FullyQualifiedSessionId;
-import org.jboss.web.tomcat.service.sso.spi.SSOCredentials;
-import org.jboss.web.tomcat.service.sso.spi.SSOLocalManager;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.transaction.Status;
-import javax.transaction.TransactionManager;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * An implementation of SSOClusterManager that uses a Infinispan cache
- * to share SSO information between cluster nodes.
- *
- * @author Brian E. Stansberry
- * @author Scott Marlow
- * @version $Revision$ $Date: 2007-01-12 03:39:24 +0100 (ven., 12 janv. 2007) $
- */
-// @Listener
-public final class SSOClusterManager implements org.jboss.web.tomcat.service.sso.spi.SSOClusterManager
-{
-   // -------------------------------------------------------------  Constants
-
-
-   /**
-    * Default global value for the threadPoolName property
-    */
-   public static final String DEFAULT_THREAD_POOL_NAME =
-      "jboss.system:service=ThreadPool";
-
-   // -------------------------------------------------------  Instance Fields
-
-   /**
-    * SSO id which the thread is currently storing to the cache
-    */
-   private volatile ThreadLocal<String> beingLocallyAdded = new ThreadLocal<String>();
-
-   /**
-    * SSO id which a thread is currently removing from the cache
-    */
-   private volatile ThreadLocal<String> beingLocallyRemoved = new ThreadLocal<String>();
-
-   /**
-    * SSO id which the thread is deregistering due to removal on another node
-    */
-   private volatile ThreadLocal<String> beingRemotelyRemoved = new ThreadLocal<String>();
-
-   /**
-    * The clustered cache that holds the SSO credentials and the sessions.
-    * The CacheKey will indicate which type it is (CacheKey.CREDENTIAL or CacheKey.SESSION);
-    */
-   private volatile Cache<CacheKey, Object> cache = null;
-
-   /**
-    * Transaction Manager
-    */
-   private volatile TransactionManager tm = null;
-
-   private volatile String threadPoolName = DEFAULT_THREAD_POOL_NAME;
-
-   private volatile ThreadPool threadPool;
-
-   /**
-    * The Log-object for this class
-    */
-   private static final Logger log = Logger.getLogger(SSOClusterManager.class);;
-
-   /**
-    * Whether we are registered as a CacheListener anywhere
-    */
-   private volatile boolean registeredAsListener = false;
-
-   /**
-    * The MBean server we use to access external components (TODO: convert to injection)
-    */
-   private volatile MBeanServer server = null;
-
-   /**
-    * The SingleSignOn for which we are providing cluster support
-    */
-   private volatile SSOLocalManager ssoValve = null;
-
-   /**
-    * Whether we have been started
-    */
-   private volatile boolean started = false;
-
-   /**
-    * Whether we have logged an error due to not having a valid cache
-    */
-   private volatile boolean missingCacheErrorLogged = false;
-
-   /**
-    * Our node's address in the cluster.
-    */
-   private volatile Object localAddress = null;
-
-   /**
-    * The new members of the last view passed to viewChange()
-    */
-   private final Set<Object> currentView = new HashSet<Object>();;
-
-   /** Mutex lock to ensure only one view change at a time is being processed */
-   private final Object cleanupMutex = new Object();
-
-   private volatile InfinispanHAPartitionCacheHandler<CacheKey, Object> cacheHandler;
-
-   // ------------------------------------------------------------  Properties
-
-   public InfinispanHAPartitionCacheHandler getCacheHandler()
-   {
-      return cacheHandler;
-   }
-
-   public void setCacheHandler(InfinispanHAPartitionCacheHandler cacheHandler)
-   {
-      this.cacheHandler = cacheHandler;
-   }
-
-   public String getThreadPoolName()
-   {
-      return threadPoolName;
-   }
-
-   public boolean isUsingThreadPool()
-   {
-      return threadPool != null;
-   }
-
-   // -----------------------------------------------------  SSOClusterManager
-
-   /**
-    * Notify the cluster of the addition of a Session to an SSO session.
-    *
-    * @param ssoId   the id of the SSO session
-    * @param sessionId id of the Session that has been added
-    */
-   public void addSession(String ssoId, FullyQualifiedSessionId sessionId)
-   {
-      if (ssoId == null || sessionId == null)
-      {
-         return;
-      }
-
-      if (!isCacheAvailable())
-      {
-         return;
-      }
-
-      if (log.isTraceEnabled())
-      {
-         log.trace("addSession(): adding Session " + sessionId.getSessionId() +
-            " to cached session set for SSO " + ssoId);
-      }
-
-      boolean doTx = false;
-      try
-      {
-         // Confirm we have a transaction manager; if not get it from Cache
-         // failure to find will throw an IllegalStateException
-         if (tm == null)
-            configureFromCache();
-
-         // Don't do anything if there is already a transaction
-         // context associated with this thread.
-         if(tm.getTransaction() == null)
-            doTx = true;
-
-         if(doTx)
-            tm.begin();
-
-         putSessionInCache(ssoId, sessionId);
-      }
-      catch (Exception e)
-      {
-         try
-         {
-            if(doTx)
-               tm.setRollbackOnly();
-         }
-         catch (Exception ignored)
-         {
-         }
-         log.error("caught exception adding session " + sessionId.getSessionId() +
-            " to SSO id " + ssoId, e);
-      }
-      finally
-      {
-         if (doTx)
-            endTransaction();
-      }
-   }
-
-
-   /**
-    * Gets the SingleSignOn valve for which this object is handling
-    * cluster communications.
-    *
-    * @return the <code>SingleSignOn</code> valve.
-    */
-   public SSOLocalManager getSSOLocalManager()
-   {
-      return ssoValve;
-   }
-
-
-   /**
-    * Sets the SingleSignOn valve for which this object is handling
-    * cluster communications.
-    * <p><b>NOTE:</b> This method must be called before calls can be
-    * made to the other methods of this interface.
-    *
-    * @param localManager a <code>SingleSignOn</code> valve.
-    */
-   public void setSSOLocalManager(SSOLocalManager localManager)
-   {
-      ssoValve = localManager;
-      if (ssoValve != null)
-      {
-         if (server == null)
-         {
-            server = ssoValve.getMBeanServer();
-         }
-         String poolName = ssoValve.getThreadPoolName();
-         if (poolName != null)
-         {
-            threadPoolName = poolName;
-         }
-      }
-   }
-
-
-   /**
-    * Notifies the cluster that a single sign on session has been terminated
-    * due to a user logout.
-    *
-    * @param ssoId
-    */
-   public void logout(String ssoId)
-   {
-      if (!isCacheAvailable())
-      {
-         return;
-      }
-
-      // Check whether we are already handling this removal
-      if (ssoId.equals(beingLocallyRemoved.get()))
-      {
-         return;
-      }
-
-      // Add this SSO to our list of in-process local removals so
-      // this.nodeRemoved() will ignore the removal
-      beingLocallyRemoved.set(ssoId);
-
-      if (log.isTraceEnabled())
-      {
-         log.trace("Registering logout of SSO " + ssoId +
-            " in clustered cache");
-      }
-
-      try
-      {
-         removeSSOFromCache(ssoId);
-      }
-      catch (Exception e)
-      {
-         log.error("Exception attempting to logout " +
-            ssoId, e);
-      }
-      finally
-      {
-         beingLocallyRemoved.set(null);
-      }
-   }
-
-
-   public SSOCredentials lookup(String ssoId)
-   {
-      if (!isCacheAvailable())
-      {
-         return null;
-      }
-
-      SSOCredentials credentials = null;
-      // Find the latest credential info from the cluster
-      try
-      {
-         credentials = getCredentialsFromCache(ssoId);
-      }
-      catch (Exception e)
-      {
-         log.error("caught exception looking up SSOCredentials for SSO id " +
-            ssoId, e);
-      }
-      return credentials;
-   }
-
-
-   /**
-    * Notifies the cluster of the creation of a new SSO entry.
-    *
-    * @param ssoId    the id of the SSO session
-    * @param authType the type of authenticator (BASIC, CLIENT-CERT, DIGEST
-    *                 or FORM) used to authenticate the SSO.
-    * @param username the username (if any) used for the authentication
-    * @param password the password (if any) used for the authentication
-    */
-   public void register(String ssoId, String authType,
-      String username, String password)
-   {
-      if (!isCacheAvailable())
-      {
-         return;
-      }
-
-      if (log.isTraceEnabled())
-      {
-         log.trace("Registering SSO " + ssoId + " in clustered cache");
-      }
-
-      storeCredentials(ssoId, authType, username, password);
-   }
-
-
-   /**
-    * Notify the cluster of the removal of a Session from an SSO session.
-    *
-    * @param ssoId   the id of the SSO session
-    * @param sessionId id of the Session that has been removed
-    */
-   public void removeSession(String ssoId, FullyQualifiedSessionId sessionId)
-   {
-      if (ssoId == null || sessionId == null)
-      {
-         return;
-      }
-
-      if (!isCacheAvailable())
-      {
-         return;
-      }
-
-      // Check that this session removal is not due to our own deregistration
-      // of an SSO following receipt of a nodeRemoved() call
-      if (ssoId.equals(beingRemotelyRemoved.get()))
-      {
-         return;
-      }
-
-      if (log.isTraceEnabled())
-      {
-         log.trace("removeSession(): removing Session " + sessionId.getSessionId() +
-            " from cached session set for SSO " + ssoId);
-      }
-
-      boolean doTx = false;
-      boolean removing = false;
-      try
-      {
-         // Confirm we have a transaction manager; if not get it from Cache
-         // failure to find will throw an IllegalStateException
-         if (tm == null)
-            configureFromCache();
-
-         // Don't do anything if there is already a transaction
-         // context associated with this thread.
-         if(tm.getTransaction() == null)
-            doTx = true;
-
-         if(doTx)
-            tm.begin();
-
-         // remove session
-         removeSessionFromCache(ssoId, sessionId);
-      }
-      catch (Exception e)
-      {
-         try
-         {
-            if(doTx)
-               tm.setRollbackOnly();
-         }
-         catch (Exception x)
-         {
-         }
-
-         log.error("caught exception removing session " + sessionId.getSessionId() +
-            " from SSO id " + ssoId, e);
-      }
-      finally
-      {
-         try
-         {
-            if (removing)
-            {
-               beingLocallyRemoved.set(null);
-            }
-         }
-         finally
-         {
-            if (doTx)
-               endTransaction();
-         }
-      }
-   }
-
-
-   /**
-    * Notifies the cluster of an update of the security credentials
-    * associated with an SSO session.
-    *
-    * @param ssoId    the id of the SSO session
-    * @param authType the type of authenticator (BASIC, CLIENT-CERT, DIGEST
-    *                 or FORM) used to authenticate the SSO.
-    * @param username the username (if any) used for the authentication
-    * @param password the password (if any) used for the authentication
-    */
-   public void updateCredentials(String ssoId, String authType,
-      String username, String password)
-   {
-      if (!isCacheAvailable())
-      {
-         return;
-      }
-
-      if (log.isTraceEnabled())
-      {
-         log.trace("Updating credentials for SSO " + ssoId +
-            " in clustered cache");
-      }
-
-      storeCredentials(ssoId, authType, username, password);
-   }
-
-
-   // ------------------------------------------------------  CacheListener
-
-   /**
-    * Extracts an SSO session id and uses it in an invocation of
-    * {@link ClusteredSingleSignOn#deregister(String) ClusteredSingleSignOn.deregister(String)}.
-    * <p/>
-    * Ignores invocations resulting from Cache changes originated by
-    * this object.
-    *
-    * @param event
-    */
-   @CacheEntryRemoved
-   public void cacheEntryRemoved(CacheEntryRemovedEvent event)
-   {
-      if (event.isPre())
-         return;
-
-      CacheKey key = (CacheKey)event.getKey();
-      String ssoId = key.getSSOID();
-
-      if (ssoId == null ||
-         key.getType() != CacheKey.Type.SESSION)
-      {
-         return;
-      }
-
-      // Entire SSO is being removed; i.e. an invalidation
-      // Ignore messages generated by our own logout activity
-      // TODO:  can we check event.isOriginLocal instead of beingLocallyRemoved? 
-      if (!ssoId.equals(beingLocallyRemoved.get()))
-      {
-         deregisterSSO(ssoId);
-      }
-      // signal the case that we have zero sessions for this ssoId
-      notifySSOEmpty(ssoId);
-   }
-
-   /**
-    * If any nodes have been removed from the view, asynchronously scans
-    * all SSOs looking for and removing sessions owned by the removed node.
-    * Notifies the SSO valve if as a result any SSOs no longer have active
-    * sessions.  If the removed node is the one associated with this object,
-    * does nothing.
-    */
-   @ViewChanged
-   public void viewChange(ViewChangedEvent event)
-   {
-      log.debug("Received ViewChangedEvent " + event);
-      boolean masterNode = false;  // true if we are the first node in the cluster group.
-      Set<Object> oldMembers = new HashSet<Object>(event.getOldMembers());
-      synchronized (currentView)
-      {
-         currentView.clear();
-         currentView.addAll(event.getNewMembers());
-
-         // If we're not in the view, just exit
-         if (localAddress == null || !currentView.contains(localAddress))
-            return;
-
-         // treat the first node in the view as the master node
-         if (currentView.iterator().next().equals(localAddress))
-         {
-            masterNode = true;
-         }
-
-         // Remove all the current members from the old set; any left
-         // are the dead members
-         oldMembers.removeAll(currentView);
-      }
-
-      /**
-       * if we are the master node, clean up any dead sessions left behind from a node that left the cluster group
-       */
-      if (oldMembers.size() > 0 && masterNode)
-      {
-         log.debug("Members have been removed; will launch cleanup task. Dead members: " + oldMembers);
-
-         launchSSOCleaner(false);
-      }
-
-   }
-
-
-   /**
-    * Instantiates a DeadMemberCleaner and assigns a thread
-    * to execute the cleanup task.
-    * @param notifyIfEmpty TODO
-    */
-   private void launchSSOCleaner(boolean notifyIfEmpty)
-   {
-
-      SSOCleanerTask cleaner = new SSOCleanerTask(notifyIfEmpty);
-      if (threadPool != null)
-      {
-         threadPool.run(cleaner);
-      }
-      else
-      {
-         Thread t = new Thread(cleaner, "ClusteredSSOCleaner");
-         t.setDaemon(true);
-         t.start();
-      }
-   }
-
-
-   /**
-    * Handles the notification that an entire SSO has been removed remotely
-    *
-    * @param ssoId id of the removed SSO
-    */
-   private void deregisterSSO(String ssoId)
-   {
-      beingRemotelyRemoved.set(ssoId);
-
-      try
-      {
-         if (log.isTraceEnabled())
-         {
-            log.trace("received a node removed message for SSO " + ssoId);
-         }
-
-         ssoValve.deregister(ssoId);
-      }
-      finally
-      {
-         beingRemotelyRemoved.set(null);
-      }
-   }
-
-   /**
-    * Checks whether any peers remain for the given SSO; if not
-    * notifies the valve that the SSO is empty.
-    *
-    * @param ssoId
-    */
-   private void notifySSOEmpty(String ssoId)
-   {
-      try
-      {
-         if (getSSOSessions(ssoId).size() == 0)
-         {
-            ssoValve.notifySSOEmpty(ssoId);
-         }
-      }
-      catch (Exception e)
-      {
-         log.error("Caught exception checking if " +  ssoId + " is empty", e);
-      }
-   }
-
-   /**
-    * Extracts an SSO session id and uses it in an invocation of
-    * {@link ClusteredSingleSignOn#update ClusteredSingleSignOn.update()}.
-    * <p/>
-    * Ignores invocations resulting from Cache changes originated by
-    * this object.
-    * <p/>
-    * Ignores invocations for SSO session id's that are not registered
-    * with the local SingleSignOn valve.
-    *
-    * @param event
-    */
-   @CacheEntryModified
-   public void cacheEntryModified(CacheEntryModifiedEvent event)
-   {
-      if (event.isPre() || event.isOriginLocal())
-         return;
-
-      CacheKey key = (CacheKey)event.getKey();
-      if (key.getType() == CacheKey.Type.CREDENTIAL)
-      {
-         handleCredentialModifiedEvent(key.getSSOID(), (SSOCredentials)event.getValue());
-      }
-      else if (key.getType() == CacheKey.Type.SESSION)
-      {
-         handleSessionModifiedEvent(key.getSSOID());
-      }
-   }
-
-   /**
-    * @param ssoId the id of the sso
-    * @param credentials 
-    */
-   private void handleCredentialModifiedEvent(String ssoId,SSOCredentials credentials)
-   {
-      // Ignore invocations that come as a result of our additions
-      // TODO: can this local check be removed since we already ignore local events in caller
-      if (ssoId.equals(beingLocallyAdded.get()))
-      {
-         return;
-      }
-
-      if (log.isTraceEnabled())
-      {
-         log.trace("received a credentials modified message for SSO " + ssoId);
-      }
-
-      try
-      {
-         if (credentials != null)
-         {
-            ssoValve.remoteUpdate(ssoId, credentials);
-         }
-      }
-      catch (Exception e)
-      {
-         log.error("failed to update credentials for SSO " + ssoId, e);
-      }
-   }
-
-   /**
-    *
-    * @param ssoId single sign-on session id
-    */
-   private void handleSessionModifiedEvent(String ssoId)
-   {
-      // Peers remove their entire node when it's empty, so any
-      // other modification means it's not empty
-      ssoValve.notifySSONotEmpty(ssoId);
-   }
-
-   /**
-    * Prepare for the beginning of active use of the public methods of this
-    * component.  This method should be called before any of the public
-    * methods of this component are utilized.  It should also send a
-    * LifecycleEvent of type START_EVENT to any registered listeners.
-    *
-    * @throws Exception if this component detects a fatal error
-    *                            that prevents this component from being used
-    */
-   public void start() throws Exception
-   {
-      // Validate and update our current component state
-      if (started)
-      {
-         throw new IllegalStateException("SSOClusterManagerImpl already Started");
-      }
-      this.cache = cacheHandler.getCache();
-      initThreadPool();
-      registerAsCacheListener();
-
-      this.tm = this.cache.getAdvancedCache().getTransactionManager();
-
-      started = true;
-   }
-
-
-   /**
-    * Gracefully terminate the active use of the public methods of this
-    * component.  This method should be the last one called on a given
-    * instance of this component.  It should also send a LifecycleEvent
-    * of type STOP_EVENT to any registered listeners.
-    *
-    * @throws Exception if this component detects a fatal error
-    *                            that needs to be reported
-    */
-   public void stop() throws Exception
-   {
-      // Validate and update our current component state
-      if (!started)
-      {
-         throw new IllegalStateException("SSOClusterManagerImpl not Started");
-      }
-
-      removeAsCacheListener();
-
-      started = false;
-   }
-
-
-   // -------------------------------------------------------  Public Methods
-
-   /**
-    * Gets the number of sessions associated with the given SSO. The same
-    * session active on more than one node will count more than once.
-    */
-   public int getSessionCount(String ssoId) throws Exception
-   {
-      return getSSOSessions(ssoId).size();
-   }
-
-   // -------------------------------------------------------  Private Methods
-
-   private Set<String> getSSOIds() throws Exception
-   {
-      Set keys = cache.keySet();
-      Set result = new HashSet<String>();
-      for (Object key: keys)
-      {
-         CacheKey ck = (CacheKey)key;
-         if (ck.getType() == CacheKey.Type.SESSION)
-         {
-            result.add(ck.getSSOID());
-         }
-      }
-
-      return result;
-   }
-
-   /**
-    *
-    * @param ssoId
-    * @return set of FullyQualifiedSessionId
-    * @throws Exception
-    */
-   private Set<FullyQualifiedSessionId> getSSOSessions(String ssoId) throws Exception
-   {
-      CacheKey key = new CacheKey(ssoId,CacheKey.Type.SESSION);
-      AtomicMap m = AtomicMapLookup.getAtomicMap(cache, key, true);
-      return m!=null ? m.keySet() : Collections.EMPTY_SET;
-   }
-
-   /**
-    * Obtains needed configuration information from the cache.
-    * Invokes "getTransactionManager" on the cache, caching the
-    * result or throwing an IllegalStateException if one is not found.
-    * Also gets our cluster-wide unique local address from the cache.
-    *
-    * @throws Exception
-    */
-   private void configureFromCache() throws Exception
-   {
-      if(tm == null)
-      {
-         tm = cache.getAdvancedCache().getTransactionManager();
-      }
-
-      if (tm == null)
-      {
-         throw new IllegalStateException("Cache does not have a " +
-                                         "transaction manager; please " +
-                                         "configure a valid " +
-                                         "TransactionManagerLookupClass");
-      }
-
-      // We no longer rule out buddy replication, as it can be valid if
-      // all activity for the SSO is meant to pinned to one server (i.e.
-      // only one session, or all sessions share the same session id cookie)
-      /*
-      if (cache.getConfiguration().getBuddyReplicationConfig() != null
-            && cache.getConfiguration().getBuddyReplicationConfig().isEnabled())
-      {
-         throw new IllegalStateException("Underlying cache is configured for " +
-                                         "buddy replication; use of buddy " +
-                                         "replication with ClusteredSingleSignOn " +
-                                         "is not supported");
-      }
-      */
-      // Find out our address
-      Address address = cache.getAdvancedCache().getRpcManager().getAddress();
-      if (address != null)
-         localAddress = address;
-      else if (Configuration.CacheMode.LOCAL == cache.getConfiguration().getCacheMode())
-         localAddress = "LOCAL";
-      else
-         throw new IllegalStateException("Cannot get local address from cache");
-
-
-      log.debug("Local address is " + localAddress);
-
-   }
-
-   private void endTransaction()
-   {
-      try
-      {
-         if(tm.getTransaction().getStatus() != Status.STATUS_MARKED_ROLLBACK)
-         {
-            tm.commit();
-         }
-         else
-         {
-            tm.rollback();
-         }
-      }
-      catch (Exception e)
-      {
-         log.error(e);
-         throw new RuntimeException("SSOClusterManagerImpl.endTransaction(): ", e);
-      }
-   }
-
-   private MBeanServer getMBeanServer()
-   {
-      if (server == null && ssoValve != null)
-      {
-         server = ssoValve.getMBeanServer();
-      }
-      return server;
-   }
-
-   private boolean isCacheAvailable()
-   {
-      //boolean avail = isCacheAvailable(false);
-      boolean avail = this.cache != null;
-      if (!avail)
-         logMissingCacheError();
-      return avail;
-   }
-
-   /**
-    * Put a new session in the cache
-    * @param ssoId session id
-    * @param fullyQualifiedSessionId  fully qualified session id
-    * @throws Exception
-    */
-   private void putSessionInCache(String ssoId, FullyQualifiedSessionId fullyQualifiedSessionId) throws Exception
-   {
-      CacheKey key = new CacheKey(ssoId,CacheKey.Type.SESSION);
-      AtomicMap m = AtomicMapLookup.getAtomicMap(cache, key, true);
-      m.put(fullyQualifiedSessionId, null);
-   }
-
-   /**
-    * Put or update user credentials in the cache
-    * @param ssoId session id
-    * @param credentials
-    * @throws Exception
-    */
-   private void putCredentialsInCache(String ssoId, SSOCredentials credentials) throws Exception
-   {
-      CacheKey key = new CacheKey(ssoId,CacheKey.Type.CREDENTIAL);
-      cache.put(key, credentials);
-   }
-
-   private SSOCredentials getCredentialsFromCache(String ssoId)
-   {
-      CacheKey key = new CacheKey(ssoId,CacheKey.Type.CREDENTIAL);
-      return (SSOCredentials)cache.get(key);
-   }
-
-   /**
-    * register as a cache listener.
-    *
-    * @throws Exception
-    */
-   private void registerAsCacheListener() throws Exception
-   {
-      cache.addListener(this);
-      registeredAsListener = true;
-   }
-
-
-   /**
-    * stop listening on the cache.
-    *
-    * @throws Exception
-    */
-   private void removeAsCacheListener() throws Exception
-   {
-      if (registeredAsListener && cache != null)
-      {
-         cache.removeListener(this);
-         registeredAsListener = false;
-      }
-   }
-
-   /**
-    * Remove the specified session from the cache (used for session.logout)
-    *
-    * @param ssoId the session id representing the shared single session
-    * @throws Exception
-    */
-   private void removeSSOFromCache(String ssoId) throws Exception
-   {
-      CacheKey key = new CacheKey(ssoId,CacheKey.Type.SESSION);
-      cache.remove(key);
-      key = new CacheKey(ssoId,CacheKey.Type.CREDENTIAL);
-      cache.remove(key);  // remove user credentials too
-   }
-
-   /**
-    * Remove one of the sessions associated with the users shared single session
-    * @param ssoId ssoId the session id representing the shared single session
-    * @param fullyQualifiedSessionId representing the session to remove
-    * @throws Exception
-    */
-   private void removeSessionFromCache(String ssoId, FullyQualifiedSessionId fullyQualifiedSessionId) throws Exception
-   {
-      CacheKey key = new CacheKey(ssoId,CacheKey.Type.SESSION);
-      AtomicMap m = AtomicMapLookup.getAtomicMap(cache, key, false);
-      if (m != null)
-      {
-         m.remove(fullyQualifiedSessionId);
-      }
-   }
-
-   /**
-    * Stores the given data to the clustered cache.
-    *
-    * @param ssoId    the id of the SSO session
-    * @param authType the type of authenticator (BASIC, CLIENT-CERT, DIGEST
-    *                 or FORM) used to authenticate the SSO.
-    * @param username the username (if any) used for the authentication
-    * @param password the password (if any) used for the authentication
-    */
-   private void storeCredentials(String ssoId, String authType, String username,
-      String password)
-   {
-      SSOCredentials credentials = new SSOCredentials(authType, username, password);
-
-      // Add this SSO to our list of in-process local adds so
-      // this.nodeModified() will ignore the addition
-      beingLocallyAdded.set(ssoId);
-
-      try
-      {
-         putCredentialsInCache(ssoId, credentials);
-      }
-      catch (Exception e)
-      {
-         log.error("Exception attempting to add Cache nodes for SSO " +
-            ssoId, e);
-      }
-      finally
-      {
-         beingLocallyAdded.set(null);
-      }
-   }
-
-   private void initThreadPool()
-   {
-      if (threadPoolName != null && getMBeanServer() != null)
-      {
-         try
-         {
-            ObjectName on = new ObjectName(threadPoolName);
-            threadPool = (ThreadPool) server.getAttribute(on, "Instance");
-            log.debug("Using ThreadPool at " + threadPoolName + " to clean dead members");
-         }
-         catch (Exception e)
-         {
-            log.info("Unable to access ThreadPool at " + threadPoolName +
-                     " -- will use individual threads for cleanup work");
-            log.debug("Failure to access ThreadPool due to: " + e);
-         }
-      }
-      else
-      {
-         log.debug("No ThreadPool configured -- will use individual threads for cleanup work");
-      }
-   }
-
-   private boolean isMissingCacheErrorLogged()
-   {
-      return missingCacheErrorLogged;
-   }
-
-   private void setMissingCacheErrorLogged(boolean missingCacheErrorLogged)
-   {
-      this.missingCacheErrorLogged = missingCacheErrorLogged;
-   }
-
-   private void logMissingCacheError()
-   {
-      StringBuffer msg = new StringBuffer("Cache is not set");
-      msg.append(" -- Cache must be started before SSOClusterManagerImpl ");
-      msg.append("can handle requests");
-
-      if (isMissingCacheErrorLogged())
-      {
-         // Just log it as a warning
-         log.warn(msg);
-      }
-      else
-      {
-         log.error(msg);
-         // Set a flag so we don't relog this error over and over
-         setMissingCacheErrorLogged(true);
-      }
-   }
-
-   // ---------------------------------------------------------  Outer Classes
-
-   /**
-    * Runnable that's run when the removal of a node from the cluster has been detected.
-    * Removes any SessionAddress objects associated with dead members from the
-    * session set of each SSO.  Operates locally only so each node can independently clean
-    * its SSOs without concern about replication lock conflicts.
-    */
-   private class SSOCleanerTask implements Runnable
-   {
-      private final boolean checkForEmpty;
-
-      private SSOCleanerTask(boolean checkForEmpty)
-      {
-         this.checkForEmpty = checkForEmpty;
-      }
-
-      public void run()
-      {
-         synchronized (cleanupMutex)
-         {
-            try
-            {
-               log.debug("check if we have to clean up SSO for any members that left the cluster.");
-               // Ensure we have a TransactionManager
-               if (tm == null)
-                  configureFromCache();
-
-               Set<String> ids = getSSOIds();
-               for (String sso : ids)
-               {
-                  cleanSSO(sso);
-               }
-            }
-            catch (Exception e)
-            {
-               log.error("Caught exception cleaning sessions from dead cluster members from SSOs ", e);
-            }
-         }
-      }
-
-      private void cleanSSO(String ssoId)
-      {
-         boolean doTx = false;
-         try
-         {
-            // Don't start tx if there is already one associated with this thread.
-            if(tm.getTransaction() == null)
-               doTx = true;
-
-            if(doTx)
-               tm.begin();
-
-            Set<FullyQualifiedSessionId> fullyQualifiedSessionIds = getSSOSessions(ssoId);
-            if (fullyQualifiedSessionIds.size() > 0)
-            {
-               for (FullyQualifiedSessionId fullyQualifiedSessionId : fullyQualifiedSessionIds)
-               {
-                  boolean alive;
-                  synchronized (currentView)
-                  {
-                     alive = currentView.contains(fullyQualifiedSessionId.getHostName());
-                  }
-                  if (!alive)
-                  {
-                     if (log.isTraceEnabled())
-                     {
-                        log.trace("Removing peer " + fullyQualifiedSessionId + " from SSO " + ssoId);
-                     }
-
-                     // Remove the peer node
-                     removeSessionFromCache(ssoId, fullyQualifiedSessionId);
-                  }
-               }
-            }
-            else if (checkForEmpty)
-            {
-               // SSO has no peers; notify our valve so we can expire it
-               ssoValve.notifySSOEmpty(ssoId);
-            }
-         }
-         catch (Exception e)
-         {
-            try
-            {
-               if(doTx)
-                  tm.setRollbackOnly();
-            }
-            catch (Exception ignored)
-            {
-            }
-            log.error("caught exception cleaning dead members from SSO " + ssoId, e);
-         }
-         finally
-         {
-            if (doTx)
-               endTransaction();
-         }
-      }
-   }
-
-}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntry.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntry.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntry.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntry.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,83 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import org.infinispan.atomic.AtomicMap;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
+
+/**
+ * Enumerates the properties of a session to be stored in a cache entry.
+ * Provides get/put methods which encapsulate away the details of the map key.
+ * @author Paul Ferraro
+ */
+public enum AtomicMapEntry
+{
+   VERSION(Integer.class), TIMESTAMP(Long.class), METADATA(DistributableSessionMetadata.class), ATTRIBUTES(Object.class);
+   
+   private Class<?> targetClass;
+   
+   private AtomicMapEntry(Class<?> targetClass)
+   {
+      this.targetClass = targetClass;
+   }
+   
+   /**
+    * Returns the value associated with this atomic map entry.
+    * @param <T> the value type
+    * @param data an atomic map
+    * @return the entry value
+    */
+   public <T> T get(AtomicMap<Object, Object> data)
+   {
+      return this.cast(data.get(this.key()));
+   }
+
+   /**
+    * Add this entry to the specified map if the specified value is non-null.
+    * @param <T> the value type
+    * @param data an atomic map
+    * @param value the entry value
+    * @return the old entry value, or null if no previous entry existed
+    */
+   public <T> T put(AtomicMap<Object, Object> data, Object value)
+   {
+      if (value == null) return null;
+      
+      if (!this.targetClass.isInstance(value))
+      {
+         throw new IllegalArgumentException(String.format("Attempt to put value of type %s into %s entry", value.getClass().getName(), this));
+      }
+      
+      return this.cast(data.put(this.key(), value));
+   }
+   
+   @SuppressWarnings("unchecked")
+   private <T> T cast(Object value)
+   {
+      return (value != null) ? (T) this.targetClass.cast(value) : null;
+   }
+   
+   private Byte key()
+   {
+      return Byte.valueOf((byte) this.ordinal());
+   }
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorage.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorage.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorage.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorage.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,69 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import java.util.Map;
+
+import org.infinispan.atomic.AtomicMap;
+import org.jboss.metadata.web.jboss.ReplicationGranularity;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingSessionGranularitySessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
+
+/**
+ * Handles session attribute load/store operations for {@link ReplicationGranularity#SESSION} distributed session managers.
+ * @author Paul Ferraro
+ */
+public class CoarseSessionAttributeStorage implements SessionAttributeStorage<OutgoingSessionGranularitySessionData>
+{
+   private final SessionAttributeMarshaller marshaller;
+   
+   public CoarseSessionAttributeStorage(SessionAttributeMarshaller marshaller)
+   {
+      this.marshaller = marshaller;
+   }
+   
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage#store(org.infinispan.atomic.AtomicMap, org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData)
+    */
+   @Override
+   public void store(AtomicMap<Object, Object> data, OutgoingSessionGranularitySessionData sessionData)
+   {
+      Map<String, Object> attributes = sessionData.getSessionAttributes();
+      
+      if (attributes != null)
+      {
+         AtomicMapEntry.ATTRIBUTES.put(data, this.marshaller.marshal(attributes));
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage#load(org.infinispan.atomic.AtomicMap)
+    */
+   @SuppressWarnings("unchecked")
+   @Override
+   public Map<String, Object> load(AtomicMap<Object, Object> data) throws Exception
+   {
+      return (Map<String, Object>) this.marshaller.unmarshal(AtomicMapEntry.ATTRIBUTES.get(data));
+   }
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManager.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManager.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManager.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManager.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,491 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.transaction.TransactionManager;
+
+import org.infinispan.Cache;
+import org.infinispan.atomic.AtomicMap;
+import org.infinispan.config.CacheLoaderManagerConfig;
+import org.infinispan.config.Configuration;
+import org.infinispan.context.Flag;
+import org.infinispan.distribution.DistributionManager;
+import org.infinispan.lifecycle.ComponentStatus;
+import org.infinispan.manager.CacheContainer;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.notifications.Listener;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryActivated;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
+import org.infinispan.notifications.cachelistener.event.CacheEntryActivatedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
+import org.infinispan.transaction.tm.BatchModeTransactionManager;
+import org.jboss.ha.ispn.CacheContainerRegistry;
+import org.jboss.ha.ispn.atomic.AtomicMapFactory;
+import org.jboss.ha.ispn.invoker.CacheInvoker;
+import org.jboss.logging.Logger;
+import org.jboss.web.tomcat.service.session.distributedcache.impl.BatchingManagerImpl;
+import org.jboss.web.tomcat.service.session.distributedcache.impl.IncomingDistributableSessionDataImpl;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.BatchingManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.IncomingDistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionOwnershipSupport;
+
+/**
+ * Distributed cache manager implementation using Infinispan.
+ * @author Paul Ferraro
+ */
+ at Listener
+public class DistributedCacheManager<T extends OutgoingDistributableSessionData> implements org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager<T>
+{
+   static String mask(String sessionId)
+   {
+      if (sessionId == null) return null;
+      
+      int length = sessionId.length();
+      
+      if (length <= 8) return sessionId;
+
+      return sessionId.substring(0, 2) + "****" + sessionId.substring(length - 6, length);
+   }
+
+   static RuntimeException getRuntimeException(String message, Exception e)
+   {   
+      if (e instanceof RuntimeException) return (RuntimeException) e;
+      
+      return new RuntimeException(message != null ? message : e.toString(), e);
+   }
+   
+   private static final Logger log = Logger.getLogger(DistributedCacheManager.class);
+   
+   private final LocalDistributableSessionManager manager;
+   private final SessionAttributeStorage<T> attributeStorage;
+   private final CacheInvoker invoker;
+   private final CacheContainerRegistry registry;
+   final AtomicMapFactory atomicMapFactory;
+   
+   private Cache<String, AtomicMap<Object, Object>> cache;
+   private BatchingManagerImpl batchingManager;
+   private boolean passivationEnabled = false;
+   
+   public DistributedCacheManager(LocalDistributableSessionManager manager, CacheContainerRegistry registry, SessionAttributeStorage<T> attributeStorage, CacheInvoker invoker, AtomicMapFactory atomicMapFactory)
+   {
+      this.manager = manager;
+      this.registry = registry;
+      this.attributeStorage = attributeStorage;
+      this.invoker = invoker;
+      this.atomicMapFactory = atomicMapFactory;
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#start()
+    */
+   @Override
+   public void start()
+   {
+      String templateCacheName = this.manager.getReplicationConfig().getCacheName();
+      
+      String containerName = null;
+      
+      if (templateCacheName != null)
+      {
+         String[] parts = templateCacheName.split(":");
+         
+         if (parts.length == 2)
+         {
+            containerName = parts[0];
+            templateCacheName = parts[1];
+         }
+      }
+      
+      CacheContainer container = this.registry.getCacheContainer(containerName);
+      
+      String hostName = this.manager.getHostName();
+      String host = (hostName == null) || hostName.isEmpty() ? "localhost" : hostName;
+      
+      String context = this.manager.getContextName();
+      String path = context.isEmpty() || context.equals("/") ? "ROOT" : context.startsWith("/") ? context.substring(1) : context;
+
+      String cacheName = host + "/" + path;
+      
+      EmbeddedCacheManager manager = (EmbeddedCacheManager) container.getCache().getCacheManager();
+      manager.defineConfiguration(cacheName, templateCacheName, new Configuration());
+      
+      this.cache = manager.getCache(cacheName);
+      
+      if (this.cache.getStatus() != ComponentStatus.RUNNING)
+      {
+         this.cache.start();
+      }
+      
+      TransactionManager tm = this.cache.getAdvancedCache().getTransactionManager();
+      
+      if (!(tm instanceof BatchModeTransactionManager))
+      {
+         throw new IllegalStateException("Unexpected transaction manager type: " + ((tm != null) ? tm.getClass().getName() : "null"));
+      }
+      
+      this.batchingManager = new BatchingManagerImpl(tm);
+      
+      this.cache.addListener(this);
+      
+      CacheLoaderManagerConfig loaderManagerConfig = this.cache.getConfiguration().getCacheLoaderManagerConfig();
+      
+      this.passivationEnabled = (loaderManagerConfig != null) ? loaderManagerConfig.isPassivation().booleanValue() && !loaderManagerConfig.isShared().booleanValue() : false;
+   }
+   
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#stop()
+    */
+   @Override
+   public void stop()
+   {
+      this.cache.removeListener(this);
+      
+      this.cache.stop();
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#getBatchingManager()
+    */
+   @Override
+   public BatchingManager getBatchingManager()
+   {
+      return this.batchingManager;
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#sessionCreated(java.lang.String)
+    */
+   @Override
+   public void sessionCreated(String sessionId)
+   {
+      // Do nothing
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#storeSessionData(org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData)
+    */
+   @Override
+   public void storeSessionData(T sessionData)
+   {
+      final String sessionId = sessionData.getRealId();
+      
+      if (log.isTraceEnabled())
+      {
+         log.trace("putSession(): putting session " + mask(sessionId));
+      }     
+      
+      Operation<AtomicMap<Object, Object>> operation = new Operation<AtomicMap<Object, Object>>()
+      {
+         @Override
+         public AtomicMap<Object, Object> invoke(Cache<String, AtomicMap<Object, Object>> cache)
+         {
+            return DistributedCacheManager.this.atomicMapFactory.getAtomicMap(cache, sessionId, true);
+         }
+      };
+      
+      AtomicMap<Object, Object> data = this.invoker.invoke(this.cache, operation);
+      
+      AtomicMapEntry.VERSION.put(data, Integer.valueOf(sessionData.getVersion()));
+      AtomicMapEntry.METADATA.put(data, sessionData.getMetadata());
+      AtomicMapEntry.TIMESTAMP.put(data, sessionData.getTimestamp());
+      
+      this.attributeStorage.store(data, sessionData);
+   }
+   
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#getSessionData(java.lang.String, boolean)
+    */
+   @Override
+   public IncomingDistributableSessionData getSessionData(String sessionId, boolean initialLoad)
+   {
+      return this.getData(sessionId, true);
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#getSessionData(java.lang.String, java.lang.String, boolean)
+    */
+   @Override
+   public IncomingDistributableSessionData getSessionData(final String sessionId, String dataOwner, boolean includeAttributes)
+   {
+      return (dataOwner == null) ? this.getData(sessionId, includeAttributes) : null;
+   }
+   
+   private IncomingDistributableSessionData getData(final String sessionId, boolean includeAttributes)
+   {
+      Operation<AtomicMap<Object, Object>> operation = new Operation<AtomicMap<Object, Object>>()
+      {
+         @Override
+         public AtomicMap<Object, Object> invoke(Cache<String, AtomicMap<Object, Object>> cache)
+         {
+            return DistributedCacheManager.this.atomicMapFactory.getAtomicMap(cache, sessionId, false);
+         }
+      };
+      
+      AtomicMap<Object, Object> data = this.invoker.invoke(this.cache, operation);
+      
+      // If requested session is no longer in the cache; return null
+      if (data == null) return null;
+      
+      try
+      {
+         Integer version = AtomicMapEntry.VERSION.get(data);
+         Long timestamp = AtomicMapEntry.TIMESTAMP.get(data);
+         DistributableSessionMetadata metadata = AtomicMapEntry.METADATA.get(data);
+         IncomingDistributableSessionDataImpl result = new IncomingDistributableSessionDataImpl(version, timestamp, metadata);
+         
+         if (includeAttributes)
+         {
+            try
+            {
+               result.setSessionAttributes(this.attributeStorage.load(data));
+            }
+            catch (Exception e)
+            {
+               throw getRuntimeException("Failed to load session attributes for session: " + mask(sessionId), e);
+            }
+         }
+
+         return result;
+      }
+      catch (Exception e)
+      {
+         String message = String.format("Problem accessing session [%s]: %s", mask(sessionId), e.toString());
+         log.warn(message);
+         log.debug(message, e);
+         
+         // Clean up
+         this.removeSessionLocal(sessionId);
+         
+         return null;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#removeSession(java.lang.String)
+    */
+   @Override
+   public void removeSession(final String sessionId)
+   {
+      this.removeSession(sessionId, false);
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#removeSessionLocal(java.lang.String)
+    */
+   @Override
+   public void removeSessionLocal(final String sessionId)
+   {
+      this.removeSession(sessionId, true);
+   }
+
+   private void removeSession(final String sessionId, final boolean local)
+   {
+      Operation<AtomicMap<Object, Object>> operation = new Operation<AtomicMap<Object, Object>>()
+      {
+         @Override
+         public AtomicMap<Object, Object> invoke(Cache<String, AtomicMap<Object, Object>> cache)
+         {
+            if (local)
+            {
+               cache.getAdvancedCache().withFlags(Flag.CACHE_MODE_LOCAL);
+            }
+            
+            return cache.remove(sessionId);
+         }
+      };
+      
+      this.invoker.invoke(this.cache, operation);
+   }
+   
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#removeSessionLocal(java.lang.String, java.lang.String)
+    */
+   @Override
+   public void removeSessionLocal(String sessionId, String dataOwner)
+   {
+      if (dataOwner == null)
+      {
+         this.removeSession(sessionId, true);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#evictSession(java.lang.String)
+    */
+   @Override
+   public void evictSession(final String sessionId)
+   {
+      Operation<Void> operation = new Operation<Void>()
+      {
+         @Override
+         public Void invoke(Cache<String, AtomicMap<Object, Object>> cache)
+         {
+            cache.evict(sessionId);
+            return null;
+         }
+      };
+      
+      this.invoker.invoke(this.cache, operation);
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#evictSession(java.lang.String, java.lang.String)
+    */
+   @Override
+   public void evictSession(String sessionId, String dataOwner)
+   {
+      if (dataOwner == null)
+      {
+         this.evictSession(sessionId);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#getSessionIds()
+    */
+   @Override
+   public Map<String, String> getSessionIds()
+   {
+      Map<String, String> result = new HashMap<String, String>();
+
+      for (String sessionId: this.cache.keySet())
+      {
+         result.put(sessionId, null);
+      }
+      
+      return result;
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#isPassivationEnabled()
+    */
+   @Override
+   public boolean isPassivationEnabled()
+   {
+      return this.passivationEnabled;
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#setForceSynchronous(boolean)
+    */
+   @Override
+   public void setForceSynchronous(boolean forceSynchronous)
+   {
+      this.invoker.setForceSynchronous(forceSynchronous);
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#getSessionOwnershipSupport()
+    */
+   @Override
+   public SessionOwnershipSupport getSessionOwnershipSupport()
+   {
+      return null;
+   }
+   
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager#isLocal(java.lang.String)
+    */
+   @Override
+   public boolean isLocal(String realId)
+   {
+      DistributionManager manager = this.cache.getAdvancedCache().getDistributionManager();
+      
+      return (manager != null) ? manager.isLocal(realId) : true;
+   }
+
+   @CacheEntryRemoved
+   public void removed(CacheEntryRemovedEvent event)
+   {
+      if (event.isPre() || event.isOriginLocal()) return;
+      
+      this.manager.notifyRemoteInvalidation((String) event.getKey());
+   }
+   
+   @CacheEntryModified
+   public void modified(CacheEntryModifiedEvent event)
+   {
+      if (event.isPre() || event.isOriginLocal()) return;
+      
+      String sessionId = (String) event.getKey();
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> data = (AtomicMap<Object, Object>) event.getValue();
+      
+      Integer version = AtomicMapEntry.VERSION.get(data);
+      Long timestamp = AtomicMapEntry.TIMESTAMP.get(data);
+      DistributableSessionMetadata metadata = AtomicMapEntry.METADATA.get(data);
+      
+      if (timestamp == null)
+      {
+         log.warn(String.format("No timestamp attribute found in node modification event for session %s", mask(sessionId)));
+         return;
+      }
+      
+      boolean updated = this.manager.sessionChangedInDistributedCache(sessionId, null, version.intValue(), timestamp.longValue(), metadata);
+      
+      if (!updated)
+      {
+         log.warn(String.format("Possible concurrency problem: Replicated version id %d is less than or equal to in-memory version for session %s", version, mask(sessionId))); 
+      }
+   }
+   
+   @CacheEntryActivated
+   public void activated(CacheEntryActivatedEvent event)
+   {
+      if (event.isPre()) return;
+      
+      if (this.manager.isPassivationEnabled())
+      {
+         this.manager.sessionActivated();
+      }
+   }
+   
+   // Simplified CacheInvoker.Operation using assigned key/value types
+   static interface Operation<R> extends CacheInvoker.Operation<String, AtomicMap<Object, Object>, R>
+   {      
+   }
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactory.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactory.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactory.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactory.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import org.jboss.ha.ispn.CacheContainerRegistry;
+import org.jboss.ha.ispn.DefaultCacheContainerRegistry;
+import org.jboss.ha.ispn.atomic.AtomicMapFactory;
+import org.jboss.ha.ispn.atomic.DefaultAtomicMapFactory;
+import org.jboss.ha.ispn.invoker.CacheInvoker;
+import org.jboss.ha.ispn.invoker.RetryingCacheInvoker;
+import org.jboss.web.tomcat.service.session.distributedcache.impl.SessionAttributeMarshallerFactoryImpl;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshallerFactory;
+
+/**
+ * Factory for creating an Infinispan-backed distributed cache manager.
+ * @author Paul Ferraro
+ */
+public class DistributedCacheManagerFactory implements org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManagerFactory
+{
+   private CacheContainerRegistry registry = DefaultCacheContainerRegistry.getInstance();
+   private SessionAttributeStorageFactory storageFactory = new SessionAttributeStorageFactoryImpl();
+   private SessionAttributeMarshallerFactory marshallerFactory = new SessionAttributeMarshallerFactoryImpl();
+   private CacheInvoker invoker = new RetryingCacheInvoker(10, 100);
+   private AtomicMapFactory atomicMapFactory = new DefaultAtomicMapFactory();
+   
+   @Override
+   public <T extends OutgoingDistributableSessionData> org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager<T> getDistributedCacheManager(LocalDistributableSessionManager manager)
+   {
+      SessionAttributeMarshaller marshaller = this.marshallerFactory.createMarshaller(manager);
+      SessionAttributeStorage<T> storage = this.storageFactory.createStorage(manager.getReplicationConfig().getReplicationGranularity(), marshaller);
+      
+      return new DistributedCacheManager<T>(manager, this.registry, storage, this.invoker, this.atomicMapFactory);
+   }
+   
+   public void setCacheContainerRegistry(CacheContainerRegistry registry)
+   {
+      this.registry = registry;
+   }
+   
+   public void setSessionAttributeStorageFactory(SessionAttributeStorageFactory storageFactory)
+   {
+      this.storageFactory = storageFactory;
+   }
+   
+   public void setSessionAttributeMarshallerFactory(SessionAttributeMarshallerFactory marshallerFactory)
+   {
+      this.marshallerFactory = marshallerFactory;
+   }
+   
+   public void setCacheInvoker(CacheInvoker invoker)
+   {
+      this.invoker = invoker;
+   }
+   
+   public void setAtomicMapFactory(AtomicMapFactory atomicMapFactory)
+   {
+      this.atomicMapFactory = atomicMapFactory;
+   }
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorage.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorage.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorage.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorage.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,109 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.infinispan.atomic.AtomicMap;
+import org.jboss.metadata.web.jboss.ReplicationGranularity;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingAttributeGranularitySessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
+
+/**
+ * Handles session attribute load/store operations for {@link ReplicationGranularity#ATTRIBUTE} distributed session managers.
+ * @author Paul Ferraro
+ */
+public class FineSessionAttributeStorage implements SessionAttributeStorage<OutgoingAttributeGranularitySessionData>
+{
+   private final SessionAttributeMarshaller marshaller;
+   
+   public FineSessionAttributeStorage(SessionAttributeMarshaller marshaller)
+   {
+      this.marshaller = marshaller;
+   }
+   
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage#store(org.infinispan.atomic.AtomicMap, org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData)
+    */
+   @Override
+   public void store(AtomicMap<Object, Object> data, OutgoingAttributeGranularitySessionData sessionData)
+   {
+      Map<String, Object> modified = sessionData.getModifiedSessionAttributes();
+      
+      if (modified != null)
+      {
+         for (Map.Entry<String, Object> entry: modified.entrySet())
+         {
+            data.put(entry.getKey(), this.marshaller.marshal(entry.getValue()));
+         }
+      }
+      
+      Set<String> removed = sessionData.getRemovedSessionAttributes();
+      
+      if (removed != null)
+      {
+         for (String attribute: removed)
+         {
+            data.remove(attribute);
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage#load(org.infinispan.atomic.AtomicMap)
+    */
+   @Override
+   public Map<String, Object> load(AtomicMap<Object, Object> data) throws Exception
+   {
+      Map<String, Object> map = new HashMap<String, Object>();
+      
+      for (Map.Entry<Object, Object> entry: data.entrySet())
+      {
+         Object key = entry.getKey();
+         
+         if (key instanceof String)
+         {
+            String attribute = (String) key;
+            
+            try
+            {
+               map.put(attribute, this.marshaller.unmarshal(entry.getValue()));
+            }
+            catch (RuntimeException e)
+            {
+               throw e;
+            }
+            catch (Exception e)
+            {
+               throw new Exception("Failed to unmarshal session attribute: " + attribute, e);
+            }
+         }
+      }
+      
+      return map;
+   }
+
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorage.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorage.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorage.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorage.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import java.util.Map;
+
+import org.infinispan.atomic.AtomicMap;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
+
+/**
+ * Strategy for 
+ * @author Paul Ferraro
+ */
+public interface SessionAttributeStorage<T extends OutgoingDistributableSessionData>
+{
+   void store(AtomicMap<Object, Object> data, T sessionData);
+   
+   Map<String, Object> load(AtomicMap<Object, Object> data) throws Exception;
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactory.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactory.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactory.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactory.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import org.jboss.metadata.web.jboss.ReplicationGranularity;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
+
+/**
+ * Factory for creating strategies for storing session attributes.
+ * @author Paul Ferraro
+ */
+public interface SessionAttributeStorageFactory
+{
+   /**
+    * Creates a session attribute storage strategy.
+    * @param <T> the type of session data appropriate for the specified granularity
+    * @param granularity the replication granularity
+    * @param marshaller a session attribute marshaller
+    * @return a strategy for storing session attributes.
+    */
+   <T extends OutgoingDistributableSessionData> SessionAttributeStorage<T> createStorage(ReplicationGranularity granularity, SessionAttributeMarshaller marshaller);
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryImpl.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryImpl.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryImpl.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryImpl.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import org.jboss.metadata.web.jboss.ReplicationGranularity;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
+
+/**
+ * Default factory for creating strategies for storing session attributes.
+ * @author Paul Ferraro
+ */
+public class SessionAttributeStorageFactoryImpl implements SessionAttributeStorageFactory
+{
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorageFactory#createStorage(org.jboss.metadata.web.jboss.ReplicationGranularity, org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller)
+    */
+   @SuppressWarnings("unchecked")
+   @Override
+   public <T extends OutgoingDistributableSessionData> SessionAttributeStorage<T> createStorage(ReplicationGranularity granularity, SessionAttributeMarshaller marshaller)
+   {
+      switch (granularity)
+      {
+         case SESSION:
+         {
+            return (SessionAttributeStorage<T>) new CoarseSessionAttributeStorage(marshaller);
+         }
+         case ATTRIBUTE:
+         {
+            return (SessionAttributeStorage<T>) new FineSessionAttributeStorage(marshaller);
+         }
+         case FIELD:
+         {
+            throw new IllegalArgumentException("FIELD replication granularity is no longer supported, use SESSION or ATTRIBUTE instead.");
+         }
+         default:
+         {
+            throw new IllegalArgumentException("Unknown replication granularity: " + granularity);
+         }
+      }
+   }
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/sso/ispn/CacheKey.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/CacheKey.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/sso/ispn/CacheKey.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/sso/ispn/CacheKey.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,73 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+
+package org.jboss.web.tomcat.service.session.sso.ispn;
+
+/**
+ * Used to represent the different types of entries in the cache store.
+ *
+ * Note that we purposely do not implement equals, which allows many different
+ * entries with the same key to be added.
+ *
+ */
+public class CacheKey
+{
+   public static enum Type { SESSION, CREDENTIAL }
+
+   private final String ssoId;
+   private final Type type;
+
+   public CacheKey(String ssoId, Type type)
+   {
+      this.ssoId = ssoId;
+      this.type = type;
+   }
+
+   public String getSSOID()
+   {
+      return this.ssoId;
+   }
+
+   public Type getType()
+   {
+      return this.type;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      int result = 17;
+      result = 37*result + this.ssoId.hashCode();
+      result = 37*result + this.type.ordinal();
+      return result;
+   }
+   
+   @Override
+   public boolean equals(Object object)
+   {
+      if ((object == null) || !(object instanceof CacheKey)) return false;
+      
+      CacheKey key = (CacheKey) object;
+      
+      return (this.type == key.type) && this.ssoId.equals(key.ssoId);
+   }
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/sso/ispn/SSOClusterManager.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/SSOClusterManager.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/sso/ispn/SSOClusterManager.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/main/java/org/jboss/web/tomcat/service/session/sso/ispn/SSOClusterManager.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,1150 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2010, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+
+package org.jboss.web.tomcat.service.session.sso.ispn;
+
+import org.infinispan.atomic.AtomicMap;
+import org.infinispan.atomic.AtomicMapLookup;
+import org.infinispan.config.Configuration;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
+import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
+import org.infinispan.notifications.cachemanagerlistener.annotation.ViewChanged;
+import org.infinispan.notifications.cachemanagerlistener.event.ViewChangedEvent;
+import org.infinispan.Cache;
+import org.infinispan.remoting.transport.Address;
+import org.jboss.ha.framework.server.ispn.InfinispanHAPartitionCacheHandler;
+import org.jboss.logging.Logger;
+import org.jboss.util.threadpool.ThreadPool;
+import org.jboss.web.tomcat.service.sso.spi.FullyQualifiedSessionId;
+import org.jboss.web.tomcat.service.sso.spi.SSOCredentials;
+import org.jboss.web.tomcat.service.sso.spi.SSOLocalManager;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.transaction.Status;
+import javax.transaction.TransactionManager;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * An implementation of SSOClusterManager that uses a Infinispan cache
+ * to share SSO information between cluster nodes.
+ *
+ * @author Brian E. Stansberry
+ * @author Scott Marlow
+ * @version $Revision$ $Date: 2007-01-12 03:39:24 +0100 (ven., 12 janv. 2007) $
+ */
+// @Listener
+public final class SSOClusterManager implements org.jboss.web.tomcat.service.sso.spi.SSOClusterManager
+{
+   // -------------------------------------------------------------  Constants
+
+
+   /**
+    * Default global value for the threadPoolName property
+    */
+   public static final String DEFAULT_THREAD_POOL_NAME =
+      "jboss.system:service=ThreadPool";
+
+   // -------------------------------------------------------  Instance Fields
+
+   /**
+    * SSO id which the thread is currently storing to the cache
+    */
+   private volatile ThreadLocal<String> beingLocallyAdded = new ThreadLocal<String>();
+
+   /**
+    * SSO id which a thread is currently removing from the cache
+    */
+   private volatile ThreadLocal<String> beingLocallyRemoved = new ThreadLocal<String>();
+
+   /**
+    * SSO id which the thread is deregistering due to removal on another node
+    */
+   private volatile ThreadLocal<String> beingRemotelyRemoved = new ThreadLocal<String>();
+
+   /**
+    * The clustered cache that holds the SSO credentials and the sessions.
+    * The CacheKey will indicate which type it is (CacheKey.CREDENTIAL or CacheKey.SESSION);
+    */
+   private volatile Cache<CacheKey, Object> cache = null;
+
+   /**
+    * Transaction Manager
+    */
+   private volatile TransactionManager tm = null;
+
+   private volatile String threadPoolName = DEFAULT_THREAD_POOL_NAME;
+
+   private volatile ThreadPool threadPool;
+
+   /**
+    * The Log-object for this class
+    */
+   private static final Logger log = Logger.getLogger(SSOClusterManager.class);;
+
+   /**
+    * Whether we are registered as a CacheListener anywhere
+    */
+   private volatile boolean registeredAsListener = false;
+
+   /**
+    * The MBean server we use to access external components (TODO: convert to injection)
+    */
+   private volatile MBeanServer server = null;
+
+   /**
+    * The SingleSignOn for which we are providing cluster support
+    */
+   private volatile SSOLocalManager ssoValve = null;
+
+   /**
+    * Whether we have been started
+    */
+   private volatile boolean started = false;
+
+   /**
+    * Whether we have logged an error due to not having a valid cache
+    */
+   private volatile boolean missingCacheErrorLogged = false;
+
+   /**
+    * Our node's address in the cluster.
+    */
+   private volatile Object localAddress = null;
+
+   /**
+    * The new members of the last view passed to viewChange()
+    */
+   private final Set<Object> currentView = new HashSet<Object>();;
+
+   /** Mutex lock to ensure only one view change at a time is being processed */
+   private final Object cleanupMutex = new Object();
+
+   private volatile InfinispanHAPartitionCacheHandler<CacheKey, Object> cacheHandler;
+
+   // ------------------------------------------------------------  Properties
+
+   public InfinispanHAPartitionCacheHandler getCacheHandler()
+   {
+      return cacheHandler;
+   }
+
+   public void setCacheHandler(InfinispanHAPartitionCacheHandler cacheHandler)
+   {
+      this.cacheHandler = cacheHandler;
+   }
+
+   public String getThreadPoolName()
+   {
+      return threadPoolName;
+   }
+
+   public boolean isUsingThreadPool()
+   {
+      return threadPool != null;
+   }
+
+   // -----------------------------------------------------  SSOClusterManager
+
+   /**
+    * Notify the cluster of the addition of a Session to an SSO session.
+    *
+    * @param ssoId   the id of the SSO session
+    * @param sessionId id of the Session that has been added
+    */
+   public void addSession(String ssoId, FullyQualifiedSessionId sessionId)
+   {
+      if (ssoId == null || sessionId == null)
+      {
+         return;
+      }
+
+      if (!isCacheAvailable())
+      {
+         return;
+      }
+
+      if (log.isTraceEnabled())
+      {
+         log.trace("addSession(): adding Session " + sessionId.getSessionId() +
+            " to cached session set for SSO " + ssoId);
+      }
+
+      boolean doTx = false;
+      try
+      {
+         // Confirm we have a transaction manager; if not get it from Cache
+         // failure to find will throw an IllegalStateException
+         if (tm == null)
+            configureFromCache();
+
+         // Don't do anything if there is already a transaction
+         // context associated with this thread.
+         if(tm.getTransaction() == null)
+            doTx = true;
+
+         if(doTx)
+            tm.begin();
+
+         putSessionInCache(ssoId, sessionId);
+      }
+      catch (Exception e)
+      {
+         try
+         {
+            if(doTx)
+               tm.setRollbackOnly();
+         }
+         catch (Exception ignored)
+         {
+         }
+         log.error("caught exception adding session " + sessionId.getSessionId() +
+            " to SSO id " + ssoId, e);
+      }
+      finally
+      {
+         if (doTx)
+            endTransaction();
+      }
+   }
+
+
+   /**
+    * Gets the SingleSignOn valve for which this object is handling
+    * cluster communications.
+    *
+    * @return the <code>SingleSignOn</code> valve.
+    */
+   public SSOLocalManager getSSOLocalManager()
+   {
+      return ssoValve;
+   }
+
+
+   /**
+    * Sets the SingleSignOn valve for which this object is handling
+    * cluster communications.
+    * <p><b>NOTE:</b> This method must be called before calls can be
+    * made to the other methods of this interface.
+    *
+    * @param localManager a <code>SingleSignOn</code> valve.
+    */
+   public void setSSOLocalManager(SSOLocalManager localManager)
+   {
+      ssoValve = localManager;
+      if (ssoValve != null)
+      {
+         if (server == null)
+         {
+            server = ssoValve.getMBeanServer();
+         }
+         String poolName = ssoValve.getThreadPoolName();
+         if (poolName != null)
+         {
+            threadPoolName = poolName;
+         }
+      }
+   }
+
+
+   /**
+    * Notifies the cluster that a single sign on session has been terminated
+    * due to a user logout.
+    *
+    * @param ssoId
+    */
+   public void logout(String ssoId)
+   {
+      if (!isCacheAvailable())
+      {
+         return;
+      }
+
+      // Check whether we are already handling this removal
+      if (ssoId.equals(beingLocallyRemoved.get()))
+      {
+         return;
+      }
+
+      // Add this SSO to our list of in-process local removals so
+      // this.nodeRemoved() will ignore the removal
+      beingLocallyRemoved.set(ssoId);
+
+      if (log.isTraceEnabled())
+      {
+         log.trace("Registering logout of SSO " + ssoId +
+            " in clustered cache");
+      }
+
+      try
+      {
+         removeSSOFromCache(ssoId);
+      }
+      catch (Exception e)
+      {
+         log.error("Exception attempting to logout " +
+            ssoId, e);
+      }
+      finally
+      {
+         beingLocallyRemoved.set(null);
+      }
+   }
+
+
+   public SSOCredentials lookup(String ssoId)
+   {
+      if (!isCacheAvailable())
+      {
+         return null;
+      }
+
+      SSOCredentials credentials = null;
+      // Find the latest credential info from the cluster
+      try
+      {
+         credentials = getCredentialsFromCache(ssoId);
+      }
+      catch (Exception e)
+      {
+         log.error("caught exception looking up SSOCredentials for SSO id " +
+            ssoId, e);
+      }
+      return credentials;
+   }
+
+
+   /**
+    * Notifies the cluster of the creation of a new SSO entry.
+    *
+    * @param ssoId    the id of the SSO session
+    * @param authType the type of authenticator (BASIC, CLIENT-CERT, DIGEST
+    *                 or FORM) used to authenticate the SSO.
+    * @param username the username (if any) used for the authentication
+    * @param password the password (if any) used for the authentication
+    */
+   public void register(String ssoId, String authType,
+      String username, String password)
+   {
+      if (!isCacheAvailable())
+      {
+         return;
+      }
+
+      if (log.isTraceEnabled())
+      {
+         log.trace("Registering SSO " + ssoId + " in clustered cache");
+      }
+
+      storeCredentials(ssoId, authType, username, password);
+   }
+
+
+   /**
+    * Notify the cluster of the removal of a Session from an SSO session.
+    *
+    * @param ssoId   the id of the SSO session
+    * @param sessionId id of the Session that has been removed
+    */
+   public void removeSession(String ssoId, FullyQualifiedSessionId sessionId)
+   {
+      if (ssoId == null || sessionId == null)
+      {
+         return;
+      }
+
+      if (!isCacheAvailable())
+      {
+         return;
+      }
+
+      // Check that this session removal is not due to our own deregistration
+      // of an SSO following receipt of a nodeRemoved() call
+      if (ssoId.equals(beingRemotelyRemoved.get()))
+      {
+         return;
+      }
+
+      if (log.isTraceEnabled())
+      {
+         log.trace("removeSession(): removing Session " + sessionId.getSessionId() +
+            " from cached session set for SSO " + ssoId);
+      }
+
+      boolean doTx = false;
+      boolean removing = false;
+      try
+      {
+         // Confirm we have a transaction manager; if not get it from Cache
+         // failure to find will throw an IllegalStateException
+         if (tm == null)
+            configureFromCache();
+
+         // Don't do anything if there is already a transaction
+         // context associated with this thread.
+         if(tm.getTransaction() == null)
+            doTx = true;
+
+         if(doTx)
+            tm.begin();
+
+         // remove session
+         removeSessionFromCache(ssoId, sessionId);
+      }
+      catch (Exception e)
+      {
+         try
+         {
+            if(doTx)
+               tm.setRollbackOnly();
+         }
+         catch (Exception x)
+         {
+         }
+
+         log.error("caught exception removing session " + sessionId.getSessionId() +
+            " from SSO id " + ssoId, e);
+      }
+      finally
+      {
+         try
+         {
+            if (removing)
+            {
+               beingLocallyRemoved.set(null);
+            }
+         }
+         finally
+         {
+            if (doTx)
+               endTransaction();
+         }
+      }
+   }
+
+
+   /**
+    * Notifies the cluster of an update of the security credentials
+    * associated with an SSO session.
+    *
+    * @param ssoId    the id of the SSO session
+    * @param authType the type of authenticator (BASIC, CLIENT-CERT, DIGEST
+    *                 or FORM) used to authenticate the SSO.
+    * @param username the username (if any) used for the authentication
+    * @param password the password (if any) used for the authentication
+    */
+   public void updateCredentials(String ssoId, String authType,
+      String username, String password)
+   {
+      if (!isCacheAvailable())
+      {
+         return;
+      }
+
+      if (log.isTraceEnabled())
+      {
+         log.trace("Updating credentials for SSO " + ssoId +
+            " in clustered cache");
+      }
+
+      storeCredentials(ssoId, authType, username, password);
+   }
+
+
+   // ------------------------------------------------------  CacheListener
+
+   /**
+    * Extracts an SSO session id and uses it in an invocation of
+    * {@link ClusteredSingleSignOn#deregister(String) ClusteredSingleSignOn.deregister(String)}.
+    * <p/>
+    * Ignores invocations resulting from Cache changes originated by
+    * this object.
+    *
+    * @param event
+    */
+   @CacheEntryRemoved
+   public void cacheEntryRemoved(CacheEntryRemovedEvent event)
+   {
+      if (event.isPre())
+         return;
+
+      CacheKey key = (CacheKey)event.getKey();
+      String ssoId = key.getSSOID();
+
+      if (ssoId == null ||
+         key.getType() != CacheKey.Type.SESSION)
+      {
+         return;
+      }
+
+      // Entire SSO is being removed; i.e. an invalidation
+      // Ignore messages generated by our own logout activity
+      // TODO:  can we check event.isOriginLocal instead of beingLocallyRemoved? 
+      if (!ssoId.equals(beingLocallyRemoved.get()))
+      {
+         deregisterSSO(ssoId);
+      }
+      // signal the case that we have zero sessions for this ssoId
+      notifySSOEmpty(ssoId);
+   }
+
+   /**
+    * If any nodes have been removed from the view, asynchronously scans
+    * all SSOs looking for and removing sessions owned by the removed node.
+    * Notifies the SSO valve if as a result any SSOs no longer have active
+    * sessions.  If the removed node is the one associated with this object,
+    * does nothing.
+    */
+   @ViewChanged
+   public void viewChange(ViewChangedEvent event)
+   {
+      log.debug("Received ViewChangedEvent " + event);
+      boolean masterNode = false;  // true if we are the first node in the cluster group.
+      Set<Object> oldMembers = new HashSet<Object>(event.getOldMembers());
+      synchronized (currentView)
+      {
+         currentView.clear();
+         currentView.addAll(event.getNewMembers());
+
+         // If we're not in the view, just exit
+         if (localAddress == null || !currentView.contains(localAddress))
+            return;
+
+         // treat the first node in the view as the master node
+         if (currentView.iterator().next().equals(localAddress))
+         {
+            masterNode = true;
+         }
+
+         // Remove all the current members from the old set; any left
+         // are the dead members
+         oldMembers.removeAll(currentView);
+      }
+
+      /**
+       * if we are the master node, clean up any dead sessions left behind from a node that left the cluster group
+       */
+      if (oldMembers.size() > 0 && masterNode)
+      {
+         log.debug("Members have been removed; will launch cleanup task. Dead members: " + oldMembers);
+
+         launchSSOCleaner(false);
+      }
+
+   }
+
+
+   /**
+    * Instantiates a DeadMemberCleaner and assigns a thread
+    * to execute the cleanup task.
+    * @param notifyIfEmpty TODO
+    */
+   private void launchSSOCleaner(boolean notifyIfEmpty)
+   {
+
+      SSOCleanerTask cleaner = new SSOCleanerTask(notifyIfEmpty);
+      if (threadPool != null)
+      {
+         threadPool.run(cleaner);
+      }
+      else
+      {
+         Thread t = new Thread(cleaner, "ClusteredSSOCleaner");
+         t.setDaemon(true);
+         t.start();
+      }
+   }
+
+
+   /**
+    * Handles the notification that an entire SSO has been removed remotely
+    *
+    * @param ssoId id of the removed SSO
+    */
+   private void deregisterSSO(String ssoId)
+   {
+      beingRemotelyRemoved.set(ssoId);
+
+      try
+      {
+         if (log.isTraceEnabled())
+         {
+            log.trace("received a node removed message for SSO " + ssoId);
+         }
+
+         ssoValve.deregister(ssoId);
+      }
+      finally
+      {
+         beingRemotelyRemoved.set(null);
+      }
+   }
+
+   /**
+    * Checks whether any peers remain for the given SSO; if not
+    * notifies the valve that the SSO is empty.
+    *
+    * @param ssoId
+    */
+   private void notifySSOEmpty(String ssoId)
+   {
+      try
+      {
+         if (getSSOSessions(ssoId).size() == 0)
+         {
+            ssoValve.notifySSOEmpty(ssoId);
+         }
+      }
+      catch (Exception e)
+      {
+         log.error("Caught exception checking if " +  ssoId + " is empty", e);
+      }
+   }
+
+   /**
+    * Extracts an SSO session id and uses it in an invocation of
+    * {@link ClusteredSingleSignOn#update ClusteredSingleSignOn.update()}.
+    * <p/>
+    * Ignores invocations resulting from Cache changes originated by
+    * this object.
+    * <p/>
+    * Ignores invocations for SSO session id's that are not registered
+    * with the local SingleSignOn valve.
+    *
+    * @param event
+    */
+   @CacheEntryModified
+   public void cacheEntryModified(CacheEntryModifiedEvent event)
+   {
+      if (event.isPre() || event.isOriginLocal())
+         return;
+
+      CacheKey key = (CacheKey)event.getKey();
+      if (key.getType() == CacheKey.Type.CREDENTIAL)
+      {
+         handleCredentialModifiedEvent(key.getSSOID(), (SSOCredentials)event.getValue());
+      }
+      else if (key.getType() == CacheKey.Type.SESSION)
+      {
+         handleSessionModifiedEvent(key.getSSOID());
+      }
+   }
+
+   /**
+    * @param ssoId the id of the sso
+    * @param credentials 
+    */
+   private void handleCredentialModifiedEvent(String ssoId,SSOCredentials credentials)
+   {
+      // Ignore invocations that come as a result of our additions
+      // TODO: can this local check be removed since we already ignore local events in caller
+      if (ssoId.equals(beingLocallyAdded.get()))
+      {
+         return;
+      }
+
+      if (log.isTraceEnabled())
+      {
+         log.trace("received a credentials modified message for SSO " + ssoId);
+      }
+
+      try
+      {
+         if (credentials != null)
+         {
+            ssoValve.remoteUpdate(ssoId, credentials);
+         }
+      }
+      catch (Exception e)
+      {
+         log.error("failed to update credentials for SSO " + ssoId, e);
+      }
+   }
+
+   /**
+    *
+    * @param ssoId single sign-on session id
+    */
+   private void handleSessionModifiedEvent(String ssoId)
+   {
+      // Peers remove their entire node when it's empty, so any
+      // other modification means it's not empty
+      ssoValve.notifySSONotEmpty(ssoId);
+   }
+
+   /**
+    * Prepare for the beginning of active use of the public methods of this
+    * component.  This method should be called before any of the public
+    * methods of this component are utilized.  It should also send a
+    * LifecycleEvent of type START_EVENT to any registered listeners.
+    *
+    * @throws Exception if this component detects a fatal error
+    *                            that prevents this component from being used
+    */
+   public void start() throws Exception
+   {
+      // Validate and update our current component state
+      if (started)
+      {
+         throw new IllegalStateException("SSOClusterManagerImpl already Started");
+      }
+      this.cache = cacheHandler.getCache();
+      initThreadPool();
+      registerAsCacheListener();
+
+      this.tm = this.cache.getAdvancedCache().getTransactionManager();
+
+      started = true;
+   }
+
+
+   /**
+    * Gracefully terminate the active use of the public methods of this
+    * component.  This method should be the last one called on a given
+    * instance of this component.  It should also send a LifecycleEvent
+    * of type STOP_EVENT to any registered listeners.
+    *
+    * @throws Exception if this component detects a fatal error
+    *                            that needs to be reported
+    */
+   public void stop() throws Exception
+   {
+      // Validate and update our current component state
+      if (!started)
+      {
+         throw new IllegalStateException("SSOClusterManagerImpl not Started");
+      }
+
+      removeAsCacheListener();
+
+      started = false;
+   }
+
+
+   // -------------------------------------------------------  Public Methods
+
+   /**
+    * Gets the number of sessions associated with the given SSO. The same
+    * session active on more than one node will count more than once.
+    */
+   public int getSessionCount(String ssoId) throws Exception
+   {
+      return getSSOSessions(ssoId).size();
+   }
+
+   // -------------------------------------------------------  Private Methods
+
+   private Set<String> getSSOIds() throws Exception
+   {
+      Set keys = cache.keySet();
+      Set result = new HashSet<String>();
+      for (Object key: keys)
+      {
+         CacheKey ck = (CacheKey)key;
+         if (ck.getType() == CacheKey.Type.SESSION)
+         {
+            result.add(ck.getSSOID());
+         }
+      }
+
+      return result;
+   }
+
+   /**
+    *
+    * @param ssoId
+    * @return set of FullyQualifiedSessionId
+    * @throws Exception
+    */
+   private Set<FullyQualifiedSessionId> getSSOSessions(String ssoId) throws Exception
+   {
+      CacheKey key = new CacheKey(ssoId,CacheKey.Type.SESSION);
+      AtomicMap m = AtomicMapLookup.getAtomicMap(cache, key, true);
+      return m!=null ? m.keySet() : Collections.EMPTY_SET;
+   }
+
+   /**
+    * Obtains needed configuration information from the cache.
+    * Invokes "getTransactionManager" on the cache, caching the
+    * result or throwing an IllegalStateException if one is not found.
+    * Also gets our cluster-wide unique local address from the cache.
+    *
+    * @throws Exception
+    */
+   private void configureFromCache() throws Exception
+   {
+      if(tm == null)
+      {
+         tm = cache.getAdvancedCache().getTransactionManager();
+      }
+
+      if (tm == null)
+      {
+         throw new IllegalStateException("Cache does not have a " +
+                                         "transaction manager; please " +
+                                         "configure a valid " +
+                                         "TransactionManagerLookupClass");
+      }
+
+      // We no longer rule out buddy replication, as it can be valid if
+      // all activity for the SSO is meant to pinned to one server (i.e.
+      // only one session, or all sessions share the same session id cookie)
+      /*
+      if (cache.getConfiguration().getBuddyReplicationConfig() != null
+            && cache.getConfiguration().getBuddyReplicationConfig().isEnabled())
+      {
+         throw new IllegalStateException("Underlying cache is configured for " +
+                                         "buddy replication; use of buddy " +
+                                         "replication with ClusteredSingleSignOn " +
+                                         "is not supported");
+      }
+      */
+      // Find out our address
+      Address address = cache.getAdvancedCache().getRpcManager().getAddress();
+      if (address != null)
+         localAddress = address;
+      else if (Configuration.CacheMode.LOCAL == cache.getConfiguration().getCacheMode())
+         localAddress = "LOCAL";
+      else
+         throw new IllegalStateException("Cannot get local address from cache");
+
+
+      log.debug("Local address is " + localAddress);
+
+   }
+
+   private void endTransaction()
+   {
+      try
+      {
+         if(tm.getTransaction().getStatus() != Status.STATUS_MARKED_ROLLBACK)
+         {
+            tm.commit();
+         }
+         else
+         {
+            tm.rollback();
+         }
+      }
+      catch (Exception e)
+      {
+         log.error(e);
+         throw new RuntimeException("SSOClusterManagerImpl.endTransaction(): ", e);
+      }
+   }
+
+   private MBeanServer getMBeanServer()
+   {
+      if (server == null && ssoValve != null)
+      {
+         server = ssoValve.getMBeanServer();
+      }
+      return server;
+   }
+
+   private boolean isCacheAvailable()
+   {
+      //boolean avail = isCacheAvailable(false);
+      boolean avail = this.cache != null;
+      if (!avail)
+         logMissingCacheError();
+      return avail;
+   }
+
+   /**
+    * Put a new session in the cache
+    * @param ssoId session id
+    * @param fullyQualifiedSessionId  fully qualified session id
+    * @throws Exception
+    */
+   private void putSessionInCache(String ssoId, FullyQualifiedSessionId fullyQualifiedSessionId) throws Exception
+   {
+      CacheKey key = new CacheKey(ssoId,CacheKey.Type.SESSION);
+      AtomicMap m = AtomicMapLookup.getAtomicMap(cache, key, true);
+      m.put(fullyQualifiedSessionId, null);
+   }
+
+   /**
+    * Put or update user credentials in the cache
+    * @param ssoId session id
+    * @param credentials
+    * @throws Exception
+    */
+   private void putCredentialsInCache(String ssoId, SSOCredentials credentials) throws Exception
+   {
+      CacheKey key = new CacheKey(ssoId,CacheKey.Type.CREDENTIAL);
+      cache.put(key, credentials);
+   }
+
+   private SSOCredentials getCredentialsFromCache(String ssoId)
+   {
+      CacheKey key = new CacheKey(ssoId,CacheKey.Type.CREDENTIAL);
+      return (SSOCredentials)cache.get(key);
+   }
+
+   /**
+    * register as a cache listener.
+    *
+    * @throws Exception
+    */
+   private void registerAsCacheListener() throws Exception
+   {
+      cache.addListener(this);
+      registeredAsListener = true;
+   }
+
+
+   /**
+    * stop listening on the cache.
+    *
+    * @throws Exception
+    */
+   private void removeAsCacheListener() throws Exception
+   {
+      if (registeredAsListener && cache != null)
+      {
+         cache.removeListener(this);
+         registeredAsListener = false;
+      }
+   }
+
+   /**
+    * Remove the specified session from the cache (used for session.logout)
+    *
+    * @param ssoId the session id representing the shared single session
+    * @throws Exception
+    */
+   private void removeSSOFromCache(String ssoId) throws Exception
+   {
+      CacheKey key = new CacheKey(ssoId,CacheKey.Type.SESSION);
+      cache.remove(key);
+      key = new CacheKey(ssoId,CacheKey.Type.CREDENTIAL);
+      cache.remove(key);  // remove user credentials too
+   }
+
+   /**
+    * Remove one of the sessions associated with the users shared single session
+    * @param ssoId ssoId the session id representing the shared single session
+    * @param fullyQualifiedSessionId representing the session to remove
+    * @throws Exception
+    */
+   private void removeSessionFromCache(String ssoId, FullyQualifiedSessionId fullyQualifiedSessionId) throws Exception
+   {
+      CacheKey key = new CacheKey(ssoId,CacheKey.Type.SESSION);
+      AtomicMap m = AtomicMapLookup.getAtomicMap(cache, key, false);
+      if (m != null)
+      {
+         m.remove(fullyQualifiedSessionId);
+      }
+   }
+
+   /**
+    * Stores the given data to the clustered cache.
+    *
+    * @param ssoId    the id of the SSO session
+    * @param authType the type of authenticator (BASIC, CLIENT-CERT, DIGEST
+    *                 or FORM) used to authenticate the SSO.
+    * @param username the username (if any) used for the authentication
+    * @param password the password (if any) used for the authentication
+    */
+   private void storeCredentials(String ssoId, String authType, String username,
+      String password)
+   {
+      SSOCredentials credentials = new SSOCredentials(authType, username, password);
+
+      // Add this SSO to our list of in-process local adds so
+      // this.nodeModified() will ignore the addition
+      beingLocallyAdded.set(ssoId);
+
+      try
+      {
+         putCredentialsInCache(ssoId, credentials);
+      }
+      catch (Exception e)
+      {
+         log.error("Exception attempting to add Cache nodes for SSO " +
+            ssoId, e);
+      }
+      finally
+      {
+         beingLocallyAdded.set(null);
+      }
+   }
+
+   private void initThreadPool()
+   {
+      if (threadPoolName != null && getMBeanServer() != null)
+      {
+         try
+         {
+            ObjectName on = new ObjectName(threadPoolName);
+            threadPool = (ThreadPool) server.getAttribute(on, "Instance");
+            log.debug("Using ThreadPool at " + threadPoolName + " to clean dead members");
+         }
+         catch (Exception e)
+         {
+            log.info("Unable to access ThreadPool at " + threadPoolName +
+                     " -- will use individual threads for cleanup work");
+            log.debug("Failure to access ThreadPool due to: " + e);
+         }
+      }
+      else
+      {
+         log.debug("No ThreadPool configured -- will use individual threads for cleanup work");
+      }
+   }
+
+   private boolean isMissingCacheErrorLogged()
+   {
+      return missingCacheErrorLogged;
+   }
+
+   private void setMissingCacheErrorLogged(boolean missingCacheErrorLogged)
+   {
+      this.missingCacheErrorLogged = missingCacheErrorLogged;
+   }
+
+   private void logMissingCacheError()
+   {
+      StringBuffer msg = new StringBuffer("Cache is not set");
+      msg.append(" -- Cache must be started before SSOClusterManagerImpl ");
+      msg.append("can handle requests");
+
+      if (isMissingCacheErrorLogged())
+      {
+         // Just log it as a warning
+         log.warn(msg);
+      }
+      else
+      {
+         log.error(msg);
+         // Set a flag so we don't relog this error over and over
+         setMissingCacheErrorLogged(true);
+      }
+   }
+
+   // ---------------------------------------------------------  Outer Classes
+
+   /**
+    * Runnable that's run when the removal of a node from the cluster has been detected.
+    * Removes any SessionAddress objects associated with dead members from the
+    * session set of each SSO.  Operates locally only so each node can independently clean
+    * its SSOs without concern about replication lock conflicts.
+    */
+   private class SSOCleanerTask implements Runnable
+   {
+      private final boolean checkForEmpty;
+
+      private SSOCleanerTask(boolean checkForEmpty)
+      {
+         this.checkForEmpty = checkForEmpty;
+      }
+
+      public void run()
+      {
+         synchronized (cleanupMutex)
+         {
+            try
+            {
+               log.debug("check if we have to clean up SSO for any members that left the cluster.");
+               // Ensure we have a TransactionManager
+               if (tm == null)
+                  configureFromCache();
+
+               Set<String> ids = getSSOIds();
+               for (String sso : ids)
+               {
+                  cleanSSO(sso);
+               }
+            }
+            catch (Exception e)
+            {
+               log.error("Caught exception cleaning sessions from dead cluster members from SSOs ", e);
+            }
+         }
+      }
+
+      private void cleanSSO(String ssoId)
+      {
+         boolean doTx = false;
+         try
+         {
+            // Don't start tx if there is already one associated with this thread.
+            if(tm.getTransaction() == null)
+               doTx = true;
+
+            if(doTx)
+               tm.begin();
+
+            Set<FullyQualifiedSessionId> fullyQualifiedSessionIds = getSSOSessions(ssoId);
+            if (fullyQualifiedSessionIds.size() > 0)
+            {
+               for (FullyQualifiedSessionId fullyQualifiedSessionId : fullyQualifiedSessionIds)
+               {
+                  boolean alive;
+                  synchronized (currentView)
+                  {
+                     alive = currentView.contains(fullyQualifiedSessionId.getHostName());
+                  }
+                  if (!alive)
+                  {
+                     if (log.isTraceEnabled())
+                     {
+                        log.trace("Removing peer " + fullyQualifiedSessionId + " from SSO " + ssoId);
+                     }
+
+                     // Remove the peer node
+                     removeSessionFromCache(ssoId, fullyQualifiedSessionId);
+                  }
+               }
+            }
+            else if (checkForEmpty)
+            {
+               // SSO has no peers; notify our valve so we can expire it
+               ssoValve.notifySSOEmpty(ssoId);
+            }
+         }
+         catch (Exception e)
+         {
+            try
+            {
+               if(doTx)
+                  tm.setRollbackOnly();
+            }
+            catch (Exception ignored)
+            {
+            }
+            log.error("caught exception cleaning dead members from SSO " + ssoId, e);
+         }
+         finally
+         {
+            if (doTx)
+               endTransaction();
+         }
+      }
+   }
+
+}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntryTest.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntryTest.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntryTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,167 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import org.easymock.EasyMock;
-import org.infinispan.atomic.AtomicMap;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.AtomicMapEntry;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * @author Paul Ferraro
- *
- */
-public class AtomicMapEntryTest
-{
-   @Test
-   public void test()
-   {
-      for (AtomicMapEntry entry: AtomicMapEntry.values())
-      {
-         switch (entry)
-         {
-            case VERSION:
-            {
-               this.test(entry, new Integer(1), new Object());
-               break;
-            }
-            case TIMESTAMP:
-            {
-               this.test(entry, new Long(1), new Object());
-               break;
-            }
-            case METADATA:
-            {
-               this.test(entry, new DistributableSessionMetadata(), new Object());
-               break;
-            }
-            case ATTRIBUTES:
-            {
-               this.test(entry, new Object(), null);
-               break;
-            }
-         }
-      }
-   }
-   
-   private void test(AtomicMapEntry entry, Object valid, Object invalid)
-   {
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
-      
-      // Test null put
-      EasyMock.replay(map);
-      
-      entry.put(map, null);
-
-      EasyMock.verify(map);
-      EasyMock.reset(map);
-      
-      
-      // Test null get
-      EasyMock.expect(map.get(Byte.valueOf((byte) entry.ordinal()))).andReturn(null);
-      
-      EasyMock.replay(map);
-      
-      Object result = entry.get(map);
-
-      EasyMock.verify(map);
-      
-      Assert.assertNull(result);
-      
-      EasyMock.reset(map);
-      
-      
-      if (invalid != null)
-      {
-         // Test illegal argument put
-         EasyMock.replay(map);
-         
-         IllegalArgumentException iae = null;
-         
-         try
-         {
-            entry.put(map, invalid);
-         }
-         catch (IllegalArgumentException e)
-         {
-            iae = e;
-         }
-         
-         EasyMock.verify(map);
-         
-         Assert.assertNotNull(iae);
-         
-         EasyMock.reset(map);
-
-
-         // Test illegal argument get
-         EasyMock.expect(map.get(Byte.valueOf((byte) entry.ordinal()))).andReturn(invalid);
-
-         EasyMock.replay(map);
-         
-         ClassCastException cce = null;
-         
-         try
-         {
-            entry.get(map);
-         }
-         catch (ClassCastException e)
-         {
-            cce = e;
-         }
-         
-         EasyMock.verify(map);
-         
-         Assert.assertNotNull(cce);
-         
-         EasyMock.reset(map);
-      }
-      
-      // Test legal argument put
-      EasyMock.expect(map.put(EasyMock.eq(Byte.valueOf((byte) entry.ordinal())), EasyMock.same(valid))).andReturn(null);
-      
-      EasyMock.replay(map);
-      
-      entry.put(map, valid);
-      
-      EasyMock.verify(map);
-      
-      EasyMock.reset(map);
-      
-      
-      // Test legal argument get
-      EasyMock.expect(map.get(Byte.valueOf((byte) entry.ordinal()))).andReturn(valid);
-      
-      EasyMock.replay(map);
-      
-      result = entry.get(map);
-      
-      EasyMock.verify(map);
-      
-      Assert.assertSame(valid, result);
-      
-      EasyMock.reset(map);
-   }
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorageTest.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorageTest.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorageTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,105 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.easymock.EasyMock;
-import org.infinispan.atomic.AtomicMap;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.AtomicMapEntry;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.CoarseSessionAttributeStorage;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingSessionGranularitySessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * @author Paul Ferraro
- *
- */
-public class CoarseSessionAttributeStorageTest
-{
-   private SessionAttributeMarshaller marshaller = EasyMock.createStrictMock(SessionAttributeMarshaller.class);
-   private SessionAttributeStorage<OutgoingSessionGranularitySessionData> storage = new CoarseSessionAttributeStorage(this.marshaller);
-   
-   @Test
-   public void store()
-   {
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
-      OutgoingSessionGranularitySessionData data = EasyMock.createStrictMock(OutgoingSessionGranularitySessionData.class);
-      Map<String, Object> attributes = Collections.emptyMap();
-      Object marshalledAttributes = new Object();
-      
-      EasyMock.expect(data.getSessionAttributes()).andReturn(attributes);
-      EasyMock.expect(this.marshaller.marshal(attributes)).andReturn(marshalledAttributes);
-      EasyMock.expect(map.put(EasyMock.eq((byte) AtomicMapEntry.ATTRIBUTES.ordinal()), EasyMock.same(marshalledAttributes))).andReturn(null);
-      
-      EasyMock.replay(this.marshaller, map, data);
-      
-      this.storage.store(map, data);
-      
-      EasyMock.verify(this.marshaller, map, data);
-      EasyMock.reset(this.marshaller, map, data);
-   }
-   
-   @Test
-   public void storeNull()
-   {
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
-      OutgoingSessionGranularitySessionData data = EasyMock.createStrictMock(OutgoingSessionGranularitySessionData.class);
-      
-      EasyMock.expect(data.getSessionAttributes()).andReturn(null);
-      
-      EasyMock.replay(this.marshaller, map, data);
-      
-      this.storage.store(map, data);
-      
-      EasyMock.verify(this.marshaller, map, data);
-      EasyMock.reset(this.marshaller, map, data);
-   }
-   
-   @Test
-   public void load() throws Exception
-   {
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
-      Object marshalledAttributes = new Object();
-      Map<String, Object> attributes = Collections.emptyMap();
-      
-      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.ATTRIBUTES.ordinal()))).andReturn(marshalledAttributes);
-      EasyMock.expect(this.marshaller.unmarshal(EasyMock.same(marshalledAttributes))).andReturn(attributes);
-      
-      EasyMock.replay(this.marshaller, map);
-      
-      Map<String, Object> result = this.storage.load(map);
-      
-      EasyMock.verify(this.marshaller, map);
-      
-      Assert.assertSame(attributes, result);
-      
-      EasyMock.reset(this.marshaller, map);
-   }
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactoryTest.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactoryTest.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactoryTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,85 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import org.easymock.EasyMock;
-import org.jboss.ha.ispn.atomic.AtomicMapFactory;
-import org.jboss.ha.ispn.invoker.CacheInvoker;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.DistributedCacheManagerFactory;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.DistributedCacheManager;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorageFactory;
-import org.jboss.metadata.web.jboss.ReplicationConfig;
-import org.jboss.metadata.web.jboss.ReplicationGranularity;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshallerFactory;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * @author Paul Ferraro
- *
- */
-public class DistributedCacheManagerFactoryTest
-{
-   private final SessionAttributeStorageFactory storageFactory = EasyMock.createStrictMock(SessionAttributeStorageFactory.class);
-   private final SessionAttributeMarshallerFactory marshallerFactory = EasyMock.createStrictMock(SessionAttributeMarshallerFactory.class);
-   private final CacheInvoker invoker = EasyMock.createStrictMock(CacheInvoker.class);
-   private final LocalDistributableSessionManager manager = EasyMock.createStrictMock(LocalDistributableSessionManager.class);
-   @SuppressWarnings("unchecked")
-   private final SessionAttributeStorage<OutgoingDistributableSessionData> storage = EasyMock.createStrictMock(SessionAttributeStorage.class);
-   private final SessionAttributeMarshaller marshaller = EasyMock.createStrictMock(SessionAttributeMarshaller.class);
-   private final AtomicMapFactory atomicMapFactory = EasyMock.createStrictMock(AtomicMapFactory.class);
-   
-   @Test
-   public void test() throws Exception
-   {
-      DistributedCacheManagerFactory factory = new DistributedCacheManagerFactory();
-      
-      factory.setAtomicMapFactory(atomicMapFactory);
-      factory.setSessionAttributeStorageFactory(this.storageFactory);
-      factory.setSessionAttributeMarshallerFactory(this.marshallerFactory);
-      factory.setCacheInvoker(this.invoker);
-      factory.setAtomicMapFactory(this.atomicMapFactory);
-      
-      ReplicationConfig config = new ReplicationConfig();
-      ReplicationGranularity granularity = ReplicationGranularity.SESSION;
-      config.setReplicationGranularity(granularity);
-      
-      EasyMock.expect(this.marshallerFactory.createMarshaller(this.manager)).andReturn(this.marshaller);
-      EasyMock.expect(this.manager.getReplicationConfig()).andReturn(config);
-      EasyMock.expect(this.storageFactory.createStorage(granularity, this.marshaller)).andReturn(this.storage);
-      
-      EasyMock.replay(this.storageFactory, this.marshallerFactory, this.invoker, this.manager, this.storage, this.marshaller, this.atomicMapFactory);
-      
-      org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager<?> result = factory.getDistributedCacheManager(this.manager);
-      
-      EasyMock.verify(this.storageFactory, this.marshallerFactory, this.invoker, this.manager, this.storage, this.marshaller, this.atomicMapFactory);
-      
-      Assert.assertNotNull(result);
-      Assert.assertTrue(result instanceof DistributedCacheManager);
-      
-      EasyMock.reset(this.storageFactory, this.marshallerFactory, this.invoker, this.manager, this.storage, this.marshaller, this.atomicMapFactory);
-   }
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerTest.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerTest.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,834 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.easymock.Capture;
-import org.easymock.EasyMock;
-import org.infinispan.AdvancedCache;
-import org.infinispan.Cache;
-import org.infinispan.atomic.AtomicMap;
-import org.infinispan.config.Configuration;
-import org.infinispan.context.Flag;
-import org.infinispan.distribution.DistributionManager;
-import org.infinispan.lifecycle.ComponentStatus;
-import org.infinispan.manager.CacheContainer;
-import org.infinispan.manager.EmbeddedCacheManager;
-import org.infinispan.notifications.cachelistener.event.CacheEntryActivatedEvent;
-import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
-import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
-import org.infinispan.transaction.tm.BatchModeTransactionManager;
-import org.jboss.ha.ispn.CacheContainerRegistry;
-import org.jboss.ha.ispn.atomic.AtomicMapFactory;
-import org.jboss.ha.ispn.invoker.CacheInvoker;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.AtomicMapEntry;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.DistributedCacheManager;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage;
-import org.jboss.metadata.web.jboss.ReplicationConfig;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.IncomingDistributableSessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionOwnershipSupport;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * @author Paul Ferraro
- *
- */
-public class DistributedCacheManagerTest
-{
-   private final CacheContainer container = EasyMock.createStrictMock(CacheContainer.class);
-   private final CacheContainerRegistry registry = EasyMock.createStrictMock(CacheContainerRegistry.class);
-   private final LocalDistributableSessionManager manager = EasyMock.createStrictMock(LocalDistributableSessionManager.class);
-   @SuppressWarnings("unchecked")
-   private final SessionAttributeStorage<OutgoingDistributableSessionData> storage = EasyMock.createStrictMock(SessionAttributeStorage.class);
-   @SuppressWarnings("unchecked")
-   private final AdvancedCache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(AdvancedCache.class);
-   private final CacheInvoker invoker = EasyMock.createStrictMock(CacheInvoker.class);
-   private final AtomicMapFactory atomicMapFactory = EasyMock.createStrictMock(AtomicMapFactory.class);
-   
-   @Test
-   public void start()
-   {
-      ReplicationConfig config = new ReplicationConfig();
-      config.setCacheName("session-cache");
-      
-      // Validate host contribution to cache name
-      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
-      this.start(null, "session-cache", "", "", "localhost/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
-      this.start(null, "session-cache", "host1", "", "host1/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
-
-      // Validate context path contribution to cache name
-      this.start(null, "session-cache", null, "/", "localhost/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
-      this.start(null, "session-cache", null, "/context1", "localhost/context1", config, ComponentStatus.INSTANTIATED, true, new Configuration());
-      this.start(null, "session-cache", null, "/path/context1", "localhost/path/context1", config, ComponentStatus.INSTANTIATED, true, new Configuration());
-      
-      // Validate starting of cache per cache status
-      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.FAILED, true, new Configuration());
-      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.INITIALIZING, true, new Configuration());
-      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.RUNNING, false, new Configuration());
-      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.STOPPING, true, new Configuration());
-      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.TERMINATED, true, new Configuration());
-      
-      // Validate cache container qualified cache name
-      config.setCacheName("default:session-cache");
-      this.start("default", "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
-   }
-   
-   private DistributedCacheManager<OutgoingDistributableSessionData> start(String containerName, String templateCacheName, String hostName, String contextName, String cacheName, ReplicationConfig config, ComponentStatus cacheStatus, boolean startCache, Configuration configuration)
-   {
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = new DistributedCacheManager<OutgoingDistributableSessionData>(this.manager, this.registry, this.storage, this.invoker, this.atomicMapFactory);
-      
-      @SuppressWarnings("unchecked")
-      Cache<Object, Object> cache = EasyMock.createStrictMock(Cache.class);
-      EmbeddedCacheManager cacheManager = EasyMock.createStrictMock(EmbeddedCacheManager.class);
-      
-      EasyMock.expect(this.manager.getReplicationConfig()).andReturn(config);
-      
-      EasyMock.expect(this.registry.getCacheContainer(containerName)).andReturn(this.container);
-      EasyMock.expect(this.manager.getHostName()).andReturn(hostName);
-      EasyMock.expect(this.manager.getContextName()).andReturn(contextName);
-      EasyMock.expect(this.container.getCache()).andReturn(cache);
-      EasyMock.expect(cache.getCacheManager()).andReturn(cacheManager);
-      EasyMock.expect(cacheManager.defineConfiguration(cacheName, templateCacheName, new Configuration())).andReturn(configuration);
-      EasyMock.expect(cacheManager.<String, AtomicMap<Object, Object>>getCache(cacheName)).andReturn(this.cache);
-      
-      EasyMock.expect(this.cache.getStatus()).andReturn(cacheStatus);
-      if (startCache)
-      {
-         this.cache.start();
-      }
-      EasyMock.expect(this.cache.getAdvancedCache()).andReturn(this.cache);
-      EasyMock.expect(this.cache.getTransactionManager()).andReturn(new BatchModeTransactionManager());
-      this.cache.addListener(manager);
-      
-      EasyMock.expect(this.cache.getConfiguration()).andReturn(configuration);
-      
-      EasyMock.replay(this.registry, this.manager, this.container, this.storage, this.cache, this.invoker, cache, cacheManager);
-      
-      manager.start();
-      
-      EasyMock.verify(this.registry, this.manager, this.container, this.storage, this.cache, this.invoker, cache, cacheManager);
-      
-      Assert.assertNotNull(manager.getBatchingManager());
-      
-      EasyMock.reset(this.registry, this.manager, this.container, this.storage, this.cache, this.invoker, cache, cacheManager);
-      
-      return manager;
-   }
-   
-   private DistributedCacheManager<OutgoingDistributableSessionData> startDistributedCacheManager()
-   {
-      ReplicationConfig config = new ReplicationConfig();
-      config.setCacheName("session-cache");
-      
-      return this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
-   }
-   
-   @Test
-   public void stop()
-   {
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      this.cache.removeListener(manager);
-      this.cache.stop();
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      manager.stop();
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void sessionCreated()
-   {
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      manager.sessionCreated("abc");
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void storeSessionData()
-   {
-      OutgoingDistributableSessionData data = EasyMock.createNiceMock(OutgoingDistributableSessionData.class);
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> map = EasyMock.createNiceMock(AtomicMap.class);
-      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
-      
-      String sessionId = "abc";
-      int version = 10;
-      long timestamp = System.currentTimeMillis();
-      DistributableSessionMetadata metadata = new DistributableSessionMetadata();
-      
-      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(map);
-
-      EasyMock.expect(data.getRealId()).andReturn(sessionId);
-      EasyMock.expect(data.getVersion()).andReturn(version);
-      EasyMock.expect(map.put(Byte.valueOf((byte) AtomicMapEntry.VERSION.ordinal()), version)).andReturn(null);
-      EasyMock.expect(data.getTimestamp()).andReturn(timestamp);
-      EasyMock.expect(map.put(Byte.valueOf((byte) AtomicMapEntry.TIMESTAMP.ordinal()), timestamp)).andReturn(null);
-      EasyMock.expect(data.getMetadata()).andReturn(metadata);
-      EasyMock.expect(map.put(Byte.valueOf((byte) AtomicMapEntry.METADATA.ordinal()), metadata)).andReturn(null);
-      
-      this.storage.store(EasyMock.same(map), EasyMock.same(data));
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data, map);
-      
-      manager.storeSessionData(data);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data, map);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data, map);
-      
-      
-      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
-      
-      EasyMock.expect(this.atomicMapFactory.getAtomicMap(EasyMock.same(cache), EasyMock.same(sessionId), EasyMock.eq(true))).andReturn(map);
-            
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data);
-      
-      AtomicMap<Object, Object> result = operation.invoke(this.cache);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data);
-      
-      Assert.assertSame(map, result);
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data);
-   }
-   
-   @Test
-   public void getSessionDataNoOwner() throws Exception
-   {
-      this.getSessionDataNoOwner(true);
-      
-      this.getSessionDataNoOwner(false);
-   }
-   
-   private void getSessionDataNoOwner(boolean includeAttributes) throws Exception
-   {
-      String sessionId = "abc";
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> map = EasyMock.createNiceMock(AtomicMap.class);
-      Map<String, Object> attributes = Collections.emptyMap();
-      
-      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
-
-      Integer version = Integer.valueOf(10);
-      Long timestamp = Long.valueOf(System.currentTimeMillis());
-      DistributableSessionMetadata metadata = new DistributableSessionMetadata();
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(map);
-      
-      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.VERSION.ordinal()))).andReturn(version);
-      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.TIMESTAMP.ordinal()))).andReturn(timestamp);
-      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.METADATA.ordinal()))).andReturn(metadata);
-      
-      if (includeAttributes)
-      {
-         EasyMock.expect(this.storage.load(map)).andReturn(attributes);
-      }
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, map);
-      
-      IncomingDistributableSessionData result = manager.getSessionData(sessionId, null, includeAttributes);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, map);
-      
-      Assert.assertNotNull(result);
-      Assert.assertEquals(version.intValue(), result.getVersion());
-      Assert.assertEquals(timestamp.longValue(), result.getTimestamp());
-      Assert.assertSame(metadata, result.getMetadata());
-      
-      if (includeAttributes)
-      {
-         Assert.assertSame(attributes, result.getSessionAttributes());
-      }
-      else
-      {
-         IllegalStateException exception = null;
-         Map<String, Object> sessionAttributes = null;
-         
-         try
-         {
-            sessionAttributes = result.getSessionAttributes();
-         }
-         catch (IllegalStateException e)
-         {
-            exception = e;
-         }
-         
-         Assert.assertNull(sessionAttributes);
-         Assert.assertNotNull(exception);
-      }
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, map);
-      
-      
-      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> expectedMap = EasyMock.createMock(AtomicMap.class);
-      
-      EasyMock.expect(this.atomicMapFactory.getAtomicMap(EasyMock.same(cache), EasyMock.same(sessionId), EasyMock.eq(false))).andReturn(expectedMap);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, expectedMap);
-      
-      AtomicMap<Object, Object> resultMap = operation.invoke(this.cache);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, expectedMap);
-      
-      Assert.assertSame(expectedMap, resultMap);
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, expectedMap);
-   }
-   
-   @Test
-   public void getMissingSessionDataNoOwner()
-   {
-      this.getMissingSessionDataNoOwner(true);
-      
-      this.getMissingSessionDataNoOwner(false);
-   }
-   
-   private void getMissingSessionDataNoOwner(boolean includeAttributes)
-   {
-      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
-      
-      IncomingDistributableSessionData result = manager.getSessionData("abc", null, includeAttributes);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
-      
-      Assert.assertNull(result);
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
-      
-      
-      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> expectedMap = EasyMock.createMock(AtomicMap.class);
-      
-      EasyMock.expect(this.atomicMapFactory.getAtomicMap(this.cache, "abc", false)).andReturn(expectedMap);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
-      
-      AtomicMap<Object, Object> resultMap = operation.invoke(this.cache);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
-      
-      Assert.assertSame(expectedMap, resultMap);
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
-   }
-   
-   @Test
-   public void getSessionDataWithOwner()
-   {
-      this.getSessionDataWithOwner(true);
-      
-      this.getSessionDataWithOwner(false);
-   }
-   
-   private void getSessionDataWithOwner(boolean includeAttributes)
-   {
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      IncomingDistributableSessionData result = manager.getSessionData("abc", "owner1", includeAttributes);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      Assert.assertNull(result);
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void removeSession()
-   {
-      String sessionId = "abc";
-      
-      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      manager.removeSession(sessionId);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      
-      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> expectedMap = EasyMock.createMock(AtomicMap.class);
-      
-      EasyMock.expect(this.cache.remove(sessionId)).andReturn(expectedMap);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      AtomicMap<Object, Object> resultMap = operation.invoke(this.cache);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      Assert.assertSame(expectedMap, resultMap);
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void removeSessionLocal()
-   {
-      String sessionId = "abc";
-      
-      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      manager.removeSessionLocal(sessionId);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      
-      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> expectedMap = EasyMock.createMock(AtomicMap.class);
-      
-      EasyMock.expect(this.cache.getAdvancedCache()).andReturn(this.cache);
-      EasyMock.expect(this.cache.withFlags(Flag.CACHE_MODE_LOCAL)).andReturn(this.cache);
-      EasyMock.expect(this.cache.remove(sessionId)).andReturn(expectedMap);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      AtomicMap<Object, Object> resultMap = operation.invoke(this.cache);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      Assert.assertSame(expectedMap, resultMap);
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void removeSessionLocalNoOwner()
-   {
-      String sessionId = "abc";
-      
-      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      manager.removeSessionLocal(sessionId, null);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      
-      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> expectedMap = EasyMock.createMock(AtomicMap.class);
-      
-      EasyMock.expect(this.cache.getAdvancedCache()).andReturn(this.cache);
-      EasyMock.expect(this.cache.withFlags(Flag.CACHE_MODE_LOCAL)).andReturn(this.cache);
-      EasyMock.expect(this.cache.remove(sessionId)).andReturn(expectedMap);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      AtomicMap<Object, Object> resultMap = operation.invoke(this.cache);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      Assert.assertSame(expectedMap, resultMap);
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void removeSessionLocalWithOwner()
-   {
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      manager.removeSessionLocal("abc", "owner1");
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void evictSession()
-   {
-      String sessionId = "abc";
-      
-      Capture<DistributedCacheManager.Operation<Void>> capturedOperation = new Capture<DistributedCacheManager.Operation<Void>>();
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      manager.evictSession(sessionId);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      
-      DistributedCacheManager.Operation<Void> operation = capturedOperation.getValue();
-      
-      this.cache.evict(sessionId);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      Void result = operation.invoke(this.cache);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      Assert.assertNull(result);
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void evictSessionNoOwner()
-   {
-      String sessionId = "abc";
-      
-      Capture<DistributedCacheManager.Operation<Void>> capturedOperation = new Capture<DistributedCacheManager.Operation<Void>>();
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      manager.evictSession(sessionId, null);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      
-      DistributedCacheManager.Operation<Void> operation = capturedOperation.getValue();
-      
-      this.cache.evict(sessionId);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      Void result = operation.invoke(this.cache);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      Assert.assertNull(result);
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void evictSessionLocalWithOwner()
-   {
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      manager.evictSession("abc", "owner1");
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void getSessionIds()
-   {
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.expect(this.cache.keySet()).andReturn(Collections.singleton("abc"));
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      Map<String, String> result = manager.getSessionIds();
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      Assert.assertNotNull(result);
-      Assert.assertEquals(1, result.size());
-      Assert.assertTrue(result.containsKey("abc"));
-      Assert.assertNull(result.get("abc"));
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void setForceSynchronous()
-   {
-      this.setForceSynchronous(true);
-      this.setForceSynchronous(false);
-   }
-   
-   private void setForceSynchronous(boolean forceSynchronous)
-   {
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      this.invoker.setForceSynchronous(forceSynchronous);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      manager.setForceSynchronous(forceSynchronous);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void getSessionOwnershipSupport()
-   {
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-      SessionOwnershipSupport support = manager.getSessionOwnershipSupport();
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
-      
-// TODO when session ownership support is added, replace these assertions
-      Assert.assertNull(support);
-//      Assert.assertSame(manager, support);
-      
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
-   }
-   
-   @Test
-   public void removed()
-   {
-      CacheEntryRemovedEvent event = EasyMock.createNiceMock(CacheEntryRemovedEvent.class);
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      
-      EasyMock.expect(event.isPre()).andReturn(true);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      manager.removed(event);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      
-      EasyMock.expect(event.isPre()).andReturn(false);
-      EasyMock.expect(event.isOriginLocal()).andReturn(true);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      manager.removed(event);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      
-      EasyMock.expect(event.isPre()).andReturn(false);
-      EasyMock.expect(event.isOriginLocal()).andReturn(false);
-      EasyMock.expect(event.getKey()).andReturn("abc");
-      
-      this.manager.notifyRemoteInvalidation("abc");
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      manager.removed(event);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-   }
-   
-   @Test
-   public void modified()
-   {
-      CacheEntryModifiedEvent event = EasyMock.createNiceMock(CacheEntryModifiedEvent.class);
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      
-      EasyMock.expect(event.isPre()).andReturn(true);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      manager.modified(event);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      
-      EasyMock.expect(event.isPre()).andReturn(false);
-      EasyMock.expect(event.isOriginLocal()).andReturn(true);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      manager.modified(event);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> map = EasyMock.createNiceMock(AtomicMap.class);
-      
-      Integer version = Integer.valueOf(10);
-      Long timestamp = Long.valueOf(System.currentTimeMillis());
-      DistributableSessionMetadata metadata = new DistributableSessionMetadata();
-      
-      EasyMock.expect(event.isPre()).andReturn(false);
-      EasyMock.expect(event.isOriginLocal()).andReturn(false);
-      EasyMock.expect(event.getKey()).andReturn("abc");
-      EasyMock.expect(event.getValue()).andReturn(map);
-      
-      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.VERSION.ordinal()))).andReturn(version);
-      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.TIMESTAMP.ordinal()))).andReturn(timestamp);
-      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.METADATA.ordinal()))).andReturn(metadata);
-      
-      EasyMock.expect(this.manager.sessionChangedInDistributedCache("abc", null, version.intValue(), timestamp.longValue(), metadata)).andReturn(false);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event, map);
-      
-      manager.modified(event);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event, map);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event, map);
-   }
-   
-   @Test
-   public void activated()
-   {
-      CacheEntryActivatedEvent event = EasyMock.createNiceMock(CacheEntryActivatedEvent.class);
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      
-      EasyMock.expect(event.isPre()).andReturn(true);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      manager.activated(event);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      
-      EasyMock.expect(this.manager.isPassivationEnabled()).andReturn(false);
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      manager.activated(event);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      
-      EasyMock.expect(this.manager.isPassivationEnabled()).andReturn(true);
-      this.manager.sessionActivated();
-      
-      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      
-      manager.activated(event);
-      
-      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
-   }
-   
-   @Test
-   public void isLocalReplicationMode()
-   {
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      String sessionId = "ABC123";
-      
-      EasyMock.expect(this.cache.getAdvancedCache()).andReturn(this.cache);
-      EasyMock.expect(this.cache.getDistributionManager()).andReturn(null);
-      
-      EasyMock.replay(this.cache);
-      
-      boolean result = manager.isLocal(sessionId);
-      
-      EasyMock.verify(this.cache);
-      
-      Assert.assertTrue(result);
-      
-      EasyMock.reset(this.cache);
-   }
-   
-   @Test
-   public void isLocalDistributionMode()
-   {
-      this.isLocalDistributionMode(true);
-      this.isLocalDistributionMode(false);
-   }
-   
-   private void isLocalDistributionMode(boolean local)
-   {
-      DistributionManager distManager = EasyMock.createStrictMock(DistributionManager.class);
-      
-      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
-      String sessionId = "ABC123";
-      
-      EasyMock.expect(this.cache.getAdvancedCache()).andReturn(this.cache);
-      EasyMock.expect(this.cache.getDistributionManager()).andReturn(distManager);
-      EasyMock.expect(distManager.isLocal(sessionId)).andReturn(local);
-      
-      EasyMock.replay(this.cache, distManager);
-      
-      boolean result = manager.isLocal(sessionId);
-      
-      EasyMock.verify(this.cache, distManager);
-      
-      Assert.assertEquals(local, result);
-      
-      EasyMock.reset(this.cache, distManager);
-   }
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorageTest.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorageTest.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorageTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,121 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import java.util.AbstractMap;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.easymock.EasyMock;
-import org.infinispan.atomic.AtomicMap;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.FineSessionAttributeStorage;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingAttributeGranularitySessionData;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * @author Paul Ferraro
- *
- */
-public class FineSessionAttributeStorageTest
-{
-   private SessionAttributeMarshaller marshaller = EasyMock.createStrictMock(SessionAttributeMarshaller.class);
-   private SessionAttributeStorage<OutgoingAttributeGranularitySessionData> storage = new FineSessionAttributeStorage(this.marshaller);
-   
-   @Test
-   public void store()
-   {
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
-      OutgoingAttributeGranularitySessionData data = EasyMock.createStrictMock(OutgoingAttributeGranularitySessionData.class);
-      Map<String, Object> modifiedAttributes = Collections.singletonMap("key", (Object) "value");
-      Set<String> removedAttributes = Collections.singleton("removed");
-      Object marshalledAttribute = new Object();
-      
-      EasyMock.expect(data.getModifiedSessionAttributes()).andReturn(modifiedAttributes);
-      EasyMock.expect(this.marshaller.marshal("value")).andReturn(marshalledAttribute);
-      EasyMock.expect(map.put(EasyMock.eq("key"), EasyMock.same(marshalledAttribute))).andReturn(null);
-      EasyMock.expect(data.getRemovedSessionAttributes()).andReturn(removedAttributes);
-      EasyMock.expect(map.remove("removed")).andReturn(null);
-      
-      EasyMock.replay(this.marshaller, map, data);
-      
-      this.storage.store(map, data);
-      
-      EasyMock.verify(this.marshaller, map, data);
-      EasyMock.reset(this.marshaller, map, data);
-   }
-   
-   @Test
-   public void storeNull()
-   {
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
-      OutgoingAttributeGranularitySessionData data = EasyMock.createStrictMock(OutgoingAttributeGranularitySessionData.class);
-      
-      EasyMock.expect(data.getModifiedSessionAttributes()).andReturn(null);
-      EasyMock.expect(data.getRemovedSessionAttributes()).andReturn(null);
-      
-      EasyMock.replay(this.marshaller, map, data);
-      
-      this.storage.store(map, data);
-      
-      EasyMock.verify(this.marshaller, map, data);
-      EasyMock.reset(this.marshaller, map, data);
-   }
-   
-   @Test
-   public void load() throws Exception
-   {
-      @SuppressWarnings("unchecked")
-      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
-      Object marshalledAttribute = new Object();
-
-      Map.Entry<Object, Object> nonAttributeEntry = new AbstractMap.SimpleImmutableEntry<Object, Object>(new Object(), new Object());
-      Map.Entry<Object, Object> attributeEntry = new AbstractMap.SimpleImmutableEntry<Object, Object>((Object) "key", marshalledAttribute);
-      @SuppressWarnings("unchecked")
-      List<Map.Entry<Object, Object>> entries = Arrays.asList(nonAttributeEntry, attributeEntry);
-      
-      EasyMock.expect(map.entrySet()).andReturn(new HashSet<Map.Entry<Object, Object>>(entries));
-      EasyMock.expect(this.marshaller.unmarshal(EasyMock.same(marshalledAttribute))).andReturn("value");
-      
-      EasyMock.replay(this.marshaller, map);
-      
-      Map<String, Object> result = this.storage.load(map);
-      
-      EasyMock.verify(this.marshaller, map);
-      
-      Assert.assertNotNull(result);
-      Assert.assertEquals(1, result.size());
-      Assert.assertTrue(result.toString(), result.containsKey("key"));
-      Assert.assertEquals("value", result.get("key"));
-      
-      EasyMock.reset(this.marshaller, map);
-   }
-
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryTest.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryTest.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,81 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ha.web.tomcat.service.session.distributedcache.ispn;
-
-import org.easymock.EasyMock;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.CoarseSessionAttributeStorage;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.FineSessionAttributeStorage;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorageFactory;
-import org.jboss.ha.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorageFactoryImpl;
-import org.jboss.metadata.web.jboss.ReplicationGranularity;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * @author Paul Ferraro
- *
- */
-public class SessionAttributeStorageFactoryTest
-{
-   @Test
-   public void testSession()
-   {
-      this.test(ReplicationGranularity.SESSION, CoarseSessionAttributeStorage.class);
-   }
-   
-   @Test
-   public void testAttribute()
-   {
-      this.test(ReplicationGranularity.ATTRIBUTE, FineSessionAttributeStorage.class);
-   }
-   
-   @Test
-   public void testField()
-   {
-      this.test(ReplicationGranularity.FIELD, null);
-   }
-   
-   private void test(ReplicationGranularity granularity, Class<? extends SessionAttributeStorage<?>> expectedClass)
-   {
-      SessionAttributeMarshaller marshaller = EasyMock.createStrictMock(SessionAttributeMarshaller.class);
-      
-      SessionAttributeStorageFactory factory = new SessionAttributeStorageFactoryImpl();
-      
-      EasyMock.replay(marshaller);
-      
-      try
-      {
-         SessionAttributeStorage<?> storage = factory.createStorage(granularity, marshaller);
-         
-         Assert.assertNotNull(expectedClass);
-         Assert.assertTrue(storage.getClass().getName(), expectedClass.isInstance(storage));
-      }
-      catch (IllegalArgumentException e)
-      {
-         Assert.assertNull(expectedClass);
-      }
-      
-      EasyMock.verify(marshaller);
-   }
-}

Deleted: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/SSOClusterManagerTest.java
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/SSOClusterManagerTest.java	2010-08-02 19:38:54 UTC (rev 107321)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/SSOClusterManagerTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -1,72 +0,0 @@
-package org.jboss.ha.web.tomcat.service.session.sso.ispn;
-
-import org.easymock.EasyMock;
-import org.infinispan.AdvancedCache;
-import org.infinispan.Cache;
-import org.infinispan.atomic.AtomicMap;
-import org.jboss.ha.framework.server.ispn.InfinispanHAPartitionCacheHandler;
-import org.jboss.ha.web.tomcat.service.session.sso.ispn.SSOClusterManager;
-import org.jboss.web.tomcat.service.sso.spi.FullyQualifiedSessionId;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.Before;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-public class SSOClusterManagerTest
-{
-
-   SSOClusterManager ssoManager;
-   Cache<Object, Object> cache;
-   String ssoId;
-
-   @Before
-   public void setup() throws Exception
-   {
-      ssoManager = new SSOClusterManager();
-      cache = EasyMock.createMock(Cache.class);
-      InfinispanHAPartitionCacheHandler cacheHandler = EasyMock.createMock(InfinispanHAPartitionCacheHandler.class);
-      EasyMock.expect(cacheHandler.getCache()).andReturn(cache);
-      EasyMock.expectLastCall().anyTimes();
-
-      cache.addListener(ssoManager);
-
-      AdvancedCache advancedCache = EasyMock.createMock(AdvancedCache.class);
-      EasyMock.expect(cache.getAdvancedCache()).andReturn(advancedCache);
-      EasyMock.expectLastCall().anyTimes();
-
-      Transaction transaction = EasyMock.createMock(Transaction.class);
-      TransactionManager tm = EasyMock.createMock(TransactionManager.class);
-      EasyMock.expect(tm.getTransaction()).andReturn(transaction);
-      EasyMock.expectLastCall().anyTimes();
-
-      tm.begin();
-      EasyMock.expectLastCall().anyTimes();
-      tm.rollback();
-      EasyMock.expectLastCall().anyTimes();
-      tm.commit();
-      EasyMock.expectLastCall().anyTimes();
-
-      EasyMock.expect(advancedCache.getTransactionManager()).andReturn(tm);
-      EasyMock.expectLastCall().anyTimes();
-
-      ssoManager.setCacheHandler(cacheHandler);
-      ssoId = "sso session 1";
-      AtomicMap atomicMap = EasyMock.createMock(AtomicMap.class);
-      EasyMock.expect(cache.get(EasyMock.anyObject())).andReturn(atomicMap);
-      EasyMock.expectLastCall().anyTimes();
-      EasyMock.replay(cache, cacheHandler, advancedCache, tm, transaction, atomicMap);
-   }
-
-   @Test
-   public void addSession() throws Exception
-   {
-      ssoManager.start();
-
-      FullyQualifiedSessionId fqs = new FullyQualifiedSessionId(ssoId, "context", "Boston");
-      ssoManager.addSession(ssoId, fqs);
-     
-   }
-
-
-}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntryTest.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntryTest.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntryTest.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/AtomicMapEntryTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,167 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import org.easymock.EasyMock;
+import org.infinispan.atomic.AtomicMap;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.AtomicMapEntry;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public class AtomicMapEntryTest
+{
+   @Test
+   public void test()
+   {
+      for (AtomicMapEntry entry: AtomicMapEntry.values())
+      {
+         switch (entry)
+         {
+            case VERSION:
+            {
+               this.test(entry, new Integer(1), new Object());
+               break;
+            }
+            case TIMESTAMP:
+            {
+               this.test(entry, new Long(1), new Object());
+               break;
+            }
+            case METADATA:
+            {
+               this.test(entry, new DistributableSessionMetadata(), new Object());
+               break;
+            }
+            case ATTRIBUTES:
+            {
+               this.test(entry, new Object(), null);
+               break;
+            }
+         }
+      }
+   }
+   
+   private void test(AtomicMapEntry entry, Object valid, Object invalid)
+   {
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
+      
+      // Test null put
+      EasyMock.replay(map);
+      
+      entry.put(map, null);
+
+      EasyMock.verify(map);
+      EasyMock.reset(map);
+      
+      
+      // Test null get
+      EasyMock.expect(map.get(Byte.valueOf((byte) entry.ordinal()))).andReturn(null);
+      
+      EasyMock.replay(map);
+      
+      Object result = entry.get(map);
+
+      EasyMock.verify(map);
+      
+      Assert.assertNull(result);
+      
+      EasyMock.reset(map);
+      
+      
+      if (invalid != null)
+      {
+         // Test illegal argument put
+         EasyMock.replay(map);
+         
+         IllegalArgumentException iae = null;
+         
+         try
+         {
+            entry.put(map, invalid);
+         }
+         catch (IllegalArgumentException e)
+         {
+            iae = e;
+         }
+         
+         EasyMock.verify(map);
+         
+         Assert.assertNotNull(iae);
+         
+         EasyMock.reset(map);
+
+
+         // Test illegal argument get
+         EasyMock.expect(map.get(Byte.valueOf((byte) entry.ordinal()))).andReturn(invalid);
+
+         EasyMock.replay(map);
+         
+         ClassCastException cce = null;
+         
+         try
+         {
+            entry.get(map);
+         }
+         catch (ClassCastException e)
+         {
+            cce = e;
+         }
+         
+         EasyMock.verify(map);
+         
+         Assert.assertNotNull(cce);
+         
+         EasyMock.reset(map);
+      }
+      
+      // Test legal argument put
+      EasyMock.expect(map.put(EasyMock.eq(Byte.valueOf((byte) entry.ordinal())), EasyMock.same(valid))).andReturn(null);
+      
+      EasyMock.replay(map);
+      
+      entry.put(map, valid);
+      
+      EasyMock.verify(map);
+      
+      EasyMock.reset(map);
+      
+      
+      // Test legal argument get
+      EasyMock.expect(map.get(Byte.valueOf((byte) entry.ordinal()))).andReturn(valid);
+      
+      EasyMock.replay(map);
+      
+      result = entry.get(map);
+      
+      EasyMock.verify(map);
+      
+      Assert.assertSame(valid, result);
+      
+      EasyMock.reset(map);
+   }
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorageTest.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorageTest.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorageTest.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/CoarseSessionAttributeStorageTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,105 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.easymock.EasyMock;
+import org.infinispan.atomic.AtomicMap;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.AtomicMapEntry;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.CoarseSessionAttributeStorage;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingSessionGranularitySessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public class CoarseSessionAttributeStorageTest
+{
+   private SessionAttributeMarshaller marshaller = EasyMock.createStrictMock(SessionAttributeMarshaller.class);
+   private SessionAttributeStorage<OutgoingSessionGranularitySessionData> storage = new CoarseSessionAttributeStorage(this.marshaller);
+   
+   @Test
+   public void store()
+   {
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
+      OutgoingSessionGranularitySessionData data = EasyMock.createStrictMock(OutgoingSessionGranularitySessionData.class);
+      Map<String, Object> attributes = Collections.emptyMap();
+      Object marshalledAttributes = new Object();
+      
+      EasyMock.expect(data.getSessionAttributes()).andReturn(attributes);
+      EasyMock.expect(this.marshaller.marshal(attributes)).andReturn(marshalledAttributes);
+      EasyMock.expect(map.put(EasyMock.eq((byte) AtomicMapEntry.ATTRIBUTES.ordinal()), EasyMock.same(marshalledAttributes))).andReturn(null);
+      
+      EasyMock.replay(this.marshaller, map, data);
+      
+      this.storage.store(map, data);
+      
+      EasyMock.verify(this.marshaller, map, data);
+      EasyMock.reset(this.marshaller, map, data);
+   }
+   
+   @Test
+   public void storeNull()
+   {
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
+      OutgoingSessionGranularitySessionData data = EasyMock.createStrictMock(OutgoingSessionGranularitySessionData.class);
+      
+      EasyMock.expect(data.getSessionAttributes()).andReturn(null);
+      
+      EasyMock.replay(this.marshaller, map, data);
+      
+      this.storage.store(map, data);
+      
+      EasyMock.verify(this.marshaller, map, data);
+      EasyMock.reset(this.marshaller, map, data);
+   }
+   
+   @Test
+   public void load() throws Exception
+   {
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
+      Object marshalledAttributes = new Object();
+      Map<String, Object> attributes = Collections.emptyMap();
+      
+      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.ATTRIBUTES.ordinal()))).andReturn(marshalledAttributes);
+      EasyMock.expect(this.marshaller.unmarshal(EasyMock.same(marshalledAttributes))).andReturn(attributes);
+      
+      EasyMock.replay(this.marshaller, map);
+      
+      Map<String, Object> result = this.storage.load(map);
+      
+      EasyMock.verify(this.marshaller, map);
+      
+      Assert.assertSame(attributes, result);
+      
+      EasyMock.reset(this.marshaller, map);
+   }
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactoryTest.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactoryTest.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactoryTest.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerFactoryTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,94 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import java.util.ServiceLoader;
+
+import org.easymock.EasyMock;
+import org.jboss.ha.ispn.atomic.AtomicMapFactory;
+import org.jboss.ha.ispn.invoker.CacheInvoker;
+import org.jboss.metadata.web.jboss.ReplicationConfig;
+import org.jboss.metadata.web.jboss.ReplicationGranularity;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.DistributedCacheManager;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.DistributedCacheManagerFactory;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorageFactory;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshallerFactory;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public class DistributedCacheManagerFactoryTest
+{
+   private final SessionAttributeStorageFactory storageFactory = EasyMock.createStrictMock(SessionAttributeStorageFactory.class);
+   private final SessionAttributeMarshallerFactory marshallerFactory = EasyMock.createStrictMock(SessionAttributeMarshallerFactory.class);
+   private final CacheInvoker invoker = EasyMock.createStrictMock(CacheInvoker.class);
+   private final LocalDistributableSessionManager manager = EasyMock.createStrictMock(LocalDistributableSessionManager.class);
+   @SuppressWarnings("unchecked")
+   private final SessionAttributeStorage<OutgoingDistributableSessionData> storage = EasyMock.createStrictMock(SessionAttributeStorage.class);
+   private final SessionAttributeMarshaller marshaller = EasyMock.createStrictMock(SessionAttributeMarshaller.class);
+   private final AtomicMapFactory atomicMapFactory = EasyMock.createStrictMock(AtomicMapFactory.class);
+   
+   @Test
+   public void test() throws Exception
+   {
+      DistributedCacheManagerFactory factory = new DistributedCacheManagerFactory();
+      
+      factory.setAtomicMapFactory(atomicMapFactory);
+      factory.setSessionAttributeStorageFactory(this.storageFactory);
+      factory.setSessionAttributeMarshallerFactory(this.marshallerFactory);
+      factory.setCacheInvoker(this.invoker);
+      factory.setAtomicMapFactory(this.atomicMapFactory);
+      
+      ReplicationConfig config = new ReplicationConfig();
+      ReplicationGranularity granularity = ReplicationGranularity.SESSION;
+      config.setReplicationGranularity(granularity);
+      
+      EasyMock.expect(this.marshallerFactory.createMarshaller(this.manager)).andReturn(this.marshaller);
+      EasyMock.expect(this.manager.getReplicationConfig()).andReturn(config);
+      EasyMock.expect(this.storageFactory.createStorage(granularity, this.marshaller)).andReturn(this.storage);
+      
+      EasyMock.replay(this.storageFactory, this.marshallerFactory, this.invoker, this.manager, this.storage, this.marshaller, this.atomicMapFactory);
+      
+      org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager<?> result = factory.getDistributedCacheManager(this.manager);
+      
+      EasyMock.verify(this.storageFactory, this.marshallerFactory, this.invoker, this.manager, this.storage, this.marshaller, this.atomicMapFactory);
+      
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof DistributedCacheManager);
+      
+      EasyMock.reset(this.storageFactory, this.marshallerFactory, this.invoker, this.manager, this.storage, this.marshaller, this.atomicMapFactory);
+   }
+/*   
+   @Test
+   public void load()
+   {
+      ServiceLoader.load(org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManagerFactory.class);
+   }
+*/
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerTest.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerTest.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerTest.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/DistributedCacheManagerTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,834 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.infinispan.AdvancedCache;
+import org.infinispan.Cache;
+import org.infinispan.atomic.AtomicMap;
+import org.infinispan.config.Configuration;
+import org.infinispan.context.Flag;
+import org.infinispan.distribution.DistributionManager;
+import org.infinispan.lifecycle.ComponentStatus;
+import org.infinispan.manager.CacheContainer;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.notifications.cachelistener.event.CacheEntryActivatedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
+import org.infinispan.transaction.tm.BatchModeTransactionManager;
+import org.jboss.ha.ispn.CacheContainerRegistry;
+import org.jboss.ha.ispn.atomic.AtomicMapFactory;
+import org.jboss.ha.ispn.invoker.CacheInvoker;
+import org.jboss.metadata.web.jboss.ReplicationConfig;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.AtomicMapEntry;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.DistributedCacheManager;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.IncomingDistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionOwnershipSupport;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public class DistributedCacheManagerTest
+{
+   private final CacheContainer container = EasyMock.createStrictMock(CacheContainer.class);
+   private final CacheContainerRegistry registry = EasyMock.createStrictMock(CacheContainerRegistry.class);
+   private final LocalDistributableSessionManager manager = EasyMock.createStrictMock(LocalDistributableSessionManager.class);
+   @SuppressWarnings("unchecked")
+   private final SessionAttributeStorage<OutgoingDistributableSessionData> storage = EasyMock.createStrictMock(SessionAttributeStorage.class);
+   @SuppressWarnings("unchecked")
+   private final AdvancedCache<String, AtomicMap<Object, Object>> cache = EasyMock.createStrictMock(AdvancedCache.class);
+   private final CacheInvoker invoker = EasyMock.createStrictMock(CacheInvoker.class);
+   private final AtomicMapFactory atomicMapFactory = EasyMock.createStrictMock(AtomicMapFactory.class);
+   
+   @Test
+   public void start()
+   {
+      ReplicationConfig config = new ReplicationConfig();
+      config.setCacheName("session-cache");
+      
+      // Validate host contribution to cache name
+      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
+      this.start(null, "session-cache", "", "", "localhost/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
+      this.start(null, "session-cache", "host1", "", "host1/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
+
+      // Validate context path contribution to cache name
+      this.start(null, "session-cache", null, "/", "localhost/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
+      this.start(null, "session-cache", null, "/context1", "localhost/context1", config, ComponentStatus.INSTANTIATED, true, new Configuration());
+      this.start(null, "session-cache", null, "/path/context1", "localhost/path/context1", config, ComponentStatus.INSTANTIATED, true, new Configuration());
+      
+      // Validate starting of cache per cache status
+      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.FAILED, true, new Configuration());
+      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.INITIALIZING, true, new Configuration());
+      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.RUNNING, false, new Configuration());
+      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.STOPPING, true, new Configuration());
+      this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.TERMINATED, true, new Configuration());
+      
+      // Validate cache container qualified cache name
+      config.setCacheName("default:session-cache");
+      this.start("default", "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
+   }
+   
+   private DistributedCacheManager<OutgoingDistributableSessionData> start(String containerName, String templateCacheName, String hostName, String contextName, String cacheName, ReplicationConfig config, ComponentStatus cacheStatus, boolean startCache, Configuration configuration)
+   {
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = new DistributedCacheManager<OutgoingDistributableSessionData>(this.manager, this.registry, this.storage, this.invoker, this.atomicMapFactory);
+      
+      @SuppressWarnings("unchecked")
+      Cache<Object, Object> cache = EasyMock.createStrictMock(Cache.class);
+      EmbeddedCacheManager cacheManager = EasyMock.createStrictMock(EmbeddedCacheManager.class);
+      
+      EasyMock.expect(this.manager.getReplicationConfig()).andReturn(config);
+      
+      EasyMock.expect(this.registry.getCacheContainer(containerName)).andReturn(this.container);
+      EasyMock.expect(this.manager.getHostName()).andReturn(hostName);
+      EasyMock.expect(this.manager.getContextName()).andReturn(contextName);
+      EasyMock.expect(this.container.getCache()).andReturn(cache);
+      EasyMock.expect(cache.getCacheManager()).andReturn(cacheManager);
+      EasyMock.expect(cacheManager.defineConfiguration(cacheName, templateCacheName, new Configuration())).andReturn(configuration);
+      EasyMock.expect(cacheManager.<String, AtomicMap<Object, Object>>getCache(cacheName)).andReturn(this.cache);
+      
+      EasyMock.expect(this.cache.getStatus()).andReturn(cacheStatus);
+      if (startCache)
+      {
+         this.cache.start();
+      }
+      EasyMock.expect(this.cache.getAdvancedCache()).andReturn(this.cache);
+      EasyMock.expect(this.cache.getTransactionManager()).andReturn(new BatchModeTransactionManager());
+      this.cache.addListener(manager);
+      
+      EasyMock.expect(this.cache.getConfiguration()).andReturn(configuration);
+      
+      EasyMock.replay(this.registry, this.manager, this.container, this.storage, this.cache, this.invoker, cache, cacheManager);
+      
+      manager.start();
+      
+      EasyMock.verify(this.registry, this.manager, this.container, this.storage, this.cache, this.invoker, cache, cacheManager);
+      
+      Assert.assertNotNull(manager.getBatchingManager());
+      
+      EasyMock.reset(this.registry, this.manager, this.container, this.storage, this.cache, this.invoker, cache, cacheManager);
+      
+      return manager;
+   }
+   
+   private DistributedCacheManager<OutgoingDistributableSessionData> startDistributedCacheManager()
+   {
+      ReplicationConfig config = new ReplicationConfig();
+      config.setCacheName("session-cache");
+      
+      return this.start(null, "session-cache", null, "", "localhost/ROOT", config, ComponentStatus.INSTANTIATED, true, new Configuration());
+   }
+   
+   @Test
+   public void stop()
+   {
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      this.cache.removeListener(manager);
+      this.cache.stop();
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      manager.stop();
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void sessionCreated()
+   {
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      manager.sessionCreated("abc");
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void storeSessionData()
+   {
+      OutgoingDistributableSessionData data = EasyMock.createNiceMock(OutgoingDistributableSessionData.class);
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> map = EasyMock.createNiceMock(AtomicMap.class);
+      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
+      
+      String sessionId = "abc";
+      int version = 10;
+      long timestamp = System.currentTimeMillis();
+      DistributableSessionMetadata metadata = new DistributableSessionMetadata();
+      
+      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(map);
+
+      EasyMock.expect(data.getRealId()).andReturn(sessionId);
+      EasyMock.expect(data.getVersion()).andReturn(version);
+      EasyMock.expect(map.put(Byte.valueOf((byte) AtomicMapEntry.VERSION.ordinal()), version)).andReturn(null);
+      EasyMock.expect(data.getTimestamp()).andReturn(timestamp);
+      EasyMock.expect(map.put(Byte.valueOf((byte) AtomicMapEntry.TIMESTAMP.ordinal()), timestamp)).andReturn(null);
+      EasyMock.expect(data.getMetadata()).andReturn(metadata);
+      EasyMock.expect(map.put(Byte.valueOf((byte) AtomicMapEntry.METADATA.ordinal()), metadata)).andReturn(null);
+      
+      this.storage.store(EasyMock.same(map), EasyMock.same(data));
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data, map);
+      
+      manager.storeSessionData(data);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data, map);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data, map);
+      
+      
+      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
+      
+      EasyMock.expect(this.atomicMapFactory.getAtomicMap(EasyMock.same(cache), EasyMock.same(sessionId), EasyMock.eq(true))).andReturn(map);
+            
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data);
+      
+      AtomicMap<Object, Object> result = operation.invoke(this.cache);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data);
+      
+      Assert.assertSame(map, result);
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, data);
+   }
+   
+   @Test
+   public void getSessionDataNoOwner() throws Exception
+   {
+      this.getSessionDataNoOwner(true);
+      
+      this.getSessionDataNoOwner(false);
+   }
+   
+   private void getSessionDataNoOwner(boolean includeAttributes) throws Exception
+   {
+      String sessionId = "abc";
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> map = EasyMock.createNiceMock(AtomicMap.class);
+      Map<String, Object> attributes = Collections.emptyMap();
+      
+      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
+
+      Integer version = Integer.valueOf(10);
+      Long timestamp = Long.valueOf(System.currentTimeMillis());
+      DistributableSessionMetadata metadata = new DistributableSessionMetadata();
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(map);
+      
+      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.VERSION.ordinal()))).andReturn(version);
+      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.TIMESTAMP.ordinal()))).andReturn(timestamp);
+      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.METADATA.ordinal()))).andReturn(metadata);
+      
+      if (includeAttributes)
+      {
+         EasyMock.expect(this.storage.load(map)).andReturn(attributes);
+      }
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, map);
+      
+      IncomingDistributableSessionData result = manager.getSessionData(sessionId, null, includeAttributes);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, map);
+      
+      Assert.assertNotNull(result);
+      Assert.assertEquals(version.intValue(), result.getVersion());
+      Assert.assertEquals(timestamp.longValue(), result.getTimestamp());
+      Assert.assertSame(metadata, result.getMetadata());
+      
+      if (includeAttributes)
+      {
+         Assert.assertSame(attributes, result.getSessionAttributes());
+      }
+      else
+      {
+         IllegalStateException exception = null;
+         Map<String, Object> sessionAttributes = null;
+         
+         try
+         {
+            sessionAttributes = result.getSessionAttributes();
+         }
+         catch (IllegalStateException e)
+         {
+            exception = e;
+         }
+         
+         Assert.assertNull(sessionAttributes);
+         Assert.assertNotNull(exception);
+      }
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, map);
+      
+      
+      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> expectedMap = EasyMock.createMock(AtomicMap.class);
+      
+      EasyMock.expect(this.atomicMapFactory.getAtomicMap(EasyMock.same(cache), EasyMock.same(sessionId), EasyMock.eq(false))).andReturn(expectedMap);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, expectedMap);
+      
+      AtomicMap<Object, Object> resultMap = operation.invoke(this.cache);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, expectedMap);
+      
+      Assert.assertSame(expectedMap, resultMap);
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory, expectedMap);
+   }
+   
+   @Test
+   public void getMissingSessionDataNoOwner()
+   {
+      this.getMissingSessionDataNoOwner(true);
+      
+      this.getMissingSessionDataNoOwner(false);
+   }
+   
+   private void getMissingSessionDataNoOwner(boolean includeAttributes)
+   {
+      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
+      
+      IncomingDistributableSessionData result = manager.getSessionData("abc", null, includeAttributes);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
+      
+      Assert.assertNull(result);
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
+      
+      
+      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> expectedMap = EasyMock.createMock(AtomicMap.class);
+      
+      EasyMock.expect(this.atomicMapFactory.getAtomicMap(this.cache, "abc", false)).andReturn(expectedMap);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
+      
+      AtomicMap<Object, Object> resultMap = operation.invoke(this.cache);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
+      
+      Assert.assertSame(expectedMap, resultMap);
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, this.atomicMapFactory);
+   }
+   
+   @Test
+   public void getSessionDataWithOwner()
+   {
+      this.getSessionDataWithOwner(true);
+      
+      this.getSessionDataWithOwner(false);
+   }
+   
+   private void getSessionDataWithOwner(boolean includeAttributes)
+   {
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      IncomingDistributableSessionData result = manager.getSessionData("abc", "owner1", includeAttributes);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      Assert.assertNull(result);
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void removeSession()
+   {
+      String sessionId = "abc";
+      
+      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      manager.removeSession(sessionId);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      
+      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> expectedMap = EasyMock.createMock(AtomicMap.class);
+      
+      EasyMock.expect(this.cache.remove(sessionId)).andReturn(expectedMap);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      AtomicMap<Object, Object> resultMap = operation.invoke(this.cache);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      Assert.assertSame(expectedMap, resultMap);
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void removeSessionLocal()
+   {
+      String sessionId = "abc";
+      
+      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      manager.removeSessionLocal(sessionId);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      
+      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> expectedMap = EasyMock.createMock(AtomicMap.class);
+      
+      EasyMock.expect(this.cache.getAdvancedCache()).andReturn(this.cache);
+      EasyMock.expect(this.cache.withFlags(Flag.CACHE_MODE_LOCAL)).andReturn(this.cache);
+      EasyMock.expect(this.cache.remove(sessionId)).andReturn(expectedMap);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      AtomicMap<Object, Object> resultMap = operation.invoke(this.cache);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      Assert.assertSame(expectedMap, resultMap);
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void removeSessionLocalNoOwner()
+   {
+      String sessionId = "abc";
+      
+      Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>> capturedOperation = new Capture<DistributedCacheManager.Operation<AtomicMap<Object, Object>>>();
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      manager.removeSessionLocal(sessionId, null);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      
+      DistributedCacheManager.Operation<AtomicMap<Object, Object>> operation = capturedOperation.getValue();
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> expectedMap = EasyMock.createMock(AtomicMap.class);
+      
+      EasyMock.expect(this.cache.getAdvancedCache()).andReturn(this.cache);
+      EasyMock.expect(this.cache.withFlags(Flag.CACHE_MODE_LOCAL)).andReturn(this.cache);
+      EasyMock.expect(this.cache.remove(sessionId)).andReturn(expectedMap);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      AtomicMap<Object, Object> resultMap = operation.invoke(this.cache);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      Assert.assertSame(expectedMap, resultMap);
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void removeSessionLocalWithOwner()
+   {
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      manager.removeSessionLocal("abc", "owner1");
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void evictSession()
+   {
+      String sessionId = "abc";
+      
+      Capture<DistributedCacheManager.Operation<Void>> capturedOperation = new Capture<DistributedCacheManager.Operation<Void>>();
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      manager.evictSession(sessionId);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      
+      DistributedCacheManager.Operation<Void> operation = capturedOperation.getValue();
+      
+      this.cache.evict(sessionId);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      Void result = operation.invoke(this.cache);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      Assert.assertNull(result);
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void evictSessionNoOwner()
+   {
+      String sessionId = "abc";
+      
+      Capture<DistributedCacheManager.Operation<Void>> capturedOperation = new Capture<DistributedCacheManager.Operation<Void>>();
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.expect(this.invoker.invoke(EasyMock.same(this.cache), EasyMock.capture(capturedOperation))).andReturn(null);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      manager.evictSession(sessionId, null);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      
+      DistributedCacheManager.Operation<Void> operation = capturedOperation.getValue();
+      
+      this.cache.evict(sessionId);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      Void result = operation.invoke(this.cache);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      Assert.assertNull(result);
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void evictSessionLocalWithOwner()
+   {
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      manager.evictSession("abc", "owner1");
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void getSessionIds()
+   {
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.expect(this.cache.keySet()).andReturn(Collections.singleton("abc"));
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      Map<String, String> result = manager.getSessionIds();
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      Assert.assertNotNull(result);
+      Assert.assertEquals(1, result.size());
+      Assert.assertTrue(result.containsKey("abc"));
+      Assert.assertNull(result.get("abc"));
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void setForceSynchronous()
+   {
+      this.setForceSynchronous(true);
+      this.setForceSynchronous(false);
+   }
+   
+   private void setForceSynchronous(boolean forceSynchronous)
+   {
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      this.invoker.setForceSynchronous(forceSynchronous);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      manager.setForceSynchronous(forceSynchronous);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void getSessionOwnershipSupport()
+   {
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+      SessionOwnershipSupport support = manager.getSessionOwnershipSupport();
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker);
+      
+// TODO when session ownership support is added, replace these assertions
+      Assert.assertNull(support);
+//      Assert.assertSame(manager, support);
+      
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker);
+   }
+   
+   @Test
+   public void removed()
+   {
+      CacheEntryRemovedEvent event = EasyMock.createNiceMock(CacheEntryRemovedEvent.class);
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      
+      EasyMock.expect(event.isPre()).andReturn(true);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      manager.removed(event);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      
+      EasyMock.expect(event.isPre()).andReturn(false);
+      EasyMock.expect(event.isOriginLocal()).andReturn(true);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      manager.removed(event);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      
+      EasyMock.expect(event.isPre()).andReturn(false);
+      EasyMock.expect(event.isOriginLocal()).andReturn(false);
+      EasyMock.expect(event.getKey()).andReturn("abc");
+      
+      this.manager.notifyRemoteInvalidation("abc");
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      manager.removed(event);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+   }
+   
+   @Test
+   public void modified()
+   {
+      CacheEntryModifiedEvent event = EasyMock.createNiceMock(CacheEntryModifiedEvent.class);
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      
+      EasyMock.expect(event.isPre()).andReturn(true);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      manager.modified(event);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      
+      EasyMock.expect(event.isPre()).andReturn(false);
+      EasyMock.expect(event.isOriginLocal()).andReturn(true);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      manager.modified(event);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> map = EasyMock.createNiceMock(AtomicMap.class);
+      
+      Integer version = Integer.valueOf(10);
+      Long timestamp = Long.valueOf(System.currentTimeMillis());
+      DistributableSessionMetadata metadata = new DistributableSessionMetadata();
+      
+      EasyMock.expect(event.isPre()).andReturn(false);
+      EasyMock.expect(event.isOriginLocal()).andReturn(false);
+      EasyMock.expect(event.getKey()).andReturn("abc");
+      EasyMock.expect(event.getValue()).andReturn(map);
+      
+      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.VERSION.ordinal()))).andReturn(version);
+      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.TIMESTAMP.ordinal()))).andReturn(timestamp);
+      EasyMock.expect(map.get(Byte.valueOf((byte) AtomicMapEntry.METADATA.ordinal()))).andReturn(metadata);
+      
+      EasyMock.expect(this.manager.sessionChangedInDistributedCache("abc", null, version.intValue(), timestamp.longValue(), metadata)).andReturn(false);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event, map);
+      
+      manager.modified(event);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event, map);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event, map);
+   }
+   
+   @Test
+   public void activated()
+   {
+      CacheEntryActivatedEvent event = EasyMock.createNiceMock(CacheEntryActivatedEvent.class);
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      
+      EasyMock.expect(event.isPre()).andReturn(true);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      manager.activated(event);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      
+      EasyMock.expect(this.manager.isPassivationEnabled()).andReturn(false);
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      manager.activated(event);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      
+      EasyMock.expect(this.manager.isPassivationEnabled()).andReturn(true);
+      this.manager.sessionActivated();
+      
+      EasyMock.replay(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      
+      manager.activated(event);
+      
+      EasyMock.verify(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+      EasyMock.reset(this.manager, this.container, this.storage, this.cache, this.invoker, event);
+   }
+   
+   @Test
+   public void isLocalReplicationMode()
+   {
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      String sessionId = "ABC123";
+      
+      EasyMock.expect(this.cache.getAdvancedCache()).andReturn(this.cache);
+      EasyMock.expect(this.cache.getDistributionManager()).andReturn(null);
+      
+      EasyMock.replay(this.cache);
+      
+      boolean result = manager.isLocal(sessionId);
+      
+      EasyMock.verify(this.cache);
+      
+      Assert.assertTrue(result);
+      
+      EasyMock.reset(this.cache);
+   }
+   
+   @Test
+   public void isLocalDistributionMode()
+   {
+      this.isLocalDistributionMode(true);
+      this.isLocalDistributionMode(false);
+   }
+   
+   private void isLocalDistributionMode(boolean local)
+   {
+      DistributionManager distManager = EasyMock.createStrictMock(DistributionManager.class);
+      
+      DistributedCacheManager<OutgoingDistributableSessionData> manager = this.startDistributedCacheManager();
+      String sessionId = "ABC123";
+      
+      EasyMock.expect(this.cache.getAdvancedCache()).andReturn(this.cache);
+      EasyMock.expect(this.cache.getDistributionManager()).andReturn(distManager);
+      EasyMock.expect(distManager.isLocal(sessionId)).andReturn(local);
+      
+      EasyMock.replay(this.cache, distManager);
+      
+      boolean result = manager.isLocal(sessionId);
+      
+      EasyMock.verify(this.cache, distManager);
+      
+      Assert.assertEquals(local, result);
+      
+      EasyMock.reset(this.cache, distManager);
+   }
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorageTest.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorageTest.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorageTest.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/FineSessionAttributeStorageTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,121 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.easymock.EasyMock;
+import org.infinispan.atomic.AtomicMap;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.FineSessionAttributeStorage;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingAttributeGranularitySessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public class FineSessionAttributeStorageTest
+{
+   private SessionAttributeMarshaller marshaller = EasyMock.createStrictMock(SessionAttributeMarshaller.class);
+   private SessionAttributeStorage<OutgoingAttributeGranularitySessionData> storage = new FineSessionAttributeStorage(this.marshaller);
+   
+   @Test
+   public void store()
+   {
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
+      OutgoingAttributeGranularitySessionData data = EasyMock.createStrictMock(OutgoingAttributeGranularitySessionData.class);
+      Map<String, Object> modifiedAttributes = Collections.singletonMap("key", (Object) "value");
+      Set<String> removedAttributes = Collections.singleton("removed");
+      Object marshalledAttribute = new Object();
+      
+      EasyMock.expect(data.getModifiedSessionAttributes()).andReturn(modifiedAttributes);
+      EasyMock.expect(this.marshaller.marshal("value")).andReturn(marshalledAttribute);
+      EasyMock.expect(map.put(EasyMock.eq("key"), EasyMock.same(marshalledAttribute))).andReturn(null);
+      EasyMock.expect(data.getRemovedSessionAttributes()).andReturn(removedAttributes);
+      EasyMock.expect(map.remove("removed")).andReturn(null);
+      
+      EasyMock.replay(this.marshaller, map, data);
+      
+      this.storage.store(map, data);
+      
+      EasyMock.verify(this.marshaller, map, data);
+      EasyMock.reset(this.marshaller, map, data);
+   }
+   
+   @Test
+   public void storeNull()
+   {
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
+      OutgoingAttributeGranularitySessionData data = EasyMock.createStrictMock(OutgoingAttributeGranularitySessionData.class);
+      
+      EasyMock.expect(data.getModifiedSessionAttributes()).andReturn(null);
+      EasyMock.expect(data.getRemovedSessionAttributes()).andReturn(null);
+      
+      EasyMock.replay(this.marshaller, map, data);
+      
+      this.storage.store(map, data);
+      
+      EasyMock.verify(this.marshaller, map, data);
+      EasyMock.reset(this.marshaller, map, data);
+   }
+   
+   @Test
+   public void load() throws Exception
+   {
+      @SuppressWarnings("unchecked")
+      AtomicMap<Object, Object> map = EasyMock.createStrictMock(AtomicMap.class);
+      Object marshalledAttribute = new Object();
+
+      Map.Entry<Object, Object> nonAttributeEntry = new AbstractMap.SimpleImmutableEntry<Object, Object>(new Object(), new Object());
+      Map.Entry<Object, Object> attributeEntry = new AbstractMap.SimpleImmutableEntry<Object, Object>((Object) "key", marshalledAttribute);
+      @SuppressWarnings("unchecked")
+      List<Map.Entry<Object, Object>> entries = Arrays.asList(nonAttributeEntry, attributeEntry);
+      
+      EasyMock.expect(map.entrySet()).andReturn(new HashSet<Map.Entry<Object, Object>>(entries));
+      EasyMock.expect(this.marshaller.unmarshal(EasyMock.same(marshalledAttribute))).andReturn("value");
+      
+      EasyMock.replay(this.marshaller, map);
+      
+      Map<String, Object> result = this.storage.load(map);
+      
+      EasyMock.verify(this.marshaller, map);
+      
+      Assert.assertNotNull(result);
+      Assert.assertEquals(1, result.size());
+      Assert.assertTrue(result.toString(), result.containsKey("key"));
+      Assert.assertEquals("value", result.get("key"));
+      
+      EasyMock.reset(this.marshaller, map);
+   }
+
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryTest.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryTest.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryTest.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/distributedcache/ispn/SessionAttributeStorageFactoryTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.service.session.distributedcache.ispn;
+
+import org.easymock.EasyMock;
+import org.jboss.metadata.web.jboss.ReplicationGranularity;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.CoarseSessionAttributeStorage;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.FineSessionAttributeStorage;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorage;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorageFactory;
+import org.jboss.web.tomcat.service.session.distributedcache.ispn.SessionAttributeStorageFactoryImpl;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.SessionAttributeMarshaller;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public class SessionAttributeStorageFactoryTest
+{
+   @Test
+   public void testSession()
+   {
+      this.test(ReplicationGranularity.SESSION, CoarseSessionAttributeStorage.class);
+   }
+   
+   @Test
+   public void testAttribute()
+   {
+      this.test(ReplicationGranularity.ATTRIBUTE, FineSessionAttributeStorage.class);
+   }
+   
+   @Test
+   public void testField()
+   {
+      this.test(ReplicationGranularity.FIELD, null);
+   }
+   
+   private void test(ReplicationGranularity granularity, Class<? extends SessionAttributeStorage<?>> expectedClass)
+   {
+      SessionAttributeMarshaller marshaller = EasyMock.createStrictMock(SessionAttributeMarshaller.class);
+      
+      SessionAttributeStorageFactory factory = new SessionAttributeStorageFactoryImpl();
+      
+      EasyMock.replay(marshaller);
+      
+      try
+      {
+         SessionAttributeStorage<?> storage = factory.createStorage(granularity, marshaller);
+         
+         Assert.assertNotNull(expectedClass);
+         Assert.assertTrue(storage.getClass().getName(), expectedClass.isInstance(storage));
+      }
+      catch (IllegalArgumentException e)
+      {
+         Assert.assertNull(expectedClass);
+      }
+      
+      EasyMock.verify(marshaller);
+   }
+}

Copied: projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/sso/ispn/SSOClusterManagerTest.java (from rev 107280, projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/ha/web/tomcat/service/session/sso/ispn/SSOClusterManagerTest.java)
===================================================================
--- projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/sso/ispn/SSOClusterManagerTest.java	                        (rev 0)
+++ projects/cluster/ha-server-cache-ispn/trunk/src/test/java/org/jboss/web/tomcat/service/session/sso/ispn/SSOClusterManagerTest.java	2010-08-02 19:56:09 UTC (rev 107322)
@@ -0,0 +1,72 @@
+package org.jboss.web.tomcat.service.session.sso.ispn;
+
+import org.easymock.EasyMock;
+import org.infinispan.AdvancedCache;
+import org.infinispan.Cache;
+import org.infinispan.atomic.AtomicMap;
+import org.jboss.ha.framework.server.ispn.InfinispanHAPartitionCacheHandler;
+import org.jboss.web.tomcat.service.session.sso.ispn.SSOClusterManager;
+import org.jboss.web.tomcat.service.sso.spi.FullyQualifiedSessionId;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.Before;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+public class SSOClusterManagerTest
+{
+
+   SSOClusterManager ssoManager;
+   Cache<Object, Object> cache;
+   String ssoId;
+
+   @Before
+   public void setup() throws Exception
+   {
+      ssoManager = new SSOClusterManager();
+      cache = EasyMock.createMock(Cache.class);
+      InfinispanHAPartitionCacheHandler cacheHandler = EasyMock.createMock(InfinispanHAPartitionCacheHandler.class);
+      EasyMock.expect(cacheHandler.getCache()).andReturn(cache);
+      EasyMock.expectLastCall().anyTimes();
+
+      cache.addListener(ssoManager);
+
+      AdvancedCache advancedCache = EasyMock.createMock(AdvancedCache.class);
+      EasyMock.expect(cache.getAdvancedCache()).andReturn(advancedCache);
+      EasyMock.expectLastCall().anyTimes();
+
+      Transaction transaction = EasyMock.createMock(Transaction.class);
+      TransactionManager tm = EasyMock.createMock(TransactionManager.class);
+      EasyMock.expect(tm.getTransaction()).andReturn(transaction);
+      EasyMock.expectLastCall().anyTimes();
+
+      tm.begin();
+      EasyMock.expectLastCall().anyTimes();
+      tm.rollback();
+      EasyMock.expectLastCall().anyTimes();
+      tm.commit();
+      EasyMock.expectLastCall().anyTimes();
+
+      EasyMock.expect(advancedCache.getTransactionManager()).andReturn(tm);
+      EasyMock.expectLastCall().anyTimes();
+
+      ssoManager.setCacheHandler(cacheHandler);
+      ssoId = "sso session 1";
+      AtomicMap atomicMap = EasyMock.createMock(AtomicMap.class);
+      EasyMock.expect(cache.get(EasyMock.anyObject())).andReturn(atomicMap);
+      EasyMock.expectLastCall().anyTimes();
+      EasyMock.replay(cache, cacheHandler, advancedCache, tm, transaction, atomicMap);
+   }
+
+   @Test
+   public void addSession() throws Exception
+   {
+      ssoManager.start();
+
+      FullyQualifiedSessionId fqs = new FullyQualifiedSessionId(ssoId, "context", "Boston");
+      ssoManager.addSession(ssoId, fqs);
+     
+   }
+
+
+}



More information about the jboss-cvs-commits mailing list