[jboss-cvs] JBossAS SVN: r100315 - in branches/JBPAPP_5_0: testsuite/src/main/org/jboss/test/cluster/testutil and 3 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Feb 2 23:12:57 EST 2010
Author: dereed
Date: 2010-02-02 23:12:56 -0500 (Tue, 02 Feb 2010)
New Revision: 100315
Added:
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/ClusteredSessionUnitTestCase.java
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/ConcurrentFailoverRequestsTestCase.java
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/testutil/JBossCacheUtil.java
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/ConcurrentRequestHandler.java
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockClusteredManager.java
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManager.java
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManagerFactory.java
Removed:
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockDistributedCacheManager.java
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockJBossManager.java
Modified:
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/JvmRouteValveUnitTestCase.java
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/testutil/SessionTestUtil.java
branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockSession.java
branches/JBPAPP_5_0/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSession.java
branches/JBPAPP_5_0/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java
Log:
[JBPAPP-2929] Port JBAS-7379 to EAP 5.0.1
Added: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/ClusteredSessionUnitTestCase.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/ClusteredSessionUnitTestCase.java (rev 0)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/ClusteredSessionUnitTestCase.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -0,0 +1,88 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009 Red Hat Middleware, Inc. 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.test.cluster.defaultcfg.simpleweb.test;
+
+import junit.framework.TestCase;
+
+import org.jboss.metadata.web.jboss.ReplicationGranularity;
+import org.jboss.test.cluster.testutil.JGroupsSystemPropertySupport;
+import org.jboss.test.cluster.testutil.SessionTestUtil;
+import org.jboss.test.cluster.web.mocks.MockDistributedCacheManagerFactory;
+import org.jboss.web.tomcat.service.session.ClusteredSession;
+import org.jboss.web.tomcat.service.session.JBossCacheManager;
+
+/**
+ * Unit tests of {@link ClusteredSession}.
+ *
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public class ClusteredSessionUnitTestCase extends TestCase
+{
+ /**
+ * Create a new ClusteredSessionUnitTestCase.
+ *
+ * @param name
+ */
+ public ClusteredSessionUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Validates the behavior of isOutdated() with respect to returning
+ * true until a creation time is set.
+ * <p>
+ * Note: the use of creation time is a convenience; it's just a field that
+ * isn't set at construction but rather after the session is either loaded
+ * from the distributed cache or is added as a brand new session.
+ *
+ * @throws Exception
+ */
+ public void testNewSessionIsOutdated() throws Exception
+ {
+ JBossCacheManager mgr = new JBossCacheManager(new MockDistributedCacheManagerFactory());
+ SessionTestUtil.setupContainer("test", null, mgr);
+ mgr.start();
+
+ mgr.setReplicationGranularity(ReplicationGranularity.SESSION);
+ ClusteredSession sess = (ClusteredSession) mgr.createEmptySession();
+ assertTrue(sess.isOutdated());
+ sess.setCreationTime(System.currentTimeMillis());
+ assertFalse(sess.isOutdated());
+
+ mgr.setReplicationGranularity(ReplicationGranularity.ATTRIBUTE);
+ sess = (ClusteredSession) mgr.createEmptySession();
+ assertTrue(sess.isOutdated());
+ sess.setCreationTime(System.currentTimeMillis());
+ assertFalse(sess.isOutdated());
+
+ mgr.setReplicationGranularity(ReplicationGranularity.FIELD);
+ sess = (ClusteredSession) mgr.createEmptySession();
+ assertTrue(sess.isOutdated());
+ sess.setCreationTime(System.currentTimeMillis());
+ assertFalse(sess.isOutdated());
+ }
+
+}
Added: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/ConcurrentFailoverRequestsTestCase.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/ConcurrentFailoverRequestsTestCase.java (rev 0)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/ConcurrentFailoverRequestsTestCase.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -0,0 +1,279 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009 Red Hat, Inc. 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.test.cluster.defaultcfg.simpleweb.test;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.TestCase;
+
+import org.apache.catalina.Manager;
+import org.apache.catalina.Session;
+import org.apache.catalina.Valve;
+import org.apache.catalina.connector.Request;
+import org.jboss.cache.Cache;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.pojo.PojoCache;
+import org.jboss.logging.Logger;
+import org.jboss.metadata.web.jboss.JBossWebMetaData;
+import org.jboss.test.cluster.testutil.JBossCacheUtil;
+import org.jboss.test.cluster.testutil.JGroupsSystemPropertySupport;
+import org.jboss.test.cluster.testutil.SessionTestUtil;
+import org.jboss.test.cluster.web.mocks.BasicRequestHandler;
+import org.jboss.test.cluster.web.mocks.ConcurrentRequestHandler;
+import org.jboss.test.cluster.web.mocks.SetAttributesRequestHandler;
+import org.jboss.web.tomcat.service.session.JBossCacheManager;
+
+/**
+ * JBAS-7379. Tests that multiple concurrent failover requests for
+ * the same session are handled properly.
+ *
+ * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
+ * @version $Revision: 85945 $
+ */
+public class ConcurrentFailoverRequestsTestCase extends TestCase
+{
+ private static final Logger log = Logger.getLogger(ConcurrentFailoverRequestsTestCase.class);
+
+ private static long testCount = System.currentTimeMillis();
+
+ private final JGroupsSystemPropertySupport jgSupport = new JGroupsSystemPropertySupport();
+ private Set<PojoCache> caches = new HashSet<PojoCache>();
+
+ private ExecutorService threadPool;
+
+ /**
+ * Create a new ConcurrentFailoverRequestsTestCase.
+ *
+ * @param name
+ */
+ public ConcurrentFailoverRequestsTestCase(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ jgSupport.setUpProperties();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ jgSupport.restoreProperties();
+
+ if (threadPool != null)
+ {
+ threadPool.shutdownNow();
+ }
+
+ SessionTestUtil.clearDistributedCacheManagerFactory();
+
+ for (PojoCache cache : caches)
+ {
+ // Try to clean up so we avoid loading sessions
+ // from storage in later tests
+ try
+ {
+ log.info("Removing /JSESSION from " + cache.getCache().getLocalAddress());
+ cache.getCache().removeNode(Fqn.fromString("/JSESSION"));
+ }
+ catch (Exception e)
+ {
+ log.error("Cache " + cache.getCache().getLocalAddress() + ": " + e.getMessage(), e);
+ }
+
+ try
+ {
+ cache.stop();
+ cache.destroy();
+ }
+ catch (Exception e)
+ {
+ log.error("Cache " + cache.getCache().getLocalAddress() + ": " + e.getMessage(), e);
+ }
+
+ }
+
+ caches.clear();
+ }
+ }
+
+ public void testConcurrentFailoverRequests() throws Exception
+ {
+ ++testCount;
+
+ JBossWebMetaData webMetaData = SessionTestUtil.createWebMetaData(100);
+ String warName = "test" + testCount;
+ JBossCacheManager jbcm0 = SessionTestUtil.createManager(warName, 30, false, null, false, false, null, caches);
+ jbcm0.init(warName, webMetaData);
+ jbcm0.start();
+
+ JBossCacheManager jbcm1 = SessionTestUtil.createManager(warName, 30, false, null, false, false, null, caches);
+ jbcm1.init(warName, webMetaData);
+ jbcm1.start();
+
+ Cache[] array = new Cache[caches.size()];
+ int index = 0;
+ for (PojoCache c : caches)
+ {
+ array[index] = c.getCache();
+ index++;
+ }
+ JBossCacheUtil.blockUntilViewsReceived(array, 10000);
+
+ Object value = "0";
+ Map<String, Object> attrs = Collections.unmodifiableMap(Collections.singletonMap("count", value));
+ SetAttributesRequestHandler setHandler = new SetAttributesRequestHandler(attrs, false);
+ SessionTestUtil.invokeRequest(jbcm0, setHandler, null);
+
+ String id1 = setHandler.getSessionId();
+ assertNotNull(id1);
+
+ // Add a second session that we can check for replication; this is a proxy
+ // for checking that first session has replicated
+ setHandler = new SetAttributesRequestHandler(attrs, false);
+ SessionTestUtil.invokeRequest(jbcm0, setHandler, null);
+
+ String id2 = setHandler.getSessionId();
+ assertNotNull(id1);
+
+ assertFalse(id1.equals(id2));
+
+ // Ensure replication of session 2 has occurred
+ boolean found = false;
+ for (int i = 0; i < 10; i++)
+ {
+ BasicRequestHandler getHandler = new BasicRequestHandler(attrs.keySet(), false);
+ SessionTestUtil.invokeRequest(jbcm1, getHandler, id2);
+ if (getHandler.getCheckedAttributes() != null && value.equals(getHandler.getCheckedAttributes().get("count")))
+ {
+ found = true;
+ break;
+ }
+ Thread.sleep(50);
+ }
+ assertTrue("sessions replicated", found);
+
+ jbcm0.stop();
+
+ int THREADS = 10;
+ threadPool = Executors.newFixedThreadPool(THREADS);
+
+ CountDownLatch startingGun = new CountDownLatch(THREADS + 1);
+ CountDownLatch finishedSignal = new CountDownLatch(THREADS);
+ ConcurrentRequestHandler concurrentHandler = new ConcurrentRequestHandler();
+ Valve pipelineHead = SessionTestUtil.setupPipeline(jbcm1, concurrentHandler);
+ Loader[] loaders = new Loader[THREADS];
+
+ for (int i = 0; i < loaders.length; i++)
+ {
+ loaders[i] = new Loader(pipelineHead, concurrentHandler, jbcm1, id1, attrs.keySet(), startingGun, finishedSignal);
+ threadPool.execute(loaders[i]);
+ }
+
+ startingGun.countDown();
+
+ assertTrue("loaders completed on time", finishedSignal.await(45, TimeUnit.SECONDS));
+
+ for (int i = 0; i < loaders.length; i++)
+ {
+ assertNotNull("got checked attributes for " + i, loaders[i].checkedAttributes);
+ assertTrue("checked 'count' attribute for " + i, loaders[i].checkedAttributes.containsKey("count"));
+ assertEquals("correct value for " + i, value, loaders[i].checkedAttributes.get("count"));
+ }
+ }
+
+ private static class Loader implements Runnable
+ {
+ private final Valve pipelineHead;
+ private final ConcurrentRequestHandler concurrentHandler;
+ private final Manager manager;
+ private final String sessionId;
+ private final Set<String> attributeKeys;
+ private final CountDownLatch startingGun;
+ private final CountDownLatch finishedSignal;
+
+ private Map<String, Object> checkedAttributes;
+
+ private Loader(Valve pipelineHead, ConcurrentRequestHandler concurrentHandler,
+ Manager manager, String sessionId, Set<String> attributeKeys,
+ CountDownLatch startingGun, CountDownLatch finishedSignal)
+ {
+ this.pipelineHead = pipelineHead;
+ this.concurrentHandler = concurrentHandler;
+ this.manager = manager;
+ this.sessionId = sessionId;
+ this.attributeKeys = attributeKeys;
+ this.startingGun = startingGun;
+ this.finishedSignal = finishedSignal;
+ }
+
+ public void run()
+ {
+ try
+ {
+ BasicRequestHandler getHandler = new BasicRequestHandler(attributeKeys, false);
+ concurrentHandler.registerHandler(getHandler);
+ Request request = SessionTestUtil.setupRequest(manager, sessionId);
+ startingGun.countDown();
+ startingGun.await();
+ System.out.println("started");
+
+ SessionTestUtil.invokeRequest(pipelineHead, request);
+ this.checkedAttributes = getHandler.getCheckedAttributes();
+ if (this.checkedAttributes != null)
+ {
+ System.out.println(this.checkedAttributes.keySet());
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.out);
+ }
+ finally
+ {
+ finishedSignal.countDown();
+
+ concurrentHandler.unregisterHandler();
+ }
+
+ }
+
+ }
+}
Modified: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/JvmRouteValveUnitTestCase.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/JvmRouteValveUnitTestCase.java 2010-02-03 02:29:36 UTC (rev 100314)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/JvmRouteValveUnitTestCase.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -27,8 +27,8 @@
import org.apache.catalina.Session;
import org.apache.catalina.connector.Response;
import org.jboss.logging.Logger;
-import org.jboss.test.cluster.web.jvmroute.MockJBossManager;
import org.jboss.test.cluster.web.jvmroute.MockRequest;
+import org.jboss.test.cluster.web.mocks.MockClusteredManager;
import org.jboss.test.cluster.web.mocks.MockValve;
import org.jboss.web.tomcat.service.session.JvmRouteValve;
@@ -64,7 +64,7 @@
{
log.info("Enter testNonFailover");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -92,7 +92,7 @@
{
log.info("Enter testFailover");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -121,7 +121,7 @@
{
log.info("Enter testFailoverFromURL");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -150,7 +150,7 @@
{
log.info("Enter testFailoverMismatchBadReq");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -178,7 +178,7 @@
{
log.info("Enter testFailoverMismatchBadReqFromURL");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -207,7 +207,7 @@
{
log.info("Enter testFailoverMismatchBadSession");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -235,7 +235,7 @@
{
log.info("Enter testFailoverMismatchBadSessionFromURL");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -264,7 +264,7 @@
{
log.info("Enter testNoSession");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -290,7 +290,7 @@
{
log.info("Enter testNoSessionFromURL");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -317,7 +317,7 @@
{
log.info("Enter testFailoverNoSession");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -344,7 +344,7 @@
{
log.info("Enter testNoSessionNoRequestedSession");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -370,7 +370,7 @@
{
log.info("Enter testSessionNoRequestedSession");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -397,7 +397,7 @@
{
log.info("Enter testSessionNoRequestedSessionFromURL");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -425,7 +425,7 @@
{
log.info("Enter testFailoverSessionNoRequestedSession");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -452,7 +452,7 @@
{
log.info("Enter testFailoverSessionNoRequestedSessionFromURL");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -480,7 +480,7 @@
{
log.info("Enter testNoJvmRouteSession");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -508,7 +508,7 @@
{
log.info("Enter testNoJvmRouteSessionFromURL");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -537,7 +537,7 @@
{
log.info("Enter testNoJvmRouteRequest");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -565,7 +565,7 @@
{
log.info("Enter testNoJvmRouteRequest");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
@@ -594,7 +594,7 @@
{
log.info("Enter testJvmRouteIncludesDomain");
- MockJBossManager mgr = new MockJBossManager();
+ MockClusteredManager mgr = new MockClusteredManager();
mgr.setJvmRoute(DOMAIN_JVM_ROUTE);
JvmRouteValve jvmRouteValve = new JvmRouteValve(mgr);
Added: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/testutil/JBossCacheUtil.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/testutil/JBossCacheUtil.java (rev 0)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/testutil/JBossCacheUtil.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -0,0 +1,175 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009 Red Hat, Inc. 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.test.cluster.testutil;
+
+import java.util.List;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheSPI;
+
+/**
+ * Utilities related to dealing with JBoss Cache.
+ *
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public class JBossCacheUtil
+{
+
+ /**
+ * Loops, continually calling {@link #areCacheViewsComplete(org.jboss.cache.Cache[])}
+ * until it either returns true or <code>timeout</code> ms have elapsed.
+ *
+ * @param caches caches which must all have consistent views
+ * @param timeout max number of ms to loop
+ * @throws RuntimeException if <code>timeout</code> ms have elapse without
+ * all caches having the same number of members.
+ */
+ public static void blockUntilViewsReceived(Cache[] caches, long timeout)
+ {
+ long failTime = System.currentTimeMillis() + timeout;
+
+ while (System.currentTimeMillis() < failTime)
+ {
+ sleepThread(100);
+ if (areCacheViewsComplete(caches))
+ {
+ return;
+ }
+ }
+
+ throw new RuntimeException("timed out before caches had complete views" + views(caches));
+ }
+
+ /**
+ * Checks each cache to see if the number of elements in the array
+ * returned by {@link CacheSPI#getMembers()} matches the size of
+ * the <code>caches</code> parameter.
+ *
+ * @param caches caches that should form a View
+ * @return <code>true</code> if all caches have
+ * <code>caches.length</code> members; false otherwise
+ * @throws IllegalStateException if any of the caches have MORE view
+ * members than caches.length
+ */
+ public static boolean areCacheViewsComplete(Cache[] caches)
+ {
+ return areCacheViewsComplete(caches, true);
+ }
+
+ public static boolean areCacheViewsComplete(Cache[] caches, boolean barfIfTooManyMembers)
+ {
+ int memberCount = caches.length;
+
+ for (int i = 0; i < memberCount; i++)
+ {
+ if (!isCacheViewComplete(caches[i], memberCount, barfIfTooManyMembers))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean isCacheViewComplete(Cache c, int memberCount)
+ {
+ return isCacheViewComplete(c, memberCount, true);
+ }
+
+ public static boolean isCacheViewComplete(Cache cache, int memberCount, boolean barfIfTooManyMembers)
+ {
+ List members = cache.getMembers();
+ if (members == null || memberCount > members.size())
+ {
+ return false;
+ }
+ else if (memberCount < members.size())
+ {
+ if (barfIfTooManyMembers)
+ {
+ // This is an exceptional condition
+ StringBuilder sb = new StringBuilder("Cache at address ");
+ sb.append(cache.getLocalAddress());
+ sb.append(" had ");
+ sb.append(members.size());
+ sb.append(" members; expecting ");
+ sb.append(memberCount);
+ sb.append(". Members were (");
+ for (int j = 0; j < members.size(); j++)
+ {
+ if (j > 0)
+ {
+ sb.append(", ");
+ }
+ sb.append(members.get(j));
+ }
+ sb.append(')');
+
+ throw new IllegalStateException(sb.toString());
+ }
+ else return false;
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Puts the current thread to sleep for the desired number of ms, suppressing
+ * any exceptions.
+ *
+ * @param sleeptime number of ms to sleep
+ */
+ public static void sleepThread(long sleeptime)
+ {
+ try
+ {
+ Thread.sleep(sleeptime);
+ }
+ catch (InterruptedException ie)
+ {
+ }
+ }
+
+ private static String views(Cache... caches)
+ {
+ StringBuilder builder = new StringBuilder("[\n");
+ for (Cache c:caches)
+ {
+ builder.append(" ").append(c.getLocalAddress()).append("->").append(c.getMembers()).append("\n");
+ }
+ builder.append("]");
+ return builder.toString();
+ }
+
+ /**
+ * Prevent instantiation
+ */
+ private JBossCacheUtil()
+ {
+ // TODO Auto-generated constructor stub
+ }
+
+}
Modified: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/testutil/SessionTestUtil.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/testutil/SessionTestUtil.java 2010-02-03 02:29:36 UTC (rev 100314)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/testutil/SessionTestUtil.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -34,6 +34,7 @@
import org.apache.catalina.Manager;
import org.apache.catalina.Pipeline;
import org.apache.catalina.Valve;
+import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.core.StandardContext;
import org.apache.commons.httpclient.Cookie;
@@ -92,11 +93,22 @@
e.printStackTrace();
}
}
+
public static JBossCacheManager createManager(String warName, int maxInactiveInterval,
boolean local, String passivationDir,
boolean totalReplication, boolean marshalling,
String jvmRoute, Set<PojoCache> allCaches)
{
+ return createManager(warName, maxInactiveInterval, local, passivationDir,
+ totalReplication, marshalling, false, jvmRoute, allCaches);
+ }
+
+ public static JBossCacheManager createManager(String warName, int maxInactiveInterval,
+ boolean local, String passivationDir,
+ boolean totalReplication, boolean marshalling,
+ boolean purgeCacheLoader,
+ String jvmRoute, Set<PojoCache> allCaches)
+ {
PojoCache cache = createCache(local, passivationDir, totalReplication, marshalling, allCaches);
return createManager(warName, maxInactiveInterval, cache, jvmRoute);
}
@@ -113,15 +125,7 @@
JBossCacheManager jbcm = new JBossCacheManager(distributedManagerFactory);
jbcm.setSnapshotMode(SnapshotMode.INSTANT);
- MockEngine engine = new MockEngine();
- engine.setJvmRoute(jvmRoute);
- MockHost host = new MockHost();
- engine.addChild(host);
- host.setName("localhost");
- StandardContext container = new StandardContext();
- container.setName(warName);
- host.addChild(container);
- container.setManager(jbcm);
+ setupContainer(warName, jvmRoute, jbcm);
// Do this after assigning the manager to the container, or else
// the container's setting will override ours
@@ -134,7 +138,13 @@
public static PojoCache createCache(boolean local, String passivationDir,
boolean totalReplication, boolean marshalling, Set<PojoCache> allCaches)
{
- Configuration cfg = getConfiguration(local, passivationDir, totalReplication, marshalling);
+ return createCache(local, passivationDir, totalReplication, marshalling, false, allCaches);
+ }
+
+ public static PojoCache createCache(boolean local, String passivationDir,
+ boolean totalReplication, boolean marshalling, boolean purgeCacheLoader, Set<PojoCache> allCaches)
+ {
+ Configuration cfg = getConfiguration(local, passivationDir, totalReplication, marshalling, purgeCacheLoader);
PojoCache cache = PojoCacheFactory.createCache(cfg, true);
if (allCaches != null)
@@ -143,7 +153,7 @@
}
public static Configuration getConfiguration(boolean local, String passivationDir,
- boolean totalReplication, boolean marshalling)
+ boolean totalReplication, boolean marshalling, boolean purgeCacheLoader)
{
PojoCache temp = PojoCacheFactory.createCache(CONFIG_LOCATION, false);
Configuration config = temp.getCache().getConfiguration();
@@ -160,6 +170,7 @@
fclc.setProperties(clc.getFirstCacheLoaderConfig().getProperties());
fclc.setLocation(passivationDir);
fclc.setFetchPersistentState(true);
+ fclc.setPurgeOnStartup(purgeCacheLoader);
ArrayList<IndividualCacheLoaderConfig> iclcs = new ArrayList<IndividualCacheLoaderConfig>();
iclcs.add(fclc);
clc.setIndividualCacheLoaderConfigs(iclcs);
@@ -197,6 +208,19 @@
{
distributedManagerFactory.clearCaches();
}
+
+ public static void setupContainer(String warName, String jvmRoute, Manager mgr)
+ {
+ MockEngine engine = new MockEngine();
+ engine.setJvmRoute(jvmRoute);
+ MockHost host = new MockHost();
+ engine.addChild(host);
+ host.setName("localhost");
+ StandardContext container = new StandardContext();
+ container.setName(warName);
+ host.addChild(container);
+ container.setManager(mgr);
+ }
public static JBossWebMetaData createWebMetaData(int maxSessions)
{
@@ -249,12 +273,14 @@
throws ServletException, IOException
{
Valve valve = setupPipeline(manager, handler);
- MockRequest request = new MockRequest();
- request.setRequestedSessionId(sessionId);
- request.setContext((Context) manager.getContainer());
- Response response = new Response();
- request.setResponse(response);
- valve.invoke(request, response);
+ Request request = setupRequest(manager, sessionId);
+ invokeRequest(valve, request);
+ }
+
+ public static void invokeRequest(Valve pipelineHead, Request request)
+ throws ServletException, IOException
+ {
+ pipelineHead.invoke(request, request.getResponse());
// StandardHostValve calls request.getSession(false) on way out, so we will too
request.getSession(false);
request.recycle();
@@ -289,6 +315,17 @@
return pipeline.getFirst();
}
+ public static Request setupRequest(Manager manager, String sessionId)
+ {
+ MockRequest request = new MockRequest();
+ request.setRequestedSessionId(sessionId);
+ request.setContext((Context) manager.getContainer());
+ Response response = new Response();
+ request.setResponse(response);
+ return request;
+
+ }
+
public static void cleanupPipeline(Manager manager)
{
Pipeline pipeline = manager.getContainer().getPipeline();
@@ -504,7 +541,7 @@
{
return Integer.valueOf(value);
}
-
+
public static void cleanPassivationDir(File root)
{
if (root.exists())
Deleted: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockDistributedCacheManager.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockDistributedCacheManager.java 2010-02-03 02:29:36 UTC (rev 100314)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockDistributedCacheManager.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -1,165 +0,0 @@
-/*
- * 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.test.cluster.web.jvmroute;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-import org.jboss.web.tomcat.service.session.distributedcache.spi.BatchingManager;
-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<OutgoingDistributableSessionData>
-{
- public static final MockDistributedCacheManager INSTANCE = new MockDistributedCacheManager();
-
-
- public void evictSession(String realId)
- {
- // no-op
- }
-
- public void evictSession(String realId, String dataOwner)
- {
- // no-op
- }
-
- public Object getAttribute(String realId, String key)
- {
- return null;
- }
-
- public Set<String> getAttributeKeys(String realId)
- {
- return Collections.emptySet();
- }
-
- public Map<String, Object> getAttributes(String realId)
- {
- return Collections.emptyMap();
- }
-
- public BatchingManager getBatchingManager()
- {
- return null;
- }
-
- 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.emptyMap();
- }
-
- public boolean isPassivationEnabled()
- {
- return false;
- }
-
- public void putAttribute(String realId, Map<String, Object> map)
- {
- // no-op
- }
-
- public void putAttribute(String realId, String key, Object value)
- {
- // no-op
- }
-
-
-
- public Object removeAttribute(String realId, String key)
- {
- return null;
- }
-
- public void removeAttributeLocal(String realId, String key)
- {
- // no-op
- }
-
- public void removeAttributes(String realId)
- {
- // no-op
- }
-
- public void removeAttributesLocal(String realId)
- {
- // no-op
- }
-
- public void removeSession(String realId)
- {
- // no-op
- }
-
- public void removeSessionLocal(String realId)
- {
- // no-op
- }
-
- public void removeSessionLocal(String realId, String dataOwner)
- {
- // no-op
- }
-
- public void start()
- {
- // no-op
- }
-
- public void stop()
- {
- // no-op
- }
-
- public boolean getSupportsAttributeOperations()
- {
- return true;
- }
-
- public void sessionCreated(String realId)
- {
- // no-op
- }
-
- public void storeSessionData(OutgoingDistributableSessionData sessionData)
- {
- // no-op
- }
-
-}
Deleted: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockJBossManager.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockJBossManager.java 2010-02-03 02:29:36 UTC (rev 100314)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockJBossManager.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -1,276 +0,0 @@
-/*
- * 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.test.cluster.web.jvmroute;
-
-import java.beans.PropertyChangeListener;
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.catalina.Container;
-import org.apache.catalina.Session;
-import org.jboss.metadata.web.jboss.JBossWebMetaData;
-import org.jboss.metadata.web.jboss.ReplicationTrigger;
-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;
-
-/**
- * @author Brian Stansberry
- *
- */
-public class MockJBossManager implements ClusteredManager<OutgoingDistributableSessionData>
-{
- private String jvmRoute = null;
- private String newCookieIdSession = null;
- private Session session = null;
-
- /**
- * Create a new MockJBossManager.
- *
- */
- public MockJBossManager()
- {
- }
-
- public String getJvmRoute()
- {
- return jvmRoute;
- }
-
- public void setJvmRoute(String jvmRoute)
- {
- this.jvmRoute = jvmRoute;
- }
-
- public void setNewSessionCookie(String sessionId, HttpServletResponse response)
- {
- newCookieIdSession = sessionId;
- }
-
- public String getNewCookieIdSession()
- {
- return newCookieIdSession;
- }
-
- public Session createSession(String s)
- {
- Session session = new MockSession(this);
- session.setId(s);
- return session;
- }
-
- public Session findSession(String s) throws IOException
- {
- return session;
- }
-
- public void add(Session session)
- {
- this.session = session;
- }
-
- public ReplicationTrigger getReplicationTrigger()
- {
- return ReplicationTrigger.SET_AND_NON_PRIMITIVE_GET;
- }
-
- public void init(String name, JBossWebMetaData webMetaData) throws ClusteringNotSupportedException
- {
-
- }
-
- public void removeLocal(Session session)
- {
- }
-
- public boolean storeSession(Session session)
- {
- return false;
- }
-
- public void addPropertyChangeListener(PropertyChangeListener propertychangelistener)
- {
- }
-
- public void backgroundProcess()
- {
- }
-
- public Session createEmptySession()
- {
- return null;
- }
-
- public Session createSession()
- {
- return null;
- }
-
- public Session[] findSessions()
- {
- return null;
- }
-
- public int getActiveSessions()
- {
- return 0;
- }
-
- public Container getContainer()
- {
- return null;
- }
-
- public boolean getDistributable()
- {
- return false;
- }
-
- public int getExpiredSessions()
- {
- return 0;
- }
-
- public String getInfo()
- {
- return null;
- }
-
- public int getMaxActive()
- {
- return 0;
- }
-
- public int getMaxInactiveInterval()
- {
- return 0;
- }
-
- public int getRejectedSessions()
- {
- return 0;
- }
-
- public int getSessionAverageAliveTime()
- {
- return 0;
- }
-
- public int getSessionCounter()
- {
- return 0;
- }
-
- public int getSessionIdLength()
- {
- return 0;
- }
-
- public int getSessionMaxAliveTime()
- {
- return 0;
- }
-
- public void load() throws ClassNotFoundException, IOException
- {
- }
-
- public void remove(Session session)
- {
- }
-
- public void removePropertyChangeListener(PropertyChangeListener propertychangelistener)
- {
- }
-
- public void setContainer(Container container)
- {
- }
-
- public void setDistributable(boolean flag)
- {
- }
-
- public void setExpiredSessions(int i)
- {
- }
-
- public void setMaxActive(int i)
- {
- }
-
- public void setMaxInactiveInterval(int i)
- {
- }
-
- public void setRejectedSessions(int i)
- {
- }
-
- public void setSessionAverageAliveTime(int i)
- {
- }
-
- public void setSessionCounter(int i)
- {
- }
-
- public void setSessionIdLength(int i)
- {
- }
-
- public void setSessionMaxAliveTime(int i)
- {
- }
-
- public void unload() throws IOException
- {
- }
-
- public DistributedCacheManager getDistributedCacheManager()
- {
- return MockDistributedCacheManager.INSTANCE;
- }
-
- public int getMaxUnreplicatedInterval()
- {
- return -1;
- }
-
- public ClusteredSessionNotificationPolicy getNotificationPolicy()
- {
- return new LegacyClusteredSessionNotificationPolicy();
- }
-
- public boolean getUseJK()
- {
- return true;
- }
-
-
-
-}
Modified: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockSession.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockSession.java 2010-02-03 02:29:36 UTC (rev 100314)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/jvmroute/MockSession.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -25,6 +25,7 @@
import javax.servlet.http.HttpSession;
import org.apache.catalina.session.StandardSessionFacade;
+import org.jboss.test.cluster.web.mocks.MockClusteredManager;
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;
@@ -43,7 +44,7 @@
*
* @param manager
*/
- public MockSession(MockJBossManager manager)
+ public MockSession(MockClusteredManager manager)
{
super(manager);
}
Added: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/ConcurrentRequestHandler.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/ConcurrentRequestHandler.java (rev 0)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/ConcurrentRequestHandler.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009 Red Hat, Inc. 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.test.cluster.web.mocks;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+
+/**
+ * Uses a ThreadLocal to allow a single RequestHandlerValve to concurrently
+ * handle requests.
+ *
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public class ConcurrentRequestHandler implements RequestHandler
+{
+ private final ThreadLocal<RequestHandler> threadHandler = new ThreadLocal<RequestHandler>();
+ private final Set<RequestHandler> handlers = new HashSet<RequestHandler>();
+
+ public void registerHandler(RequestHandler handler)
+ {
+ threadHandler.set(handler);
+ }
+
+ public void unregisterHandler()
+ {
+ threadHandler.remove();
+ }
+
+ public void clear()
+ {
+ for (RequestHandler handler : handlers)
+ {
+ handler.clear();
+ }
+ }
+
+ public void handleRequest(Request request, Response response)
+ {
+ RequestHandler handler = threadHandler.get();
+ if (handler == null)
+ {
+ throw new IllegalStateException("No handler; call registerHandler before executing requet");
+ }
+ handler.handleRequest(request, response);
+ }
+
+}
Added: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockClusteredManager.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockClusteredManager.java (rev 0)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockClusteredManager.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -0,0 +1,277 @@
+/*
+ * 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.test.cluster.web.mocks;
+
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Session;
+import org.jboss.metadata.web.jboss.JBossWebMetaData;
+import org.jboss.metadata.web.jboss.ReplicationTrigger;
+import org.jboss.test.cluster.web.jvmroute.MockSession;
+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;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class MockClusteredManager implements ClusteredManager<OutgoingDistributableSessionData>
+{
+ private String jvmRoute = null;
+ private String newCookieIdSession = null;
+ private Session session = null;
+
+ /**
+ * Create a new MockJBossManager.
+ *
+ */
+ public MockClusteredManager()
+ {
+ }
+
+ public String getJvmRoute()
+ {
+ return jvmRoute;
+ }
+
+ public void setJvmRoute(String jvmRoute)
+ {
+ this.jvmRoute = jvmRoute;
+ }
+
+ public void setNewSessionCookie(String sessionId, HttpServletResponse response)
+ {
+ newCookieIdSession = sessionId;
+ }
+
+ public String getNewCookieIdSession()
+ {
+ return newCookieIdSession;
+ }
+
+ public Session createSession(String s)
+ {
+ Session session = new MockSession(this);
+ session.setId(s);
+ return session;
+ }
+
+ public Session findSession(String s) throws IOException
+ {
+ return session;
+ }
+
+ public void add(Session session)
+ {
+ this.session = session;
+ }
+
+ public ReplicationTrigger getReplicationTrigger()
+ {
+ return ReplicationTrigger.SET_AND_NON_PRIMITIVE_GET;
+ }
+
+ public void init(String name, JBossWebMetaData webMetaData) throws ClusteringNotSupportedException
+ {
+
+ }
+
+ public void removeLocal(Session session)
+ {
+ }
+
+ public boolean storeSession(Session session)
+ {
+ return false;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener propertychangelistener)
+ {
+ }
+
+ public void backgroundProcess()
+ {
+ }
+
+ public Session createEmptySession()
+ {
+ return null;
+ }
+
+ public Session createSession()
+ {
+ return null;
+ }
+
+ public Session[] findSessions()
+ {
+ return null;
+ }
+
+ public int getActiveSessions()
+ {
+ return 0;
+ }
+
+ public Container getContainer()
+ {
+ return null;
+ }
+
+ public boolean getDistributable()
+ {
+ return false;
+ }
+
+ public int getExpiredSessions()
+ {
+ return 0;
+ }
+
+ public String getInfo()
+ {
+ return null;
+ }
+
+ public int getMaxActive()
+ {
+ return 0;
+ }
+
+ public int getMaxInactiveInterval()
+ {
+ return 0;
+ }
+
+ public int getRejectedSessions()
+ {
+ return 0;
+ }
+
+ public int getSessionAverageAliveTime()
+ {
+ return 0;
+ }
+
+ public int getSessionCounter()
+ {
+ return 0;
+ }
+
+ public int getSessionIdLength()
+ {
+ return 0;
+ }
+
+ public int getSessionMaxAliveTime()
+ {
+ return 0;
+ }
+
+ public void load() throws ClassNotFoundException, IOException
+ {
+ }
+
+ public void remove(Session session)
+ {
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener propertychangelistener)
+ {
+ }
+
+ public void setContainer(Container container)
+ {
+ }
+
+ public void setDistributable(boolean flag)
+ {
+ }
+
+ public void setExpiredSessions(int i)
+ {
+ }
+
+ public void setMaxActive(int i)
+ {
+ }
+
+ public void setMaxInactiveInterval(int i)
+ {
+ }
+
+ public void setRejectedSessions(int i)
+ {
+ }
+
+ public void setSessionAverageAliveTime(int i)
+ {
+ }
+
+ public void setSessionCounter(int i)
+ {
+ }
+
+ public void setSessionIdLength(int i)
+ {
+ }
+
+ public void setSessionMaxAliveTime(int i)
+ {
+ }
+
+ public void unload() throws IOException
+ {
+ }
+
+ public DistributedCacheManager getDistributedCacheManager()
+ {
+ return MockDistributedCacheManager.INSTANCE;
+ }
+
+ public int getMaxUnreplicatedInterval()
+ {
+ return -1;
+ }
+
+ public ClusteredSessionNotificationPolicy getNotificationPolicy()
+ {
+ return new LegacyClusteredSessionNotificationPolicy();
+ }
+
+ public boolean getUseJK()
+ {
+ return true;
+ }
+
+
+
+}
Added: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManager.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManager.java (rev 0)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManager.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -0,0 +1,195 @@
+/*
+ * 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.test.cluster.web.mocks;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.web.tomcat.service.session.distributedcache.spi.BatchingManager;
+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<OutgoingDistributableSessionData>
+{
+ public static final MockDistributedCacheManager INSTANCE = new MockDistributedCacheManager();
+
+
+ public void evictSession(String realId)
+ {
+ // no-op
+ }
+
+ public void evictSession(String realId, String dataOwner)
+ {
+ // no-op
+ }
+
+ public Object getAttribute(String realId, String key)
+ {
+ return null;
+ }
+
+ public Set<String> getAttributeKeys(String realId)
+ {
+ return Collections.emptySet();
+ }
+
+ public Map<String, Object> getAttributes(String realId)
+ {
+ return Collections.emptyMap();
+ }
+
+ public BatchingManager getBatchingManager()
+ {
+ return MockBatchingManager.INSTANCE;
+ }
+
+ 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.emptyMap();
+ }
+
+ public boolean isPassivationEnabled()
+ {
+ return false;
+ }
+
+ public void putAttribute(String realId, Map<String, Object> map)
+ {
+ // no-op
+ }
+
+ public void putAttribute(String realId, String key, Object value)
+ {
+ // no-op
+ }
+
+
+
+ public Object removeAttribute(String realId, String key)
+ {
+ return null;
+ }
+
+ public void removeAttributeLocal(String realId, String key)
+ {
+ // no-op
+ }
+
+ public void removeAttributes(String realId)
+ {
+ // no-op
+ }
+
+ public void removeAttributesLocal(String realId)
+ {
+ // no-op
+ }
+
+ public void removeSession(String realId)
+ {
+ // no-op
+ }
+
+ public void removeSessionLocal(String realId)
+ {
+ // no-op
+ }
+
+ public void removeSessionLocal(String realId, String dataOwner)
+ {
+ // no-op
+ }
+
+ public void start()
+ {
+ // no-op
+ }
+
+ public void stop()
+ {
+ // no-op
+ }
+
+ public boolean getSupportsAttributeOperations()
+ {
+ return true;
+ }
+
+ public void sessionCreated(String realId)
+ {
+ // no-op
+ }
+
+ public void storeSessionData(OutgoingDistributableSessionData sessionData)
+ {
+ // no-op
+ }
+
+ private static class MockBatchingManager implements BatchingManager
+ {
+ private static final MockBatchingManager INSTANCE = new MockBatchingManager();
+
+ public void endBatch()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public boolean isBatchInProgress() throws Exception
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void setBatchRollbackOnly() throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void startBatch() throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ }
+
+}
Added: branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManagerFactory.java
===================================================================
--- branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManagerFactory.java (rev 0)
+++ branches/JBPAPP_5_0/testsuite/src/main/org/jboss/test/cluster/web/mocks/MockDistributedCacheManagerFactory.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009 Red Hat, Inc. 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.test.cluster.web.mocks;
+
+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.DistributedCacheManagerFactory;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
+import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
+
+/**
+ *
+ *
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public class MockDistributedCacheManagerFactory implements DistributedCacheManagerFactory
+{
+
+ public <T extends OutgoingDistributableSessionData> DistributedCacheManager<T> getDistributedCacheManager(
+ LocalDistributableSessionManager localManager) throws ClusteringNotSupportedException
+ {
+ return (DistributedCacheManager<T>) MockDistributedCacheManager.INSTANCE;
+ }
+
+}
Modified: branches/JBPAPP_5_0/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSession.java
===================================================================
--- branches/JBPAPP_5_0/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSession.java 2010-02-03 02:29:36 UTC (rev 100314)
+++ branches/JBPAPP_5_0/tomcat/src/main/org/jboss/web/tomcat/service/session/ClusteredSession.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -1310,7 +1310,9 @@
*/
public boolean isOutdated()
{
- return thisAccessedTime < outdatedTime;
+ // if creationTime == 0 we've neither been synced with the
+ // distributed cache nor had creation time set (i.e. brand new session)
+ return thisAccessedTime < outdatedTime || this.creationTime == 0;
}
public boolean isSessionDirty()
Modified: branches/JBPAPP_5_0/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java
===================================================================
--- branches/JBPAPP_5_0/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java 2010-02-03 02:29:36 UTC (rev 100314)
+++ branches/JBPAPP_5_0/tomcat/src/main/org/jboss/web/tomcat/service/session/JBossCacheManager.java 2010-02-03 04:12:56 UTC (rev 100315)
@@ -31,6 +31,7 @@
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@@ -106,6 +107,13 @@
/** Id/timestamp of sessions in distributedcache that we haven't loaded locally*/
private Map<String, OwnedSessionUpdate> unloadedSessions_ =
new ConcurrentHashMap<String, OwnedSessionUpdate>();
+
+ /**
+ * Sessions that have been created but not yet loaded. Used to ensure
+ * concurrent threads trying to load the same session
+ */
+ private final ConcurrentMap<String, ClusteredSession<? extends OutgoingDistributableSessionData>> embryonicSessions =
+ new ConcurrentHashMap<String, ClusteredSession<? extends OutgoingDistributableSessionData>>();
/** Number of passivated sessions */
private AtomicInteger passivatedCount_ = new AtomicInteger();
@@ -2008,6 +2016,15 @@
// a replication message from another server
mustAdd = true;
session = createEmptyClusteredSession();
+
+ // JBAS-7379 Ensure concurrent threads trying to load same session id
+ // use the same session
+ ClusteredSession<? extends OutgoingDistributableSessionData> embryo =
+ this.embryonicSessions.putIfAbsent(realId, session);
+ if (embryo != null)
+ {
+ session = embryo;
+ }
OwnedSessionUpdate osu = unloadedSessions_.get(realId);
passivated = (osu != null && osu.isPassivated());
@@ -2015,6 +2032,14 @@
synchronized (session)
{
+ // JBAS-7379 check if we lost the race to the sync block
+ // and another thread has already loaded this session
+ if (initialLoad && session.isOutdated() == false)
+ {
+ // some one else loaded this
+ return session;
+ }
+
ContextClassLoaderSwitcher.SwitchContext switcher = null;
boolean doTx = false;
boolean loadCompleted = false;
More information about the jboss-cvs-commits
mailing list