[Jboss-cvs] JBossAS SVN: r56126 - in trunk: testsuite/src/main/org/jboss/test/cluster/test testsuite/src/resources/cluster/http/http-cross-ctx-first/WEB-INF testsuite/src/resources/cluster/http/http-cross-ctx-second/WEB-INF testsuite/src/resources/cluster/http/http-cross-ctx-third/WEB-INF testsuite/src/resources/cluster/http/http-field testsuite/src/resources/cluster/http/http-field/WEB-INF testsuite/src/resources/cluster/http/http-field-jdk5 testsuite/src/resources/cluster/http/http-field-jdk5/WEB-INF testsuite/src/resources/cluster/http/http-jk/WEB-INF testsuite/src/resources/cluster/http/http-scoped testsuite/src/resources/cluster/http/http-scoped/WEB-INF tomcat/src/main/org/jboss/web/tomcat/tc5/session tomcat/src/main/org/jboss/web/tomcat/tc6/session tomcat/src/resources

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Aug 21 12:49:53 EDT 2006


Author: hmesha
Date: 2006-08-21 12:49:34 -0400 (Mon, 21 Aug 2006)
New Revision: 56126

Modified:
   trunk/testsuite/src/main/org/jboss/test/cluster/test/CrossContextCallsTestCase.java
   trunk/testsuite/src/main/org/jboss/test/cluster/test/FieldBasedTestCase.java
   trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedAttrBasedTestCase.java
   trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedFieldBasedTestCase.java
   trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedSetAttributeTestCase.java
   trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedSetTriggerTestCase.java
   trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedTestCase.java
   trunk/testsuite/src/main/org/jboss/test/cluster/test/SessionTestUtil.java
   trunk/testsuite/src/main/org/jboss/test/cluster/test/StateTransferTestCase.java
   trunk/testsuite/src/main/org/jboss/test/cluster/test/UndeployTestCase.java
   trunk/testsuite/src/resources/cluster/http/http-cross-ctx-first/WEB-INF/jboss-web.xml
   trunk/testsuite/src/resources/cluster/http/http-cross-ctx-second/WEB-INF/jboss-web.xml
   trunk/testsuite/src/resources/cluster/http/http-cross-ctx-third/WEB-INF/jboss-web.xml
   trunk/testsuite/src/resources/cluster/http/http-field-jdk5/WEB-INF/jboss-web.xml
   trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field-batch-false.xml
   trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field-scoped.xml
   trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field.xml
   trunk/testsuite/src/resources/cluster/http/http-field/WEB-INF/jboss-web.xml
   trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field-batch-false.xml
   trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field-scoped.xml
   trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field.xml
   trunk/testsuite/src/resources/cluster/http/http-jk/WEB-INF/jboss-web.xml
   trunk/testsuite/src/resources/cluster/http/http-scoped/WEB-INF/jboss-web.xml
   trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-attr-based.xml
   trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-attr-set.xml
   trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-set-trigger.xml
   trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web.xml
   trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/CacheListener.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheManager.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheService.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheWrapper.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossManager.java
   trunk/tomcat/src/resources/tc6-cluster-service.xml
Log:
JBCLUSTER-125

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/test/CrossContextCallsTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/test/CrossContextCallsTestCase.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/test/CrossContextCallsTestCase.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -71,6 +71,11 @@
       return response;
    }
    
+   protected String getWarName()
+   {
+      return "http-cross-ctx-first";
+   }
+   
    /**
     * Makes a http call to the jsp that retrieves the attribute stored on the
     * session. When the attribute values mathes with the one retrieved earlier,

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/test/FieldBasedTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/test/FieldBasedTestCase.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/test/FieldBasedTestCase.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -64,6 +64,11 @@
       modifySubjectUrl = warName_ +modifySubjectUrlBase_;
    }
    
+   protected String getWarName()
+   {
+      return "http-field";
+   }
+   
    public void testSubjectObserver() throws Exception
    {
       getLog().debug("Enter testSubjectObserver");

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedAttrBasedTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedAttrBasedTestCase.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedAttrBasedTestCase.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -42,6 +42,11 @@
 
       concatenate();
    }
+   
+   protected String getWarName()
+   {
+      return "http-scoped-attr";
+   }
 
    public static Test suite() throws Exception
    {

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedFieldBasedTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedFieldBasedTestCase.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedFieldBasedTestCase.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -42,14 +42,17 @@
 
       concatenate();
    }
+   
+   protected String getWarName()
+   {
+      return "http-scoped-field";
+   }
 
    public static Test suite() throws Exception
    {
       Test t1 = JBossClusteredTestCase.getDeploySetup(ScopedFieldBasedTestCase.class,
             "http-scoped-field.war");
       return t1;
-   }
-   
-   
+   }   
 
 }

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedSetAttributeTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedSetAttributeTestCase.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedSetAttributeTestCase.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -46,6 +46,11 @@
       
       concatenate();
    }
+   
+   protected String getWarName()
+   {
+      return "http-scoped-set-attr";
+   }
 
    public static Test suite() throws Exception
    {

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedSetTriggerTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedSetTriggerTestCase.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedSetTriggerTestCase.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -46,6 +46,11 @@
       concatenate();
    }
 
+   protected String getWarName()
+   {
+      return "http-scoped-set";
+   }
+   
    public static Test suite() throws Exception
    {
       Test t1 = JBossClusteredTestCase.getDeploySetup(ScopedSetTriggerTestCase.class,

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedTestCase.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/test/ScopedTestCase.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -24,6 +24,8 @@
 import java.io.IOException;
 import java.net.HttpURLConnection;
 
+import javax.management.ObjectName;
+
 import junit.framework.Test;
 
 import org.apache.commons.httpclient.Cookie;
@@ -32,6 +34,8 @@
 import org.apache.commons.httpclient.HttpState;
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.methods.PostMethod;
+import org.jboss.cache.Fqn;
+import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
 import org.jboss.test.JBossClusteredTestCase;
 
 /**
@@ -72,6 +76,9 @@
    protected String loginFormUrlBase_;
    protected String setSecuritySubjectUrlBase_;
    protected String getSecuritySubjectUrlBase_;
+   
+   private ObjectName warObjectName;
+   private String warFqn_;
 
    public ScopedTestCase(String name)
    {
@@ -112,6 +119,11 @@
       setSecuritySubjectUrl_ = warName_ + setSecuritySubjectUrlBase_;
       getSecuritySubjectUrl_ = warName_ + getSecuritySubjectUrlBase_;
    }
+   
+   protected String getWarName()
+   {
+      return "http-scoped";
+   }
 
    public static Test suite() throws Exception
    {
@@ -123,6 +135,19 @@
    protected void setUp() throws Exception
    {
       super.setUp();
+      
+      if (warObjectName == null)
+      {
+         String oname = "jboss.web:J2EEApplication=none,J2EEServer=none," +
+                        "j2eeType=WebModule,name=//localhost/" + getWarName();
+         warObjectName = new ObjectName(oname);
+         
+         RMIAdaptor[] adaptors = getAdaptors();
+         
+         Object[] names = {"JSESSION", "localhost", getWarName() };
+         Fqn fqn = new Fqn(names);
+         warFqn_ = fqn.toString();
+      }
    }
 
    protected void tearDown() throws Exception
@@ -606,6 +631,120 @@
       if( body.indexOf("j_security_check") > 0 )
          fail("get of "+baseURL1_ + protectedUrl_+" redirected to login page");       
    }
+   
+   /**
+    * Tests the ability to passivate session when max idle for session is reached
+    * 
+    * @throws Exception
+    */
+   public void testSessionPassivationWMaxIdle() throws Exception
+   {
+      getLog().debug("Enter testSessionPassivationWMaxActive");
 
+      getLog().debug(setUrl + ":::::::" + getUrl);
 
+      // Create an instance of HttpClient.
+      HttpClient client = new HttpClient();
+      // Set the session attribute first
+      makeGet(client, baseURL0_ +setUrl);
+      
+      // Get the Attribute set
+      String attr0 = makeGet(client, baseURL0_ +getUrl);
+      
+      // Find out the session id and use it to build an FQN
+      String sessionID = getSessionID(client, servers_[0]);
+      // Strip off the jvmRoute, if there is one
+      sessionID = stripJvmRoute(sessionID);
+      String sessionFqn = "/JSESSION/localhost" + warName_ + sessionID;
+      
+      sleepThread(DEFAULT_SLEEP);
+      
+      // Make connection to server 1 and get
+      setCookieDomainToThisServer(client, servers_[1]);
+      String attr1 = makeGet(client, baseURL1_ + getUrl);
+      
+      // check for replication first
+      assertEquals("attributes match", attr0, attr1);
+      
+      // sleep up to 11 secs to allow max idle to be reached 
+      // and tomcat background process to run
+      // assuming that max idle in jboss-web.xml = 10 secs
+      // and tomcat background process is using the default = 10 secs
+      sleepThread(11000);
+      
+      RMIAdaptor[] adaptors = getAdaptors();
+      getLog().debug("Session in the cache = " + SessionTestUtil.getSessionVersion(adaptors[0], sessionFqn));
+      //session is passivate should not exist in the cache
+      assertNull("Session is passivated therefore it is not in the cache...", SessionTestUtil.getSessionVersion(adaptors[0], sessionFqn));
+      
+      // activate the session by requesting the attrribute
+      // Make connection to server 0 and get
+      setCookieDomainToThisServer(client, servers_[0]);
+      String attr2 = makeGet(client, baseURL0_ + getUrl);
+      
+      assertEquals("attribute match after activation", attr0, attr2);
+   }
+   
+   /**
+    * Tests the ability to passivate session when max number of active sessions reached
+    * 
+    * @throws Exception
+    */
+   public void testSessionPassivationWMaxActive() throws Exception
+   {
+      getLog().debug("Enter testSessionPassivationWMaxActive");
+
+      getLog().debug(setUrl + ":::::::" + getUrl);
+
+      RMIAdaptor[] adaptors = getAdaptors();
+      // Create an instance of HttpClient.
+      HttpClient client = new HttpClient();
+      // Set the session attribute first
+      makeGet(client, baseURL0_ +setUrl);
+      
+      // Get the Attribute set
+      String attr0 = makeGet(client, baseURL0_ +getUrl);
+      
+      // Find out the session id and use it to build an FQN
+      String sessionID = getSessionID(client, servers_[0]);
+      // Strip off the jvmRoute, if there is one
+      sessionID = stripJvmRoute(sessionID);
+      String sessionFqn = "/JSESSION/localhost" + warName_ + sessionID;
+      
+      sleepThread(DEFAULT_SLEEP);
+      
+      // Make connection to server 1 and get
+      setCookieDomainToThisServer(client, servers_[1]);
+      String attr1 = makeGet(client, baseURL1_ + getUrl);
+      
+      // check for replication first
+      assertEquals("attributes match", attr0, attr1);
+      
+      // Create 3 more sessions on server0
+      // assuming that max-active-sessions is set to 20 in jboss-web.xml
+      getLog().debug("current active sessions = " + SessionTestUtil.getSessionIds(adaptors[0], warFqn_));
+      int numberOfActiveSessions = SessionTestUtil.getSessionIds(adaptors[0], warFqn_).size(); 
+      HttpClient[] clients = new HttpClient[(20 - numberOfActiveSessions + 1)];
+      String[] attrs = new String[clients.length];
+      for (int i = 0; i < clients.length; i++)
+      {
+         clients[i] = new HttpClient();
+         makeGet(clients[i], baseURL0_ +setUrl);
+         attrs[i] = makeGet(clients[i], baseURL0_ + getUrl);
+         // Set cookie domain to server1
+         this.setCookieDomainToThisServer(clients[i], servers_[1]);
+      }
+      getLog().debug("to reach max active sessions we needed to create " + clients.length + " clients");
+      
+      getLog().debug("Session in the cache = " + SessionTestUtil.getSessionVersion(adaptors[0], sessionFqn));
+      //session is passivate should not exist in the cache
+      assertNull("Session is passivated therefore it is not in the cache...",  SessionTestUtil.getSessionVersion(adaptors[0], sessionFqn));
+      
+      // activate the session by requesting the attrribute
+      // Make connection to server 0 and get
+      setCookieDomainToThisServer(client, servers_[0]);
+      String attr2 = makeGet(client, baseURL0_ + getUrl);
+      
+      assertEquals("attribute match after activation", attr0, attr2);      
+   }
 }

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/test/SessionTestUtil.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/test/SessionTestUtil.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/test/SessionTestUtil.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -22,6 +22,7 @@
 
 package org.jboss.test.cluster.test;
 
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 
@@ -29,6 +30,7 @@
 import javax.management.ObjectName;
 
 import org.jboss.cache.Fqn;
+import org.jboss.cache.buddyreplication.BuddyManager;
 import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
 
 /**
@@ -86,6 +88,40 @@
 
       return replVersion;
    }
+   
+   public static Set getSessionIds(RMIAdaptor adaptor, String warFqn) throws Exception
+   {
+      Set result = new HashSet();
+      Set s = (Set) adaptor.invoke(CACHE_OBJECT_NAME, 
+                     "getChildrenNames",
+                     new Object[] { warFqn },
+                     new String[] { String.class.getName() });
+      if (s != null)
+         result.addAll(s);
+      
+//    Check in the buddy backup tree
+      Set buddies = (Set) adaptor.invoke(CACHE_OBJECT_NAME, 
+            "getChildrenNames",
+            new Object[] { BuddyManager.BUDDY_BACKUP_SUBTREE_FQN },
+            new String[] { Fqn.class.getName() });
+      
+      if (buddies != null)
+      {
+         for (Iterator it = buddies.iterator(); it.hasNext(); )
+         {
+            Fqn fqn = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, it.next());
+            fqn = new Fqn(fqn, Fqn.fromString(warFqn));
+            s = (Set) adaptor.invoke(CACHE_OBJECT_NAME, 
+                  "getChildrenNames",
+                  new Object[] { fqn.toString() },
+                  new String[] { String.class.getName() });
+            if (s != null)
+               result.addAll(s);
+         }
+      }
+      
+      return result;
+   }
 
    private SessionTestUtil() {}
 }

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/test/StateTransferTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/test/StateTransferTestCase.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/test/StateTransferTestCase.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -155,7 +155,7 @@
       getLog().debug("Sessions created");
       
       // Confirm there are no sessions in the server1 cache
-      Set sessions = getSessionIds(adaptor1_);
+      Set sessions = SessionTestUtil.getSessionIds(adaptor1_, warFqn_);
       
       assertTrue("server1 has no cached sessions", sessions.size() == 0);
       
@@ -167,7 +167,7 @@
       getLog().debug("Server1 started");
       
       // Confirm the sessions are in the server1 cache
-      sessions = getSessionIds(adaptor1_);
+      sessions = SessionTestUtil.getSessionIds(adaptor1_, warFqn_);
 
       assertEquals("server1 has cached sessions", clients.length, sessions.size());
       
@@ -189,45 +189,10 @@
       adaptor0_.invoke(warObjectName, "stop" , NULL_ARGS, NULL_TYPES);
       
       // Confirm there are no sessions in the server0 cache
-      sessions = getSessionIds(adaptor0_);
+      sessions = SessionTestUtil.getSessionIds(adaptor0_, warFqn_);
       
       assertTrue("server0 has no cached sessions", sessions.size() == 0);
       
       getLog().debug("Server0 has no cached sessions");
    }
-   
-   private Set getSessionIds(RMIAdaptor adaptor) throws Exception
-   {
-      Set result = new HashSet();
-      Set s = (Set) adaptor.invoke(CACHE_OBJECT_NAME, 
-                     "getChildrenNames",
-                     new Object[] { warFqn_ },
-                     new String[] { String.class.getName() });
-      if (s != null)
-         result.addAll(s);
-      
-//    Check in the buddy backup tree
-      Set buddies = (Set) adaptor.invoke(CACHE_OBJECT_NAME, 
-            "getChildrenNames",
-            new Object[] { BuddyManager.BUDDY_BACKUP_SUBTREE_FQN },
-            new String[] { Fqn.class.getName() });
-      
-      if (buddies != null)
-      {
-         for (Iterator it = buddies.iterator(); it.hasNext(); )
-         {
-            Fqn fqn = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, it.next());
-            fqn = new Fqn(fqn, Fqn.fromString(warFqn_));
-            s = (Set) adaptor.invoke(CACHE_OBJECT_NAME, 
-                  "getChildrenNames",
-                  new Object[] { fqn.toString() },
-                  new String[] { String.class.getName() });
-            if (s != null)
-               result.addAll(s);
-         }
-      }
-      
-      return result;
-   }
-
 }

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/test/UndeployTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/test/UndeployTestCase.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/test/UndeployTestCase.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -85,7 +85,69 @@
       assertEquals("Get attribute should be but is ", attr, attr2);
       getLog().debug("Exit testNonPrimitiveGet");
    }
+   
+   /**
+    * Tests the ability to passivate sessions on undeployment of an application
+    * and to activate it on restart or redeployment of an application
+    * @throws Exception
+    */
+   public void testSessionPassivationActivation() throws Exception
+   {
+	   getLog().info("Enter testSessionPassivationActivation");
+	   
+	   getLog().debug(setUrl_ + ":::::::" + getUrl_);
+       
+       // force deployment
+       RMIAdaptor[] adaptors = getAdaptors();
+       String warName = getWarName();
+       deploy(adaptors[0], warName);
+       deploy(adaptors[1], warName);
+       
+       sleep(2000);
+          
+        // the code above should be removed when we figure out what's wrong 
+        // with configure cluster.
+	   
+       // Create an instance of HttpClient.
+	   HttpClient client = new HttpClient();
 
+	   // Set the session attribute first
+	   makeGet(client, baseURL0_ +setUrl_);
+	   
+	   // replicate the session to server1
+	   sleepThread(DEFAULT_SLEEP);
+       
+       //   Get the Attribute set
+       String attr = makeGetWithState(client, baseURL0_ +getUrl_);
+       
+       // Make connection to server 1 and get
+       setCookieDomainToThisServer(client, servers_[1]);
+       String attr2 = makeGetWithState(client, baseURL1_ + getUrl_);
+       
+       assertEquals("attribute match", attr, attr2);
+       
+       
+	   
+	   // undeploy server0, which passivates the session to the distributed store
+       undeploy(adaptors[0], warName);
+       
+
+       sleep(2000);	   
+       // redeploy the application on server 0
+       deploy(adaptors[0], warName);
+
+       sleep(2000);
+       
+       // Get the Attribute using the same session ID
+       setCookieDomainToThisServer(client, servers_[0]);
+       String attr0 = makeGet(client, baseURL0_ +getUrl_);
+       
+       assertEquals("attributeMatches after activation", attr0, attr);
+       
+	   getLog().debug("Exit testSessionPassivationActivation");
+	   
+   }
+
    protected void concatenate()
    {
       setUrl_ = getContextPath() +setUrlBase_;

Modified: trunk/testsuite/src/resources/cluster/http/http-cross-ctx-first/WEB-INF/jboss-web.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-cross-ctx-first/WEB-INF/jboss-web.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-cross-ctx-first/WEB-INF/jboss-web.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -9,5 +9,11 @@
    <replication-config>
       <replication-trigger>SET_AND_GET</replication-trigger>
       <replication-granularity>SESSION</replication-granularity>
-   </replication-config>
+   </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-cross-ctx-second/WEB-INF/jboss-web.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-cross-ctx-second/WEB-INF/jboss-web.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-cross-ctx-second/WEB-INF/jboss-web.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -9,5 +9,11 @@
    <replication-config>
       <replication-trigger>SET_AND_GET</replication-trigger>
       <replication-granularity>SESSION</replication-granularity>
-   </replication-config>
+   </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-cross-ctx-third/WEB-INF/jboss-web.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-cross-ctx-third/WEB-INF/jboss-web.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-cross-ctx-third/WEB-INF/jboss-web.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -9,5 +9,11 @@
    <replication-config>
       <replication-trigger>SET_AND_GET</replication-trigger>
       <replication-granularity>SESSION</replication-granularity>
-   </replication-config>
+   </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-field/WEB-INF/jboss-web.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-field/WEB-INF/jboss-web.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-field/WEB-INF/jboss-web.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -10,4 +10,10 @@
       <replication-trigger>SET_AND_GET</replication-trigger>
       <replication-granularity>SESSION</replication-granularity>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field-batch-false.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field-batch-false.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field-batch-false.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -10,4 +10,10 @@
       <replication-granularity>FIELD</replication-granularity>
       <replication-field-batch-mode>FALSE</replication-field-batch-mode>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field-scoped.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field-scoped.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field-scoped.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -10,4 +10,10 @@
       <replication-granularity>FIELD</replication-granularity>
       <replication-field-batch-mode>TRUE</replication-field-batch-mode>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-field/jboss-web-field.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -12,4 +12,10 @@
       <replication-granularity>FIELD</replication-granularity>
       <replication-field-batch-mode>TRUE</replication-field-batch-mode>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-field-jdk5/WEB-INF/jboss-web.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-field-jdk5/WEB-INF/jboss-web.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-field-jdk5/WEB-INF/jboss-web.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -10,4 +10,10 @@
       <replication-trigger>SET_AND_GET</replication-trigger>
       <replication-granularity>SESSION</replication-granularity>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field-batch-false.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field-batch-false.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field-batch-false.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -10,4 +10,10 @@
       <replication-granularity>FIELD</replication-granularity>
       <replication-field-batch-mode>FALSE</replication-field-batch-mode>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field-scoped.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field-scoped.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field-scoped.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -10,4 +10,10 @@
       <replication-granularity>FIELD</replication-granularity>
       <replication-field-batch-mode>TRUE</replication-field-batch-mode>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-field-jdk5/jboss-web-field.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -12,4 +12,10 @@
       <replication-granularity>FIELD</replication-granularity>
       <replication-field-batch-mode>TRUE</replication-field-batch-mode>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-jk/WEB-INF/jboss-web.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-jk/WEB-INF/jboss-web.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-jk/WEB-INF/jboss-web.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -12,4 +12,10 @@
       <replication-trigger>SET_AND_GET</replication-trigger>
       <replication-granularity>SESSION</replication-granularity>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-scoped/WEB-INF/jboss-web.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-scoped/WEB-INF/jboss-web.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-scoped/WEB-INF/jboss-web.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -10,4 +10,10 @@
       <replication-trigger>SET_AND_GET</replication-trigger>
       <replication-granularity>SESSION</replication-granularity>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-attr-based.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-attr-based.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-attr-based.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -10,4 +10,10 @@
       <replication-trigger>SET_AND_NON_PRIMITIVE_GET</replication-trigger>
       <replication-granularity>ATTRIBUTE</replication-granularity>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>   
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-attr-set.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-attr-set.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-attr-set.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -10,4 +10,10 @@
       <replication-trigger>SET</replication-trigger>
       <replication-granularity>ATTRIBUTE</replication-granularity>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>   
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-set-trigger.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-set-trigger.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web-set-trigger.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -10,4 +10,10 @@
       <replication-trigger>SET</replication-trigger>
       <replication-granularity>SESSION</replication-granularity>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>
 </jboss-web>

Modified: trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web.xml
===================================================================
--- trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/testsuite/src/resources/cluster/http/http-scoped/jboss-web.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -10,4 +10,10 @@
       <replication-trigger>SET_AND_NON_PRIMITIVE_GET</replication-trigger>
       <replication-granularity>SESSION</replication-granularity>
    </replication-config>
+   <max-active-sessions>20</max-active-sessions>
+   <passivation-config>
+      <use-session-passivation>TRUE</use-session-passivation>
+      <passivation-min-idle-time>5</passivation-min-idle-time>
+      <passivation-max-idle-time>10</passivation-max-idle-time>
+   </passivation-config>   
 </jboss-web>

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -57,12 +57,6 @@
  * @author Ben Wang
  * @author Brian Stansberry
  * @author Hany Mesha
- * 
-<<<<<<< JBossCacheManager.java
- * @version $Revision$
-=======
- * @version $Revision$
->>>>>>> 1.47
  */
 public class JBossCacheManager
    extends JBossManager

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/CacheListener.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/CacheListener.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/CacheListener.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -23,13 +23,13 @@
 
 import org.jboss.cache.Fqn;
 import org.jboss.cache.TreeCache;
-import org.jboss.cache.TreeCacheListener;
+import org.jboss.cache.AbstractTreeCacheListener;
 import org.jboss.logging.Logger;
 import org.jboss.metadata.WebMetaData;
 import org.jgroups.View;
 
 
-public class CacheListener implements TreeCacheListener
+public class CacheListener extends AbstractTreeCacheListener
 {
    // Element within an FQN that is the session id
    private static final int SESSION_ID_FQN_INDEX = 3;
@@ -195,6 +195,37 @@
    {
       // We don't care for this event.
    }
+   
+   public void nodeActivate(Fqn fqn, boolean pre)
+   {
+      //no-op
+      // we don't need to handle node activation notification since the session manager will do upon
+      // loading the session from the distrubted store.
+   }
+   
+   public void nodePassivate(Fqn fqn, boolean pre)
+   {
+      // Parse the Fqn so if it has a buddy backup region in it
+      // we can just deal with the part below that
+      ParsedBuddyFqn pfqn = new ParsedBuddyFqn(fqn);
+      Fqn noBuddy = pfqn.noBuddy;
+      
+      // Check if we need to handle this event. If this is from myself or not for
+      // my webapp, then I should skip it.
+      // We only deal with events for the root node of a session,
+      // so skip all others
+      if(noBuddy == null || noBuddy.size() != SESSION_FQN_SIZE || !needToHandle(noBuddy)) return;
+      
+      if(pre)
+      {
+         // A session has been passivated on another node;
+         // need to inform the manager
+         String realId = getIdFromFqn(noBuddy);
+         // process the session passivation
+         manager_.processSessionPassivation(realId, pfqn.owner);
+      }
+           
+   }
 
    protected String getIdFromFqn(Fqn fqn)
    {

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheManager.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheManager.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -56,7 +56,7 @@
  *
  * @author Ben Wang
  * @author Brian Stansberry
- * 
+ * @author Hany Mesha
  * @version $Revision$
  */
 public class JBossCacheManager
@@ -508,20 +508,32 @@
       for(int i=0; i < sessions.length; i++)
       {
          ClusteredSession ses = sessions[i];
+         // JBCLUSTER-15
+         // if session passivation is enabled, passivate sessions instead of expiring them which means
+         // they'll be available to the manager for activation after a restart. 
          if (log_.isDebugEnabled())
          {
-             log_.debug("clearSessions(): clear session by expiring: " + ses);
+             log_.debug("clearSessions(): clear session by expiring or passivating: " + ses);
          }
          boolean notify = true;
          boolean localCall = true;
          boolean localOnly = true;
          try
          {
-            ses.expire(notify, localCall, localOnly);
+            if(isPassivationEnabled() && ses.isValid())
+            {
+               
+               processSessionPassivation(ses.getRealId(), this.getContainer().getParent().getName());
+            }
+            else
+            {
+               ses.expire(notify, localCall, localOnly);               
+            }
+
          }
          catch (Throwable t)
          {
-            log_.warn("clearSessions(): Caught exception expiring session " +
+            log_.warn("clearSessions(): Caught exception expiring or passivating session " +
                      ses.getIdInternal(), t);
          }
          finally
@@ -532,14 +544,17 @@
          }
       }
 
-      // Next, the local copy of the distributed cache
-      Map unloaded = new HashMap(unloadedSessions_);
-      Set keys = unloaded.keySet();
-      for (Iterator it = keys.iterator(); it.hasNext(); )
+      if(!isPassivationEnabled())
       {
-         String realId = (String) it.next();
-         proxy_.removeSessionLocal(realId);
-         unloadedSessions_.remove(realId);
+//       Next, the local copy of the distributed cache
+         Map unloaded = new HashMap(unloadedSessions_);
+         Set keys = unloaded.keySet();
+         for (Iterator it = keys.iterator(); it.hasNext(); )
+         {
+            String realId = (String) it.next();
+            proxy_.removeSessionLocal(realId);
+            unloadedSessions_.remove(realId);
+         }
       }
    }
 
@@ -564,21 +579,34 @@
     */
    public Session createSession(String sessionId)
    {
+      if (log_.isTraceEnabled())
+      {
+         log_.trace("createSession: active sessions = " + activeCounter_ +
+                    " , session map size = " + sessions_.size() +
+                    " and max allowed sessions = " + maxActive_);
+      }
       // We check here for maxActive instead of in add().  add() gets called
       // when we load an already existing session from the distributed cache
       // (e.g. in a failover) and we don't want to fail in that situation.
 
+      // JBCLUSTER-15
+      // first check if passivation is enabled and reached the max allowed sessions, 
+      /// then try to expire/passivate sessions to free memory 
+      if(maxActive_ != -1 && sessions_.size() >= maxActive_ && isPassivationEnabled())
+      {
+         processExpires();
+      }
       // maxActive_ -1 is unlimited
-      if (maxActive_ != -1 && activeCounter_ >= maxActive_)
+      if (maxActive_ != -1 && sessions_.size() >= maxActive_)
       {
          // Exceeds limit. We need to reject it.
          rejectedCounter_++;
          // Catalina api does not specify what happens
          // but we will throw a runtime exception for now.
          String msgEnd = (sessionId == null) ? "" : " id " + sessionId;
-         throw new IllegalStateException("JBossCacheManager.add(): number of " +
+         throw new IllegalStateException("JBossCacheManager.createSession(): number of " +
                 "active sessions exceeds the maximum limit: " +
-                maxActive_ + " when trying to add session" + msgEnd);
+                maxActive_ + " when trying to create session" + msgEnd);
       }
 
       ClusteredSession session = createEmptyClusteredSession();
@@ -611,6 +639,9 @@
       }
 
       createdCounter_++;
+      // JBCLUSTER-15 - if we have created a session it must be handled by this manager
+      // therefore we must increment the active counter
+      activeCounter_++;
       
       // Add this session to the set of those potentially needing replication
       // We use the realId here
@@ -955,8 +986,36 @@
       long begin = System.currentTimeMillis();
       boolean mustAdd = false;
       ClusteredSession session = (ClusteredSession) sessions_.get(realId);
+      
       if (session == null)
       {
+         // JBCLUSTER-15
+         // We need to check for maxActive first before attempting to create a new session
+         if (log_.isTraceEnabled())
+         {
+            log_.trace("createSession: active sessions = " + activeCounter_ +
+                       " , session map size = " + sessions_.size() +
+                       " and max allowed sessions = " + maxActive_);
+         }
+         // first check if passivation is enabled and reached the max allowed sessions, 
+         /// then try to expire/passivate sessions to free memory 
+         if(maxActive_ != -1 && sessions_.size() >= maxActive_ && isPassivationEnabled())
+         {
+            processExpires();
+         }
+         // maxActive_ -1 is unlimited
+         if (maxActive_ != -1 && sessions_.size() >= maxActive_)
+         {
+            // Exceeds limit. We need to reject it.
+            rejectedCounter_++;
+            // Catalina api does not specify what happens
+            // but we will throw a runtime exception for now.
+            String msgEnd = (realId == null) ? "" : " id " + realId;
+            throw new IllegalStateException("JBossCacheManager.createSession(): number of " +
+                   "active sessions exceeds the maximum limit: " +
+                   maxActive_ + " when trying to load session" + msgEnd);
+         }
+         
          // 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
@@ -1160,9 +1219,10 @@
 
       if (log_.isDebugEnabled())
       {
-         log_.debug("Looking for sessions that have expired ...");
+         log_.debug("processExpires():max active sessions = " + maxActive_);
+         log_.debug("processExpires(): passivation mode = " + isPassivationEnabled()); 
+         log_.debug("processExpires(): Looking for sessions that have expired ...");
       }
-
       try
       {
          // First, handle the sessions we are actively managing
@@ -1196,6 +1256,44 @@
                // properly internally; synchronizing externally can lead
                // to deadlocks!!
                if (!session.isValid()) continue;
+               
+               // JBCLUSTER-15
+               if (log_.isTraceEnabled())
+               {
+                  log_.trace("processExpires(): Checking passivation for session " + session.getId());
+               } 
+               // now that we have valid session, see if we need to 
+               // passivate it based on the configurable passivation min and max Idle time
+               if (isPassivationEnabled())
+               {
+                  long timeNow = System.currentTimeMillis();
+                  int timeIdle = (int) ((timeNow - session.getLastAccessedTimeInternal()) / 1000L);
+                  // if maxIdle time configured, means that we need to passivate sessions that have
+                  // exceeded the max allowed idle time
+                  if (passivationMaxIdleTime_ >= 0 && timeIdle > passivationMaxIdleTime_)
+                  {
+                     if(log_.isTraceEnabled())
+                     {
+                        log_.trace("JBossCacheManager.processExpires() passivating session " + session.getRealId());
+                     }
+                     processSessionPassivation(session.getRealId(), this.getContainer().getParent().getName());
+                  }
+                  // If the session didn't exceed the passivationMaxIdleTime_, See   
+                  // if the number of sessions managed by this manager greater than the max allowed 
+                  // active sessions, passivate the session if it exceed passivationMinIdleTime_ 
+                  else if (maxActive_ > 0 && passivationMinIdleTime_ > 0 && sessions_.size()> maxActive_)
+                  {
+                     if(timeIdle > passivationMinIdleTime_)
+                     {
+                        if(log_.isTraceEnabled())
+                        {
+                           log_.debug("JBossCacheManager.processExpires() passivating session " + session.getRealId());
+                        }
+                        processSessionPassivation(session.getRealId(), this.getContainer().getParent().getName());
+                     }
+                  }
+               }
+               
             }
             catch (Exception ex)
             {
@@ -1223,6 +1321,12 @@
                   proxy_.removeSessionLocal(realId, osu.owner);
                   unloadedSessions_.remove(realId);
                }
+                              
+               // JBClUSTER-15
+               // we don't need to worry about session passivation here, since the 
+               // method processSessionPassivation() takes care of unloadedSessions_ map
+               // when it receives a notification of passivation event happened in the 
+               // distributed store from the CacheListener
                catch (Exception ex)
                {
                   log_.error("processExpire(): failed removing unloaded session " + 
@@ -1314,7 +1418,54 @@
          activeCounter_--;
       }
    }
+   
+   public void processSessionPassivation(String realId, String dataOwner)
+   {
+      // get the session from the local map
+      ClusteredSession session = findLocalSession(realId);
+      // only remove actively managed session and add to the unloaded sessions
+      // if it's already unloaded session (session == null) don't do anything, 
+      // the evict notification will tell the server that has the session to remove it. 
+      if (session != null)
+      {
+         synchronized (session)
+         {
+            if (log_.isTraceEnabled())
+            {
+               log_.trace("Passivating session with id: " + realId);
+            }
 
+            try {
+               // Tell the proxy to ignore cache notifications we are about
+               // to generate for this session.
+               LocalSessionActivity.startLocalActivity(realId);
+               session.passivate();
+               proxy_.evictSession(realId);
+            }
+            finally {
+               LocalSessionActivity.finishLocalActivity();
+            }
+
+            Object obj = unloadedSessions_.put(realId, 
+                  new OwnedSessionUpdate(dataOwner, session.getLastAccessedTime()));
+            if (log_.isTraceEnabled())
+            {
+               if (obj == null)
+               {
+                  log_.trace("New session " + realId + " added to unloaded session map");
+               }
+               else
+               {
+                  log_.trace("Updated timestamp for unloaded session " + realId);
+               }
+            }
+            sessions_.remove(realId);
+            stats_.removeStats(realId);
+         }
+         activeCounter_--;
+      }
+   }
+
    /**
     * Gets the session id with any jvmRoute removed.
     * 
@@ -1350,7 +1501,17 @@
          }
       }
    }
-
+   
+   /**
+    * Returns true if the passivation mode is set to true in JBoss-web.xml and JBoss Cache passivation
+    * has been enabled with proper configured cache loader. Otherwise, it returns false
+    * 
+    * @return
+    */
+   protected boolean isPassivationEnabled()
+   {
+      return (passivationMode_ && proxy_.isCachePassivationEnabled());
+   }
    // ----------------------------------------------------  Lifecyle Unembedded
    
    /**

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheService.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheService.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheService.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -47,6 +47,7 @@
 import org.jboss.aspects.patterns.observable.Subject;
 import org.jboss.cache.CacheException;
 import org.jboss.cache.Fqn;
+import org.jboss.cache.aop.PojoCache;
 import org.jboss.cache.aop.PojoCacheMBean;
 import org.jboss.cache.transaction.BatchModeTransactionManager;
 import org.jboss.invocation.MarshalledValue;
@@ -127,28 +128,21 @@
          // Create Proxy-Object for this service
          proxy_ = (PojoCacheMBean) MBeanProxyExt.create(PojoCacheMBean.class,
                                                         cacheServiceName_);
+         if (proxy_ == null)
+         {
+            throw new RuntimeException("JBossCacheService: locate null TomcatCacheMbean");
+         }
+
+         cacheWrapper_ = new JBossCacheWrapper(proxy_);
+         
+         useTreeCacheMarshalling_ = proxy_.getUseRegionBasedMarshalling();
       }
-      catch (Exception e)
+      catch (Throwable e)
       {
-         String str = "Could not access TreeCache service " + 
-                      (cacheServiceName_ == null ? "<null>" : cacheServiceName_.toString()) + 
-                      " for Tomcat clustering";
-         log_.debug(str, e);
-         throw new ClusteringNotSupportedException(str, e);
-      }
-      
-      if (proxy_ == null)
-      {
-         String str = "Could not access TreeCache service " + 
-                     (cacheServiceName_ == null ? "<null>" : cacheServiceName_.toString()) + 
-                     " for Tomcat clustering";
-         log_.debug(str);
+         String str = cacheServiceName_ + " service to Tomcat clustering not found";
+         log_.error(str);
          throw new ClusteringNotSupportedException(str);
       }
-
-      cacheWrapper_ = new JBossCacheWrapper(proxy_);
-      
-      useTreeCacheMarshalling_ = proxy_.getUseRegionBasedMarshalling();
    }
 
    public void start(ClassLoader tcl, JBossCacheManager manager)
@@ -206,6 +200,15 @@
          throw new RuntimeException("JBossCacheService.start(): JBossCacheAop transaction manager is not type BatchModeTransactionManager." +
                  " Please check the tc6-cluster-service.xml TransactionManagerClassLookup field.");
       }
+      
+      if(isCachePassivationEnabled())
+      {
+         log_.info("JBossCacheService.start(): JBossCache passivation is enabled");
+      }
+      else
+      {
+         log_.info("JBossCacheService.start(): JBossCache passivation is disabled");
+      }
    }
 
    public void stop()
@@ -234,8 +237,7 @@
       }
 
       // remove session data
-      cacheWrapper_.evictSubtree(pathFqn);
-      
+      cacheWrapper_.removeLocalSubtree(pathFqn);
    }
 
    /**
@@ -365,7 +367,7 @@
       {
          log_.debug("Remove session from my own distributed store only. Fqn: " + fqn);
       }
-      cacheWrapper_.evictSubtree(fqn);
+      cacheWrapper_.removeLocalSubtree(fqn);
    }
 
    public void removeSessionLocal(String realId, String dataOwner)
@@ -381,9 +383,21 @@
          {
             log_.debug("Remove session from my own distributed store only. Fqn: " + fqn);
          }
-         cacheWrapper_.evictSubtree(fqn);
+         cacheWrapper_.removeLocalSubtree(fqn);
       }
    }
+   
+      
+   public void evictSession(String realId)
+   {
+      Fqn fqn = getSessionFqn(realId);
+      if(log_.isDebugEnabled())
+      {
+         log_.debug("evictSession(): evicting session from my distributed store");
+      }
+      cacheWrapper_.evictSubtree(fqn);
+      
+   }
 
    public boolean exists(String realId)
    {
@@ -442,7 +456,7 @@
       {
          log_.debug("Remove attributes from my own distributed store only. Fqn: " + fqn);
       }
-      cacheWrapper_.evict(fqn);
+      cacheWrapper_.removeLocal(fqn);
    }
 
    /**
@@ -605,7 +619,7 @@
       try {
          // Ignore any cache notifications that our own work generates 
          LocalSessionActivity.startLocalActivity(realId);
-         cacheWrapper_.evictSubtree(fqn);
+         cacheWrapper_.removeLocalSubtree(fqn);
       }
       finally {
          LocalSessionActivity.finishLocalActivity();
@@ -629,7 +643,7 @@
       try {
          // Ignore any cache notifications that our own work generates 
          LocalSessionActivity.startLocalActivity(realId);
-         cacheWrapper_.evictSubtree(fqn);
+         cacheWrapper_.removeLocalSubtree(fqn);
       }
       finally {
          LocalSessionActivity.finishLocalActivity();
@@ -911,7 +925,20 @@
       
       stack.pop();
    }
-
+ 
+   public boolean isCachePassivationEnabled()
+   {
+      if(proxy_.getCacheLoader() != null)
+      {
+         return (proxy_.getCacheLoaderPassivation() &&
+            !proxy_.getCacheLoaderShared());
+      }
+      else
+      {
+         return false;
+      }
+   }
+   
    private Fqn getFieldFqn(String id, String key)
    {
       // /SESSION/id/ATTR/key

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheWrapper.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheWrapper.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossCacheWrapper.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -207,6 +207,35 @@
       }
       throw new RuntimeException("JBossCacheService: exception occurred in cache remove after retry ... ", ex);
    }
+   
+   /**
+    * Wrapper to embed retry logic.
+    *
+    * @param fqn
+    */
+   void removeLocal(Fqn fqn)
+   {
+      Exception ex = null;
+      for (int i = 0; i < RETRY; i++)
+      {
+         try
+         {
+            Option localOverride = new Option();
+            localOverride.setCacheModeLocal(true);
+            proxy_.remove(fqn, localOverride);
+            return;
+         }
+         catch (TimeoutException e)
+         {
+            ex = e;
+         }
+         catch (Exception e)
+         {
+            throw new RuntimeException("JBossCacheService: exception occurred in cache removeLocal ... ", e);
+         }
+      }
+      throw new RuntimeException("JBossCacheService: exception occurred in cache removeLocal after retry ... ", ex);
+   }
 
    /**
     * Wrapper to embed retry logic.
@@ -236,8 +265,7 @@
    }
    
    void evictSubtree(Fqn fqn)
-   {
-      
+   {      
       Exception ex = null;
       for (int i = 0; i < RETRY; i++)
       {
@@ -272,9 +300,51 @@
             throw new RuntimeException("JBossCacheService: exception occurred in cache evict ... ", e);
          }
       }
-      throw new RuntimeException("JBossCacheService: exception occurred in cache evictSubtree after retry ... ", ex);
-      
-      
+      throw new RuntimeException("JBossCacheService: exception occurred in cache evictSubtree after retry ... ", ex);  
    }
+   
+   void removeLocalSubtree(Fqn fqn)
+   {
+      // First remove the node itself.  If it is the root of an AOP
+      // object tree, this will do everything
+      removeLocal(fqn);
 
+      // Next, clear any children      
+      Exception ex = null;
+      for (int i = 0; i < RETRY; i++)
+      {
+         try
+         {
+            // Evict the node itself first, since if it stores a Pojo
+            // that will do everything
+            removeLocal(fqn);
+            
+            // next do a depth first removal; this ensure all nodes
+            // are removed, not just their data map
+            Set children = proxy_.getChildrenNames(fqn);
+            if (children != null)
+            {
+               for (Iterator it = children.iterator(); it.hasNext(); )
+               {
+                  Fqn child = new Fqn(fqn, it.next());
+                  removeLocal(child);
+               }
+               
+               removeLocal(fqn);
+            }
+            return;
+            
+         }
+         catch (TimeoutException e)
+         {
+            ex = e;
+         }
+         catch (Exception e)
+         {
+            throw new RuntimeException("JBossCacheService: exception occurred in cache removeLocal ... ", e);
+         }
+      }
+      throw new RuntimeException("JBossCacheService: exception occurred in cache removeLocalSubtree after retry ... ", ex);
+   } 
+
 }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossManager.java	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/session/JBossManager.java	2006-08-21 16:49:34 UTC (rev 56126)
@@ -57,6 +57,7 @@
  * session operations, e.g., add, remove, etc.
  *
  * @author Ben Wang
+ * @author Hany Mesha
  * @version $Revision$
  */
 public abstract class JBossManager
@@ -81,7 +82,29 @@
     * Replication granulairty.
     */
    protected int replicationGranularity_ = WebMetaData.REPLICATION_GRANULARITY_SESSION;
+   
    /**
+    * Session passivation flag set in jboss-web.xml by the user.
+    * If true, then the session passivation is enabled for this web application, 
+    * otherwise, it's disabled
+    */
+   protected boolean passivationMode_ = false;
+   
+   /**
+    * Min time (seconds) the session must be idle since lastAccesstime before it's eligable for passivation
+    * This overrides maxActive_, to prevent thrashing if the there are lots of active sessions.
+    * Setting to -1 means it's ignored
+    */
+   protected int passivationMinIdleTime_ = -1;
+   
+   /**
+    * Max time (seconds) the session must be idle since lastAccesstime before it's eligable for passivation
+    * This overrides maxActive_, to prevent thrashing if the there are lots of active sessions.
+    * Setting to -1 means session should not be forced out.
+    */
+   protected int passivationMaxIdleTime_ = -1;
+   
+   /**
     * The lifecycle_ event support for this component.
     */
    protected LifecycleSupport lifecycle_ = new LifecycleSupport(this);
@@ -173,9 +196,18 @@
    {
       replicationGranularity_ = webMetaData.getReplicationGranularity();
       invalidateSessionPolicy_ = webMetaData.getInvalidateSessionPolicy();
+      maxActive_ = webMetaData.getMaxActiveSessionsAllowed();
+      passivationMode_ = webMetaData.getSessionPassivationMode();
+      if (passivationMode_)
+      {
+         passivationMinIdleTime_ = webMetaData.getSessionPassivationMinIdleTime();
+         passivationMaxIdleTime_ = webMetaData.getSessionPassivationMaxIdleTime();
+      }
       useLocalCache_ = useLocalCache;
       log_.info("init(): replicationGranularity_ is " + replicationGranularity_ +
-         " and invaldateSessionPolicy is " + invalidateSessionPolicy_);
+         " and invaldateSessionPolicy is " + invalidateSessionPolicy_ +
+         " and maxActiveSessions allowed is " + maxActive_ +
+         " and passivationMode is " + passivationMode_);
 
       try
       {

Modified: trunk/tomcat/src/resources/tc6-cluster-service.xml
===================================================================
--- trunk/tomcat/src/resources/tc6-cluster-service.xml	2006-08-21 16:48:04 UTC (rev 56125)
+++ trunk/tomcat/src/resources/tc6-cluster-service.xml	2006-08-21 16:49:34 UTC (rev 56126)
@@ -177,7 +177,25 @@
 
             </config>
         </attribute>
-		  
+
+		<!-- passivation store config using jboss cache 1.3 + -->
+ 
+        <attribute name="CacheLoaderConfiguration">
+            <config>
+                <passivation>true</passivation>
+                <preload>/</preload>
+                <shared>false</shared>
+                <cacheloader>
+                    <class>org.jboss.cache.loader.FileCacheLoader</class>
+                    <properties>
+                        location=/tmp
+                    </properties>
+                    <async>true</async>
+                    <fetchPersistentState>true</fetchPersistentState>
+                    <ignoreModifications>false</ignoreModifications>
+                </cacheloader>
+            </config>
+        </attribute>
     </mbean>
 
 </server>




More information about the jboss-cvs-commits mailing list