[jboss-cvs] JBossAS SVN: r87314 - in trunk: testsuite/src/main/org/jboss/test/cluster/web and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Apr 14 20:30:23 EDT 2009


Author: bstansberry at jboss.com
Date: 2009-04-14 20:30:22 -0400 (Tue, 14 Apr 2009)
New Revision: 87314

Added:
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/OutgoingDistributableSessionDataImpl.java
Modified:
   trunk/component-matrix/pom.xml
   trunk/testsuite/src/main/org/jboss/test/cluster/web/CacheHelper.java
   trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockDistributedCacheManager.java
   trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockJBossManager.java
   trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockSession.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/AttributeBasedClusteredSession.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredManager.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSession.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSessionValve.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/FieldBasedClusteredSession.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/InstantSnapshotManager.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/IntervalSnapshotManager.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheCluster.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManager.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JvmRouteValve.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SessionBasedClusteredSession.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SessionReplicationContext.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SnapshotManager.java
Log:
[JBAS-6780] Get rid of DistributableSession interface
[JBAS-6779] Use ha-server-cache-jbc 2.0.0.CR1
[JBAS-6778] Use ha-server-cache-spi 2.0.0.GA 

Modified: trunk/component-matrix/pom.xml
===================================================================
--- trunk/component-matrix/pom.xml	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/component-matrix/pom.xml	2009-04-15 00:30:22 UTC (rev 87314)
@@ -57,8 +57,8 @@
     <version.org.jboss.cache.core>3.1.0.CR1</version.org.jboss.cache.core>
     <version.org.jboss.cache.pojo>3.0.0.GA</version.org.jboss.cache.pojo>
     <version.org.jboss.cl>2.0.3.GA</version.org.jboss.cl>
-    <version.org.jboss.cluster.cache.jbc>1.1.0.GA</version.org.jboss.cluster.cache.jbc>
-    <version.org.jboss.cluster.cache.spi>1.1.0.GA</version.org.jboss.cluster.cache.spi>
+    <version.org.jboss.cluster.cache.jbc>2.0.0.CR1</version.org.jboss.cluster.cache.jbc>
+    <version.org.jboss.cluster.cache.spi>2.0.0.GA</version.org.jboss.cluster.cache.spi>
     <version.org.jboss.cluster.client>1.1.1.GA</version.org.jboss.cluster.client>
     <version.org.jboss.cluster.server.api>1.1.0.GA</version.org.jboss.cluster.server.api>
     <version.org.jboss.common.core>2.2.12.GA</version.org.jboss.common.core>

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/web/CacheHelper.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/web/CacheHelper.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/web/CacheHelper.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -109,8 +109,7 @@
    
    public Object getSessionVersion(String sessionFqn)
    {
-      AtomicInteger version = (AtomicInteger) getCache().get(Fqn.fromString(sessionFqn), VERSION_KEY);
-      return version == null ? null : new Integer(version.get());
+      return getCache().get(Fqn.fromString(sessionFqn), VERSION_KEY);
    }
    
    public Object getBuddySessionVersion(String sessionFqn) throws Exception
@@ -126,8 +125,7 @@
          Node session = buddy.getChild(fqn);
          if (session != null)
          {
-            AtomicInteger version = (AtomicInteger) session.get(VERSION_KEY);
-            result = version == null ? null : new Integer(version.get());
+            result = (Integer) session.get(VERSION_KEY);
             break;
          }
       }

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockDistributedCacheManager.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockDistributedCacheManager.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockDistributedCacheManager.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -27,15 +27,15 @@
 import java.util.Set;
 
 import org.jboss.web.tomcat.service.session.distributedcache.spi.BatchingManager;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSession;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionData;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.IncomingDistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 
 /**
  * @author Brian Stansberry
  *
  */
-public class MockDistributedCacheManager implements DistributedCacheManager
+public class MockDistributedCacheManager implements DistributedCacheManager<OutgoingDistributableSessionData>
 {
    public static final MockDistributedCacheManager INSTANCE = new MockDistributedCacheManager();
    
@@ -55,14 +55,14 @@
       return null;
    }
 
-   public Set getAttributeKeys(String realId)
+   public Set<String> getAttributeKeys(String realId)
    {
-      return Collections.EMPTY_SET;
+      return Collections.emptySet();
    }
 
-   public Map getAttributes(String realId)
+   public Map<String, Object> getAttributes(String realId)
    {
-      return Collections.EMPTY_MAP;
+      return Collections.emptyMap();
    }
 
    public BatchingManager getBatchingManager()
@@ -70,14 +70,19 @@
       return null;
    }
 
-   public DistributableSessionData getSessionData(String realId, String dataOwner, boolean includeAttributes)
+   public IncomingDistributableSessionData getSessionData(String realId, boolean initialLoad)
    {
       return null;
    }
 
+   public IncomingDistributableSessionData getSessionData(String realId, String dataOwner, boolean includeAttributes)
+   {
+      return null;
+   }
+
    public Map<String, String> getSessionIds()
    {
-      return Collections.EMPTY_MAP;
+      return Collections.emptyMap();
    }
 
    public boolean isPassivationEnabled()
@@ -85,11 +90,6 @@
       return false;
    }
 
-   public <T extends DistributableSession> T loadSession(String realId, T toLoad)
-   {
-      return null;
-   }
-
    public void putAttribute(String realId, Map<String, Object> map)
    {
       // no-op
@@ -99,12 +99,9 @@
    {
       // no-op
    }
+   
+   
 
-   public void putSession(DistributableSession session)
-   {
-      // no-op
-   }
-
    public Object removeAttribute(String realId, String key)
    {
       return null;
@@ -155,9 +152,14 @@
       return true;
    }
 
-   public void sessionCreated(DistributableSession session)
+   public void sessionCreated(String realId)
    {
       // no-op
    }
 
+   public void storeSessionData(OutgoingDistributableSessionData sessionData)
+   {
+      // no-op      
+   }
+
 }

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockJBossManager.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockJBossManager.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockJBossManager.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -34,6 +34,7 @@
 import org.jboss.web.tomcat.service.session.ClusteredManager;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.ClusteringNotSupportedException;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 import org.jboss.web.tomcat.service.session.notification.ClusteredSessionNotificationPolicy;
 import org.jboss.web.tomcat.service.session.notification.LegacyClusteredSessionNotificationPolicy;
 
@@ -41,7 +42,7 @@
  * @author Brian Stansberry
  *
  */
-public class MockJBossManager implements ClusteredManager
+public class MockJBossManager implements ClusteredManager<OutgoingDistributableSessionData>
 {
    private String jvmRoute = null;
    private String newCookieIdSession = null;
@@ -250,7 +251,7 @@
    {
    }
 
-   public DistributedCacheManager getDistributedCacheManager()
+   public DistributedCacheManager<OutgoingDistributableSessionData> getDistributedCacheManager()
    {
       return MockDistributedCacheManager.INSTANCE;
    }

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockSession.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockSession.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockSession.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -26,13 +26,14 @@
 
 import org.apache.catalina.session.StandardSessionFacade;
 import org.jboss.web.tomcat.service.session.ClusteredSession;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 import org.jboss.web.tomcat.service.session.notification.ClusteredSessionNotificationCause;
 
 /**
  * @author Brian Stansberry
  *
  */
-public class MockSession extends ClusteredSession
+public class MockSession extends ClusteredSession<OutgoingDistributableSessionData>
 {
    /** The serialVersionUID */
    private static final long serialVersionUID = 1L;
@@ -105,6 +106,12 @@
    protected Object removeAttributeInternal(String name, boolean localCall, boolean localOnly)
    {
       return null;
+   }
+
+   @Override
+   protected OutgoingDistributableSessionData getOutgoingSessionData()
+   {
+      return null;
    }   
    
    

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/AttributeBasedClusteredSession.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/AttributeBasedClusteredSession.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/AttributeBasedClusteredSession.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -22,9 +22,12 @@
 package org.jboss.web.tomcat.service.session;
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingAttributeGranularitySessionData;
 
 /**
  * Implementation of a clustered session where the replication granularity
@@ -41,7 +44,7 @@
  * @version $Revision$
  */
 class AttributeBasedClusteredSession
-   extends ClusteredSession
+   extends ClusteredSession<OutgoingAttributeGranularitySessionData>
 {
    static final long serialVersionUID = -5625209785550936713L;
    /**
@@ -51,14 +54,13 @@
 
    // Transient map to store attr changes for replication.
    private transient Map<String, Object> attrModifiedMap_ = new HashMap<String, Object>();
-   // Note that the removed attr is intentionally stored in a map 
-   // instead of a Set so it is faster to lookup and remove.
-   private transient Map<String, Object> attrRemovedMap_ = new HashMap<String, Object>();
+   // Transient set to store attr removals for replication
+   private transient Set<String> attrRemovedSet_ = new HashSet<String>();
 
    // ------------------------------------------------------------ Constructors
    
 
-   public AttributeBasedClusteredSession(ClusteredManager manager)
+   public AttributeBasedClusteredSession(ClusteredManager<OutgoingAttributeGranularitySessionData> manager)
    {
       super(manager);
    }
@@ -90,23 +92,29 @@
 
    // -------------------------------------------- Overridden Protected Methods
 
-//   /**
-//    * Populate the attributes stored in the distributed store to local transient ones.
-//    */
-//   @Override
-//   protected void populateAttributes(Map<String, Object> distributedCacheAttributes)
-//   {
-//      Map<String, Object> existing = getAttributesInternal();
-//      Map<String, Object> excluded = removeExcludedAttributes(existing);
-//      existing.clear();
-//      
-//      existing.putAll(distributedCacheAttributes);
-//      if (excluded != null)
-//         existing.putAll(excluded);
-//      
-//      attrModifiedMap_.clear();
-//      attrRemovedMap_.clear();
-//   }
+   @Override
+   protected OutgoingAttributeGranularitySessionData getOutgoingSessionData()
+   {
+      Map<String, Object> modAttrs = null;
+      Set<String> removeAttrs = null;
+      if (isSessionAttributeMapDirty())
+      {
+         if (attrModifiedMap_.size() > 0)
+         {
+            modAttrs = new HashMap<String, Object>(attrModifiedMap_);
+         }
+         
+         if (attrRemovedSet_.size() > 0)
+         {         
+            removeAttrs = new HashSet<String>(attrRemovedSet_);
+         }
+         
+         clearAttrChangedMaps();
+      }
+      DistributableSessionMetadata metadata = isSessionMetadataDirty() ? getSessionMetadata() : null;
+      Long timestamp = modAttrs != null || removeAttrs != null || metadata != null || getMustReplicateTimestamp() ? Long.valueOf(getSessionTimestamp()) : null;
+      return new OutgoingData(getRealId(), getVersion(), timestamp, metadata, modAttrs, removeAttrs);
+   }
 
    @Override
    protected Object getAttributeInternal(String name)
@@ -143,47 +151,6 @@
       return old;
    }
 
-   /**
-    * Overrides the superclass version to read in the attributes.
-    */
-   @Override
-   protected synchronized void replicateAttributes()
-   {
-      // Go thru the attribute change list
-      String myRealId = getRealId();
-      if (isSessionAttributeMapDirty())
-      {
-         DistributedCacheManager distributedCacheManager = getDistributedCacheManager();
-         
-         // Go thru the modified attr list first
-         int modCount = attrModifiedMap_.size();
-         if (modCount == 1)
-         {
-            for (Map.Entry<String, Object> entry : attrModifiedMap_.entrySet())
-            {
-               distributedCacheManager.putAttribute(myRealId, entry.getKey(), entry.getValue());
-            }
-         }
-         else if (modCount > 0)
-         {
-            // It's more efficient to write a map than 2 method calls,
-            // plus it reduces the number of CacheListener notifications
-            distributedCacheManager.putAttribute(myRealId, attrModifiedMap_);
-         }
-         
-         // Go thru the remove attr list
-         if (attrRemovedMap_.size() > 0)
-         {         
-            for (String key : attrRemovedMap_.keySet())
-            {
-               distributedCacheManager.removeAttribute(myRealId, key);
-            }
-         }
-         
-         clearAttrChangedMaps();
-      }
-   }
-
    // ------------------------------------------------------- Private Methods
 
    private synchronized void attributeChanged(String key, Object value, boolean removal)
@@ -194,13 +161,13 @@
          {
             attrModifiedMap_.remove(key);
          }
-         attrRemovedMap_.put(key, value);
+         attrRemovedSet_.add(key);
       }
       else
       {
-         if (attrRemovedMap_.containsKey(key))
+         if (attrRemovedSet_.contains(key))
          {
-            attrRemovedMap_.remove(key);
+            attrRemovedSet_.remove(key);
          }
          attrModifiedMap_.put(key, value);
       }
@@ -209,7 +176,36 @@
 
    private synchronized void clearAttrChangedMaps()
    {
-      attrRemovedMap_.clear();
+      attrRemovedSet_.clear();
       attrModifiedMap_.clear();
    }
+
+   // ----------------------------------------------------------------- Classes
+
+   private static class OutgoingData
+         extends OutgoingDistributableSessionDataImpl
+         implements OutgoingAttributeGranularitySessionData
+   {
+      private final Map<String, Object> modifiedAttributes;
+      private final Set<String> removedAttributes;
+      
+      public OutgoingData(String realId, int version, 
+            Long timestamp, DistributableSessionMetadata metadata,
+            Map<String, Object> modifiedAttributes, Set<String> removedAttributes)
+      {
+         super(realId, version, timestamp, metadata);
+         this.modifiedAttributes = modifiedAttributes;
+         this.removedAttributes = removedAttributes;
+      }
+
+      public Map<String, Object> getModifiedSessionAttributes()
+      {
+         return modifiedAttributes;
+      }
+
+      public Set<String> getRemovedSessionAttributes()
+      {
+         return removedAttributes;
+      }
+   }
 }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredManager.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredManager.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -24,6 +24,7 @@
 
 import org.jboss.metadata.web.jboss.ReplicationTrigger;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 import org.jboss.web.tomcat.service.session.notification.ClusteredSessionNotificationPolicy;
 
 /**
@@ -32,7 +33,7 @@
  * @author Brian Stansberry
  *
  */
-public interface ClusteredManager extends AbstractJBossManager
+public interface ClusteredManager<O extends OutgoingDistributableSessionData> extends AbstractJBossManager
 {
    
    /**
@@ -85,5 +86,5 @@
     * Gets the <code>DistributedCacheManager</code> through which we interact
     * with the distributed cache.
     */
-   DistributedCacheManager getDistributedCacheManager();
+   DistributedCacheManager<O> getDistributedCacheManager();
 }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSession.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSession.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSession.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -63,10 +63,10 @@
 import org.apache.catalina.util.StringManager;
 import org.jboss.logging.Logger;
 import org.jboss.metadata.web.jboss.ReplicationTrigger;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSession;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionData;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.IncomingDistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 import org.jboss.web.tomcat.service.session.notification.ClusteredSessionManagementStatus;
 import org.jboss.web.tomcat.service.session.notification.ClusteredSessionNotificationCause;
 import org.jboss.web.tomcat.service.session.notification.ClusteredSessionNotificationPolicy;
@@ -80,8 +80,8 @@
  * 
  * @version $Revision$
  */
-public abstract class ClusteredSession
-   implements HttpSession, Session, DistributableSession
+public abstract class ClusteredSession<O extends OutgoingDistributableSessionData>
+   implements HttpSession, Session
 {
    // --------------------------------------------------------------- Constants
    
@@ -220,12 +220,12 @@
    /**
     * The Manager with which this Session is associated.
     */
-   private transient ClusteredManager manager = null;
+   private transient ClusteredManager<O> manager = null;
    
    /**
     * Our proxy to the distributed cache.
     */
-   private transient DistributedCacheManager distributedCacheManager;
+   private transient DistributedCacheManager<O> distributedCacheManager;
 
    /**
     * The maximum time interval, in seconds, between client requests before
@@ -388,7 +388,7 @@
     * 
     * @param manager the manager for this session
     */
-   protected ClusteredSession(ClusteredManager manager)
+   protected ClusteredSession(ClusteredManager<O> manager)
    {
       super();
       
@@ -493,8 +493,9 @@
    {
       if ((manager instanceof ClusteredManager) == false)
          throw new IllegalArgumentException("manager must implement ClusteredManager");
-      
-      this.manager = (ClusteredManager) manager;
+      @SuppressWarnings("unchecked")
+      ClusteredManager<O> unchecked = (ClusteredManager) manager;
+      this.manager = unchecked;
 
       
       this.invalidationPolicy = this.manager.getReplicationTrigger();
@@ -1010,10 +1011,10 @@
    public void removeValue(String name) 
    {
       removeAttribute(name);
-   }
-   
-   // ---------------------------------------------------- DistributableSession
+   }   
 
+   // ------------------------------------------------------------------ Public
+
    /**
     * Gets the session id with any appended jvmRoute info removed.
     *
@@ -1024,38 +1025,6 @@
       return realId;
    }
    
-   public boolean getCreateRegionForSession()
-   {
-      // By default, regions are not needed. Subclasses that need them
-      // can override.
-      return false;
-   }
-   
-   public boolean needRegionForSession()
-   {
-      // By default, regions are not needed. Subclasses that need them
-      // can override.
-      return false;
-   }
-   
-   public boolean hasRegionForSession()
-   {
-      // By default, regions are not needed. Subclasses that need them
-      // can override.
-      return false;
-   }
-   
-   public void createdRegionForSession()
-   {
-      // By default, regions are not needed. Subclasses that need them
-      // can override.      
-   }
-
-   public AtomicInteger getVersion()
-   {
-      return version;
-   }
-   
    public boolean getMustReplicateTimestamp()
    {
       // If the access times are the same, access() was never called
@@ -1072,48 +1041,11 @@
       return exceeds;
    }
    
-   public AtomicLong getSessionTimestamp()
-   {
-      this.timestamp.set(this.thisAccessedTime);
-      return this.timestamp;
-   }
-   
-   public boolean isSessionMetadataDirty()
-   {
-      return sessionMetadataDirty;
-   }
-   
-   public DistributableSessionMetadata getSessionMetadata()
-   {
-      this.metadata.setId(id);
-      this.metadata.setCreationTime(creationTime);
-      this.metadata.setMaxInactiveInterval(maxInactiveInterval);
-      this.metadata.setNew(isNew);
-      this.metadata.setValid(isValid);
-      
-      return this.metadata;
-   }
-   
-   public boolean isSessionAttributeMapDirty()
-   {
-      return sessionAttributesDirty;
-   }
-
    /**
     * {@inheritDoc}
-    * 
-    * @return this default impl always returns <code>null</code>
     */
-   public Map<String, Object> getSessionAttributeMap()
+   public void update(IncomingDistributableSessionData sessionData)
    {
-      return null;
-   }
-   
-   /**
-    * {@inheritDoc}
-    */
-   public void update(DistributableSessionData sessionData)
-   {
       assert sessionData != null : "sessionData is null";
       
       this.version.set(sessionData.getVersion());
@@ -1181,10 +1113,8 @@
       
       // We are no longer outdated vis a vis distributed cache
       clearOutdated();
-   }   
+   }
 
-   // ------------------------------------------------------------------ Public
-
    /**
     * Increment our version and propagate ourself to the distributed cache.
     */
@@ -1197,10 +1127,9 @@
                    "version from: " + getVersion() + " and replicate.");
       }
       version.incrementAndGet();
-      distributedCacheManager.putSession(this);
       
-      // Allow subclasses to replicate attributes if needed
-      replicateAttributes();
+      O outgoingData = getOutgoingSessionData();
+      distributedCacheManager.storeSessionData(outgoingData);
       
       sessionAttributesDirty = false;
       sessionMetadataDirty = false;
@@ -1297,7 +1226,7 @@
     */
    public boolean setVersionFromDistributedCache(int version)
    {
-      boolean outdated = getVersion().get() < version;
+      boolean outdated = getVersion() < version;
       if (outdated)
       {
          this.outdatedVersion = version;
@@ -1667,6 +1596,8 @@
    protected abstract Object setAttributeInternal(String name, Object value);
 
    protected abstract Object removeAttributeInternal(String name, boolean localCall, boolean localOnly);
+   
+   protected abstract O getOutgoingSessionData();
 
    protected Object getAttributeInternal(String name)
    {
@@ -1703,17 +1634,17 @@
       return attributes;
    }
    
-   protected final ClusteredManager getManagerInternal()
+   protected final ClusteredManager<O> getManagerInternal()
    {
       return manager;
    }
    
-   protected final DistributedCacheManager getDistributedCacheManager()
+   protected final DistributedCacheManager<O> getDistributedCacheManager()
    {
       return distributedCacheManager;
    }
    
-   protected final void setDistributedCacheManager(DistributedCacheManager distributedCacheManager)
+   protected final void setDistributedCacheManager(DistributedCacheManager<O> distributedCacheManager)
    {
       this.distributedCacheManager = distributedCacheManager;
    }   
@@ -1809,15 +1740,6 @@
          }
       }
    }
-   
-   /**
-    * Extension point for subclasses to handle replication of attributes.
-    * This default implementation does nothing.
-    */
-   protected void replicateAttributes()
-   {
-      // no-op
-   }
 
    protected final void sessionAttributesDirty()
    {
@@ -1832,6 +1754,38 @@
       this.hasActivationListener = Boolean.valueOf(hasListener);
    }
 
+   protected int getVersion()
+   {
+      return version.get();
+   }
+   
+   protected long getSessionTimestamp()
+   {
+      this.timestamp.set(this.thisAccessedTime);
+      return this.timestamp.get();
+   }
+   
+   protected boolean isSessionMetadataDirty()
+   {
+      return sessionMetadataDirty;
+   }
+   
+   protected DistributableSessionMetadata getSessionMetadata()
+   {
+      this.metadata.setId(id);
+      this.metadata.setCreationTime(creationTime);
+      this.metadata.setMaxInactiveInterval(maxInactiveInterval);
+      this.metadata.setNew(isNew);
+      this.metadata.setValid(isValid);
+      
+      return this.metadata;
+   }
+   
+   protected boolean isSessionAttributeMapDirty()
+   {
+      return sessionAttributesDirty;
+   }
+
    // ----------------------------------------------------------------- Private
    
    private void checkAlwaysReplicateTimestamp()

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSessionValve.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSessionValve.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSessionValve.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -36,6 +36,7 @@
 import org.apache.catalina.valves.ValveBase;
 import org.jboss.servlet.http.HttpEvent;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.BatchingManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 
 /**
  * This Valve detects all sessions that were used in a request. All sessions are given to a snapshot
@@ -123,10 +124,10 @@
             {
                // Cross-context request touched multiple sesssions;
                // need to replicate them all
-               Map<ClusteredSession, SnapshotManager> sessions = ctx.getCrossContextSessions();
+               Map<ClusteredSession<? extends OutgoingDistributableSessionData>, SnapshotManager> sessions = ctx.getCrossContextSessions();
                if (sessions != null && sessions.size() > 0)
                {
-                  for (Map.Entry<ClusteredSession, SnapshotManager> entry : sessions.entrySet())
+                  for (Map.Entry<ClusteredSession<? extends OutgoingDistributableSessionData>, SnapshotManager> entry : sessions.entrySet())
                   {
                      entry.getValue().snapshot(entry.getKey());
                   }
@@ -188,10 +189,10 @@
             {
                // Cross-context request touched multiple sesssions;
                // need to replicate them all
-               Map<ClusteredSession, SnapshotManager> sessions = ctx.getCrossContextSessions();
+               Map<ClusteredSession<? extends OutgoingDistributableSessionData>, SnapshotManager> sessions = ctx.getCrossContextSessions();
                if (sessions != null && sessions.size() > 0)
                {
-                  for (Map.Entry<ClusteredSession, SnapshotManager> entry : sessions.entrySet())
+                  for (Map.Entry<ClusteredSession<? extends OutgoingDistributableSessionData>, SnapshotManager> entry : sessions.entrySet())
                   {
                      entry.getValue().snapshot(entry.getKey());
                   }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/FieldBasedClusteredSession.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/FieldBasedClusteredSession.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/FieldBasedClusteredSession.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -25,6 +25,8 @@
 import java.util.Map;
 
 import org.jboss.aop.Advised;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 /**
  * <p>
  * Implementation of a clustered session for JBossCacheManager. The replication granularity
@@ -49,7 +51,7 @@
  * @version $Revision$
  */
 class FieldBasedClusteredSession
-   extends ClusteredSession
+   extends ClusteredSession<OutgoingDistributableSessionData>
 {
    /** The serialVersionUID */
    private static final long serialVersionUID = 8347544395334247623L;
@@ -58,14 +60,12 @@
     * Descriptive information describing this Session implementation.
     */
    protected static final String info = "FieldBasedClusteredSession/1.0";
-   
-   protected transient boolean needRegion_ = true;
 
    
    // ------------------------------------------------------------ Constructors
    
    
-   public FieldBasedClusteredSession(ClusteredManager manager)
+   public FieldBasedClusteredSession(ClusteredManager<OutgoingDistributableSessionData> manager)
    {
       super(manager);
    }
@@ -80,43 +80,16 @@
    }
 
 
-   /**
-    * Override the superclass to additionally reset this class' fields.
-    * <p>
-    * <strong>NOTE:</strong> It is not anticipated that this method will be
-    * called on a ClusteredSession, but we are overriding the method to be
-    * thorough.
-    * </p>
-    */
-   @Override
-   public void recycle()
-   {
-      super.recycle();
+   // --------------------------------------------- Overridden Protected Methods
 
-      needRegion_ = true;
-   }
-
    @Override
-   public boolean needRegionForSession()
+   protected OutgoingDistributableSessionData getOutgoingSessionData()
    {
-      return needRegion_;
+      DistributableSessionMetadata metadata = isSessionMetadataDirty() ? getSessionMetadata() : null;
+      Long timestamp = metadata != null || isSessionAttributeMapDirty() || getMustReplicateTimestamp() ? Long.valueOf(getSessionTimestamp()) : null;
+      return new OutgoingDistributableSessionDataImpl(getRealId(), getVersion(), timestamp, metadata);
    }
-   
-   @Override
-   public boolean hasRegionForSession()
-   {
-      return !needRegion_;
-   }
 
-   @Override
-   public void createdRegionForSession()
-   {
-      needRegion_ = false;
-   }
-
-
-   // --------------------------------------------- Overridden Protected Methods
-
    /**
     * Overrides the superclass to treat classes implementing Subject
     * as "immutable", since as an Observer we will detect any changes

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/InstantSnapshotManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/InstantSnapshotManager.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/InstantSnapshotManager.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -21,6 +21,7 @@
  */
 package org.jboss.web.tomcat.service.session;
 
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 
 /**
  * A concrete implementation of the snapshot manager interface
@@ -40,7 +41,7 @@
    /**
     * Instant replication of the modified session
     */
-   public void snapshot(ClusteredSession session)
+   public void snapshot(ClusteredSession<? extends OutgoingDistributableSessionData> session)
    {
       if (session != null)
       {

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/IntervalSnapshotManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/IntervalSnapshotManager.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/IntervalSnapshotManager.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -21,10 +21,12 @@
  */
 package org.jboss.web.tomcat.service.session;
 
+import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.Set;
 
 import org.jboss.logging.Logger;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 
 /**
  * A snapshot manager that collects all modified sessions over a given
@@ -42,7 +44,7 @@
    private int interval = 1000;
 
    // the modified sessions
-   private Set<ClusteredSession> sessions = new LinkedHashSet<ClusteredSession>();
+   private Set<ClusteredSession<? extends OutgoingDistributableSessionData>> sessions = new LinkedHashSet<ClusteredSession<? extends OutgoingDistributableSessionData>>();
 
    // the distribute thread
    private Thread thread = null;
@@ -67,7 +69,7 @@
    /**
     * Store the modified session in a hashmap for the distributor thread
     */
-   public void snapshot(ClusteredSession session)
+   public void snapshot(ClusteredSession<? extends OutgoingDistributableSessionData> session)
    {
       try
       {      
@@ -88,16 +90,15 @@
     */
    protected void processSessions()
    {
-      ClusteredSession[] toProcess = null;
+      Set<ClusteredSession<? extends OutgoingDistributableSessionData>> toProcess = null;
       synchronized (sessions)
       {
-         toProcess = new ClusteredSession[sessions.size()];
-         toProcess = (ClusteredSession[]) sessions.toArray(toProcess);
+         toProcess = new HashSet<ClusteredSession<? extends OutgoingDistributableSessionData>>(sessions);
          sessions.clear();
       }
 
       AbstractJBossManager mgr = getManager();
-      for (int i = 0; i < toProcess.length; i++)
+      for (ClusteredSession<? extends OutgoingDistributableSessionData> session : toProcess)
       {
          // Confirm we haven't been stopped
          if (!processingAllowed)
@@ -105,11 +106,11 @@
          
          try
          {
-            mgr.storeSession(toProcess[i]);
+            mgr.storeSession(session);
          }
          catch (Exception e)
          {
-            getLog().error("Caught exception processing session " + toProcess[i].getRealId(), e);
+            getLog().error("Caught exception processing session " + session.getRealId(), e);
          }
       }
    }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheCluster.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheCluster.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheCluster.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -46,6 +46,7 @@
 import org.jboss.metadata.web.jboss.SnapshotMode;
 import org.jboss.mx.util.MBeanServerLocator;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManagerFactoryFactory;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.TomcatClusterConfig;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.TomcatClusterDistributedCacheManagerFactory;
 
@@ -510,6 +511,7 @@
    /**
     * @see org.apache.catalina.Cluster#createManager(java.lang.String)
     */
+   @SuppressWarnings("unchecked")
    public Manager createManager(String name)
    {
       if (log.isDebugEnabled())
@@ -620,7 +622,7 @@
     * <code>Manager</code>-specific properties with cluster-wide defaults 
     * if the <code>Manager</code>-specfic properties have already been set.
     */
-   public void configureManager(JBossCacheManager manager)
+   public void configureManager(JBossCacheManager<? extends OutgoingDistributableSessionData> manager)
    {
       manager.setSnapshotMode(snapshotMode);
       manager.setSnapshotInterval(snapshotInterval);

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -54,12 +54,15 @@
 import org.jboss.util.loading.ContextClassLoaderSwitcher;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.BatchingManager;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.ClusteringNotSupportedException;
-import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionData;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManager;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManagerFactory;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributedCacheManagerFactoryFactory;
+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.OutgoingAttributeGranularitySessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingSessionGranularitySessionData;
 import org.jboss.web.tomcat.service.session.notification.ClusteredSessionNotificationCapability;
 import org.jboss.web.tomcat.service.session.notification.ClusteredSessionNotificationCause;
 import org.jboss.web.tomcat.service.session.notification.ClusteredSessionNotificationPolicy;
@@ -74,9 +77,9 @@
  * @author Hany Mesha
  * @version $Revision$
  */
-public class JBossCacheManager
+public class JBossCacheManager<O extends OutgoingDistributableSessionData>
    extends JBossManager
-   implements JBossCacheManagerMBean, LocalDistributableSessionManager, ClusteredManager
+   implements JBossCacheManagerMBean, LocalDistributableSessionManager, ClusteredManager<O>
 {
    // --------------------------------------------------------------- Constants
    
@@ -93,7 +96,7 @@
    private BatchingManager batchingManager;
 
    /** Proxy-object for the JBossCache */
-   private DistributedCacheManager proxy_;
+   private DistributedCacheManager<O> proxy_;
 
    /** The factory for our distributed cache manager */
    private final DistributedCacheManagerFactory distributedCacheManagerFactory;
@@ -235,7 +238,7 @@
     */
    public void removeLocal(Session session)
    {
-      ClusteredSession clusterSess = (ClusteredSession) session;
+      ClusteredSession<? extends OutgoingDistributableSessionData> clusterSess = uncheckedCastSession(session);
       synchronized (clusterSess)
       {
          String realId = clusterSess.getRealId();
@@ -278,7 +281,7 @@
       boolean stored = false;
       if(baseSession != null && started_)
       {
-         ClusteredSession session = (ClusteredSession) baseSession;
+         ClusteredSession<? extends OutgoingDistributableSessionData> session = uncheckedCastSession(baseSession);
 
          synchronized (session)
          {
@@ -334,8 +337,7 @@
                session.getClass().getName());
       }
 
-//      add((ClusteredSession) session, true);
-      add((ClusteredSession) session, false); // wait to replicate until req end
+      add(uncheckedCastSession(session), false); // wait to replicate until req end
    }
 
    // Satisfy the Manager interface.  Internally we use
@@ -393,7 +395,7 @@
          }
       }
 
-      ClusteredSession session = createEmptyClusteredSession();
+      ClusteredSession<? extends OutgoingDistributableSessionData> session = createEmptyClusteredSession();
 
       session.setNew(true);
       session.setCreationTime(System.currentTimeMillis());
@@ -423,7 +425,7 @@
 
       session.setId(sessionId); // Setting the id leads to a call to add()
       
-      getDistributedCacheManager().sessionCreated(session);
+      getDistributedCacheManager().sessionCreated(session.getRealId());
       
       session.tellNew(ClusteredSessionNotificationCause.CREATE);
 
@@ -464,7 +466,7 @@
    {
       String realId = getRealId(id);
       // Find it from the local store first
-      ClusteredSession session = findLocalSession(realId);
+      ClusteredSession<? extends OutgoingDistributableSessionData> session = findLocalSession(realId);
       
       // If we didn't find it locally, only check the distributed cache
       // if we haven't previously handled this session id on this request.
@@ -569,7 +571,7 @@
     */
    public void remove(Session session)
    {
-      ClusteredSession clusterSess = (ClusteredSession) session;
+      ClusteredSession<? extends OutgoingDistributableSessionData> clusterSess = uncheckedCastSession(session);
       synchronized (clusterSess)
       {
          String realId = clusterSess.getRealId();
@@ -610,7 +612,7 @@
     * Gets the <code>JBossCacheService</code> through which we interact
     * with the <code>Cache</code>.
     */
-   public DistributedCacheManager getDistributedCacheManager()
+   public DistributedCacheManager<O> getDistributedCacheManager()
    {
       return proxy_;
    }
@@ -806,7 +808,7 @@
    public String getSessionAttribute(String sessionId, String key)
    {
       Object attr = null;
-      ClusteredSession session = (ClusteredSession) findSession(sessionId);
+      ClusteredSession<? extends OutgoingDistributableSessionData> session = uncheckedCastSession(findSession(sessionId));
       if (session != null)
       {
          attr = session.getAttribute(key);
@@ -956,7 +958,7 @@
    public void notifyRemoteInvalidation(String realId)
    {
       // Remove the session from our local map
-      ClusteredSession session = (ClusteredSession) sessions_.remove(realId);
+      ClusteredSession<? extends OutgoingDistributableSessionData> session = sessions_.remove(realId);
       if (session == null)
       {
          // We weren't managing the session anyway.  But remove it
@@ -1024,7 +1026,7 @@
     */
    public void notifyLocalAttributeModification(String realId)
    {
-      ClusteredSession session = (ClusteredSession) sessions_.get(realId);
+      ClusteredSession<? extends OutgoingDistributableSessionData> session = sessions_.get(realId);
       if (session != null)
       {
          session.sessionAttributesDirty();
@@ -1069,7 +1071,7 @@
    {
       boolean updated = true;
       
-      ClusteredSession session = findLocalSession(realId);
+      ClusteredSession<? extends OutgoingDistributableSessionData> session = findLocalSession(realId);
       if (session != null)
       {
          // Need to invalidate the loaded session. We get back whether
@@ -1277,12 +1279,12 @@
          SessionInvalidationTracker.suspend();
          
          // First, handle the sessions we are actively managing
-         Session sessions[] = findLocalSessions();
+         ClusteredSession<? extends OutgoingDistributableSessionData> sessions[] = findLocalSessions();
          for (int i = 0; i < sessions.length; ++i)
          {
             try
             {
-               ClusteredSession session = (ClusteredSession) sessions[i];
+               ClusteredSession<? extends OutgoingDistributableSessionData> session = sessions[i];
                if(session == null)
                {
                   log_.warn("processExpirationPassivation(): processing null session at index " +i);
@@ -1462,20 +1464,23 @@
    
    // ------------------------------------------------------ Session Management
 
-   private ClusteredSession createEmptyClusteredSession()
+   private ClusteredSession<? extends OutgoingDistributableSessionData> createEmptyClusteredSession()
    {     
 
-      ClusteredSession session = null;
+      ClusteredSession<? extends OutgoingDistributableSessionData> session = null;
       switch (replicationGranularity_)
       {
          case ATTRIBUTE:
-         session = new AttributeBasedClusteredSession(this);
+            ClusteredManager<OutgoingAttributeGranularitySessionData> amgr = uncheckedCastManager(this);
+            session = new AttributeBasedClusteredSession(amgr);
             break;
          case FIELD:
-            session = new FieldBasedClusteredSession(this);
+            ClusteredManager<OutgoingDistributableSessionData> fmgr = uncheckedCastManager(this);
+            session = new FieldBasedClusteredSession(fmgr);
             break;
          default:
-            session = new SessionBasedClusteredSession(this);
+            ClusteredManager<OutgoingSessionGranularitySessionData> smgr = uncheckedCastManager(this);
+            session = new SessionBasedClusteredSession(smgr);
             break;
       }
       return session;
@@ -1490,7 +1495,7 @@
     *
     * @throws NullPointerException if <code>session</code> is <code>null</code>.
     */
-   private void add(ClusteredSession session, boolean replicate)
+   private void add(ClusteredSession<? extends OutgoingDistributableSessionData> session, boolean replicate)
    {
       // TODO -- why are we doing this check? The request checks session 
       // validity and will expire the session; this seems redundant
@@ -1537,7 +1542,7 @@
     * @return the session or <code>null</code> if the session cannot be found
     *         in the distributed store
     */
-   private ClusteredSession loadSession(String realId)
+   private ClusteredSession<? extends OutgoingDistributableSessionData> loadSession(String realId)
    {
       if (realId == null)
       {
@@ -1548,10 +1553,11 @@
       boolean mustAdd = false;
       boolean passivated = false;
       
-      ClusteredSession session = sessions_.get(realId);
-      
+      ClusteredSession<? extends OutgoingDistributableSessionData> session = sessions_.get(realId);
+      boolean initialLoad = false;
       if (session == null)
       {                 
+         initialLoad = true;
          // This is either the first time we've seen this session on this
          // server, or we previously expired it and have since gotten
          // a replication message from another server
@@ -1583,16 +1589,16 @@
             switcher = getContextClassLoaderSwitcher().getSwitchContext();
             switcher.setClassLoader(tcl_);
                         
-            try
+            IncomingDistributableSessionData data = proxy_.getSessionData(realId, initialLoad);
+            if (data != null)
             {
-               session = proxy_.loadSession(realId, session);
+               session.update(data);
             }
-            catch (IllegalStateException ise) // FIXME do this in the ha-server-cache-jbc layer
+            else
             {
-               log_.warn("Aborting load due to invalid session state in the distributed cache for " + 
-                     realId + " -- " + ise.getLocalizedMessage());
+               // Clunky; we set the session variable to null to indicate
+               // no data so move on
                session = null;
-               proxy_.removeSessionLocal(realId);
             }
             
             if (session != null)
@@ -1671,7 +1677,7 @@
     *
     * @param session  the session.  Cannot be <code>null</code>.
     */
-   private void processSessionRepl(ClusteredSession session)
+   private void processSessionRepl(ClusteredSession<? extends OutgoingDistributableSessionData> session)
    {
       // If we are using SESSION granularity, we don't want to initiate a TX
       // for a single put
@@ -1731,7 +1737,7 @@
    private void processSessionPassivation(String realId)
    {
       // get the session from the local map
-      ClusteredSession session = findLocalSession(realId);
+      ClusteredSession<? extends OutgoingDistributableSessionData> session = findLocalSession(realId);
       // Remove actively managed session and add to the unloaded sessions
       // if it's already unloaded session (session == null) don't do anything, 
       if (session != null)
@@ -1971,7 +1977,7 @@
             DistributableSessionMetadata md = null;
             try
             {
-               DistributableSessionData sessionData = proxy_.getSessionData(realId, owner, false);
+               IncomingDistributableSessionData sessionData = proxy_.getSessionData(realId, owner, false);
                ts = sessionData.getTimestamp();
                md = sessionData.getMetadata();
             }
@@ -2170,10 +2176,10 @@
    {
       boolean passivation = isPassivationEnabled();
       // First, the sessions we have actively loaded
-      ClusteredSession[] sessions = findLocalSessions();
+      ClusteredSession<? extends OutgoingDistributableSessionData>[] sessions = findLocalSessions();
       for(int i=0; i < sessions.length; i++)
       {
-         ClusteredSession ses = sessions[i];
+         ClusteredSession<? extends OutgoingDistributableSessionData> ses = sessions[i];
          
          if (trace_)
          {
@@ -2327,11 +2333,24 @@
       return sb.toString();
    }   
    
+   @SuppressWarnings("unchecked")
    private static ContextClassLoaderSwitcher getContextClassLoaderSwitcher()
    {
       return (ContextClassLoaderSwitcher) AccessController.doPrivileged(ContextClassLoaderSwitcher.INSTANTIATOR);
    }
    
+   @SuppressWarnings("unchecked")
+   private static <T extends OutgoingDistributableSessionData> JBossCacheManager<T> uncheckedCastManager(JBossCacheManager mgr)
+   {
+      return mgr;
+   }
+   
+   @SuppressWarnings("unchecked")
+   private static ClusteredSession<? extends OutgoingDistributableSessionData> uncheckedCastSession(Session session)
+   {
+      return (ClusteredSession) session;
+   }
+   
    // ------------------------------------------------------------ Inner Classes
    
    private class OwnedSessionUpdate
@@ -2354,7 +2373,7 @@
    {
       private final String realId;
       private final OwnedSessionUpdate osu;
-      private final ClusteredSession session;
+      private final ClusteredSession<? extends OutgoingDistributableSessionData> session;
       
       private PassivationCheck(String realId, OwnedSessionUpdate osu)
       {
@@ -2366,7 +2385,7 @@
          this.session = null;
       }
       
-      private PassivationCheck(ClusteredSession session)
+      private PassivationCheck(ClusteredSession<? extends OutgoingDistributableSessionData> session)
       {
          assert session != null : "session is null";
          

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManager.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossManager.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -55,6 +55,7 @@
 import org.jboss.metadata.web.jboss.JBossWebMetaData;
 import org.jboss.metadata.web.jboss.PassivationConfig;
 import org.jboss.web.tomcat.service.session.distributedcache.spi.ClusteringNotSupportedException;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 import org.jboss.web.tomcat.statistics.ReplicationStatistics;
 
 
@@ -177,7 +178,8 @@
    protected AtomicLong processingTime_ = new AtomicLong();
    
    /** Stores the locally active sessions. */
-   protected final Map<String, ClusteredSession> sessions_ = new ConcurrentHashMap<String,ClusteredSession>();
+   protected final Map<String, ClusteredSession<? extends OutgoingDistributableSessionData>> sessions_ = 
+      new ConcurrentHashMap<String,ClusteredSession<? extends OutgoingDistributableSessionData>>();
 
    /** The property change support for this component. */
    protected PropertyChangeSupport support_ = new PropertyChangeSupport(this);
@@ -990,7 +992,7 @@
     *
     * @see #getRealId(String)
     */
-   protected ClusteredSession findLocalSession(String realId)
+   protected ClusteredSession<? extends OutgoingDistributableSessionData> findLocalSession(String realId)
    {
       return sessions_.get(realId);
    }
@@ -1002,10 +1004,11 @@
     * {@link #findLocalSession(String)} as well as all sessions brought into
     * local management by a call to {@link #findSessions()}.
     */
-   protected ClusteredSession[] findLocalSessions()
+   protected ClusteredSession<? extends OutgoingDistributableSessionData>[] findLocalSessions()
    {
-      Collection<ClusteredSession> coll = sessions_.values();
-      ClusteredSession[] sess = new ClusteredSession[coll.size()];
+      Collection<ClusteredSession<? extends OutgoingDistributableSessionData>> coll = sessions_.values();
+      @SuppressWarnings("unchecked")
+      ClusteredSession<? extends OutgoingDistributableSessionData>[] sess = new ClusteredSession[coll.size()];
       return coll.toArray(sess);
    }
 

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JvmRouteValve.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JvmRouteValve.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/JvmRouteValve.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -32,6 +32,7 @@
 import org.apache.catalina.util.LifecycleSupport;
 import org.apache.catalina.valves.ValveBase;
 import org.jboss.logging.Logger;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 
 /**
  * Web request valve to specifically handle Tomcat jvmRoute using mod_jk(2)
@@ -209,7 +210,8 @@
    private void resetSessionId(String oldId, String newId)
          throws IOException
    {
-      ClusteredSession session = (ClusteredSession)manager_.findSession(oldId);
+      @SuppressWarnings("unchecked")
+      ClusteredSession<? extends OutgoingDistributableSessionData> session = (ClusteredSession) manager_.findSession(oldId);
       // change session id with the new one using local jvmRoute.
       if( session != null )
       {

Copied: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/OutgoingDistributableSessionDataImpl.java (from rev 87305, branches/Branch_5_x/tomcat/src/main/org/jboss/web/tomcat/service/session/OutgoingDistributableSessionDataImpl.java)
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/OutgoingDistributableSessionDataImpl.java	                        (rev 0)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/OutgoingDistributableSessionDataImpl.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -0,0 +1,70 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, 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;
+
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
+
+/**
+ * @author Brian Stansberry
+ */
+public class OutgoingDistributableSessionDataImpl implements OutgoingDistributableSessionData
+{
+   private final String realId;
+   private final int version;
+   private final Long timestamp;
+   private final DistributableSessionMetadata metadata;
+   
+   public OutgoingDistributableSessionDataImpl(String realId, int version, 
+                                               Long timestamp, 
+                                               DistributableSessionMetadata metadata)
+   {
+      assert realId != null : "realId is null";
+      
+      this.realId = realId;
+      this.version = version;
+      this.timestamp = timestamp;
+      this.metadata = metadata;
+   }
+   
+   public DistributableSessionMetadata getMetadata()
+   {
+      return metadata;
+   }
+
+   public String getRealId()
+   {
+      return realId;
+   }
+
+   public Long getTimestamp()
+   {
+      return timestamp;
+   }
+
+   public int getVersion()
+   {
+      return version;
+   }
+
+}

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SessionBasedClusteredSession.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SessionBasedClusteredSession.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SessionBasedClusteredSession.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -24,6 +24,8 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.jboss.web.tomcat.service.session.distributedcache.spi.DistributableSessionMetadata;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingSessionGranularitySessionData;
 
 /**
  * Implementation of a ClusteredSession where the replication granularity level 
@@ -39,7 +41,7 @@
  * @version $Revision$
  */
 class SessionBasedClusteredSession
-   extends ClusteredSession
+   extends ClusteredSession<OutgoingSessionGranularitySessionData>
 {
    static final long serialVersionUID = 3200976125245487256L;
 
@@ -51,7 +53,7 @@
    // ----------------------------------------------------------- Constructors
 
    
-   public SessionBasedClusteredSession(ClusteredManager manager)
+   public SessionBasedClusteredSession(ClusteredManager<OutgoingSessionGranularitySessionData> manager)
    {
       super(manager);
    }
@@ -65,44 +67,15 @@
       return (info);
    }
 
-   
    @Override
-   public Map<String, Object> getSessionAttributeMap()
+   protected OutgoingSessionGranularitySessionData getOutgoingSessionData()
    {
-      Map<String, Object> attrs = new HashMap<String, Object>(getAttributesInternal());
-      removeExcludedAttributes(attrs);
-      return attrs;
+      Map<String, Object> attrs = isSessionAttributeMapDirty() ? getSessionAttributeMap() : null;
+      DistributableSessionMetadata metadata = isSessionMetadataDirty() ? getSessionMetadata() : null;
+      Long timestamp = attrs != null || metadata != null || getMustReplicateTimestamp() ? Long.valueOf(getSessionTimestamp()) : null;
+      return new OutgoingData(getRealId(), getVersion(), timestamp, metadata, attrs);
    }
 
-   // -------------------------------------------- Overridden Protected Methods
-   
-//   @Override
-//   protected void populateAttributes(Map<String, Object> distributedCacheAttributes)
-//   {
-//      Map<String, Object> existing = getAttributesInternal();
-//      Map<String, Object> excluded = removeExcludedAttributes(existing);
-//      existing.clear();
-//      
-//      existing.putAll(distributedCacheAttributes);
-//      if (excluded != null)
-//         existing.putAll(excluded);
-//   }
-
-//   @Override
-//   protected Object getAttributeInternal(String name)
-//   {
-//      Object result = getAttributesInternal().get(name);
-//
-//      // Do dirty check even if result is null, as w/ SET_AND_GET null
-//      // still makes us dirty (ensures timely replication w/o using ACCESS)
-//      if (isGetDirty(result))
-//      {
-//         sessionAttributesDirty();
-//      }
-//
-//      return result;
-//   }
-
    @Override
    protected Object removeAttributeInternal(String name, 
                                             boolean localCall, 
@@ -120,4 +93,35 @@
       return getAttributesInternal().put(name, value);
    }
 
+   
+   // ----------------------------------------------------------------- Private
+
+   private Map<String, Object> getSessionAttributeMap()
+   {
+      Map<String, Object> attrs = new HashMap<String, Object>(getAttributesInternal());
+      removeExcludedAttributes(attrs);
+      return attrs;
+   }
+
+   // ----------------------------------------------------------------- Classes
+
+   private static class OutgoingData
+         extends OutgoingDistributableSessionDataImpl
+         implements OutgoingSessionGranularitySessionData
+   {
+      private final Map<String, Object> attributes;
+      
+      public OutgoingData(String realId, int version, 
+            Long timestamp, DistributableSessionMetadata metadata,
+            Map<String, Object> attributes)
+      {
+         super(realId, version, timestamp, metadata);
+         this.attributes = attributes;
+      }
+
+      public Map<String, Object> getSessionAttributes()
+      {
+         return attributes;
+      }
+   }
 }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SessionReplicationContext.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SessionReplicationContext.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SessionReplicationContext.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -26,6 +26,7 @@
 
 import org.apache.catalina.connector.Request;
 import org.apache.catalina.connector.Response;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 
 public final class SessionReplicationContext
 {
@@ -34,9 +35,10 @@
    private static final SessionReplicationContext EMPTY = new SessionReplicationContext();
    
    private int webappCount;
+//   private int activityCount;
    private SnapshotManager soleManager;
-   private ClusteredSession soleSession;
-   private Map<ClusteredSession, SnapshotManager> crossCtxSessions;
+   private ClusteredSession<? extends OutgoingDistributableSessionData> soleSession;
+   private Map<ClusteredSession<? extends OutgoingDistributableSessionData>, SnapshotManager> crossCtxSessions;
    private Request outerRequest;
    private Response outerResponse;
    
@@ -98,7 +100,7 @@
       
    }
    
-   public static void bindSession(ClusteredSession session, SnapshotManager manager)
+   public static void bindSession(ClusteredSession<? extends OutgoingDistributableSessionData> session, SnapshotManager manager)
    {
       SessionReplicationContext ctx = getCurrentContext();
       if (ctx != null && ctx.webappCount > 0)
@@ -111,7 +113,7 @@
       }*/
    }
    
-   public static void sessionExpired(ClusteredSession session, String realId, SnapshotManager manager)
+   public static void sessionExpired(ClusteredSession<? extends OutgoingDistributableSessionData> session, String realId, SnapshotManager manager)
    {
       SessionReplicationContext ctx = getCurrentContext();
       if (ctx != null && ctx.webappCount > 0)
@@ -201,7 +203,7 @@
     * with more than one SnapshotManager (i.e the request crossed session
     * contexts.)
     */
-   public Map<ClusteredSession, SnapshotManager> getCrossContextSessions()
+   public Map<ClusteredSession<? extends OutgoingDistributableSessionData>, SnapshotManager> getCrossContextSessions()
    {
       return crossCtxSessions;
    }
@@ -225,12 +227,12 @@
     * otherwise, in which case a cross-context request is a possibility,
     * and {@link #getCrossContextSessions()} should be checked.
     */
-   public ClusteredSession getSoleSession()
+   public ClusteredSession<? extends OutgoingDistributableSessionData> getSoleSession()
    {
       return soleSession;
    }
    
-   private void addReplicatableSession(ClusteredSession session, SnapshotManager mgr)
+   private void addReplicatableSession(ClusteredSession<? extends OutgoingDistributableSessionData> session, SnapshotManager mgr)
    {
       if (crossCtxSessions != null)
       {
@@ -245,7 +247,7 @@
       else if (!mgr.equals(soleManager))
       {
          // We have a cross-context call; need a Map for the sessions
-         crossCtxSessions = new HashMap<ClusteredSession, SnapshotManager>();
+         crossCtxSessions = new HashMap<ClusteredSession<? extends OutgoingDistributableSessionData>, SnapshotManager>();
          crossCtxSessions.put(soleSession, soleManager);
          crossCtxSessions.put(session, mgr);
          soleManager = null;
@@ -257,7 +259,7 @@
       }
    }
    
-   private void sessionExpired(ClusteredSession session, SnapshotManager manager)
+   private void sessionExpired(ClusteredSession<? extends OutgoingDistributableSessionData> session, SnapshotManager manager)
    {
       if (manager.equals(soleManager))
       {

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SnapshotManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SnapshotManager.java	2009-04-14 23:42:36 UTC (rev 87313)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/session/SnapshotManager.java	2009-04-15 00:30:22 UTC (rev 87314)
@@ -22,6 +22,7 @@
 package org.jboss.web.tomcat.service.session;
 
 import org.jboss.logging.Logger;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
 
 /**
  * Abstract base class for a session snapshot manager.
@@ -54,7 +55,7 @@
     * Tell the snapshot manager which session was modified and
     * must be replicated
     */
-   public abstract void snapshot(ClusteredSession session);
+   public abstract void snapshot(ClusteredSession<? extends OutgoingDistributableSessionData> session);
 
    /**
     * Start the snapshot manager




More information about the jboss-cvs-commits mailing list