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

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed May 26 12:03:52 EDT 2010


Author: pferraro
Date: 2010-05-26 12:03:50 -0400 (Wed, 26 May 2010)
New Revision: 105263

Modified:
   trunk/component-matrix/pom.xml
   trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/web/test/CleanShutdownTestCase.java
   trunk/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManager.java
   trunk/testsuite/src/resources/cluster/http/sleep.jsp
   trunk/tomcat/src/main/java/org/jboss/web/tomcat/service/session/JBossCacheManager.java
   trunk/tomcat/src/main/java/org/jboss/web/tomcat/service/session/persistent/PersistentStoreDistributedCacheManager.java
Log:
[JBAS-7859] Toggle web session replication to synchronous during server shutdown.
Upgrade jboss-ha-server-cache-spi to 2.2.0.Final, jboss-ha-server-cache-jbc to 2.3.0.Final.

Modified: trunk/component-matrix/pom.xml
===================================================================
--- trunk/component-matrix/pom.xml	2010-05-26 15:48:20 UTC (rev 105262)
+++ trunk/component-matrix/pom.xml	2010-05-26 16:03:50 UTC (rev 105263)
@@ -80,7 +80,7 @@
     <version.ops4j.pax.web>0.7.2</version.ops4j.pax.web>
     <version.org.hibernate>3.5.2-Final</version.org.hibernate>
     <version.org.hibernate.commons.annotations>3.2.0.Final</version.org.hibernate.commons.annotations>
-<version.org.hibernate.entity.manager>${version.org.hibernate}</version.org.hibernate.entity.manager>
+    <version.org.hibernate.entity.manager>${version.org.hibernate}</version.org.hibernate.entity.manager>
     <version.org.hibernate.javax.persistence>1.0.0.Final</version.org.hibernate.javax.persistence>
     <version.org.hibernate.validator>4.0.2.GA</version.org.hibernate.validator>
     <version.org.jboss.aop>2.2.0.Final</version.org.jboss.aop>
@@ -93,8 +93,8 @@
     <version.org.jboss.cache.pojo>3.0.0.GA</version.org.jboss.cache.pojo>
     <version.org.jboss.cl>2.2.0.Alpha4</version.org.jboss.cl>
     <version.org.jboss.classpool>1.0.0.Alpha5</version.org.jboss.classpool>
-    <version.org.jboss.cluster.cache.jbc>2.2.2.Final</version.org.jboss.cluster.cache.jbc>
-    <version.org.jboss.cluster.cache.spi>2.1.0.Final</version.org.jboss.cluster.cache.spi>
+    <version.org.jboss.cluster.cache.jbc>2.3.0.Final</version.org.jboss.cluster.cache.jbc>
+    <version.org.jboss.cluster.cache.spi>2.2.0.Final</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>2.0.0.Alpha3</version.org.jboss.cluster.server.api>
     <version.org.jboss.common.core>2.2.17.GA</version.org.jboss.common.core>
@@ -154,7 +154,7 @@
     <version.staxex>2.1.1</version.staxex>
     <version.streambuffer>1.0</version.streambuffer>
     <version.org.jboss.spec.javaee>1.0.0.Beta1</version.org.jboss.spec.javaee>
-	<version.spec.javaee.ejb.api>1.0.0.Beta2</version.spec.javaee.ejb.api>
+    <version.spec.javaee.ejb.api>1.0.0.Beta2</version.spec.javaee.ejb.api>
     <version.sun.jaxb>2.2</version.sun.jaxb>
     <version.sun-jaxws>2.2</version.sun-jaxws>
     <version.sun-policy>2.0-b01</version.sun-policy>

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/web/test/CleanShutdownTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/web/test/CleanShutdownTestCase.java	2010-05-26 15:48:20 UTC (rev 105262)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/web/test/CleanShutdownTestCase.java	2010-05-26 16:03:50 UTC (rev 105263)
@@ -27,13 +27,13 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 
-import javax.management.MBeanServerConnection;
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
 import junit.framework.Assert;
 import junit.framework.Test;
 
+import org.apache.commons.httpclient.Cookie;
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
 import org.apache.commons.httpclient.methods.GetMethod;
@@ -50,15 +50,15 @@
    private static final String SERVER_NAME = "jboss.web.deployment:war=/http-sr";
    private static final String SHUTDOWN_METHOD = "stop";
    private static final String URL = "%s/http-sr/sleep.jsp?sleep=%d";
+   private static final String COOKIE_NAME = "sleep";
    private static final int MAX_THREADS = 2;
    private static final int REQUEST_DURATION = 10000;
    
    ObjectName name;
-   MBeanServerConnection server;
    HttpClient client;
-   String baseURL;
    
    private MultiThreadedHttpConnectionManager manager;
+   private ExecutorService executor;
    
    public static Test suite() throws Exception
    {
@@ -85,8 +85,6 @@
       super.setUp();
       
       this.name = ObjectName.getInstance(SERVER_NAME);
-      this.server = this.getAdaptors()[0];
-      this.baseURL = this.getHttpURLs()[0];
 
       this.manager = new MultiThreadedHttpConnectionManager();
       
@@ -97,6 +95,7 @@
       this.manager.setParams(params);
 
       this.client = new HttpClient();
+      this.executor = Executors.newFixedThreadPool(MAX_THREADS);
    }
 
    /**
@@ -106,6 +105,7 @@
    protected void tearDown() throws Exception
    {
       this.manager.shutdown();
+      this.executor.shutdownNow();
       
       try
       {
@@ -119,60 +119,95 @@
 
    public void testShutdown() throws Exception
    {
-      ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS);
+      // Make sure a normal request will succeed
+      Assert.assertEquals(200, new RequestTask(0, 0).call().intValue());
       
+      Assert.assertNull(this.findCookie(0, COOKIE_NAME));
+      
+      // Send a long request - in parallel
+      Future<Integer> future = executor.submit(new RequestTask(0, REQUEST_DURATION));
+
+      // Make sure long request has started
+      Thread.sleep(1000);
+
+      // Shutdown server
+      this.getAdaptors()[0].invoke(this.name, SHUTDOWN_METHOD, null, null);
+
+      // Get result of long request
+      // This request should succeed since it initiated before server shutdown
       try
       {
-         // Make sure a normal request will succeed
-         Assert.assertEquals(200, new RequestTask(0).call().intValue());
+         Assert.assertEquals(200, future.get().intValue());
+      }
+      catch (ExecutionException e)
+      {
+         e.printStackTrace(System.err);
          
-         // Send a long request - in parallel
-         Future<Integer> future = executor.submit(new RequestTask(REQUEST_DURATION));
-
-         // Make sure long request has started
-         Thread.sleep(1000);
-
-         // Shutdown server
-         this.server.invoke(this.name, SHUTDOWN_METHOD, null, null);
-
-         // Get result of long request
-         // This request should succeed since it initiated before server shutdown
-         try
+         Assert.fail(e.getCause().getMessage());
+      }
+      
+      Cookie cookie = this.findCookie(0, COOKIE_NAME);
+      Assert.assertNotNull(cookie);
+      Assert.assertEquals("0", cookie.getValue());
+      
+      // Subsequent request should return 404
+      Assert.assertEquals(404, new RequestTask(0, 0).call().intValue());
+      
+      // Copy cookies from server[0] to server[1]
+      for (Cookie c: this.client.getState().getCookies())
+      {
+         if (c.getDomain().equals(this.getServers()[0]) && c.getName().equals("JSESSIONID"))
          {
-            Assert.assertEquals(200, future.get().intValue());
+            this.client.getState().addCookie(new Cookie(this.getServers()[1], c.getName(), c.getValue(), c.getPath(), c.getExpiryDate(), c.getSecure()));
          }
-         catch (ExecutionException e)
+      }
+      
+      Assert.assertEquals(200, new RequestTask(1, 0).call().intValue());
+      
+      // If old session had replicated successfully, cookie value should equal old sleep duration
+      cookie = this.findCookie(1, COOKIE_NAME);
+      Assert.assertNotNull(cookie);
+      Assert.assertEquals(String.valueOf(REQUEST_DURATION), cookie.getValue());
+   }
+   
+   private Cookie findCookie(int serverIndex, String name) throws Exception
+   {
+      String domain = this.getServers()[serverIndex];
+      
+      for (Cookie cookie: this.client.getState().getCookies())
+      {
+         if (cookie.getDomain().equalsIgnoreCase(domain) && cookie.getName().equals(name))
          {
-            e.printStackTrace(System.err);
-            
-            Assert.fail(e.getCause().getMessage());
+            return cookie;
          }
-         
-         // Subsequent request should return 404
-         Assert.assertEquals(404, new RequestTask(0).call().intValue());
       }
-      finally
-      {
-         executor.shutdownNow();
-      }
+      
+      return null;
    }
    
    private class RequestTask implements Callable<Integer>
    {
+      private final int server;
       private final int sleep;
       
-      RequestTask(int sleep)
+      RequestTask(int server, int sleep)
       {
+         this.server = server;
          this.sleep = sleep;
       }
       
       public Integer call() throws Exception
       {
-         GetMethod method = new GetMethod(String.format(URL, CleanShutdownTestCase.this.baseURL, this.sleep));
+         GetMethod method = new GetMethod(String.format(URL, CleanShutdownTestCase.this.getHttpURLs()[this.server], this.sleep));
          
          try
          {
-            return CleanShutdownTestCase.this.client.executeMethod(method);
+            int response = CleanShutdownTestCase.this.client.executeMethod(method);
+            for (Cookie cookie: CleanShutdownTestCase.this.client.getState().getCookies())
+            {
+               System.out.println(cookie.getDomain() + "\t" + cookie.getName() + "\t" + cookie.getPath() + "\t" + cookie.getValue());
+            }
+            return response;
          }
          finally
          {

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManager.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManager.java	2010-05-26 15:48:20 UTC (rev 105262)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManager.java	2010-05-26 16:03:50 UTC (rev 105263)
@@ -162,6 +162,11 @@
       // no-op      
    }
    
+   public void setForceSynchronous(boolean forceSynchronous)
+   {
+      // no-op
+   }
+
    private static class MockBatchingManager implements BatchingManager
    {
       private static final MockBatchingManager INSTANCE = new MockBatchingManager();

Modified: trunk/testsuite/src/resources/cluster/http/sleep.jsp
===================================================================
--- trunk/testsuite/src/resources/cluster/http/sleep.jsp	2010-05-26 15:48:20 UTC (rev 105262)
+++ trunk/testsuite/src/resources/cluster/http/sleep.jsp	2010-05-26 16:03:50 UTC (rev 105263)
@@ -10,6 +10,11 @@
          Thread.sleep(ms);
       }
       
+      String value = (String) session.getAttribute("sleep");
       session.setAttribute("sleep", sleep);
+      if (value != null)
+      {
+         response.addCookie(new javax.servlet.http.Cookie("sleep", value));
+      }
    }
 %>
\ No newline at end of file

Modified: trunk/tomcat/src/main/java/org/jboss/web/tomcat/service/session/JBossCacheManager.java
===================================================================
--- trunk/tomcat/src/main/java/org/jboss/web/tomcat/service/session/JBossCacheManager.java	2010-05-26 15:48:20 UTC (rev 105262)
+++ trunk/tomcat/src/main/java/org/jboss/web/tomcat/service/session/JBossCacheManager.java	2010-05-26 16:03:50 UTC (rev 105263)
@@ -38,11 +38,18 @@
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 
+import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.NotificationListener;
 import javax.management.ObjectName;
 
+import org.apache.catalina.Container;
 import org.apache.catalina.Context;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
 import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleListener;
 import org.apache.catalina.Session;
 import org.apache.catalina.Valve;
 import org.apache.catalina.core.ContainerBase;
@@ -53,6 +60,8 @@
 import org.jboss.metadata.web.jboss.ReplicationTrigger;
 import org.jboss.metadata.web.jboss.SnapshotMode;
 import org.jboss.util.loading.ContextClassLoaderSwitcher;
+import org.jboss.web.tomcat.service.deployers.TomcatDeployer;
+import org.jboss.web.tomcat.service.deployers.TomcatDeployerMBean;
 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.DistributableSessionMetadata;
@@ -80,7 +89,7 @@
  */
 public class JBossCacheManager<O extends OutgoingDistributableSessionData>
    extends JBossManager
-   implements JBossCacheManagerMBean, LocalDistributableSessionManager, ClusteredManager<O>
+   implements JBossCacheManagerMBean, LocalDistributableSessionManager, ClusteredManager<O>, NotificationListener, LifecycleListener
 {
    // --------------------------------------------------------------- Constants
    
@@ -808,6 +817,42 @@
          startUnembedded();
       }
       
+      Container container = this.getContainer();
+      if (container instanceof Lifecycle)
+      {
+         Lifecycle lifecycle = (Lifecycle) container;
+         LifecycleListener[] listeners = lifecycle.findLifecycleListeners();
+         
+         // Remove existing listeners
+         for (LifecycleListener listener: listeners)
+         {
+            lifecycle.removeLifecycleListener(listener);
+         }
+         
+         // Register our listener first
+         lifecycle.addLifecycleListener(this);
+         
+         // Re-register the old listeners
+         for (LifecycleListener listener: listeners)
+         {
+            lifecycle.addLifecycleListener(listener);
+         }
+      }
+
+      try
+      {
+         MBeanServer server = this.getMBeanServer();
+         
+         if (server.isRegistered(TomcatDeployer.TOMCAT_SERVICE_NAME))
+         {
+            server.addNotificationListener(TomcatDeployer.TOMCAT_SERVICE_NAME, this, null, null);
+         }
+      }
+      catch (Exception e)
+      {
+         throw new LifecycleException(e);
+      }
+      
       // Handle re-entrance
       if (!this.semaphore.tryAcquire())
       {
@@ -857,6 +902,26 @@
          }
       }
       
+      Container container = this.getContainer();
+      if (container instanceof Lifecycle)
+      {
+         ((Lifecycle) container).removeLifecycleListener(this);
+      }
+
+      try
+      {
+         MBeanServer server = this.getMBeanServer();
+         
+         if (server.isRegistered(TomcatDeployer.TOMCAT_SERVICE_NAME))
+         {
+            server.removeNotificationListener(TomcatDeployer.TOMCAT_SERVICE_NAME, this);
+         }
+      }
+      catch (Exception e)
+      {
+         throw new LifecycleException(e);
+      }
+      
       // Handle re-entrance
       if (this.semaphore.tryAcquire())
       {
@@ -2677,8 +2742,55 @@
       return (ClusteredSession) session;
    }
    
+   /**
+    * {@inheritDoc}
+    * @see org.apache.catalina.LifecycleListener#lifecycleEvent(org.apache.catalina.LifecycleEvent)
+    */
+   @Override
+   public void lifecycleEvent(LifecycleEvent event)
+   {
+      // Force synchronous replication upon initiating undeploy
+      // to ensure sessions get replicated prior to stopping context
+      this.handleForceSynchronousNotification(event.getType(), Lifecycle.BEFORE_STOP_EVENT, Lifecycle.AFTER_STOP_EVENT);
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see javax.management.NotificationListener#handleNotification(javax.management.Notification, java.lang.Object)
+    */
+   @Override
+   public void handleNotification(Notification notification, Object callback)
+   {
+      // Force synchronous replication during initial stages of AS shutdown, prior to stopping connectors
+      this.handleForceSynchronousNotification(notification.getType(), TomcatDeployerMBean.TOMCAT_CONNECTORS_STOPPED, TomcatDeployerMBean.TOMCAT_CONNECTORS_STARTED);
+   }
+
+   private void handleForceSynchronousNotification(String type, String enableType, String disableType)
+   {
+      boolean enabled = type.equals(enableType);
+      
+      if (enabled || type.equals(disableType))
+      {
+         if (this.proxy_ != null)
+         {
+            this.proxy_.setForceSynchronous(enabled);
+         }
+      }
+   }
+   
+   /**
+    * {@inheritDoc}
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode()
+   {
+      // Hack to nudge us to the front of the notification order
+      return 0;
+   }
+   
    // ------------------------------------------------------------ Inner Classes
-   
+
    private class PassivationCheck implements Comparable<PassivationCheck>
    {
       private final String realId;

Modified: trunk/tomcat/src/main/java/org/jboss/web/tomcat/service/session/persistent/PersistentStoreDistributedCacheManager.java
===================================================================
--- trunk/tomcat/src/main/java/org/jboss/web/tomcat/service/session/persistent/PersistentStoreDistributedCacheManager.java	2010-05-26 15:48:20 UTC (rev 105262)
+++ trunk/tomcat/src/main/java/org/jboss/web/tomcat/service/session/persistent/PersistentStoreDistributedCacheManager.java	2010-05-26 16:03:50 UTC (rev 105263)
@@ -195,6 +195,12 @@
             "with ReplicationGranularity " + ReplicationGranularity.SESSION);
    }
    
+   @Override
+   public void setForceSynchronous(boolean forceSynchronous)
+   {
+      // Do nothing
+   }
+
    public static class NoOpBatchingManager implements BatchingManager
    {
       public boolean isBatchInProgress() throws Exception




More information about the jboss-cvs-commits mailing list