Author: bstansberry(a)jboss.com
Date: 2008-11-24 02:01:36 -0500 (Mon, 24 Nov 2008)
New Revision: 7186
Added:
core/trunk/src/test/java/org/jboss/cache/integration/CacheManagerSupport.java
core/trunk/src/test/java/org/jboss/cache/integration/JGroupsUtil.java
core/trunk/src/test/java/org/jboss/cache/integration/MockChannelFactory.java
core/trunk/src/test/java/org/jboss/cache/integration/UnitTestCacheFactoryCacheManager.java
core/trunk/src/test/java/org/jboss/cache/integration/UnitTestCacheFactoryConfigurationRegistry.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/
core/trunk/src/test/java/org/jboss/cache/integration/websession/BuddyReplicationFailoverTest.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/AbstractServlet.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/BuddyReplicationAssertions.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/DirtyMetadataServlet.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/FqnUtil.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/GetAttributesServlet.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/InvalidationServlet.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/MultipleActionServlet.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/RemoveAttributesServlet.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Request.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Servlet.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Session.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionManager.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionManagerSupport.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionMetadata.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SetAttributesServlet.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/WebAppMetadata.java
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/WebSessionTestBase.java
core/trunk/src/test/resources/configs/integration/
core/trunk/src/test/resources/configs/integration/hibernate-cache-configs.xml
core/trunk/src/test/resources/configs/integration/jgroups-channelfactory-stacks.xml
core/trunk/src/test/resources/configs/integration/sfsb-cache-configs.xml
core/trunk/src/test/resources/configs/integration/web-session-cache-configs.xml
Log:
[JBCACHE-1445] Add test showing problem with cleanup after data gravitation
Added: core/trunk/src/test/java/org/jboss/cache/integration/CacheManagerSupport.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/integration/CacheManagerSupport.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/CacheManagerSupport.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,89 @@
+/*
+ * 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.cache.integration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.cache.CacheManager;
+
+/**
+ * @author Brian Stansberry
+ */
+public class CacheManagerSupport
+{
+ /**
+ * For each thread holds list of cache managers created using this factory.
+ */
+ private static final ThreadLocal<List<UnitTestCacheFactoryCacheManager>>
threadCacheManagers =
+ new ThreadLocal<List<UnitTestCacheFactoryCacheManager>>()
+ {
+ @Override
+ protected List<UnitTestCacheFactoryCacheManager> initialValue()
+ {
+ return new ArrayList<UnitTestCacheFactoryCacheManager>();
+ }
+ };
+
+ public static List<CacheManager> createCacheManagers(int count, String
cacheConfigFileName, String stacksXmlFileName)
+ {
+ List<UnitTestCacheFactoryCacheManager> existing = threadCacheManagers.get();
+ List<CacheManager> result = new ArrayList<CacheManager>(count);
+ int added = 0;
+ for (UnitTestCacheFactoryCacheManager cm : existing)
+ {
+ if (cacheConfigFileName.equals(cm.getCacheConfigFileName()) &&
stacksXmlFileName.equals(cm.getStacksXMLFileName()))
+ {
+ result.add(cm);
+ added++;
+ }
+ }
+
+ for (; added < count; added++)
+ {
+ UnitTestCacheFactoryCacheManager cm = new
UnitTestCacheFactoryCacheManager(cacheConfigFileName, stacksXmlFileName);
+ try
+ {
+ cm.start();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ result.add(cm);
+ existing.add(cm);
+ }
+
+ return result;
+ }
+
+ public static void tearDown()
+ {
+ List<UnitTestCacheFactoryCacheManager> existing = threadCacheManagers.get();
+ for (UnitTestCacheFactoryCacheManager cm : existing)
+ {
+ cm.stop();
+ }
+ threadCacheManagers.remove();
+ }
+}
Added: core/trunk/src/test/java/org/jboss/cache/integration/JGroupsUtil.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/integration/JGroupsUtil.java
(rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/integration/JGroupsUtil.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,153 @@
+/*
+ * 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.cache.integration;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.jboss.cache.config.ConfigurationException;
+import org.jboss.cache.util.FileLookup;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * JGroups-related utilities.
+ *
+ * @author Brian Stansberry
+ */
+public class JGroupsUtil
+{
+ private final static String PROTOCOL_STACKS = "protocol_stacks";
+ private final static String STACK = "stack";
+ private static final String NAME = "name";
+ private static final String CONFIG = "config";
+
+ public static Map<String, Element> getStackConfigs(String stacksXmlResource)
throws Exception
+ {
+ FileLookup fileLookup = new FileLookup();
+ InputStream is = fileLookup.lookupFile(stacksXmlResource);
+ if (is == null)
+ {
+ throw new ConfigurationException("Unable to find config file " +
stacksXmlResource + " either in classpath or on the filesystem!");
+ }
+
+ return getStackConfigs(is);
+ }
+
+ /**
+ * Parses a set if "config" elements out of a JGroups stacks.xml file.
+ *
+ * @param input
+ * @return
+ * @throws Exception
+ */
+ public static Map<String, Element> getStackConfigs(InputStream input) throws
Exception
+ {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating(false); //for now
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document document = builder.parse(input);
+
+ // The root element of the document should be the "config" element,
+ // but the parser(Element) method checks this so a check is not
+ // needed here.
+ Element configElement = document.getDocumentElement();
+ return getStackConfigs(configElement);
+ }
+
+ private static Map<String, Element> getStackConfigs(Element root) throws
Exception
+ {
+ Map<String, Element> result = new HashMap<String, Element>();
+
+ String root_name = root.getNodeName();
+ if (!PROTOCOL_STACKS.equals(root_name.trim().toLowerCase()))
+ {
+ String error = "XML protocol stack configuration does not start with a
'<config>' element; "
+ + "maybe the XML configuration needs to be converted to the new
format ?\n"
+ + "use 'java org.jgroups.conf.XmlConfigurator <old XML
file> -new_format' to do so";
+ throw new IOException("invalid XML configuration: " + error);
+ }
+
+ NodeList tmp_stacks = root.getChildNodes();
+ for (int i = 0; i < tmp_stacks.getLength(); i++)
+ {
+ Node node = tmp_stacks.item(i);
+ if (node.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+
+ Element stack = (Element) node;
+ String tmp = stack.getNodeName();
+ if (!STACK.equals(tmp.trim().toLowerCase()))
+ {
+ throw new IOException("invalid configuration: didn't find a
\"" + STACK + "\" element under \""
+ + PROTOCOL_STACKS + "\"");
+ }
+
+ NamedNodeMap attrs = stack.getAttributes();
+ Node name = attrs.getNamedItem(NAME);
+ String st_name = name.getNodeValue();
+
+ NodeList configs = stack.getChildNodes();
+ for (int j = 0; j < configs.getLength(); j++)
+ {
+ Node tmp_config = configs.item(j);
+ if (tmp_config.getNodeType() != Node.ELEMENT_NODE)
+ continue;
+ Element cfg = (Element) tmp_config;
+ tmp = cfg.getNodeName();
+ if (!CONFIG.equals(tmp))
+ throw new IOException("invalid configuration: didn't find a
\"" + CONFIG + "\" element under \"" + STACK
+ + "\"");
+
+ if (!result.containsKey(st_name))
+ {
+ result.put(st_name, cfg);
+ }
+ else
+ {
+ throw new IllegalStateException("didn't add config '" +
st_name
+ + " because one of the same name already existed");
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Prevent instantiation.
+ */
+ private JGroupsUtil()
+ {
+ throw new UnsupportedOperationException("just a static util class");
+ }
+
+}
Added: core/trunk/src/test/java/org/jboss/cache/integration/MockChannelFactory.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/integration/MockChannelFactory.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/MockChannelFactory.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,94 @@
+/*
+ * 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.cache.integration;
+
+import java.io.File;
+import java.net.URL;
+
+import org.jgroups.Channel;
+import org.jgroups.ChannelException;
+import org.jgroups.ChannelFactory;
+import org.w3c.dom.Element;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class MockChannelFactory implements ChannelFactory
+{
+ public static final MockChannelFactory INSTANCE = new MockChannelFactory();
+
+ private MockChannelFactory() {}
+
+ public Channel createChannel() throws ChannelException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Channel createChannel(Object props) throws ChannelException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Channel createChannel(String stack_name) throws Exception
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Channel createMultiplexerChannel(String stack_name, String id) throws
Exception
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Channel createMultiplexerChannel(String stack_name, String id, boolean
register_for_state_transfer,
+ String substate_id) throws Exception
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setMultiplexerConfig(Object properties) throws Exception
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setMultiplexerConfig(File properties) throws Exception
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setMultiplexerConfig(Element properties) throws Exception
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setMultiplexerConfig(URL properties) throws Exception
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setMultiplexerConfig(String properties) throws Exception
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/UnitTestCacheFactoryCacheManager.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/UnitTestCacheFactoryCacheManager.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/UnitTestCacheFactoryCacheManager.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,81 @@
+/*
+ * 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.cache.integration;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheManagerImpl;
+import org.jboss.cache.UnitTestCacheFactory;
+import org.jboss.cache.config.Configuration;
+
+/**
+ * CacheManager implementation that integrates with UnitTestCacheFactory.
+ *
+ * @author Brian Stansberry
+ */
+public class UnitTestCacheFactoryCacheManager extends CacheManagerImpl
+{
+ private final String cacheConfigFileName;
+ private final String stacksXMLFileName;
+
+ /**
+ * Create a new UnitTestCacheFactoryCacheManager.
+ *
+ * @param configFileName
+ * @param factory
+ */
+ public UnitTestCacheFactoryCacheManager(String cacheConfigFileName, String
stacksXMLFileName)
+ {
+ super(new UnitTestCacheFactoryConfigurationRegistry(cacheConfigFileName,
stacksXMLFileName), MockChannelFactory.INSTANCE);
+ this.cacheConfigFileName = cacheConfigFileName;
+ this.stacksXMLFileName = stacksXMLFileName;
+ }
+
+ public String getCacheConfigFileName()
+ {
+ return cacheConfigFileName;
+ }
+
+ public String getStacksXMLFileName()
+ {
+ return stacksXMLFileName;
+ }
+
+ @Override
+ public void start() throws Exception
+ {
+ ((UnitTestCacheFactoryConfigurationRegistry) getConfigurationRegistry()).start();
+ super.start();
+ }
+
+ /**
+ * Overrides superclass to use UnitTestCacheFactory to create the cache.
+ */
+ @Override
+ protected Cache<Object, Object> createCache(Configuration config)
+ {
+ return new UnitTestCacheFactory<Object, Object>().createCache(config,
false);
+ }
+
+
+
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/UnitTestCacheFactoryConfigurationRegistry.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/UnitTestCacheFactoryConfigurationRegistry.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/UnitTestCacheFactoryConfigurationRegistry.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,177 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 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.cache.integration;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.ConfigurationRegistry;
+import org.jboss.cache.config.parsing.CacheConfigsXmlParser;
+import org.w3c.dom.Element;
+
+/**
+ * XmlParsingConfigurationRegistry variant that replaces any MuxStackName in
+ * configurations with a corresponding Element parsed out of the provided
+ * JGroups stacks.xml file. UnitTestCacheFactory can then mangle the element.
+ *
+ * @author <a href="brian.stansberry(a)jboss.com">Brian
Stansberry</a>
+ * @version $Revision: 7168 $
+ */
+public class UnitTestCacheFactoryConfigurationRegistry implements ConfigurationRegistry
+{
+ public static final String DEFAULT_STACKS_XML_RESOURCE =
"configs/integration/jgroups-channelfactory-stacks.xml";
+
+ private final CacheConfigsXmlParser parser;
+ private final String configResource;
+ private final Map<String, Element> stacks;
+ private final Map<String, Configuration> configs = new Hashtable<String,
Configuration>();
+ private boolean started;
+
+ public UnitTestCacheFactoryConfigurationRegistry(String cacheConfigResource)
+ {
+ this(cacheConfigResource, DEFAULT_STACKS_XML_RESOURCE);
+ }
+
+ public UnitTestCacheFactoryConfigurationRegistry(String cacheConfigResource, String
stacksXmlResource)
+ {
+ parser = new CacheConfigsXmlParser();
+ this.configResource = cacheConfigResource;
+ try
+ {
+ this.stacks = JGroupsUtil.getStackConfigs(stacksXmlResource);
+ }
+ catch (RuntimeException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("problem parsing JGroups stacks", e);
+ }
+ }
+
+ public void start() throws Exception
+ {
+ if (!started)
+ {
+ if (configResource != null)
+ {
+ Map<String, Configuration> parsed =
parser.parseConfigs(configResource);
+ for (Map.Entry<String, Configuration> entry : parsed.entrySet())
+ {
+ registerConfiguration(entry.getKey(), entry.getValue());
+ }
+ }
+ started = true;
+ }
+ }
+
+ public void stop()
+ {
+ if (started)
+ {
+ synchronized (configs)
+ {
+ configs.clear();
+ }
+ started = false;
+ }
+ }
+
+ public String getConfigResource()
+ {
+ return configResource;
+ }
+
+ public Set<String> getConfigurationNames()
+ {
+ return new HashSet<String>(configs.keySet());
+ }
+
+ public void registerConfiguration(String configName, Configuration config)
+ throws CloneNotSupportedException
+ {
+ synchronized (configs)
+ {
+ if (configs.containsKey(configName))
+ throw new IllegalStateException(configName + " already
registered");
+ Configuration clone = config.clone();
+ fixJGroupsConfig(clone);
+ configs.put(configName, clone);
+ }
+ }
+
+ public void unregisterConfiguration(String configName)
+ {
+ synchronized (configs)
+ {
+ if (configs.remove(configName) == null)
+ throw new IllegalStateException(configName + " not registered");
+ }
+ }
+
+ public Configuration getConfiguration(String configName)
+ {
+ Configuration config;
+ synchronized (configs)
+ {
+ config = configs.get(configName);
+ }
+
+ if (config == null)
+ throw new IllegalArgumentException("unknown config " + configName);
+
+ // Don't hand out a ref to our master copy
+ try
+ {
+ return config.clone();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ // This should not happen, as we already cloned the config
+ throw new RuntimeException("Could not clone configuration " +
configName, e);
+ }
+ }
+
+ /** Replace a stack name with a stack element that UnitTestCacheFactory can mangle */
+ private void fixJGroupsConfig(Configuration clone)
+ {
+ String stackName = clone.getMultiplexerStack();
+ if (stackName != null)
+ {
+ clone.setMultiplexerStack(null);
+ Element e = stacks.get(stackName);
+ if (e == null)
+ {
+ throw new IllegalStateException("unknown stack " + stackName);
+ }
+
+ clone.setClusterConfig(e);
+ }
+
+ }
+
+
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/BuddyReplicationFailoverTest.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/BuddyReplicationFailoverTest.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/BuddyReplicationFailoverTest.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,159 @@
+/*
+ * 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.cache.integration.websession;
+
+import java.util.Collections;
+
+import org.jboss.cache.commands.write.PutDataMapCommand;
+import org.jboss.cache.commands.write.RemoveNodeCommand;
+import org.jboss.cache.integration.websession.util.BuddyReplicationAssertions;
+import org.jboss.cache.integration.websession.util.GetAttributesServlet;
+import org.jboss.cache.integration.websession.util.InvalidationServlet;
+import org.jboss.cache.integration.websession.util.MultipleActionServlet;
+import org.jboss.cache.integration.websession.util.Request;
+import org.jboss.cache.integration.websession.util.SessionManager;
+import org.jboss.cache.integration.websession.util.SetAttributesServlet;
+import org.jboss.cache.integration.websession.util.WebSessionTestBase;
+import org.jboss.cache.util.internals.replicationlisteners.ReplicationListener;
+import org.testng.annotations.Test;
+
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+@Test(groups = "integration", sequential = true, testName =
"integration.websession.BuddyReplicationFailoverTest")
+public class BuddyReplicationFailoverTest extends WebSessionTestBase
+{
+ public static final String KEY = "key";
+
+ @Override
+ protected String getCacheConfigName()
+ {
+ return "br-standard-session-cache";
+ }
+
+ @Override
+ protected int getNumCacheManagers()
+ {
+ return 4;
+ }
+
+ @Override
+ protected boolean getCreateManagersInSetup()
+ {
+ return true;
+ }
+
+ public void testFailoverAndFailBack()
+ {
+ int attr = 0;
+
+ SessionManager mgr0 = getSessionManagers().get(0);
+ SessionManager mgr1 = getSessionManagers().get(1);
+ SessionManager mgr2 = getSessionManagers().get(2);
+ SessionManager mgr3 = getSessionManagers().get(3);
+
+ String contextHostName = mgr0.getContextHostName();
+
+ // Create the session
+ SetAttributesServlet sas = new SetAttributesServlet(Collections.singletonMap(KEY,
getAttributeValue(attr++)));
+ ReplicationListener replListener1 =
ReplicationListener.getReplicationListener(mgr1.getCache());
+ replListener1.expectWithTx(PutDataMapCommand.class);
+
+ Request req = new Request(mgr0, null, sas);
+ req.execute();
+ replListener1.waitForReplicationToOccur();
+
+ String sessionId = sas.getSessionId();
+ assert sessionId != null : "session id is null";
+ // validate cache contents
+ BuddyReplicationAssertions.assertBuddyBackup(contextHostName, sessionId,
mgr0.getCache(), mgr1.getCache());
+
+ // Modify the session
+ sas = new SetAttributesServlet(Collections.singletonMap(KEY,
getAttributeValue(attr++)));
+ replListener1.expectWithTx(PutDataMapCommand.class);
+
+ req = new Request(mgr0, sessionId, sas);
+ req.execute();
+ replListener1.waitForReplicationToOccur();
+
+ // Fail over; request reads the session and then modifies the session
+ GetAttributesServlet gas = new GetAttributesServlet(Collections.singleton(KEY));
+ sas = new SetAttributesServlet(Collections.singletonMap(KEY,
getAttributeValue(attr++)));
+ MultipleActionServlet mas = new MultipleActionServlet(gas, sas);
+ ReplicationListener replListener0 =
ReplicationListener.getReplicationListener(mgr0.getCache());
+ replListener0.expectWithTx(PutDataMapCommand.class);
+
+ req = new Request(mgr3, sessionId, mas);
+ req.execute();
+ replListener0.waitForReplicationToOccur();
+
+ assert sessionId.equals(mas.getSessionId()) : "wrong session id; expected
" + sessionId + " got " + mas.getSessionId();
+ Integer integer = (Integer) gas.getReadAttributes().get(KEY);
+ assert integer != null : "null attribute value";
+ assert integer.intValue() == (attr - 2) : "wrong val " + integer + "
expected " + (attr -2);
+
+ BuddyReplicationAssertions.assertBuddyBackup(contextHostName, sessionId,
mgr3.getCache(), mgr0.getCache());
+ BuddyReplicationAssertions.assertUnrelated(contextHostName, sessionId,
mgr1.getCache());
+
+ // Modify the session again
+ sas = new SetAttributesServlet(Collections.singletonMap(KEY,
getAttributeValue(attr++)));
+ replListener0.expectWithTx(PutDataMapCommand.class);
+
+ req = new Request(mgr3, sessionId, sas);
+ req.execute();
+ replListener0.waitForReplicationToOccur();
+
+ // Fail back; request reads the session and then modifies the session
+ gas = new GetAttributesServlet(Collections.singleton(KEY));
+ sas = new SetAttributesServlet(Collections.singletonMap(KEY,
getAttributeValue(attr++)));
+ mas = new MultipleActionServlet(gas, sas);
+ replListener1.expectWithTx(PutDataMapCommand.class);
+
+ req = new Request(mgr0, sessionId, mas);
+ req.execute();
+ replListener1.waitForReplicationToOccur();
+
+ assert sessionId.equals(mas.getSessionId()) : "wrong session id; expected
" + sessionId + " got " + mas.getSessionId();
+ integer = (Integer) gas.getReadAttributes().get(KEY);
+ assert integer != null : "null attribute value";
+ assert integer.intValue() == attr - 2 : "wrong val " + integer + "
expected " + (attr -2);
+
+ BuddyReplicationAssertions.assertBuddyBackup(contextHostName, sessionId,
mgr0.getCache(), mgr1.getCache());
+ BuddyReplicationAssertions.assertUnrelated(contextHostName, sessionId,
mgr3.getCache());
+
+ // Invalidate the session
+ InvalidationServlet invs = new InvalidationServlet();
+ replListener1.expectWithTx(RemoveNodeCommand.class);
+
+ req = new Request(mgr0, sessionId, invs);
+ req.execute();
+ replListener1.waitForReplicationToOccur();
+
+ BuddyReplicationAssertions.assertUnrelated(contextHostName, sessionId,
mgr0.getCache());
+ BuddyReplicationAssertions.assertUnrelated(contextHostName, sessionId,
mgr1.getCache());
+ BuddyReplicationAssertions.assertUnrelated(contextHostName, sessionId,
mgr2.getCache());
+ BuddyReplicationAssertions.assertUnrelated(contextHostName, sessionId,
mgr3.getCache());
+ }
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/AbstractServlet.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/AbstractServlet.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/AbstractServlet.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,57 @@
+/*
+ * 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.cache.integration.websession.util;
+
+/**
+ * Basic Servlet impl. Caches a reference to the session.
+ * @author Brian Stansberry
+ *
+ */
+public abstract class AbstractServlet implements Servlet
+{
+ private Session session;
+
+ protected Session extractSession(Request request)
+ {
+ if (session == null)
+ {
+ session = request.getSession(true);
+ }
+ return session;
+ }
+
+ protected void clearSession()
+ {
+ session = null;
+ }
+
+ public Session getSession()
+ {
+ return session;
+ }
+
+ public String getSessionId()
+ {
+ return session == null ? null : session.getId();
+ }
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/BuddyReplicationAssertions.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/BuddyReplicationAssertions.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/BuddyReplicationAssertions.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,89 @@
+/*
+ * 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.cache.integration.websession.util;
+
+import java.util.Map;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.buddyreplication.BuddyFqnTransformer;
+import org.jboss.cache.buddyreplication.BuddyManager;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class BuddyReplicationAssertions
+{
+ public static void assertBuddyBackup(String contextHostName, String sessionId,
Cache<Object, Object> owner, Cache<Object, Object> backup)
+ {
+ Fqn<String> fqn = Fqn.fromElements(FqnUtil.JSESSION, contextHostName,
sessionId);
+ Map<Object, Object> owned = owner.getData(fqn);
+ assert owned != null : "owned is null";
+
+ Fqn bFqn = new BuddyFqnTransformer().getBackupFqn(owner.getLocalAddress(), fqn);
+ Map<Object, Object> backed = owner.getData(fqn);
+ assert backed != null : "backed is null";
+
+ assert owned.size() == backed.size() : "sizes differ; owned = " +
owned.size() + " backed = " + backed.size();
+
+ for (Map.Entry<Object, Object> entry : owned.entrySet())
+ {
+ Object backVal = backed.get(entry.getKey());
+ assert backVal != null : "null backVal for " + entry.getKey();
+ assert backVal.equals(entry.getValue()) : "differing val for " +
entry.getKey() + " " + entry.getValue() + " vs. " + backVal;
+ }
+
+ assertMainTreeClear(contextHostName, sessionId, backup);
+ assertBuddyTreeClear(contextHostName, sessionId, owner);
+ }
+
+ public static void assertUnrelated(String contextHostName, String sessionId,
Cache<Object, Object> cache)
+ {
+ assertMainTreeClear(contextHostName, sessionId, cache);
+ assertBuddyTreeClear(contextHostName, sessionId, cache);
+ }
+
+ public static void assertMainTreeClear(String contextHostName, String sessionId,
Cache<Object, Object> cache)
+ {
+ Fqn<String> fqn = Fqn.fromElements(FqnUtil.JSESSION, contextHostName,
sessionId);
+ assert cache.getNode(fqn) == null : "found node for " + fqn;
+ }
+
+ public static void assertBuddyTreeClear(String contextHostName, String sessionId,
Cache<Object, Object> cache)
+ {
+ Fqn<String> fqn = Fqn.fromElements(FqnUtil.JSESSION, contextHostName,
sessionId);
+ Node<Object, Object> bbRoot =
cache.getNode(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN);
+ if (bbRoot != null)
+ {
+ for(Node<Object, Object> child : bbRoot.getChildren())
+ {
+ Node<Object, Object> bad = child.getChild(fqn);
+ assert bad == null : "found bad node at " +
Fqn.fromRelativeFqn(child.getFqn(), fqn);
+ }
+ }
+ }
+
+ private BuddyReplicationAssertions() {}
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/DirtyMetadataServlet.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/DirtyMetadataServlet.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/DirtyMetadataServlet.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,38 @@
+/*
+ * 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.cache.integration.websession.util;
+
+
+/**
+ * A Servlet the marks the session metadata dirty.
+ *
+ * @author Brian Stansberry
+ */
+public class DirtyMetadataServlet extends AbstractServlet
+{
+ public void handleRequest(Request request)
+ {
+ extractSession(request).setMetadataDirty();
+ }
+
+}
Added: core/trunk/src/test/java/org/jboss/cache/integration/websession/util/FqnUtil.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/integration/websession/util/FqnUtil.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/FqnUtil.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,135 @@
+/*
+ * 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.cache.integration.websession.util;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.buddyreplication.BuddyManager;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class FqnUtil
+{
+ public static final String JSESSION = "JSESSION";
+ public static final String ATTRIBUTE = "ATTRIBUTE";
+ private static final int JSESSION_FQN_INDEX = 0;
+ private static final int WEBAPP_FQN_INDEX = 1;
+ private static final int SESSION_ID_FQN_INDEX = 2;
+ private static final int SESSION_FQN_SIZE = SESSION_ID_FQN_INDEX + 1;
+ private static final int BUDDY_BACKUP_ROOT_OWNER_INDEX =
BuddyManager.BUDDY_BACKUP_SUBTREE_FQN.size();
+ private static final int BUDDY_BACKUP_ROOT_OWNER_SIZE = BUDDY_BACKUP_ROOT_OWNER_INDEX
+ 1;
+ // Element within an FQN that is the root of a Pojo attribute map
+ private static final int POJO_ATTRIBUTE_FQN_INDEX = SESSION_ID_FQN_INDEX + 1;
+ // Element within an FQN that is the root of an individual Pojo attribute
+ private static final int POJO_KEY_FQN_INDEX = POJO_ATTRIBUTE_FQN_INDEX + 1;
+ // Element within an FQN that is the root of a session's internal pojo storage
area
+ private static final int POJO_INTERNAL_FQN_INDEX = SESSION_ID_FQN_INDEX + 1;
+ // Minimum size of an FQN that is below the root of a session's internal pojo
storage area
+ private static final int POJO_INTERNAL_FQN_SIZE = POJO_INTERNAL_FQN_INDEX + 1;
+
+ public static boolean isBuddyFqn(Fqn<String> fqn)
+ {
+ try
+ {
+ return BuddyManager.BUDDY_BACKUP_SUBTREE.equals(fqn.get(0));
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ // Can only happen if fqn is ROOT, and we shouldn't get
+ // notifications for ROOT.
+ // If it does, just means it's not a buddy
+ return false;
+ }
+ }
+
+ public static boolean isFqnSessionRootSized(Fqn<String> fqn, boolean isBuddy)
+ {
+ return fqn.size() == (isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE + SESSION_FQN_SIZE :
SESSION_FQN_SIZE);
+ }
+
+ public static String getPojoKeyFromFqn(Fqn<String> fqn, boolean isBuddy)
+ {
+ return (String) fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE +
POJO_KEY_FQN_INDEX: POJO_KEY_FQN_INDEX);
+ }
+
+ /**
+ * Check if the fqn is big enough to be in the internal pojo area but
+ * isn't in the regular attribute area.
+ *
+ * Structure in the cache is:
+ *
+ * /JSESSION
+ * ++ /contextPath_hostname
+ * ++++ /sessionid
+ * ++++++ /ATTRIBUTE
+ * ++++++ /_JBossInternal_
+ * ++++++++ etc etc
+ *
+ * If the Fqn size is big enough to be "etc etc" or lower, but the 4th
+ * level is not "ATTRIBUTE", it must be under _JBossInternal_. We
discriminate
+ * based on != ATTRIBUTE to avoid having to code to the internal PojoCache
+ * _JBossInternal_ name.
+ *
+ * @param fqn
+ * @return
+ */
+ public static boolean isPossibleInternalPojoFqn(Fqn<String> fqn)
+ {
+ return (fqn.size() > POJO_INTERNAL_FQN_SIZE
+ && ATTRIBUTE.equals(fqn.get(POJO_INTERNAL_FQN_INDEX)) == false);
+ }
+
+ public static String getIdFromFqn(Fqn<String> fqn, boolean isBuddy)
+ {
+ return (String)fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE +
SESSION_ID_FQN_INDEX : SESSION_ID_FQN_INDEX);
+ }
+
+ /**
+ * Extracts the owner portion of an buddy subtree Fqn.
+ *
+ * @param fqn An Fqn that is a child of the buddy backup root node.
+ */
+ public static String getBuddyOwner(Fqn<String> fqn)
+ {
+ return (String) fqn.get(BUDDY_BACKUP_ROOT_OWNER_INDEX);
+ }
+
+ public static boolean isFqnForOurWebapp(Fqn<String> fqn, String contextHostPath,
boolean isBuddy)
+ {
+ try
+ {
+ if (contextHostPath.equals(fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE +
WEBAPP_FQN_INDEX : WEBAPP_FQN_INDEX))
+ && JSESSION.equals(fqn.get(isBuddy ? BUDDY_BACKUP_ROOT_OWNER_SIZE
+ JSESSION_FQN_INDEX : JSESSION_FQN_INDEX)))
+ return true;
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ // can't be ours; too small; just fall through
+ }
+
+ return false;
+ }
+
+ private FqnUtil() {}
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/GetAttributesServlet.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/GetAttributesServlet.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/GetAttributesServlet.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,58 @@
+/*
+ * 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.cache.integration.websession.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A Servlet that reads attributes from the session.
+ *
+ * @author Brian Stansberry
+ */
+public class GetAttributesServlet extends AbstractServlet
+{
+ private final Set<String> toGet;
+ private final Map<String, Object> readAttributes = new HashMap<String,
Object>();
+
+ public GetAttributesServlet(Set<String> toGet)
+ {
+ this.toGet = new HashSet<String>(toGet);
+ }
+
+ public void handleRequest(Request request)
+ {
+ Session session = extractSession(request);
+ for (String key : toGet)
+ {
+ readAttributes.put(key, session.getAttribute(key));
+ }
+ }
+ public Map<String, Object> getReadAttributes()
+ {
+ return readAttributes;
+ }
+
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/InvalidationServlet.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/InvalidationServlet.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/InvalidationServlet.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,38 @@
+/*
+ * 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.cache.integration.websession.util;
+
+
+/**
+ * A Servlet that invalidates the session.
+ *
+ * @author Brian Stansberry
+ */
+public class InvalidationServlet extends AbstractServlet
+{
+ public void handleRequest(Request request)
+ {
+ extractSession(request).invalidate();
+ }
+
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/MultipleActionServlet.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/MultipleActionServlet.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/MultipleActionServlet.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,51 @@
+/*
+ * 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.cache.integration.websession.util;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A Servlet that call other servlets in order.
+ *
+ * @author Brian Stansberry
+ */
+public class MultipleActionServlet extends AbstractServlet
+{
+ private final List<Servlet> actions;
+
+ public MultipleActionServlet(Servlet... action)
+ {
+ this.actions = Arrays.asList(action);
+ }
+
+ public void handleRequest(Request request)
+ {
+ extractSession(request);
+ for (Servlet action : actions)
+ {
+ action.handleRequest(request);
+ }
+ }
+
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/RemoveAttributesServlet.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/RemoveAttributesServlet.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/RemoveAttributesServlet.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,51 @@
+/*
+ * 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.cache.integration.websession.util;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A Servlet that removes attributes from the session.
+ *
+ * @author Brian Stansberry
+ */
+public class RemoveAttributesServlet extends AbstractServlet
+{
+ private final Set<String> toRemove;
+
+ public RemoveAttributesServlet(Set<String> toRemove)
+ {
+ this.toRemove = new HashSet<String>(toRemove);
+ }
+
+ public void handleRequest(Request request)
+ {
+ Session session = extractSession(request);
+ for (String key : toRemove)
+ {
+ session.removeAttribute(key);
+ }
+ }
+
+}
Added: core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Request.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Request.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Request.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,91 @@
+/*
+ * 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.cache.integration.websession.util;
+
+/**
+ * Mocks the JBoss AS clustered webapp request handling.
+ *
+ * @author Brian Stansberry
+ */
+public class Request
+{
+ private final SessionManager manager;
+ private final String sessionId;
+ private final Servlet servlet;
+ private Session session;
+
+ public Request(SessionManager manager, String sessionId, Servlet servlet)
+ {
+ this.manager = manager;
+ this.sessionId = sessionId;
+ this.servlet = servlet;
+ }
+
+ public void execute()
+ {
+ // Gravitate the session outside of the batch
+ getSession(false);
+
+ manager.startBatch();
+ try
+ {
+ servlet.handleRequest(this);
+ }
+ finally
+ {
+ try
+ {
+ if (session != null && session.isValid())
+ session.store();
+ }
+ finally
+ {
+ manager.endBatch();
+ }
+ }
+ }
+
+ /**
+ * Meant for internal use in this class and by a Servlet; test driver
+ * should get a session ref from a Servlet impl.
+ */
+ public Session getSession(boolean create)
+ {
+ if (session == null && sessionId != null)
+ {
+ session = manager.findSession(sessionId);
+ }
+
+ if (session != null && !session.isValid())
+ session = null;
+
+ if (create && session == null)
+ session = manager.createSession();
+
+ if (session != null)
+ session.access();
+
+ return session;
+ }
+
+}
Added: core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Servlet.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Servlet.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Servlet.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,34 @@
+/*
+ * 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.cache.integration.websession.util;
+
+/**
+ * Implementations of this interface will actually do something with
+ * the session.
+ *
+ * @author Brian Stansberry
+ */
+public interface Servlet
+{
+ void handleRequest(Request request);
+}
Added: core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Session.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Session.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/Session.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,200 @@
+/*
+ * 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.cache.integration.websession.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Mock version of a JBoss AS clustered session.
+ *
+ * @author Brian Stansberry
+ */
+public class Session
+{
+ private volatile SessionMetadata metadata = new SessionMetadata();
+ private final AtomicInteger version = new AtomicInteger();
+ private final AtomicLong timestamp = new AtomicLong(metadata.creationTime);
+ private final Map<String, Object> attributes = new ConcurrentHashMap<String,
Object>();
+ private final Set<String> modifiedKeys = new HashSet<String>();
+ private final Set<String> removedKeys = new HashSet<String>();
+ private final SessionManager manager;
+ private boolean outdated;
+ private boolean metadataDirty = true;
+
+ public Session(SessionManager manager)
+ {
+ this.manager = manager;
+ }
+
+ public String getId()
+ {
+ return metadata.id;
+ }
+
+ public long getCreationTime()
+ {
+ return metadata.creationTime;
+ }
+
+ public boolean isValid()
+ {
+ return metadata.valid;
+ }
+
+ public void invalidate()
+ {
+ this.metadata.valid = false;
+ manager.removeSession(getId(), false, true);
+ }
+
+ public Object setAttribute(String key, Object value)
+ {
+ modifiedKeys.add(key);
+ removedKeys.remove(key);
+ return attributes.put(key, value);
+ }
+
+ public Object removeAttribute(String key)
+ {
+ removedKeys.add(key);
+ modifiedKeys.remove(key);
+ return attributes.remove(key);
+ }
+
+ public Object getAttribute(String key)
+ {
+ return attributes.get(key);
+ }
+
+ public AtomicLong getTimestamp()
+ {
+ return timestamp;
+ }
+
+ public void setMetadataDirty()
+ {
+ this.metadataDirty = true;
+ }
+
+ public void access()
+ {
+ this.timestamp.set(System.currentTimeMillis());
+ }
+
+ public void store()
+ {
+ version.incrementAndGet();
+
+ switch (manager.getGranularity())
+ {
+ case SESSION:
+ manager.storeSession(getId(), version, timestamp,
getMetadataForReplication(), getAttributesForReplication());
+ break;
+ case ATTRIBUTE:
+ Map<String, Object> modified = new HashMap<String, Object>();
+ for (String key : modifiedKeys)
+ {
+ modified.put(key, attributes.get(key));
+ }
+ manager.storeSession(getId(), version, timestamp,
getMetadataForReplication(), modified, removedKeys);
+ break;
+ case FIELD:
+ throw new UnsupportedOperationException("implement me");
+ }
+ this.metadataDirty = false;
+ }
+
+ public SessionManager getManager()
+ {
+ return manager;
+ }
+
+ protected Map<String, Object> getAttributes()
+ {
+ return attributes;
+ }
+
+ protected SessionMetadata getMetadata()
+ {
+ return metadata;
+ }
+
+ protected AtomicInteger getVersion()
+ {
+ return version;
+ }
+
+ protected Map<String, Object> getAttributesForReplication()
+ {
+ return attributes;
+ }
+
+ private SessionMetadata getMetadataForReplication()
+ {
+ return metadataDirty ? metadata : null;
+ }
+
+ protected void replicateAttributeChanges()
+ {
+ // no-op
+ }
+
+ protected boolean isOutdated()
+ {
+ return outdated;
+ }
+
+ protected void setOutdated(boolean outdated)
+ {
+ this.outdated = outdated;
+ }
+
+ protected void update(AtomicInteger version, AtomicLong timestamp, SessionMetadata
metadata,
+ Map<String, Object> attributes)
+ {
+ if (version == null)
+ throw new IllegalArgumentException("version is null");
+ if (timestamp == null)
+ throw new IllegalArgumentException("timestamp is null");
+ if (metadata == null)
+ throw new IllegalArgumentException("metadata is null");
+ if (attributes == null)
+ throw new IllegalArgumentException("attributes is null");
+
+ this.version.set(version.get());
+ this.timestamp.set(version.get());
+ this.metadata = metadata;
+
+ this.attributes.clear();
+ this.attributes.putAll(attributes);
+
+ this.outdated = false;
+ }
+
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionManager.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionManager.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionManager.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,530 @@
+/*
+ * 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.cache.integration.websession.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheManager;
+import org.jboss.cache.CacheStatus;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.BuddyReplicationConfig;
+import org.jboss.cache.integration.websession.util.WebAppMetadata.Granularity;
+import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.NodeModified;
+import org.jboss.cache.notifications.annotation.NodeRemoved;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.notifications.event.NodeRemovedEvent;
+
+/**
+ * Mock version of a JBoss AS web session manager.
+ *
+ * @author Brian Stansberry
+ */
+@CacheListener
+public class SessionManager
+{
+
+ private static final Integer VERSION = Integer.valueOf(0);
+ private static final Integer TIMESTAMP = Integer.valueOf(1);
+ private static final Integer METADATA = Integer.valueOf(2);
+ private static final Integer ATTRIBUTES = Integer.valueOf(3);
+
+ private final CacheManager cacheManager;
+ private final WebAppMetadata appMetadata;
+ private final String contextHostName;
+ private final Fqn<String> baseFqn;
+ private final Map<String, Session> sessions = new ConcurrentHashMap<String,
Session>();
+ private Cache<Object, Object> cache;
+ private TransactionManager tm;
+ private boolean buddyReplication;
+ private boolean started;
+ private final boolean fieldBased;
+ private final boolean attributeBased;
+ private final Log log = LogFactory.getLog(getClass());
+
+ // ------------------------------------------------------------ Constructors
+
+ public SessionManager(CacheManager cacheManager, WebAppMetadata metadata)
+ {
+ this.cacheManager = cacheManager;
+ this.appMetadata = metadata;
+ this.contextHostName = appMetadata.warName + "_localhost";
+ this.baseFqn = Fqn.fromElements(FqnUtil.JSESSION, contextHostName);
+ this.fieldBased = appMetadata.granularity == Granularity.FIELD;
+ this.attributeBased = appMetadata.granularity == Granularity.ATTRIBUTE;
+ }
+
+ // --------------------------------------------------------- Test Driver API
+
+ public boolean isStarted()
+ {
+ return started;
+ }
+
+ public void start()
+ {
+ this.started = true;;
+
+ try
+ {
+ this.cache = cacheManager.getCache(appMetadata.cacheConfigName, false);
+ }
+ catch (RuntimeException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+
+ cache.addCacheListener(this);
+
+ if (cache.getCacheStatus() != CacheStatus.STARTED)
+ {
+ cache.start();
+ }
+ this.tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
+ if (tm == null)
+ {
+ throw new IllegalStateException("tm is null");
+ }
+ BuddyReplicationConfig brc = cache.getConfiguration().getBuddyReplicationConfig();
+ this.buddyReplication = brc != null && brc.isEnabled();
+ }
+
+ public void stop()
+ {
+ if (started)
+ {
+
+
+ if (cache != null)
+ {
+ cache.removeCacheListener(this);
+
+ // FIXME see if we need more sophisticated cache cleanup
+ cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+ cache.removeNode(baseFqn);
+ cacheManager.releaseCache(appMetadata.cacheConfigName);
+ cache = null;
+ }
+ }
+ }
+
+ /**
+ * Allows test driver to mock Tomcat background processes' expiration
+ * of an overage session.
+ *
+ * FIXME deal with buddy backup tree
+ *
+ * @param id the session id
+ */
+ public void expireSession(String id)
+ {
+ Session session = removeSession(id, true, true);
+ if (session != null)
+ session.getMetadata().valid = false;
+ }
+
+ /**
+ * Allows test driver to mock Tomcat background processes' passivation
+ * of a session.
+ *
+ * FIXME deal with buddy backup tree
+ *
+ * @param id the session id
+ */
+ public void passivate(String id)
+ {
+ if (!appMetadata.passivation)
+ throw new IllegalStateException("passivation not supported");
+
+ sessions.remove(id);
+
+ cache.evict(getSessionFqn(id), true);
+ }
+
+ public Cache<Object, Object> getCache()
+ {
+ return cache;
+ }
+
+ public String getContextHostName()
+ {
+ return contextHostName;
+ }
+
+
+
+ // ----------------------------------------------------------- CacheListener
+
+
+ @NodeRemoved
+ public void nodeRemoved(NodeRemovedEvent event)
+ {
+ if (event.isPre())
+ return;
+
+ boolean local = event.isOriginLocal();
+ if (!fieldBased && local)
+ return;
+
+ @SuppressWarnings("unchecked")
+ Fqn<String> fqn = event.getFqn();
+ boolean isBuddy = FqnUtil.isBuddyFqn(fqn);
+
+ if (!local
+ && FqnUtil.isFqnSessionRootSized(fqn, isBuddy)
+ && FqnUtil.isFqnForOurWebapp(fqn, contextHostName, isBuddy))
+ {
+ // A session has been invalidated from another node;
+ // need to inform manager
+ String sessId = FqnUtil.getIdFromFqn(fqn, isBuddy);
+ removeSession(sessId, true, false);
+ }
+ else if (local && !isBuddy
+ && FqnUtil.isPossibleInternalPojoFqn(fqn)
+ && FqnUtil.isFqnForOurWebapp(fqn, contextHostName, isBuddy))
+ {
+ // One of our sessions' pojos is modified; need to inform
+ // the manager so it can mark the session dirty
+ String sessId = FqnUtil.getIdFromFqn(fqn, isBuddy);
+ notifyLocalAttributeModification(sessId);
+ }
+ }
+
+ @NodeModified
+ public void nodeModified(NodeModifiedEvent event)
+ {
+ if (event.isPre())
+ return;
+
+ boolean local = event.isOriginLocal();
+ if (!fieldBased && local)
+ return;
+
+ @SuppressWarnings("unchecked")
+ Fqn<String> fqn = event.getFqn();
+ boolean isBuddy = FqnUtil.isBuddyFqn(fqn);
+
+ if (!local
+ && FqnUtil.isFqnSessionRootSized(fqn, isBuddy)
+ && FqnUtil.isFqnForOurWebapp(fqn, contextHostName, isBuddy))
+ {
+ // Query if we have version value in the distributed cache.
+ // If we have a version value, compare the version and invalidate if necessary.
+ @SuppressWarnings("unchecked")
+ Map<Object, Object> data = event.getData();
+ AtomicInteger version = (AtomicInteger) data.get(VERSION);
+ if(version != null)
+ {
+ String realId = FqnUtil.getIdFromFqn(fqn, isBuddy);
+ String owner = isBuddy ? FqnUtil.getBuddyOwner(fqn) : null;
+ AtomicLong timestamp = (AtomicLong) data.get(TIMESTAMP);
+ if (timestamp == null)
+ {
+ log.warn("No timestamp attribute found in " + fqn);
+ }
+ else
+ {
+ // Notify the manager that a session has been updated
+ boolean updated = sessionChangedInDistributedCache(realId, owner,
+ version.get());
+ if (!updated && !isBuddy)
+ {
+ log.warn("Possible concurrency problem: Replicated version id
" +
+ version + " is less than or equal to in-memory version
for session " + realId);
+ }
+ /*else
+ {
+ We have a local session but got a modification for the buddy tree.
+ This means another node is in the process of taking over the session;
+ we don't worry about it
+ }
+ */
+ }
+ }
+ else if (!attributeBased) // other granularities can modify attributes only
+ {
+ log.warn("No version attribute found in " + fqn);
+ }
+ }
+ else if (local && !isBuddy
+ && FqnUtil.isPossibleInternalPojoFqn(fqn)
+ && FqnUtil.isFqnForOurWebapp(fqn, contextHostName, isBuddy))
+ {
+ // One of our sessions' pojos is modified; need to inform
+ // the manager so it can mark the session dirty
+ String sessId = FqnUtil.getIdFromFqn(fqn, isBuddy);
+ notifyLocalAttributeModification(sessId);
+ }
+ }
+
+ // ------------------------------------------------------------ Internal API
+
+ protected boolean isBatchStarted()
+ {
+ try
+ {
+ return tm.getTransaction() != null;
+ }
+ catch (SystemException e)
+ {
+ throw new RuntimeException("failed checking for tx", e);
+ }
+ }
+
+ protected void startBatch()
+ {
+ try
+ {
+ tm.begin();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("failed starting tx", e);
+ }
+ }
+
+ protected void endBatch()
+ {
+ try
+ {
+ tm.commit();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("failed committing tx", e);
+ }
+ }
+
+ protected Session findSession(String id)
+ {
+ Session session = sessions.get(id);
+ if (session == null || session.isOutdated())
+ {
+ session = loadSession(id);
+ if (session != null)
+ {
+ sessions.put(id, session);
+ }
+ }
+ return session;
+ }
+
+ protected Session createSession()
+ {
+ Session session = createEmptySession();
+ sessions.put(session.getId(), session);
+ return session;
+ }
+
+ protected Session removeSession(String id, boolean localOnly, boolean localCall)
+ {
+ Session session = sessions.remove(id);
+ if (localCall)
+ {
+ // TODO mock the bit where each individual attribute is removed first
+
+ // Remove the session node
+ if (localOnly)
+ {
+ cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+ }
+ cache.removeNode(getSessionFqn(id));
+ }
+
+ return session;
+ }
+
+ protected Granularity getGranularity()
+ {
+ return appMetadata.granularity;
+ }
+
+ private Fqn<String> getSessionFqn(String id)
+ {
+ return Fqn.fromRelativeElements(baseFqn, id);
+ }
+
+ private Session createEmptySession()
+ {
+ Session session = null;
+ switch (appMetadata.granularity)
+ {
+ case SESSION:
+ case ATTRIBUTE:
+ session = new Session(this);
+ break;
+ case FIELD:
+ throw new IllegalStateException("implement");
+ }
+ return session;
+ }
+
+ /**
+ * JBC read of a session.
+ */
+ private Session loadSession(String id)
+ {
+ Session session = null;
+
+ boolean startTx = !isBatchStarted();
+ if (startTx)
+ startBatch();
+ Map<Object, Object> data = null;
+ try
+ {
+ if (buddyReplication)
+ {
+
cache.getInvocationContext().getOptionOverrides().setForceDataGravitation(true);
+ }
+ data = cache.getData(getSessionFqn(id));
+ }
+ finally
+ {
+ if (startTx)
+ endBatch();
+ }
+
+ if (data != null)
+ {
+ session = createEmptySession();
+ AtomicInteger version = (AtomicInteger) data.get(VERSION);
+ AtomicLong timestamp = (AtomicLong) data.get(TIMESTAMP);
+ SessionMetadata metadata = (SessionMetadata) data.get(METADATA);
+ Map<String, Object> attributes = loadSessionAttributes(id, data);
+ session.update(version, timestamp, metadata, attributes);
+ }
+ return session;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Map<String, Object> loadSessionAttributes(String id, Map<Object,
Object> sessionNodeData)
+ {
+ Map<String, Object> result = new HashMap<String, Object>();
+ switch (appMetadata.granularity)
+ {
+ case SESSION:
+ result.putAll((Map<String, Object>) sessionNodeData.get(ATTRIBUTES));
+ break;
+ case ATTRIBUTE:
+ for (Map.Entry<Object, Object> entry : sessionNodeData.entrySet())
+ {
+ if (entry.getKey() instanceof String)
+ {
+ result.put((String) entry.getKey(), entry.getValue());
+ }
+ }
+ break;
+ case FIELD:
+ throw new IllegalStateException("implement");
+ }
+
+ return result;
+ }
+
+ /**
+ * JBC write for granularity SESSION.
+ */
+ protected void storeSession(String id, AtomicInteger version, AtomicLong timestamp,
SessionMetadata metadata, Map<String, Object> attributes)
+ {
+ if (version == null)
+ throw new IllegalArgumentException("version is null");
+ if (timestamp == null)
+ throw new IllegalArgumentException("timestamp is null");
+
+ Fqn<String> fqn = getSessionFqn(id);
+
+ Map<Object, Object> data = new HashMap<Object, Object>();
+ data.put(VERSION, version);
+ data.put(TIMESTAMP, timestamp);
+ if (metadata != null)
+ {
+ data.put(METADATA, metadata);
+ }
+ if (attributes != null)
+ {
+ data.put(ATTRIBUTES, attributes);
+ }
+
+ cache.put(fqn, data);
+ }
+
+ /**
+ * JBC write for granularity ATTRIBUTE.
+ */
+ protected void storeSession(String id, AtomicInteger version, AtomicLong timestamp,
SessionMetadata metadata, Map<String, Object> modifiedAttributes, Set<String>
removedAttributes)
+ {
+ storeSession(id, version, timestamp, metadata, null);
+
+ Fqn<String> fqn = getSessionFqn(id);
+
+ if (modifiedAttributes != null)
+ {
+ cache.put(fqn, modifiedAttributes);
+ }
+
+ if (removedAttributes != null)
+ {
+ for (String key : removedAttributes)
+ {
+ cache.remove(fqn, key);
+ }
+ }
+ }
+
+ private boolean sessionChangedInDistributedCache(String realId, String owner, int
version)
+ {
+ Session session = sessions.get(realId);
+ if (session != null)
+ {
+ session.setOutdated(true);
+ if (session.getVersion().get() >= version)
+ return false;
+ }
+ return true;
+ }
+
+ private void notifyLocalAttributeModification(String sessId)
+ {
+ Session session = sessions.get(sessId);
+ if (session != null)
+ {
+ session.setOutdated(true);
+ }
+ }
+
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionManagerSupport.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionManagerSupport.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionManagerSupport.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,73 @@
+/*
+ * 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.cache.integration.websession.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.cache.CacheManager;
+
+/**
+ * @author Brian Stansberry
+ *
+ */
+public class SessionManagerSupport
+{
+ /**
+ * For each thread holds list of session managers created using this factory.
+ */
+ private static final ThreadLocal<List<SessionManager>>
threadSessionManagers =
+ new ThreadLocal<List<SessionManager>>()
+ {
+ @Override
+ protected List<SessionManager> initialValue()
+ {
+ return new ArrayList<SessionManager>();
+ }
+ };
+
+ public static List<SessionManager> createSessionManagers(List<CacheManager>
cacheManagers, WebAppMetadata metadata)
+ {
+ List<SessionManager> existing = threadSessionManagers.get();
+ existing.clear();
+ for (CacheManager cm : cacheManagers)
+ {
+ SessionManager sm = new SessionManager(cm, metadata);
+ existing.add(sm);
+ }
+
+ return new ArrayList<SessionManager>(existing);
+ }
+
+ public static void tearDown()
+ {
+ List<SessionManager> existing = threadSessionManagers.get();
+ for (SessionManager sm : existing)
+ {
+ if (sm.isStarted())
+ sm.stop();
+ }
+ existing.clear();
+ }
+
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionMetadata.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionMetadata.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SessionMetadata.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,42 @@
+/*
+ * 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.cache.integration.websession.util;
+
+import java.io.Serializable;
+
+/**
+ * Metadata about a session that is only replicated infrequently.
+ *
+ * @author Brian Stansberry
+ */
+public class SessionMetadata implements Serializable
+{
+ /** The serialVersionUID */
+ private static final long serialVersionUID = 1L;
+
+ private static volatile int counter;
+
+ public final String id = String.valueOf(++counter);
+ public final long creationTime = System.currentTimeMillis();
+ public boolean valid = true;
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SetAttributesServlet.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SetAttributesServlet.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/SetAttributesServlet.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,51 @@
+/*
+ * 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.cache.integration.websession.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A Servlet that sets attributes on the session.
+ *
+ * @author Brian Stansberry
+ */
+public class SetAttributesServlet extends AbstractServlet
+{
+ private final Map<String, Object> toSet;
+
+ public SetAttributesServlet(Map<String, Object> toSet)
+ {
+ this.toSet = new HashMap<String, Object>(toSet);
+ }
+
+ public void handleRequest(Request request)
+ {
+ Session session = extractSession(request);
+ for (Map.Entry<String, Object> entry : toSet.entrySet())
+ {
+ session.setAttribute(entry.getKey(), entry.getValue());
+ }
+ }
+
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/WebAppMetadata.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/WebAppMetadata.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/WebAppMetadata.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,53 @@
+/*
+ * 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.cache.integration.websession.util;
+
+/**
+ * Metadata about a webapp; mocks the object created from a jboss-web.xml.
+ *
+ * @author Brian Stansberry
+ */
+public class WebAppMetadata
+{
+ public static final String DEFAULT_CACHE_CONFIG = "standard-session-cache";
+
+ public enum Granularity { SESSION, ATTRIBUTE, FIELD };
+
+ public final String warName;
+ public final String cacheConfigName;
+ public final boolean passivation;
+ public final Granularity granularity;
+
+ public WebAppMetadata(String warName)
+ {
+ this(warName, DEFAULT_CACHE_CONFIG, true, Granularity.SESSION);
+ }
+
+ public WebAppMetadata(String warName, String cacheConfigName, boolean passivation,
Granularity granularity)
+ {
+ this.warName = warName;
+ this.cacheConfigName = cacheConfigName;
+ this.passivation = passivation;
+ this.granularity = granularity;
+ }
+}
Added:
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/WebSessionTestBase.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/WebSessionTestBase.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/integration/websession/util/WebSessionTestBase.java 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,157 @@
+/*
+ * 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.cache.integration.websession.util;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheManager;
+import org.jboss.cache.CacheStatus;
+import org.jboss.cache.integration.CacheManagerSupport;
+import org.jboss.cache.integration.UnitTestCacheFactoryConfigurationRegistry;
+import org.jboss.cache.integration.websession.util.WebAppMetadata.Granularity;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+
+/**
+ * Base class that handles standard before/after class/method stuff.
+ *
+ * @author Brian Stansberry
+ */
+public abstract class WebSessionTestBase
+{
+ public static final String DEFAULT_CACHE_CONFIG_FILE_NAME =
"configs/integration/web-session-cache-configs.xml";
+
+ private AtomicInteger testCount = new AtomicInteger();
+ private List<CacheManager> cacheManagers;
+ private List<SessionManager> sessionManagers;
+
+ @BeforeClass(alwaysRun = true)
+ public void beforeClass() throws Exception
+ {
+ cacheManagers = CacheManagerSupport.createCacheManagers(getNumCacheManagers(),
getCacheConfigFileName(), getStacksXmlFileName());
+ if (getStartCachesInBeforeClass() && getCacheConfigName() != null)
+ {
+ for (CacheManager cm : cacheManagers)
+ {
+ Cache<Object, Object> cache = cm.getCache(getCacheConfigName(), true);
+ if (cache.getCacheStatus() != CacheStatus.STARTED)
+ cache.start();
+ }
+ }
+ }
+
+ @AfterClass(alwaysRun = true)
+ public void afterClass()
+ {
+ CacheManagerSupport.tearDown();
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void setup()
+ {
+ testCount.incrementAndGet();
+
+ if (getCreateManagersInSetup() && getWebAppMetaData() != null)
+ {
+ sessionManagers = SessionManagerSupport.createSessionManagers(cacheManagers,
getWebAppMetaData());
+ for (SessionManager mgr : sessionManagers)
+ {
+ mgr.start();
+ }
+ }
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown() throws Exception
+ {
+ SessionManagerSupport.tearDown();
+ }
+
+ protected abstract int getNumCacheManagers();
+
+ protected String getCacheConfigFileName()
+ {
+ return DEFAULT_CACHE_CONFIG_FILE_NAME;
+ }
+
+ protected String getStacksXmlFileName()
+ {
+ return UnitTestCacheFactoryConfigurationRegistry.DEFAULT_STACKS_XML_RESOURCE;
+ }
+
+ protected boolean getStartCachesInBeforeClass()
+ {
+ return true;
+ }
+
+ protected abstract String getCacheConfigName();
+
+ protected boolean getCreateManagersInSetup()
+ {
+ return false;
+ }
+
+ protected boolean getUsePassivation()
+ {
+ return true;
+ }
+
+ protected Granularity getGranularity()
+ {
+ return Granularity.SESSION;
+ }
+
+ protected WebAppMetadata getWebAppMetaData()
+ {
+ return new WebAppMetadata(getWarNameForTest(), getCacheConfigName(),
getUsePassivation(), getGranularity());
+ }
+
+ protected List<CacheManager> getCacheManagers()
+ {
+ return cacheManagers;
+ }
+
+ protected List<SessionManager> getSessionManagers()
+ {
+ return sessionManagers;
+ }
+
+ protected int getTestCount()
+ {
+ return testCount.get();
+ }
+
+ protected String getWarNameForTest()
+ {
+ return getClass().getSimpleName() + getTestCount();
+ }
+
+ protected Object getAttributeValue(int value)
+ {
+ return Integer.valueOf(value);
+ }
+}
Added: core/trunk/src/test/resources/configs/integration/hibernate-cache-configs.xml
===================================================================
--- core/trunk/src/test/resources/configs/integration/hibernate-cache-configs.xml
(rev 0)
+++
core/trunk/src/test/resources/configs/integration/hibernate-cache-configs.xml 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,741 @@
+<cache-configs>
+
+ <!--
+ | Following are JBoss Cache configurations suitable for different
+ | Hibernate 2nd Level Cache uses (e.g. entities vs. queries).
+ |
+ | In all cases, TransactionManager configuration not required.
+ | Hibernate will plug in its own transaction manager integration.
+ -->
+
+
+ <!-- A config appropriate for entity/collection caching. -->
+ <cache-config name="optimistic-entity">
+
+ <!-- Node locking scheme -->
+ <attribute name="NodeLockingScheme">OPTIMISTIC</attribute>
+
+ <!-- Mode of communication with peer caches.
+
+ INVALIDATION_SYNC is highly recommended as the mode for use
+ with entity and collection caches.
+ -->
+ <attribute name="CacheMode">INVALIDATION_SYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-optimistic-entity</attribute>
+
+ <!-- Use a UDP (multicast) based stack. A udp-sync stack might be
+ slightly better (no JGroups FC) but we stick with udp to
+ help ensure this cache and others like timestamps-cache
+ that require FC can use the same underlying JGroups resources. -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Whether or not to fetch state on joining a cluster. -->
+ <attribute name="FetchInMemoryState">false</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup. Ignored if FetchInMemoryState=false.
+ -->
+ <attribute name="StateRetrievalTimeout">20000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">20000</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!--
+ Indicate whether to use marshalling or not. Set this to true if you
+ are running under a scoped class loader, e.g., inside an application
+ server.
+ -->
+ <attribute
name="UseRegionBasedMarshalling">true</attribute>
+ <!-- Must match the value of "useRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">true</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <!-- Eviction policy configurations. -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
+ <!-- Cache wide default -->
+ <region name="/_default_">
+ <!-- Evict LRU node once we have more than this number of nodes -->
+ <attribute name="maxNodes">10000</attribute>
+ <!-- And, evict any node that hasn't been accessed in this many
seconds -->
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ <!-- Don't evict a node that's been accessed within this many
seconds.
+ Set this to a value greater than your max expected transaction length.
-->
+ <attribute name="minTimeToLiveSeconds">120</attribute>
+ </region>
+ <!-- Don't ever evict modification timestamps -->
+ <region name="/TS"
policyClass="org.jboss.cache.eviction.NullEvictionPolicy"/>
+ </config>
+ </attribute>
+
+ </cache-config>
+
+ <!-- A config appropriate for entity/collection caching that
+ uses pessimistic locking -->
+ <cache-config name="pessimistic-entity">
+
+ <!-- Node locking scheme -->
+ <attribute
name="NodeLockingScheme">PESSIMISTIC</attribute>
+
+ <!--
+ READ_COMMITTED is as strong as necessary for most
+ 2nd Level Cache use cases.
+ -->
+ <attribute
name="IsolationLevel">READ_COMMITTED</attribute>
+
+ <!-- Mode of communication with peer caches.
+
+ INVALIDATION_SYNC is highly recommended as the mode for use
+ with entity and collection caches.
+ -->
+ <attribute name="CacheMode">INVALIDATION_SYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-pessimistic-entity</attribute>
+
+ <!-- Use a UDP (multicast) based stack. A udp-sync stack might be
+ slightly better (no JGroups FC) but we stick with udp to
+ help ensure this cache and others like timestamps-cache
+ that require FC can use the same underlying JGroups resources. -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Whether or not to fetch state on joining a cluster. -->
+ <attribute name="FetchInMemoryState">false</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup. Ignored if FetchInMemoryState=false.
+ -->
+ <attribute name="StateRetrievalTimeout">20000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">20000</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!--
+ Indicate whether to use marshalling or not. Set this to true if you
+ are running under a scoped class loader, e.g., inside an application
+ server.
+ -->
+ <attribute
name="UseRegionBasedMarshalling">true</attribute>
+ <!-- Must match the value of "useRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">true</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <!-- Eviction policy configurations. -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
+ <!-- Cache wide default -->
+ <region name="/_default_">
+ <!-- Evict LRU node once we have more than this number of nodes -->
+ <attribute name="maxNodes">10000</attribute>
+ <!-- And, evict any node that hasn't been accessed in this many
seconds -->
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ <!-- Don't evict a node that's been accessed within this many
seconds.
+ Set this to a value greater than your max expected transaction length.
-->
+ <attribute name="minTimeToLiveSeconds">120</attribute>
+ </region>
+ <!-- Don't ever evict modification timestamps -->
+ <region name="/TS"
policyClass="org.jboss.cache.eviction.NullEvictionPolicy"/>
+ </config>
+ </attribute>
+
+ </cache-config>
+
+
+
+ <!-- Same as "pessimistic-entity" but here we use REPEATABLE_READ
+ instead of READ_COMMITTED. REPEATABLE_READ is only useful if the
+ application evicts/clears entities from the Hibernate Session and
+ then expects to repeatably re-read them in the same transaction.
+ Otherwise, the Session's internal cache provides a repeatable-read
+ semantic. Before choosing this config, carefully read the docs
+ and make sure you really need REPEATABLE_READ.
+ -->
+ <cache-config name="pessimistic-entity-repeatable">
+
+ <!-- Node locking scheme -->
+ <attribute
name="NodeLockingScheme">PESSIMISTIC</attribute>
+
+ <!-- Here we use REPEATABLE_READ. -->
+ <attribute
name="IsolationLevel">REPEATABLE_READ</attribute>
+
+ <!-- Mode of communication with peer caches.
+
+ INVALIDATION_SYNC is highly recommended as the mode for use
+ with entity and collection caches.
+ -->
+ <attribute name="CacheMode">INVALIDATION_SYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-pessimistic-entity-rr</attribute>
+
+ <!-- Use a UDP (multicast) based stack. A udp-sync stack might be
+ slightly better (no JGroups FC) but we stick with udp to
+ help ensure this cache and others like timestamps-cache
+ that require FC can use the same underlying JGroups resources. -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Whether or not to fetch state on joining a cluster. -->
+ <attribute name="FetchInMemoryState">false</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup. Ignored if FetchInMemoryState=false.
+ -->
+ <attribute name="StateRetrievalTimeout">20000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">20000</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!--
+ Indicate whether to use marshalling or not. Set this to true if you
+ are running under a scoped class loader, e.g., inside an application
+ server.
+ -->
+ <attribute
name="UseRegionBasedMarshalling">true</attribute>
+ <!-- Must match the value of "useRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">true</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <!-- Eviction policy configurations. -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
+ <!-- Cache wide default -->
+ <region name="/_default_">
+ <!-- Evict LRU node once we have more than this number of nodes -->
+ <attribute name="maxNodes">10000</attribute>
+ <!-- And, evict any node that hasn't been accessed in this many
seconds -->
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ <!-- Don't evict a node that's been accessed within this many
seconds.
+ Set this to a value greater than your max expected transaction length.
-->
+ <attribute name="minTimeToLiveSeconds">120</attribute>
+ </region>
+ <!-- Don't ever evict modification timestamps -->
+ <region name="/TS"
policyClass="org.jboss.cache.eviction.NullEvictionPolicy"/>
+ </config>
+ </attribute>
+
+ </cache-config>
+
+
+
+ <!-- A config appropriate for query caching. Does not replicate
+ queries. DO NOT STORE TIMESTAMPS IN THIS CACHE.
+ -->
+ <cache-config name="local-query">
+
+ <!-- Node locking scheme -->
+ <attribute name="NodeLockingScheme">OPTIMISTIC</attribute>
+
+ <attribute name="CacheMode">LOCAL</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!-- Eviction policy configurations. -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
+ <!-- Cache wide default -->
+ <region name="/_default_">
+ <!-- Evict LRU node once we have more than this number of nodes -->
+ <attribute name="maxNodes">10000</attribute>
+ <!-- And, evict any node that hasn't been accessed in this many
seconds -->
+ <attribute
name="timeToLiveSeconds">1000</attribute>
+ <!-- Don't evict a node that's been accessed within this many
seconds.
+ Set this to a value greater than your max expected transaction
length. -->
+ <attribute
name="minTimeToLiveSeconds">120</attribute>
+ </region>
+ <!-- Don't ever evict modification timestamps -->
+ <region name="/TS"
policyClass="org.jboss.cache.eviction.NullEvictionPolicy"/>
+ </config>
+ </attribute>
+
+ </cache-config>
+
+
+ <!-- A query cache that replicates queries. Replication is asynchronous.
+ DO NOT STORE TIMESTAMPS IN THIS CACHE as no initial state transfer
+ is performed.
+ -->
+ <cache-config name="replicated-query">
+
+ <!-- Node locking scheme -->
+ <attribute name="NodeLockingScheme">OPTIMISTIC</attribute>
+
+ <!-- Mode of communication with peer caches.
+
+ REPL_ASYNC means replicate but sender does not block waiting for
+ peers to acknowledge applying the change. Valid for queries as
+ the timestamp cache mechanism will allow Hibernate to discard
+ out-of-date queries.
+ -->
+ <attribute name="CacheMode">REPL_ASYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-replicated-query</attribute>
+
+ <!-- Use a UDP (multicast) based stack -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Whether or not to fetch state on joining a cluster. -->
+ <attribute name="FetchInMemoryState">false</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup. Ignored if FetchInMemoryState=false.
+ -->
+ <attribute name="StateRetrievalTimeout">20000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">20000</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!--
+ Indicate whether to use marshalling or not. Set this to true if you
+ are running under a scoped class loader, e.g., inside an application
+ server.
+ -->
+ <attribute
name="UseRegionBasedMarshalling">true</attribute>
+ <!-- Must match the value of "useRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">true</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <!-- Eviction policy configurations. -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
+ <!-- Cache wide default -->
+ <region name="/_default_">
+ <!-- Evict LRU node once we have more than this number of nodes -->
+ <attribute name="maxNodes">10000</attribute>
+ <!-- And, evict any node that hasn't been accessed in this many
seconds -->
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ <!-- Don't evict a node that's been accessed within this many
seconds.
+ Set this to a value greater than your max expected transaction length.
-->
+ <attribute name="minTimeToLiveSeconds">120</attribute>
+ </region>
+ <!-- Don't ever evict modification timestamps -->
+ <region name="/TS"
policyClass="org.jboss.cache.eviction.NullEvictionPolicy"/>
+ </config>
+ </attribute>
+
+ </cache-config>
+
+
+
+ <!-- Optimized for timestamp caching. A clustered timestamp cache
+ is required if query caching is used, even if the query cache
+ itself is configured with CacheMode=LOCAL.
+ -->
+ <cache-config name="timestamps-cache">
+
+ <!-- Node locking scheme -->
+ <attribute
name="NodeLockingScheme">PESSIMISTIC</attribute>
+
+ <!--
+ READ_COMMITTED is as strong as necessary.
+ -->
+ <attribute
name="IsolationLevel">REPEATABLE_READ</attribute>
+
+ <!-- Cannot be INVALIDATION. ASYNC for improved performance. -->
+ <attribute name="CacheMode">REPL_ASYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-timestamps-cache</attribute>
+
+ <!-- Use a UDP (multicast) based stack -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Used for timestamps, so must fetch state. -->
+ <attribute name="FetchInMemoryState">true</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup. Ignored if FetchInMemoryState=false.
+ -->
+ <attribute name="StateRetrievalTimeout">20000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">20000</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!--
+ Indicate whether to use marshalling or not. Set this to true if you
+ are running under a scoped class loader, e.g., inside an application
+ server.
+ -->
+ <attribute
name="UseRegionBasedMarshalling">true</attribute>
+ <!-- Must match the value of "useRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">true</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <!-- Eviction policy configurations. -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
+ <!-- Cache wide default -->
+ <region name="/_default_">
+ <!-- Evict LRU node once we have more than this number of nodes -->
+ <attribute name="maxNodes">10000</attribute>
+ <!-- And, evict any node that hasn't been accessed in this many
seconds -->
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ <!-- Don't evict a node that's been accessed within this many
seconds.
+ Set this to a value greater than your max expected transaction length.
-->
+ <attribute name="minTimeToLiveSeconds">120</attribute>
+ </region>
+ <!-- Don't ever evict modification timestamps -->
+ <region name="/TS"
policyClass="org.jboss.cache.eviction.NullEvictionPolicy"/>
+ </config>
+ </attribute>
+
+ </cache-config>
+
+
+
+ <!-- A config appropriate for a cache that's shared for
+ entity, collection, query and timestamp caching. Not an advised
+ configuration, since it requires cache mode REPL_SYNC, which is the
+ least efficient mode. Also requires a full state transfer at startup,
+ which can be expensive. Uses optimistic locking -->
+ <cache-config name="optimistic-shared">
+
+ <!-- Node locking scheme -->
+ <attribute name="NodeLockingScheme">OPTIMISTIC</attribute>
+
+ <!-- Must use REPL since used for timestamp caching.
+ Must use SYNC to maintain cache consistency for entities.
+ -->
+ <attribute name="CacheMode">REPL_SYNC</attribute>
+
+ <!-- With OPTIMISTIC with replication we need to use synchronous commits.
-->
+ <attribute name="SyncCommitPhase">true</attribute>
+ <attribute name="SyncRollbackPhase">true</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-optimistic-shared</attribute>
+
+ <!-- Use a UDP (multicast) based stack. Need JGroups flow control (FC)
+ because timestamp communication will not require a synchronous response.
+ -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Used for timestamps, so must fetch state. -->
+ <attribute name="FetchInMemoryState">true</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup. Ignored if FetchInMemoryState=false.
+ -->
+ <attribute name="StateRetrievalTimeout">20000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">20000</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!--
+ Indicate whether to use marshalling or not. Set this to true if you
+ are running under a scoped class loader, e.g., inside an application
+ server.
+ -->
+ <attribute
name="UseRegionBasedMarshalling">true</attribute>
+ <!-- Must match the value of "useRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">true</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <!-- Eviction policy configurations. -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
+ <!-- Cache wide default -->
+ <region name="/_default_">
+ <!-- Evict LRU node once we have more than this number of nodes -->
+ <attribute name="maxNodes">10000</attribute>
+ <!-- And, evict any node that hasn't been accessed in this many
seconds -->
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ <!-- Don't evict a node that's been accessed within this many
seconds.
+ Set this to a value greater than your max expected transaction length.
-->
+ <attribute name="minTimeToLiveSeconds">120</attribute>
+ </region>
+ <!-- Don't ever evict modification timestamps -->
+ <region name="/TS"
policyClass="org.jboss.cache.eviction.NullEvictionPolicy"/>
+ </config>
+ </attribute>
+
+ </cache-config>
+
+
+
+ <!-- A config appropriate for a cache that's shared for
+ entity, collection, query and timestamp caching. Not an advised
+ configuration, since it requires cache mode REPL_SYNC, which is the
+ least efficient mode. Also requires a full state transfer at startup,
+ which can be expensive. Uses pessmistic locking.
+ -->
+ <cache-config name="pessimistic-shared">
+
+ <!-- Node locking scheme -->
+ <attribute
name="NodeLockingScheme">PESSIMISTIC</attribute>
+
+ <!--
+ READ_COMMITTED is as strong as necessary for most
+ 2nd Level Cache use cases.
+ -->
+ <attribute
name="IsolationLevel">REPEATABLE_READ</attribute>
+
+ <!-- Must use REPL since used for timestamp caching.
+ Must use SYNC to maintain cache consistency for entities.
+ -->
+ <attribute name="CacheMode">REPL_SYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-pessimistic-shared</attribute>
+
+ <!-- Use a UDP (multicast) based stack. Need JGroups flow control (FC)
+ because timestamp communication will not require a synchronous response.
+ -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Used for timestamps, so must fetch state. -->
+ <attribute name="FetchInMemoryState">true</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup.
+ -->
+ <attribute name="StateRetrievalTimeout">20000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">20000</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!--
+ Indicate whether to use marshalling or not. Set this to true if you
+ are running under a scoped class loader, e.g., inside an application
+ server. Default is "false".
+ -->
+ <attribute
name="UseRegionBasedMarshalling">true</attribute>
+ <!-- Must match the value of "useRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">true</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <!-- Eviction policy configurations. -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
+ <!-- Cache wide default -->
+ <region name="/_default_">
+ <!-- Evict LRU node once we have more than this number of nodes -->
+ <attribute name="maxNodes">10000</attribute>
+ <!-- And, evict any node that hasn't been accessed in this many
seconds -->
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ <!-- Don't evict a node that's been accessed within this many
seconds.
+ Set this to a value greater than your max expected transaction length.
-->
+ <attribute name="minTimeToLiveSeconds">120</attribute>
+ </region>
+ <!-- Don't ever evict modification timestamps -->
+ <region name="/TS"
policyClass="org.jboss.cache.eviction.NullEvictionPolicy"/>
+ </config>
+ </attribute>
+
+ </cache-config>
+
+
+
+ <!-- Same as "pessimistic-shared" but here we use REPEATABLE_READ
+ instead of READ_COMMITTED. REPEATABLE_READ is only useful if the
+ application evicts/clears entities from the Hibernate Session and
+ then expects to repeatably re-read them in the same transaction.
+ Otherwise, the Session's internal cache provides a repeatable-read
+ semantic. Before choosing this config, carefully read the docs
+ and make sure you really need REPEATABLE_READ.
+ -->
+ <cache-config name="pessimistic-shared-repeatable">
+
+ <!-- Node locking scheme -->
+ <attribute
name="NodeLockingScheme">PESSIMISTIC</attribute>
+
+ <!-- Here we use REPEATABLE_READ. -->
+ <attribute
name="IsolationLevel">REPEATABLE_READ</attribute>
+
+ <!-- Must use REPL since used for timestamp caching.
+ Must use SYNC to maintain cache coherency for entities.
+ -->
+ <attribute name="CacheMode">REPL_SYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-pessimistic-shared-rr</attribute>
+
+ <!-- Use a UDP (multicast) based stack. Need JGroups flow control (FC)
+ because timestamp communication will not require a synchronous response.
+ -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Used for timestamps, so must fetch state. -->
+ <attribute name="FetchInMemoryState">true</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup.
+ -->
+ <attribute name="StateRetrievalTimeout">20000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">20000</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!--
+ Indicate whether to use marshalling or not. Set this to true if you
+ are running under a scoped class loader, e.g., inside an application
+ server.
+ -->
+ <attribute
name="UseRegionBasedMarshalling">true</attribute>
+ <!-- Must match the value of "useRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">true</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <!-- Eviction policy configurations. -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.LRUPolicy</attribute>
+ <!-- Cache wide default -->
+ <region name="/_default_">
+ <!-- Evict LRU node once we have more than this number of nodes -->
+ <attribute name="maxNodes">10000</attribute>
+ <!-- And, evict any node that hasn't been accessed in this many
seconds -->
+ <attribute name="timeToLiveSeconds">1000</attribute>
+ <!-- Don't evict a node that's been accessed within this many
seconds.
+ Set this to a value greater than your max expected transaction length.
-->
+ <attribute name="minTimeToLiveSeconds">120</attribute>
+ </region>
+ <!-- Don't ever evict modification timestamps -->
+ <region name="/TS"
policyClass="org.jboss.cache.eviction.NullEvictionPolicy"/>
+ </config>
+ </attribute>
+
+ </cache-config>
+
+</cache-configs>
Added:
core/trunk/src/test/resources/configs/integration/jgroups-channelfactory-stacks.xml
===================================================================
--- core/trunk/src/test/resources/configs/integration/jgroups-channelfactory-stacks.xml
(rev 0)
+++
core/trunk/src/test/resources/configs/integration/jgroups-channelfactory-stacks.xml 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,378 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE protocol_stacks [
+ <!ENTITY shared-udp '
+ <!-- UDP transport config meant to be shared between different channels
+ with different requirements. Message bundling is disabled in this
+ general-purpose config as it can add latency to synchronous RPCs. -->
+ <UDP
+ mcast_port="${jboss.jgroups.udp.mcast_port:45688}"
+ mcast_addr="${jgroups.udp.mcast_addr:228.11.11.11}"
+ tos="8"
+ ucast_recv_buf_size="20000000"
+ ucast_send_buf_size="640000"
+ mcast_recv_buf_size="25000000"
+ mcast_send_buf_size="640000"
+ loopback="true"
+ discard_incompatible_packets="true"
+ enable_bundling="false"
+ max_bundle_size="64000"
+ max_bundle_timeout="30"
+ use_incoming_packet_handler="true"
+ ip_ttl="2"
+ thread_naming_pattern="cl"
+ timer.num_threads="12"
+
+ use_concurrent_stack="true"
+
+ thread_pool.enabled="true"
+ thread_pool.min_threads="20"
+ thread_pool.max_threads="200"
+ thread_pool.keep_alive_time="5000"
+ thread_pool.queue_enabled="true"
+ thread_pool.queue_max_size="1000"
+ thread_pool.rejection_policy="discard"
+
+ oob_thread_pool.enabled="true"
+ oob_thread_pool.min_threads="1"
+ oob_thread_pool.max_threads="20"
+ oob_thread_pool.keep_alive_time="5000"
+ oob_thread_pool.queue_enabled="false"
+ oob_thread_pool.queue_max_size="100"
+ oob_thread_pool.rejection_policy="run"/>
+ '>
+]>
+
+
+<!--
+ Standard JGroups protocol stacks definitions, used by the JChannelFactory bean.
+
+ Author: Bela Ban, Brian Stansberry
+ Version: $Id:jgroups-channelfactory-stacks.xml 71313 2008-03-26 19:46:59Z
bstansberry(a)jboss.com $
+-->
+<protocol_stacks>
+ <stack name="udp"
+ description="Default: IP multicast based stack, with flow
control.">
+ <config>
+ <!-- UDP transport config meant to be shared between different channels,
+ including a JBoss Messaging channel that uses the 'jbm-control'
+ stack listed below. Message bundling is disabled, as it can add
+ latency to synchronous group RPCs. Services that only make
+ asynchronous RPCs (e.g. JBoss Cache configured for REPL_ASYNC)
+ and do so in high volume may be able to improve performance by
+ configuring their cache to use the udp-async stack below.
+ Services that only make synchronous RPCs (e.g. JBoss Cache
+ configured for REPL_SYNC or INVALIDATION_SYNC) may be able
+ to improve performance by using the udp-sync stack below, which
+ does not include flow control.
+
+ The UDP config is included via an XML entity to ensure that
+ it remains consistent between this stack and the 'jbm-control'
+ stack below.
+ -->
+ &shared-udp;
+ <PING timeout="2000" num_initial_members="3"/>
+ <MERGE2 max_interval="100000" min_interval="20000"/>
+ <FD_SOCK/>
+ <FD timeout="6000" max_tries="5"
shun="true"/>
+ <VERIFY_SUSPECT timeout="1500"/>
+ <pbcast.NAKACK use_mcast_xmit="false" gc_lag="0"
+ retransmit_timeout="300,600,1200,2400,4800"
+ discard_delivered_msgs="true"/>
+ <UNICAST timeout="300,600,1200,2400,3600"/>
+ <pbcast.STABLE stability_delay="1000"
desired_avg_gossip="50000"
+ max_bytes="400000"/>
+ <pbcast.GMS print_local_addr="true" join_timeout="3000"
+ shun="true"
+ view_bundling="true"
+ view_ack_collection_timeout="5000"/>
+ <FC max_credits="2000000" min_threshold="0.10"/>
+ <FRAG2 frag_size="60000"/>
+ <!-- pbcast.STREAMING_STATE_TRANSFER use_reading_thread="true"/
-->
+ <pbcast.STATE_TRANSFER/>
+ <pbcast.FLUSH timeout="0"/>
+ </config>
+ </stack>
+
+
+ <stack name="udp-async"
+ description="Same as the default 'udp' stack above, except
message bundling
+ is enabled in the transport protocol (enable_bundling=true).
+ Useful for services that make high-volume asynchronous
+ RPCs (e.g. high volume JBoss Cache instances configured
+ for REPL_ASYNC) where message bundling may improve
performance.">
+ <config>
+ <UDP
+ mcast_port="${jboss.jgroups.udp_async.mcast_port:45689}"
+ mcast_addr="${jgroups.udp.mcast_addr:228.11.11.11}"
+ tos="8"
+ ucast_recv_buf_size="20000000"
+ ucast_send_buf_size="640000"
+ mcast_recv_buf_size="25000000"
+ mcast_send_buf_size="640000"
+ loopback="true"
+ discard_incompatible_packets="true"
+ enable_bundling="false"
+ max_bundle_size="64000"
+ max_bundle_timeout="30"
+ use_incoming_packet_handler="true"
+ ip_ttl="2"
+ thread_naming_pattern="cl"
+ timer.num_threads="12"
+
+ use_concurrent_stack="true"
+
+ thread_pool.enabled="true"
+ thread_pool.min_threads="8"
+ thread_pool.max_threads="200"
+ thread_pool.keep_alive_time="5000"
+ thread_pool.queue_enabled="true"
+ thread_pool.queue_max_size="1000"
+ thread_pool.rejection_policy="discard"
+
+ oob_thread_pool.enabled="true"
+ oob_thread_pool.min_threads="1"
+ oob_thread_pool.max_threads="8"
+ oob_thread_pool.keep_alive_time="5000"
+ oob_thread_pool.queue_enabled="false"
+ oob_thread_pool.queue_max_size="100"
+ oob_thread_pool.rejection_policy="run"/>
+ <PING timeout="2000" num_initial_members="3"/>
+ <MERGE2 max_interval="100000" min_interval="20000"/>
+ <FD_SOCK/>
+ <FD timeout="6000" max_tries="5"
shun="true"/>
+ <VERIFY_SUSPECT timeout="1500"/>
+ <pbcast.NAKACK use_mcast_xmit="false" gc_lag="0"
+ retransmit_timeout="300,600,1200,2400,4800"
+ discard_delivered_msgs="true"/>
+ <UNICAST timeout="300,600,1200,2400,3600"/>
+ <pbcast.STABLE stability_delay="1000"
desired_avg_gossip="50000"
+ max_bytes="400000"/>
+ <pbcast.GMS print_local_addr="true" join_timeout="3000"
+ shun="true"
+ view_bundling="true"
+ view_ack_collection_timeout="5000"/>
+ <FC max_credits="2000000" min_threshold="0.10"/>
+ <FRAG2 frag_size="60000"/>
+ <!-- pbcast.STREAMING_STATE_TRANSFER use_reading_thread="true"/
-->
+ <pbcast.STATE_TRANSFER/>
+ <pbcast.FLUSH timeout="0"/>
+ </config>
+ </stack>
+
+
+ <stack name="udp-sync"
+ description="IP multicast based stack, without flow control and
+ without message bundling. This should be used instead
+ of 'udp' if (1) synchronous calls are used and (2) the
+ message volume (rate and size) is not that large. Don't
+ use this configuration if you send messages at a high
+ sustained rate, or you might run out of memory">
+ <config>
+ <UDP
+ mcast_port="${jgroups.udp_sync.mcast_port:45699}"
+ mcast_addr="${jgroups.udp.mcast_addr:229.11.11.11}"
+ tos="8"
+ ucast_recv_buf_size="20000000"
+ ucast_send_buf_size="640000"
+ mcast_recv_buf_size="25000000"
+ mcast_send_buf_size="640000"
+ loopback="true"
+ discard_incompatible_packets="true"
+ enable_bundling="false"
+ max_bundle_size="64000"
+ max_bundle_timeout="30"
+ use_incoming_packet_handler="true"
+ ip_ttl="2"
+
+ use_concurrent_stack="true"
+
+ thread_pool.enabled="true"
+ thread_pool.min_threads="8"
+ thread_pool.max_threads="200"
+ thread_pool.keep_alive_time="5000"
+ thread_pool.queue_enabled="true"
+ thread_pool.queue_max_size="1000"
+ thread_pool.rejection_policy="discard"
+
+ oob_thread_pool.enabled="true"
+ oob_thread_pool.min_threads="1"
+ oob_thread_pool.max_threads="8"
+ oob_thread_pool.keep_alive_time="5000"
+ oob_thread_pool.queue_enabled="false"
+ oob_thread_pool.queue_max_size="100"
+ oob_thread_pool.rejection_policy="run"/>
+ <PING timeout="2000" num_initial_members="3"/>
+ <MERGE2 max_interval="100000"
min_interval="20000"/>
+ <FD_SOCK/>
+ <FD timeout="6000" max_tries="5"
shun="true"/>
+ <VERIFY_SUSPECT timeout="1500"/>
+ <pbcast.NAKACK use_mcast_xmit="false" gc_lag="0"
+ retransmit_timeout="300,600,1200,2400,4800"
+ discard_delivered_msgs="true"/>
+ <UNICAST timeout="300,600,1200,2400,3600"/>
+ <pbcast.STABLE stability_delay="1000"
desired_avg_gossip="50000"
+ max_bytes="400000"/>
+ <pbcast.GMS print_local_addr="true"
join_timeout="3000"
+ shun="true"
+ view_bundling="true"
+ view_ack_collection_timeout="5000"/>
+ <FRAG2 frag_size="60000"/>
+ <!--pbcast.STREAMING_STATE_TRANSFER use_reading_thread="true"/
-->
+ <pbcast.STATE_TRANSFER/>
+ <pbcast.FLUSH timeout="0"/>
+ </config>
+ </stack>
+
+
+ <stack name="tcp"
+ description="TCP based stack, with flow control and message bundling.
+ This is usually used when IP multicasting cannot be used
+ in a network, e.g. because it is disabled (e.g. routers
+ discard multicast)">
+ <config>
+ <TCP
+ start_port="7600"
+ tcp_nodelay="true"
+ loopback="false"
+ recv_buf_size="20000000"
+ send_buf_size="640000"
+ discard_incompatible_packets="true"
+ max_bundle_size="64000"
+ max_bundle_timeout="30"
+ use_incoming_packet_handler="true"
+ enable_bundling="true"
+ use_send_queues="false"
+ sock_conn_timeout="300"
+ skip_suspected_members="true"
+ timer.num_threads="12"
+
+ use_concurrent_stack="true"
+
+ thread_pool.enabled="true"
+ thread_pool.min_threads="20"
+ thread_pool.max_threads="200"
+ thread_pool.keep_alive_time="5000"
+ thread_pool.queue_enabled="true"
+ thread_pool.queue_max_size="1000"
+ thread_pool.rejection_policy="discard"
+
+ oob_thread_pool.enabled="true"
+ oob_thread_pool.min_threads="1"
+ oob_thread_pool.max_threads="20"
+ oob_thread_pool.keep_alive_time="5000"
+ oob_thread_pool.queue_enabled="false"
+ oob_thread_pool.queue_max_size="100"
+ oob_thread_pool.rejection_policy="run"/>
+ <!-- Alternative 1: multicast-based automatic discovery. -->
+ <MPING timeout="3000"
+ num_initial_members="3"
+ mcast_addr="${jgroups.udp.mcast_addr:230.11.11.11}"
+ mcast_port="${jgroups.tcp_mping.mcast_port:45700}"
+ ip_ttl="2"/>
+ <!-- Alternative 2: non multicast-based replacement for MPING. Requires a
static configuration
+ of *all* possible cluster members.
+ <TCPPING timeout="3000"
+
initial_hosts="${jgroups.tcpping.initial_hosts:localhost[7600],localhost[7601]}"
+ port_range="1"
+ num_initial_members="3"/>
+ -->
+ <MERGE2 max_interval="100000"
min_interval="20000"/>
+ <FD_SOCK/>
+ <FD timeout="6000" max_tries="5"
shun="true"/>
+ <VERIFY_SUSPECT timeout="1500"/>
+ <pbcast.NAKACK use_mcast_xmit="false" gc_lag="0"
+ retransmit_timeout="300,600,1200,2400,4800"
+ discard_delivered_msgs="true"/>
+ <UNICAST timeout="300,600,1200,2400,3600"/>
+ <pbcast.STABLE stability_delay="1000"
desired_avg_gossip="50000"
+ max_bytes="400000"/>
+ <pbcast.GMS print_local_addr="true"
join_timeout="3000"
+ shun="true"
+ view_bundling="true"
+ view_ack_collection_timeout="5000"/>
+ <FC max_credits="2000000" min_threshold="0.10"/>
+ <FRAG2 frag_size="60000"/>
+ <!-- pbcast.STREAMING_STATE_TRANSFER use_reading_thread="true"/
-->
+ <pbcast.STATE_TRANSFER/>
+ <pbcast.FLUSH timeout="0"/>
+ </config>
+ </stack>
+
+
+ <stack name="tcp-sync"
+ description="TCP based stack, without flow control and without
+ message bundling. This is usually used when IP
+ multicasting cannot be used in a network (e.g.routers
+ discard multicast). This configuration should be used
+ instead of 'tcp' above when (1) synchronous calls are
+ used and (2) the message volume (rate and size) is not
+ that large.">
+ <config>
+ <TCP
+ start_port="7650"
+ tcp_nodelay="true"
+ loopback="false"
+ recv_buf_size="20000000"
+ send_buf_size="640000"
+ discard_incompatible_packets="true"
+ max_bundle_size="64000"
+ max_bundle_timeout="30"
+ use_incoming_packet_handler="true"
+ enable_bundling="false"
+ use_send_queues="false"
+ sock_conn_timeout="300"
+ skip_suspected_members="true"
+
+ use_concurrent_stack="true"
+
+ thread_pool.enabled="true"
+ thread_pool.min_threads="8"
+ thread_pool.max_threads="200"
+ thread_pool.keep_alive_time="5000"
+ thread_pool.queue_enabled="true"
+ thread_pool.queue_max_size="1000"
+ thread_pool.rejection_policy="discard"
+
+ oob_thread_pool.enabled="true"
+ oob_thread_pool.min_threads="1"
+ oob_thread_pool.max_threads="8"
+ oob_thread_pool.keep_alive_time="5000"
+ oob_thread_pool.queue_enabled="false"
+ oob_thread_pool.queue_max_size="100"
+ oob_thread_pool.rejection_policy="run"/>
+ <!-- Alternative 1: multicast-based automatic discovery. -->
+ <MPING timeout="3000"
+ num_initial_members="3"
+ mcast_addr="${jgroups.udp.mcast_addr:231.11.11.11}"
+ mcast_port="${jgroups.tcp_sync_mping.mcast_port:45701}"
+ ip_ttl="2"/>
+ <!-- Alternative 2: non multicast-based replacement for MPING. Requires a
static configuration
+ of all possible cluster members.
+ <TCPPING timeout="3000"
+
initial_hosts="${jgroups.tcpping.initial_hosts:localhost[7650],localhost[7651]}"
+ port_range="1"
+ num_initial_members="3"/>
+ -->
+ <MERGE2 max_interval="100000"
min_interval="20000"/>
+ <FD_SOCK/>
+ <FD timeout="6000" max_tries="5"
shun="true"/>
+ <VERIFY_SUSPECT timeout="1500"/>
+ <pbcast.NAKACK use_mcast_xmit="false" gc_lag="0"
+ retransmit_timeout="300,600,1200,2400,4800"
+ discard_delivered_msgs="true"/>
+ <UNICAST timeout="300,600,1200,2400,3600"/>
+ <pbcast.STABLE stability_delay="1000"
desired_avg_gossip="50000"
+ max_bytes="400000"/>
+ <pbcast.GMS print_local_addr="true"
join_timeout="3000"
+ shun="true"
+ view_bundling="true"
+ view_ack_collection_timeout="5000"/>
+ <!-- pbcast.STREAMING_STATE_TRANSFER use_reading_thread="true"/
-->
+ <pbcast.STATE_TRANSFER/>
+ <pbcast.FLUSH timeout="0"/>
+ </config>
+ </stack>
+
+</protocol_stacks>
+
+
Added: core/trunk/src/test/resources/configs/integration/sfsb-cache-configs.xml
===================================================================
--- core/trunk/src/test/resources/configs/integration/sfsb-cache-configs.xml
(rev 0)
+++ core/trunk/src/test/resources/configs/integration/sfsb-cache-configs.xml 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,263 @@
+<cache-configs>
+
+ <!--
+ | A config appropriate for EJB3 SFSB caching.
+ -->
+ <cache-config name="sfsb-cache">
+ <!-- No transaction manager lookup -->
+
+ <attribute
name="NodeLockingScheme">PESSIMISTIC</attribute>
+ <attribute
name="IsolationLevel">REPEATABLE_READ</attribute>
+
+ <!-- Valid modes are LOCAL
+ REPL_ASYNC
+ REPL_SYNC
+ -->
+ <attribute name="CacheMode">REPL_ASYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-SFSBCache</attribute>
+
+ <!-- Use a UDP (multicast) based stack. Need JGroups flow control (FC)
+ because we are using asynchronous replication.
+ -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Must fetch state. -->
+ <attribute name="FetchInMemoryState">true</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup.
+ -->
+ <attribute name="StateRetrievalTimeout">60000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">17500</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!--
+ SFSBs use region-based marshalling to provide for partial state
+ transfer during deployment/undeployment.
+ -->
+ <attribute
name="UseRegionBasedMarshalling">true</attribute>
+ <!-- Must match the value of "useRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">true</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <attribute
name="ExposeManagementStatistics">true</attribute>
+
+ <!-- Buddy Replication config -->
+ <attribute name="BuddyReplicationConfig">
+ <config>
+ <buddyReplicationEnabled>false</buddyReplicationEnabled>
+
<buddyLocatorClass>org.jboss.cache.buddyreplication.NextMemberBuddyLocator</buddyLocatorClass>
+ <!-- numBuddies is the number of backup nodes each node maintains.
+ ignoreColocatedBuddies means that each node will *try* to
+ select a buddy on a different physical host. If not able to do
+ so though, it will fall back to colocated nodes. -->
+ <buddyLocatorProperties>
+ numBuddies = 1
+ ignoreColocatedBuddies = true
+ </buddyLocatorProperties>
+
+ <!-- A way to specify a preferred replication group. If specified,
+ we try and pick a buddy why shares the same pool name (falling
+ back to other buddies if not available). This allows the sysdmin
+ to hint at backup buddies are picked, so for example, nodes may
+ be hinted topick buddies on a different physical rack or power
+ supply for added fault tolerance.
+ -->
+ <buddyPoolName>default</buddyPoolName>
+ <!-- communication timeout for inter-buddy group organisation
+ messages (such as assigning to and removing from groups -->
+ <buddyCommunicationTimeout>17500</buddyCommunicationTimeout>
+
+ <!-- Do not change these -->
+ <autoDataGravitation>false</autoDataGravitation>
+ <dataGravitationRemoveOnFind>true</dataGravitationRemoveOnFind>
+
<dataGravitationSearchBackupTrees>true</dataGravitationSearchBackupTrees>
+
+ </config>
+ </attribute>
+
+ <!-- Cache Loader for session passivation -->
+ <attribute name="CacheLoaderConfig">
+ <config>
+ <passivation>true</passivation>
+ <shared>false</shared>
+
+ <purgeOnStartup>true</purgeOnStartup>
+
+ <cacheloader>
+ <class>org.jboss.cache.loader.FileCacheLoader</class>
+ <properties>
+ location=${java.io.tmpdir}${/}sfsb
+ </properties>
+ <async>false</async>
+ <fetchPersistentState>true</fetchPersistentState>
+ <ignoreModifications>false</ignoreModifications>
+ <checkCharacterPortability>false</checkCharacterPortability>
+ </cacheloader>
+
+ </config>
+ </attribute>
+
+ <!-- SFSBs use JBoss Cache eviction -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.NullEvictionPolicy</attribute>
+ <!-- Cache wide default region -->
+ <region name="/_default_"/>
+ <!-- EJB3 integration code will programatically create
+ other regions as beans are deployed -->
+ </config>
+ </attribute>
+
+ </cache-config>
+
+ <!--
+ | A buddy replication enabled config appropriate for EJB3 SFSB caching.
+ -->
+ <cache-config name="br-sfsb-cache">
+ <!-- No transaction manager lookup -->
+
+ <attribute
name="NodeLockingScheme">PESSIMISTIC</attribute>
+ <attribute
name="IsolationLevel">REPEATABLE_READ</attribute>
+
+ <!-- Valid modes are LOCAL
+ REPL_ASYNC
+ REPL_SYNC
+ -->
+ <attribute name="CacheMode">REPL_ASYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-SFSBCache</attribute>
+
+ <!-- Use a UDP (multicast) based stack. Need JGroups flow control (FC)
+ because we are using asynchronous replication.
+ -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Must fetch state. -->
+ <attribute name="FetchInMemoryState">true</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup.
+ -->
+ <attribute name="StateRetrievalTimeout">60000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">17500</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!--
+ SFSBs use region-based marshalling to provide for partial state
+ transfer during deployment/undeployment.
+ -->
+ <attribute
name="UseRegionBasedMarshalling">true</attribute>
+ <!-- Must match the value of "useRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">true</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <attribute
name="ExposeManagementStatistics">true</attribute>
+
+ <!-- Buddy Replication config -->
+ <attribute name="BuddyReplicationConfig">
+ <config>
+ <buddyReplicationEnabled>true</buddyReplicationEnabled>
+
<buddyLocatorClass>org.jboss.cache.buddyreplication.NextMemberBuddyLocator</buddyLocatorClass>
+ <!-- numBuddies is the number of backup nodes each node maintains.
+ ignoreColocatedBuddies means that each node will *try* to
+ select a buddy on a different physical host. If not able to do
+ so though, it will fall back to colocated nodes. -->
+ <buddyLocatorProperties>
+ numBuddies = 1
+ ignoreColocatedBuddies = true
+ </buddyLocatorProperties>
+
+ <!-- A way to specify a preferred replication group. If specified,
+ we try and pick a buddy why shares the same pool name (falling
+ back to other buddies if not available). This allows the sysdmin
+ to hint at backup buddies are picked, so for example, nodes may
+ be hinted topick buddies on a different physical rack or power
+ supply for added fault tolerance.
+ -->
+ <buddyPoolName>default</buddyPoolName>
+ <!-- communication timeout for inter-buddy group organisation
+ messages (such as assigning to and removing from groups -->
+ <buddyCommunicationTimeout>17500</buddyCommunicationTimeout>
+
+ <!-- Do not change these -->
+ <autoDataGravitation>false</autoDataGravitation>
+ <dataGravitationRemoveOnFind>true</dataGravitationRemoveOnFind>
+
<dataGravitationSearchBackupTrees>true</dataGravitationSearchBackupTrees>
+
+ </config>
+ </attribute>
+
+ <!-- Cache Loader for session passivation -->
+ <attribute name="CacheLoaderConfig">
+ <config>
+ <passivation>true</passivation>
+ <shared>false</shared>
+
+ <purgeOnStartup>true</purgeOnStartup>
+
+ <cacheloader>
+ <class>org.jboss.cache.loader.FileCacheLoader</class>
+ <properties>
+ location=${java.io.tmpdir}${/}sfsb
+ </properties>
+ <async>false</async>
+ <fetchPersistentState>true</fetchPersistentState>
+ <ignoreModifications>false</ignoreModifications>
+ <checkCharacterPortability>false</checkCharacterPortability>
+ </cacheloader>
+
+ </config>
+ </attribute>
+
+ <!-- SFSBs use JBoss Cache eviction -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.NullEvictionPolicy</attribute>
+ <!-- Cache wide default region -->
+ <region name="/_default_"/>
+ <!-- EJB3 integration code will programatically create
+ other regions as beans are deployed -->
+ </config>
+ </attribute>
+
+ </cache-config>
+
+</cache-configs>
Added: core/trunk/src/test/resources/configs/integration/web-session-cache-configs.xml
===================================================================
--- core/trunk/src/test/resources/configs/integration/web-session-cache-configs.xml
(rev 0)
+++
core/trunk/src/test/resources/configs/integration/web-session-cache-configs.xml 2008-11-24
07:01:36 UTC (rev 7186)
@@ -0,0 +1,372 @@
+<cache-configs>
+
+ <!--
+ | A config appropriate for HttpSession caches.
+ | Not for use with FIELD replication granularity webapps.
+ -->
+ <cache-config name="standard-session-cache">
+
+ <attribute
name="TransactionManagerLookupClass">org.jboss.cache.transaction.BatchModeTransactionManagerLookup</attribute>
+
+ <attribute
name="NodeLockingScheme">PESSIMISTIC</attribute>
+ <attribute
name="IsolationLevel">REPEATABLE_READ</attribute>
+
+ <!-- Valid modes are REPL_ASYNC and REPL_SYNC -->
+ <attribute name="CacheMode">REPL_ASYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-SessionCache</attribute>
+
+ <!-- Use a UDP (multicast) based stack. Need JGroups flow control (FC)
+ because we are using asynchronous replication.
+ -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Must fetch state. -->
+ <attribute name="FetchInMemoryState">true</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup.
+ -->
+ <attribute name="StateRetrievalTimeout">60000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">17500</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!-- Region-based marshalling is not needed. -->
+ <attribute
name="UseRegionBasedMarshalling">false</attribute>
+ <!-- Must match the value of "UseRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">false</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <attribute
name="ExposeManagementStatistics">true</attribute>
+
+ <!-- Buddy Replication config -->
+ <attribute name="BuddyReplicationConfig">
+ <config>
+ <buddyReplicationEnabled>false</buddyReplicationEnabled>
+
<buddyLocatorClass>org.jboss.cache.buddyreplication.NextMemberBuddyLocator</buddyLocatorClass>
+ <!-- numBuddies is the number of backup nodes each node maintains.
+ ignoreColocatedBuddies means that each node will *try* to
+ select a buddy on a different physical host. If not able to do
+ so though, it will fall back to colocated nodes. -->
+ <buddyLocatorProperties>
+ numBuddies = 1
+ ignoreColocatedBuddies = true
+ </buddyLocatorProperties>
+
+ <!-- A way to specify a preferred replication group. If specified,
+ we try and pick a buddy why shares the same pool name (falling
+ back to other buddies if not available). This allows the sysdmin
+ to hint at backup buddies are picked, so for example, nodes may
+ be hinted topick buddies on a different physical rack or power
+ supply for added fault tolerance.
+ -->
+ <buddyPoolName>default</buddyPoolName>
+ <!-- communication timeout for inter-buddy group organisation
+ messages (such as assigning to and removing from groups -->
+ <buddyCommunicationTimeout>17500</buddyCommunicationTimeout>
+
+ <!-- Do not change these -->
+ <autoDataGravitation>false</autoDataGravitation>
+ <dataGravitationRemoveOnFind>true</dataGravitationRemoveOnFind>
+
<dataGravitationSearchBackupTrees>true</dataGravitationSearchBackupTrees>
+
+ </config>
+ </attribute>
+
+ <!-- Cache Loader for session passivation -->
+ <attribute name="CacheLoaderConfig">
+ <config>
+ <passivation>true</passivation>
+ <shared>false</shared>
+
+ <purgeOnStartup>true</purgeOnStartup>
+
+ <cacheloader>
+ <class>org.jboss.cache.loader.FileCacheLoader</class>
+ <properties>
+ location=${java.io.tmpdir}${/}session
+ </properties>
+ <async>false</async>
+ <fetchPersistentState>true</fetchPersistentState>
+ <ignoreModifications>false</ignoreModifications>
+ <checkCharacterPortability>false</checkCharacterPortability>
+ </cacheloader>
+
+ </config>
+ </attribute>
+
+ <!--
+ JBoss Cache eviction is not needed; webapp or SFSB container
+ manages eviction by itself.
+ -->
+
+ </cache-config>
+
+ <!--
+ | A config appropriate for HttpSession caches for webapps
+ | that use FIELD replication granularity.
+ -->
+ <cache-config name="field-granularity-session-cache">
+
+ <attribute
name="TransactionManagerLookupClass">org.jboss.cache.transaction.BatchModeTransactionManagerLookup</attribute>
+
+ <attribute
name="NodeLockingScheme">PESSIMISTIC</attribute>
+ <attribute
name="IsolationLevel">REPEATABLE_READ</attribute>
+
+ <!-- Valid modes are LOCAL
+ REPL_ASYNC
+ REPL_SYNC
+ -->
+ <attribute name="CacheMode">REPL_ASYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-FieldSessionCache</attribute>
+
+ <!-- Use a UDP (multicast) based stack. Need JGroups flow control (FC)
+ because we are using asynchronous replication.
+ -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Must fetch state. -->
+ <attribute name="FetchInMemoryState">true</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup.
+ -->
+ <attribute name="StateRetrievalTimeout">60000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">17500</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!--
+ Indicate whether to use marshalling or not. Set this to true if you
+ are running under a scoped class loader, e.g., inside an application
+ server. Default is "false".
+ -->
+ <attribute
name="UseRegionBasedMarshalling">true</attribute>
+ <!-- Must match the value of "useRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">true</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <attribute
name="ExposeManagementStatistics">true</attribute>
+
+ <!-- Buddy Replication config -->
+ <attribute name="BuddyReplicationConfig">
+ <config>
+ <buddyReplicationEnabled>false</buddyReplicationEnabled>
+
<buddyLocatorClass>org.jboss.cache.buddyreplication.NextMemberBuddyLocator</buddyLocatorClass>
+ <!-- numBuddies is the number of backup nodes each node maintains.
+ ignoreColocatedBuddies means that each node will *try* to
+ select a buddy on a different physical host. If not able to do
+ so though, it will fall back to colocated nodes. -->
+ <buddyLocatorProperties>
+ numBuddies = 1
+ ignoreColocatedBuddies = true
+ </buddyLocatorProperties>
+
+ <!-- A way to specify a preferred replication group. If specified,
+ we try and pick a buddy why shares the same pool name (falling
+ back to other buddies if not available). This allows the sysdmin
+ to hint at backup buddies are picked, so for example, nodes may
+ be hinted topick buddies on a different physical rack or power
+ supply for added fault tolerance.
+ -->
+ <buddyPoolName>default</buddyPoolName>
+ <!-- communication timeout for inter-buddy group organisation
+ messages (such as assigning to and removing from groups -->
+ <buddyCommunicationTimeout>17500</buddyCommunicationTimeout>
+
+ <!-- Do not change these -->
+ <autoDataGravitation>false</autoDataGravitation>
+ <dataGravitationRemoveOnFind>true</dataGravitationRemoveOnFind>
+
<dataGravitationSearchBackupTrees>true</dataGravitationSearchBackupTrees>
+
+ </config>
+ </attribute>
+
+ <!-- Cache Loader for session passivation -->
+ <attribute name="CacheLoaderConfig">
+ <config>
+ <passivation>true</passivation>
+ <shared>false</shared>
+
+ <purgeOnStartup>true</purgeOnStartup>
+
+ <cacheloader>
+ <class>org.jboss.cache.loader.FileCacheLoader</class>
+ <properties>
+ location=${java.io.tmpdir}${/}field-session
+ </properties>
+ <async>false</async>
+ <fetchPersistentState>true</fetchPersistentState>
+ <ignoreModifications>false</ignoreModifications>
+ <checkCharacterPortability>false</checkCharacterPortability>
+ </cacheloader>
+
+ </config>
+ </attribute>
+
+ <!-- FIELD granularity webapps use JBoss Cache eviction -->
+ <attribute name="EvictionPolicyConfig">
+ <config>
+ <attribute name="wakeUpIntervalSeconds">5</attribute>
+ <!-- Name of the DEFAULT eviction policy class. -->
+ <attribute
name="policyClass">org.jboss.cache.eviction.NullEvictionPolicy</attribute>
+ <!-- Cache wide default region -->
+ <region name="/_default_"/>
+ <!-- JBossWeb integration code will programatically create
+ other regions as webapps are deployed -->
+ </config>
+ </attribute>
+
+ </cache-config>
+
+ <!--
+ | A buddy replication enabled config appropriate for HttpSession caches.
+ | Not for use with FIELD replication granularity webapps.
+ -->
+ <cache-config name="br-standard-session-cache">
+
+ <attribute
name="TransactionManagerLookupClass">org.jboss.cache.transaction.BatchModeTransactionManagerLookup</attribute>
+
+ <attribute
name="NodeLockingScheme">PESSIMISTIC</attribute>
+ <attribute
name="IsolationLevel">REPEATABLE_READ</attribute>
+
+ <!-- Valid modes are REPL_ASYNC and REPL_SYNC -->
+ <attribute name="CacheMode">REPL_ASYNC</attribute>
+
+ <!-- Name of cluster. Needs to be the same for all members, in order
+ to find each other -->
+ <attribute
name="ClusterName">${jboss.partition.name:JBCTest}-SessionCache</attribute>
+
+ <!-- Use a UDP (multicast) based stack. Need JGroups flow control (FC)
+ because we are using asynchronous replication.
+ -->
+ <attribute
name="MultiplexerStack">${jboss.default.jgroups.stack:udp}</attribute>
+
+ <!-- Must fetch state. -->
+ <attribute name="FetchInMemoryState">true</attribute>
+
+ <!--
+ The max amount of time (in milliseconds) we wait until the
+ state (ie. the contents of the cache) are retrieved from
+ existing members at startup.
+ -->
+ <attribute name="StateRetrievalTimeout">60000</attribute>
+
+ <!--
+ Number of milliseconds to wait until all responses for a
+ synchronous call have been received.
+ -->
+ <attribute name="SyncReplTimeout">17500</attribute>
+
+ <!-- Max number of milliseconds to wait for a lock acquisition -->
+ <attribute name="LockAcquisitionTimeout">15000</attribute>
+
+ <!-- Region-based marshalling is not needed. -->
+ <attribute
name="UseRegionBasedMarshalling">false</attribute>
+ <!-- Must match the value of "UseRegionBasedMarshalling" -->
+ <attribute name="InactiveOnStartup">false</attribute>
+
+ <!-- Disable asynchronous RPC marshalling/sending -->
+ <attribute
name="SerializationExecutorPoolSize">0</attribute>
+
+ <!-- We have no asynchronous notification listeners -->
+ <attribute name="ListenerAsyncPoolSize">0</attribute>
+
+ <attribute
name="ExposeManagementStatistics">true</attribute>
+
+ <!-- Buddy Replication config -->
+ <attribute name="BuddyReplicationConfig">
+ <config>
+ <buddyReplicationEnabled>true</buddyReplicationEnabled>
+
<buddyLocatorClass>org.jboss.cache.buddyreplication.NextMemberBuddyLocator</buddyLocatorClass>
+ <!-- numBuddies is the number of backup nodes each node maintains.
+ ignoreColocatedBuddies means that each node will *try* to
+ select a buddy on a different physical host. If not able to do
+ so though, it will fall back to colocated nodes. -->
+ <buddyLocatorProperties>
+ numBuddies = 1
+ ignoreColocatedBuddies = true
+ </buddyLocatorProperties>
+
+ <!-- A way to specify a preferred replication group. If specified,
+ we try and pick a buddy why shares the same pool name (falling
+ back to other buddies if not available). This allows the sysdmin
+ to hint at backup buddies are picked, so for example, nodes may
+ be hinted topick buddies on a different physical rack or power
+ supply for added fault tolerance.
+ -->
+ <buddyPoolName>default</buddyPoolName>
+ <!-- communication timeout for inter-buddy group organisation
+ messages (such as assigning to and removing from groups -->
+ <buddyCommunicationTimeout>17500</buddyCommunicationTimeout>
+
+ <!-- Do not change these -->
+ <autoDataGravitation>false</autoDataGravitation>
+ <dataGravitationRemoveOnFind>true</dataGravitationRemoveOnFind>
+
<dataGravitationSearchBackupTrees>true</dataGravitationSearchBackupTrees>
+
+ </config>
+ </attribute>
+
+ <!-- Cache Loader for session passivation -->
+ <attribute name="CacheLoaderConfig">
+ <config>
+ <passivation>true</passivation>
+ <shared>false</shared>
+
+ <purgeOnStartup>true</purgeOnStartup>
+
+ <cacheloader>
+ <class>org.jboss.cache.loader.FileCacheLoader</class>
+ <properties>
+ location=${java.io.tmpdir}${/}session
+ </properties>
+ <async>false</async>
+ <fetchPersistentState>true</fetchPersistentState>
+ <ignoreModifications>false</ignoreModifications>
+ <checkCharacterPortability>false</checkCharacterPortability>
+ </cacheloader>
+
+ </config>
+ </attribute>
+
+ <!--
+ JBoss Cache eviction is not needed; webapp or SFSB container
+ manages eviction by itself.
+ -->
+
+ </cache-config>
+
+</cache-configs>