[jboss-cvs] JBossAS SVN: r106021 - in branches/JBPAPP_4_2_0_GA_CP: tomcat/src/main/org/jboss/web/tomcat/service/sso and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Jun 14 00:41:07 EDT 2010
Author: jiwils
Date: 2010-06-14 00:41:06 -0400 (Mon, 14 Jun 2010)
New Revision: 106021
Modified:
branches/JBPAPP_4_2_0_GA_CP/testsuite/src/main/org/jboss/test/web/test/TreeCacheSSOClusterManagerUnitTestCase.java
branches/JBPAPP_4_2_0_GA_CP/tomcat/src/main/org/jboss/web/tomcat/service/sso/TreeCacheSSOClusterManager.java
Log:
Fix for JBPAPP-4473. JBossWeb Host and Context are now taken into account when managing SSO sessions.
Modified: branches/JBPAPP_4_2_0_GA_CP/testsuite/src/main/org/jboss/test/web/test/TreeCacheSSOClusterManagerUnitTestCase.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP/testsuite/src/main/org/jboss/test/web/test/TreeCacheSSOClusterManagerUnitTestCase.java 2010-06-14 04:38:56 UTC (rev 106020)
+++ branches/JBPAPP_4_2_0_GA_CP/testsuite/src/main/org/jboss/test/web/test/TreeCacheSSOClusterManagerUnitTestCase.java 2010-06-14 04:41:06 UTC (rev 106021)
@@ -30,8 +30,10 @@
import javax.management.ObjectName;
import javax.transaction.TransactionManager;
+import org.apache.catalina.Container;
import org.apache.catalina.Manager;
import org.apache.catalina.Session;
+import org.apache.catalina.core.ContainerBase;
import org.apache.catalina.session.StandardManager;
import org.apache.catalina.session.StandardSession;
import org.jboss.cache.AbstractTreeCacheListener;
@@ -53,19 +55,19 @@
/**
* Test of the TreeCacheSSOClusterManager class.
- *
+ *
* @author Brian Stansberry
*/
public class TreeCacheSSOClusterManagerUnitTestCase extends JBossTestCase
{
private static IpAddress LOCAL_ADDRESS;
private static IpAddress REMOTE_ADDRESS;
-
+
public TreeCacheSSOClusterManagerUnitTestCase(String name)
{
super(name);
}
-
+
@Override
protected void setUp() throws Exception
{
@@ -78,19 +80,69 @@
{
deadMemberCleanupTest(true);
}
-
+
public void testDeadMemberCleanupWithoutPool() throws Exception
{
deadMemberCleanupTest(false);
}
-
+
+ // See JBPAPP-4473.
+ public void testMultipleAppsSameSession() throws Exception
+ {
+ log.debug("+++ testMultipleAppsSameSession");
+
+ MBeanServer mbeanServer =
+ MBeanServerFactory.createMBeanServer("multipleAppsSameSessionTest");
+
+ try
+ {
+ // The following initial code is the same as for the dead member tests,
+ // and it could be factored out into various methods, but this was left
+ // as is on purpose so it is clear what is happening in this test.
+
+ // Register a cache
+ MockTreeCache cache = new MockTreeCache();
+ cache.setTransactionManagerLookup(new MockTransactionManagerLookup());
+ mbeanServer.registerMBean(cache, new ObjectName(TreeCacheSSOClusterManager.DEFAULT_GLOBAL_CACHE_NAME));
+ cache.startService();
+
+ // Build up an SSO infrastructure based on LOCAL_ADDRESS
+ TreeCacheSSOClusterManager localManager = new TreeCacheSSOClusterManager(mbeanServer);
+ localManager.setCacheName(TreeCacheSSOClusterManager.DEFAULT_GLOBAL_CACHE_NAME);
+
+ MockSSOValve localValve = new MockSSOValve();
+ localValve.setClusterManager(localManager);
+ localManager.setSingleSignOnValve(localValve);
+ localManager.start();
+
+ // Begin test specific code.
+ localManager.register("MultipleApps", "FORM", "Jimmy", "password");
+ final String sessionId = "9";
+
+ Manager localSessMgrApp1 = createSessionManager("localSessMgrApp1");
+ Session sess9 = new MockSession(localSessMgrApp1, sessionId);
+ Manager localSessMgrApp2 = createSessionManager("localSessMgrApp2");
+ Session sess9DiffApp = new MockSession(localSessMgrApp2, sessionId);
+ localManager.addSession("MultipleApps", sess9);
+ localManager.addSession("MultipleApps", sess9DiffApp);
+
+ Set sso5 = (Set) cache.get("/SSO/MultipleApps/sessions", "key");
+ assertNotNull("SSO MultipleApps exists", sso5);
+ assertEquals("SSO MultipleApps has correct number of sessions", 2, sso5.size());
+ }
+ finally
+ {
+ MBeanServerFactory.releaseMBeanServer(mbeanServer);
+ }
+ }
+
private void deadMemberCleanupTest(boolean usePool) throws Exception
{
log.debug("+++ testDeadMemberCleanup()");
-
- MBeanServer mbeanServer =
+
+ MBeanServer mbeanServer =
MBeanServerFactory.createMBeanServer("deadMemberTest");
- try
+ try
{
// Register a cache
MockTreeCache cache = new MockTreeCache();
@@ -100,82 +152,82 @@
cache.setTransactionManagerLookup(new MockTransactionManagerLookup());
mbeanServer.registerMBean(cache, new ObjectName(TreeCacheSSOClusterManager.DEFAULT_GLOBAL_CACHE_NAME));
cache.startService();
-
+
if (usePool)
{
BasicThreadPool pool = new BasicThreadPool();
mbeanServer.registerMBean(pool, new ObjectName(TreeCacheSSOClusterManager.DEFAULT_THREAD_POOL_NAME));
}
-
- // Build up an SSO infrastructure based on LOCAL_ADDRESS
+
+ // Build up an SSO infrastructure based on LOCAL_ADDRESS
TreeCacheSSOClusterManager localManager = new TreeCacheSSOClusterManager(mbeanServer);
localManager.setCacheName(TreeCacheSSOClusterManager.DEFAULT_GLOBAL_CACHE_NAME);
-
+
MockSSOValve localValve = new MockSSOValve();
localValve.setClusterManager(localManager);
localManager.setSingleSignOnValve(localValve);
localManager.start();
-
+
assertEquals("Thread pool usage as expected", usePool, localManager.isUsingThreadPool());
-
+
// Build up a second SSO infrastructure based on LOCAL_ADDRESS
// It uses the same mock cache, but we change the cache address
// so it thinks it's a different address when it starts
cache.setOurAddress(REMOTE_ADDRESS);
-
+
TreeCacheSSOClusterManager remoteManager = new TreeCacheSSOClusterManager(mbeanServer);
remoteManager.setCacheName(TreeCacheSSOClusterManager.DEFAULT_GLOBAL_CACHE_NAME);
-
+
MockSSOValve remoteValve = new MockSSOValve();
remoteValve.setClusterManager(remoteManager);
remoteManager.setSingleSignOnValve(localValve);
remoteManager.start();
-
-
+
+
// Create an SSO that will have sessions from both valves
localManager.register("1", "FORM", "Brian", "password");
-
- Manager localSessMgr1 = new StandardManager();
+
+ Manager localSessMgr1 = createSessionManager("localSessMgr1");
Session sess1 = new MockSession(localSessMgr1, "1");
localManager.addSession("1", sess1);
-
- Manager remoteSessMgr1 = new StandardManager();
+
+ Manager remoteSessMgr1 = createSessionManager("remoteSessMgr1");
Session sess2 = new MockSession(remoteSessMgr1, "2");
remoteManager.addSession("1", sess2);
-
-
+
+
// Create another SSO with sessions only from remote
remoteManager.register("2", "FORM", "Brian", "password");
-
- Manager remoteSessMgr2 = new StandardManager();
+
+ Manager remoteSessMgr2 = createSessionManager("remoteSessMgr2");
Session sess3 = new MockSession(remoteSessMgr2, "3");
remoteManager.addSession("2", sess3);
-
-
+
+
// Create a third SSO that will have sessions from both valves
localManager.register("3", "FORM", "Brian", "password");
-
- Manager localSessMgr2 = new StandardManager();
+
+ Manager localSessMgr2 = createSessionManager("localSessMgr2");
Session sess4 = new MockSession(localSessMgr2, "4");
localManager.addSession("3", sess4);
-
- Manager remoteSessMgr3 = new StandardManager();
+
+ Manager remoteSessMgr3 = createSessionManager("remoteSessMgr3");
Session sess5 = new MockSession(remoteSessMgr3, "5");
remoteManager.addSession("3", sess5);
-
-
+
+
// Create a fourth SSO that will have sessions from both valves
localManager.register("4", "FORM", "Brian", "password");
-
- Manager localSessMgr3 = new StandardManager();
+
+ Manager localSessMgr3 = createSessionManager("localSessMgr3");
Session sess6 = new MockSession(localSessMgr3, "6");
localManager.addSession("4", sess6);
-
- Manager remoteSessMgr4 = new StandardManager();
+
+ Manager remoteSessMgr4 = createSessionManager("remoteSessMgr4");
Session sess7 = new MockSession(remoteSessMgr4, "7");
remoteManager.addSession("4", sess7);
-
-
+
+
// Confirm that data is cached properly
Set sso1 = (Set) cache.get("/SSO/1/sessions", "key");
assertNotNull("SSO 1 exists", sso1);
@@ -189,14 +241,14 @@
Set sso4 = (Set) cache.get("/SSO/4/sessions", "key");
assertNotNull("SSO 4 exists", sso4);
assertEquals("SSO 4 has correct number of sessions", 2, sso4.size());
-
+
// Put in a new view with REMOTE_ADDRESS dead
ViewId viewId = new ViewId(LOCAL_ADDRESS, 1);
Vector v = new Vector();
v.add(LOCAL_ADDRESS);
localManager.viewChange(new View(viewId, v));
-
-
+
+
// Test that a regular remove call cleans up dead members
// (BES: the cleanup thread may have dealt with this; I see no
// clean way to force this being done by the caller thread)
@@ -204,20 +256,20 @@
sso3 = (Set) cache.get("/SSO/3/sessions", "key");
assertNotNull("SSO 3 exists", sso3);
assertEquals("SSO 3 has correct number of sessions", 0, sso3.size());
-
+
// Test that a regular add call cleans up dead members
// (BES: the cleanup thread may have dealt with this; I see no
// clean way to force this being done by the caller thread)
- Manager localSessMgr4 = new StandardManager();
+ Manager localSessMgr4 = createSessionManager("localSessMgr4");
Session sess8 = new MockSession(localSessMgr4, "8");
localManager.addSession("4", sess8);
sso4 = (Set) cache.get("/SSO/4/sessions", "key");
assertNotNull("SSO 4 exists", sso4);
assertEquals("SSO 4 has correct number of sessions", 2, sso4.size());
-
+
// Give the cleanup thread time to finish
Thread.sleep(300);
-
+
// Confirm that cached data is properly cleaned up
sso1 = (Set) cache.get("/SSO/1/sessions", "key");
assertNotNull("SSO 1 exists", sso1);
@@ -230,19 +282,37 @@
assertEquals("SSO 3 has correct number of sessions", 0, sso3.size());
sso4 = (Set) cache.get("/SSO/4/sessions", "key");
assertNotNull("SSO 4 exists", sso4);
- assertEquals("SSO 4 has correct number of sessions", 2, sso4.size());
+ assertEquals("SSO 4 has correct number of sessions", 2, sso4.size());
}
finally
{
MBeanServerFactory.releaseMBeanServer(mbeanServer);
- }
+ }
}
-
-
+
+ /**
+ * Creates a session manager with context and host container names to avoid
+ * NPEs specific to this test case.
+ */
+ private Manager createSessionManager(String name)
+ {
+ Container contextContainer = new MockContainer();
+ contextContainer.setName(name + "-context");
+
+ Container hostContainer = new MockContainer();
+ hostContainer.setName(name + "-host");
+
+ contextContainer.setParent(hostContainer);
+
+ Manager sessionManager = new StandardManager();
+ sessionManager.setContainer(contextContainer);
+ return sessionManager;
+ }
+
static class MockTreeCache extends TreeCache
{
private IpAddress ourAddress = LOCAL_ADDRESS;
-
+
public MockTreeCache() throws Exception
{
super();
@@ -254,7 +324,7 @@
{
return ourAddress;
}
-
+
void setOurAddress(IpAddress address)
{
ourAddress = address;
@@ -267,10 +337,10 @@
v.add(LOCAL_ADDRESS);
v.add(REMOTE_ADDRESS);
return v;
- }
-
+ }
+
}
-
+
/**
* Override ClusteredSingleSignOn to suppress the empty SSO callbacks
*/
@@ -286,35 +356,44 @@
protected void notifySSONotEmpty(String ssoId)
{
// no-op
- }
+ }
}
-
+
+ /**
+ * Override container to provide context and host container names to avoid
+ * NPEs specific to this test case. This class only exists because
+ * ContainerBase is abstract.
+ */
+ static class MockContainer extends ContainerBase
+ {
+ }
+
static class MockSession extends StandardSession
{
private static final long serialVersionUID = 1L;
-
+
private String ourId;
-
+
MockSession(Manager manager, String id)
{
super(manager);
ourId = id;
}
-
+
@Override
public String getId()
{
return ourId;
}
}
-
+
static class MockTransactionManagerLookup implements TransactionManagerLookup
{
public TransactionManager getTransactionManager() throws Exception
{
return new BatchModeTransactionManager();
}
-
+
}
}
Modified: branches/JBPAPP_4_2_0_GA_CP/tomcat/src/main/org/jboss/web/tomcat/service/sso/TreeCacheSSOClusterManager.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP/tomcat/src/main/org/jboss/web/tomcat/service/sso/TreeCacheSSOClusterManager.java 2010-06-14 04:38:56 UTC (rev 106020)
+++ branches/JBPAPP_4_2_0_GA_CP/tomcat/src/main/org/jboss/web/tomcat/service/sso/TreeCacheSSOClusterManager.java 2010-06-14 04:41:06 UTC (rev 106021)
@@ -36,6 +36,7 @@
import javax.transaction.Status;
import javax.transaction.TransactionManager;
+import org.apache.catalina.Container;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Session;
@@ -112,27 +113,27 @@
* Parameter signature used for TreeCache.put calls over JMX
*/
private static final String[] PUT_SIGNATURE =
- {Fqn.class.getName(), Object.class.getName(),
+ {Fqn.class.getName(), Object.class.getName(),
Object.class.getName(), Option.class.getName()};
/**
* Parameter signature used for TreeCache.remove calls over JMX
*/
- private static final String[] REMOVE_SIGNATURE =
+ private static final String[] REMOVE_SIGNATURE =
{Fqn.class.getName(), Option.class.getName()};
-
+
private static final Option GRAVITATE_OPTION = new Option();
private static final Option LOCAL_OPTION = new Option();
-
+
static
{
GRAVITATE_OPTION.setForceDataGravitation(true);
LOCAL_OPTION.setCacheModeLocal(true);
}
-
-
+
+
// ------------------------------------------------------- Instance Fields
-
+
/**
* SSO id which the thread is currently storing to the cache
*/
@@ -152,11 +153,11 @@
* ObjectName of the TreeCache
*/
private ObjectName cacheObjectName = null;
-
+
private String threadPoolName = DEFAULT_THREAD_POOL_NAME;
private ThreadPool threadPool;
-
+
/**
* String version of the object name to use to access the TreeCache
*/
@@ -166,7 +167,7 @@
* Transaction Manager
*/
private TransactionManager tm = null;
-
+
/**
* The lifecycle event support for this component.
*/
@@ -206,23 +207,23 @@
* Whether we have logged an error due to not having a valid cache
*/
private boolean missingCacheErrorLogged = false;
-
+
/**
* Our node's address in the cluster.
*/
private Serializable localAddress = null;
-
+
/** The members of the last view passed to viewChange() */
private Set currentView;
-
+
/** Mutex lock to ensure only one view change at a time is being processed */
private Object cleanupMutex = new Object();
-
+
private boolean checkForInvalidAddresses = false;
-
+
// ---------------------------------------------------------- Constructors
-
+
/**
* Creates a new TreeCacheSSOClusterManager
*/
@@ -234,7 +235,7 @@
server = MBeanServerLocator.locate();
}
-
+
/**
* Creates a new TreeCacheSSOClusterManager that works with the given
* MBeanServer. This constructor is only intended for use in unit testing.
@@ -243,10 +244,10 @@
{
this.server = server;
}
-
-
+
+
// ------------------------------------------------------------ Properties
-
+
public String getCacheName()
{
return cacheName;
@@ -283,7 +284,7 @@
removeAsTreeCacheListener();
this.tm = null;
-
+
this.cacheObjectName = objectName;
this.cacheName = (objectName == null
? null
@@ -304,7 +305,7 @@
}
}
}
-
+
public String getThreadPoolName()
{
return threadPoolName;
@@ -322,12 +323,12 @@
this.threadPoolName = threadPoolName;
}
}
-
+
public boolean isUsingThreadPool()
{
return threadPool != null;
}
-
+
// ----------------------------------------------------- SSOClusterManager
@@ -363,18 +364,18 @@
// failure to find will throw an IllegalStateException
if (tm == null)
configureFromCache();
-
- // Don't do anything if there is already a transaction
+
+ // Don't do anything if there is already a transaction
// context associated with this thread.
if(tm.getTransaction() == null)
doTx = true;
if(doTx)
tm.begin();
-
+
Set sessions = getSessionSet(fqn, true, false);
- sessions.add(new SessionAddress(session.getId(), localAddress));
-
+ sessions.add(new SessionAddress(getSessionAddressId(session), localAddress));
+
if (checkForInvalidAddresses)
{
cleanDeadMembers(sessions, new HashSet(currentView));
@@ -441,13 +442,13 @@
{
return;
}
-
- // Check whether we are already handling this removal
+
+ // Check whether we are already handling this removal
if (ssoId.equals(beingLocallyRemoved.get()))
{
return;
- }
-
+ }
+
// Add this SSO to our list of in-process local removals so
// this.nodeRemoved() will ignore the removal
beingLocallyRemoved.set(ssoId);
@@ -459,7 +460,7 @@
}
Fqn fqn = getSingleSignOnFqn(ssoId);
-
+
try
{
removeFromTreeCache(fqn);
@@ -553,19 +554,19 @@
{
return;
}
-
+
if (!checkTreeCacheAvailable())
{
return;
}
-
+
// Check that this session removal is not due to our own deregistration
// of an SSO following receipt of a nodeRemoved() call
if (ssoId.equals(beingRemotelyRemoved.get()))
{
return;
}
-
+
Fqn fqn = getSessionsFqn(ssoId);
boolean doTx = false;
// boolean removing = false;
@@ -576,18 +577,18 @@
if (tm == null)
configureFromCache();
- // Don't do anything if there is already a transaction
+ // Don't do anything if there is already a transaction
// context associated with this thread.
if(tm.getTransaction() == null)
doTx = true;
if(doTx)
tm.begin();
-
+
Set sessions = getSessionSet(fqn, false, false);
if (sessions != null)
{
- sessions.remove(new SessionAddress(session.getId(), localAddress));
+ sessions.remove(new SessionAddress(getSessionAddressId(session), localAddress));
if (log.isTraceEnabled())
{
@@ -595,8 +596,8 @@
" from cached session set for SSO " + ssoId + " -- " +
sessions.size() + " sessions remain");
}
-
+
if (checkForInvalidAddresses)
{
cleanDeadMembers(sessions, new HashSet(currentView));
@@ -615,7 +616,7 @@
catch (Exception x)
{
}
-
+
String sessId = (session == null ? "NULL" : session.getId());
log.error("caught exception removing session " + sessId +
" from SSO id " + ssoId, e);
@@ -655,7 +656,7 @@
storeSSOData(ssoId, authType, username, password);
}
-
+
// ------------------------------------------------------ TreeCacheListener
/**
@@ -670,7 +671,7 @@
public void nodeRemoved(Fqn fqn)
{
String ssoId = getIdFromFqn(fqn);
-
+
if (ssoId == null)
return;
@@ -679,7 +680,7 @@
{
return;
}
-
+
beingRemotelyRemoved.set(ssoId);
try
@@ -729,7 +730,7 @@
/**
- *
+ *
* @param fqn an Fqn that points to the CREDENTIALS node of an SSO
*/
private void handleCredentialUpdate(Fqn fqn)
@@ -782,9 +783,9 @@
log.error("failed to update credentials for SSO " + ssoId, e);
}
}
-
+
/**
- *
+ *
* @param fqn an Fqn that points to the SESSIONS node of an SSO
*/
private void handleSessionSetChange(Fqn fqn)
@@ -792,19 +793,19 @@
// Here we *want* to handle local activity as well as remote,
// as the distributed cache set of sessions is the only
// complete representation
-
+
String ssoId = getIdFromFqn(fqn);
- try
+ try
{
Set sessions = (Set) getFromTreeCache(fqn, false);
if (sessions == null)
{
- // don't think we'd get this event;
+ // don't think we'd get this event;
// in any case we don't deal with this
}
else if (sessions.size() == 0)
{
- ssoValve.notifySSOEmpty(ssoId);
+ ssoValve.notifySSOEmpty(ssoId);
}
else
{
@@ -826,20 +827,20 @@
*/
public synchronized void viewChange(View new_view)
{
- Set oldMembers = currentView;
+ Set oldMembers = currentView;
currentView = new HashSet(new_view.getMembers());
-
+
if (oldMembers == null)
return; // we must not be started yet
-
+
// If we're not in the view, just exit
if (localAddress == null || !currentView.contains((Address) localAddress))
return;
-
- // Remove all the current members from the old set; any left
+
+ // Remove all the current members from the old set; any left
// are the dead members
oldMembers.removeAll(currentView);
-
+
if (oldMembers.size() > 0)
{
// Inform threads updating our SSOs to check for dead members so
@@ -858,9 +859,9 @@
t.start();
}
}
-
- }
-
+
+ }
+
// ------------------------------------------------------------- Lifecycle
@@ -913,7 +914,7 @@
("TreeCacheSSOClusterManager already Started");
}
- try
+ try
{
if (isTreeCacheAvailable(true))
{
@@ -925,9 +926,9 @@
throw new LifecycleException("Caught exception looking up " +
"TransactionManager from TreeCache", e);
}
-
+
initThreadPool();
-
+
started = true;
// Notify our interested LifecycleListeners
@@ -952,14 +953,14 @@
throw new LifecycleException
("TreeCacheSSOClusterManager not Started");
}
-
+
started = false;
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
}
-
+
// ------------------------------------------------------- Private Methods
private Object getFromTreeCache(Fqn fqn, boolean localOnly) throws Exception
@@ -967,12 +968,12 @@
Object[] args = new Object[]{fqn, KEY, localOnly ? LOCAL_OPTION : GRAVITATE_OPTION};
return server.invoke(getCacheObjectName(), "get", args, GET_SIGNATURE);
}
-
+
private Set getSSOIds() throws Exception
{
Fqn ssoRoot = new Fqn(new Object[] {SSO});
- Set ssoIds = (Set) server.invoke(getCacheObjectName(), "getChildrenNames",
- new Object[]{ ssoRoot },
+ Set ssoIds = (Set) server.invoke(getCacheObjectName(), "getChildrenNames",
+ new Object[]{ ssoRoot },
new String[]{ Fqn.class.getName() });
return ssoIds == null ? Collections.emptySet() : ssoIds;
}
@@ -1038,28 +1039,28 @@
type = (String) fqn.get(2);
return type;
}
-
+
/**
* Obtains needed configuration information from the tree cache.
* Invokes "getTransactionManager" on the tree cache, caching the
* result or throwing an IllegalStateException if one is not found.
* Also get our cluster-wide unique local address from the cache.
- *
+ *
* @throws Exception
*/
private void configureFromCache() throws Exception
- {
- tm = (TransactionManager) server.getAttribute(getCacheObjectName(),
+ {
+ tm = (TransactionManager) server.getAttribute(getCacheObjectName(),
"TransactionManager");
- if (tm == null)
+ if (tm == null)
{
throw new IllegalStateException("TreeCache does not have a " +
"transaction manager; please " +
"configure a valid " +
"TransactionManagerLookupClass");
}
-
+
// Find out our address
Object address = server.getAttribute(cacheObjectName, "LocalAddress");
// In reality this is a JGroups IpAddress, but the API says
@@ -1068,29 +1069,29 @@
localAddress = (Serializable) address;
else
localAddress = address.toString();
-
+
// Get the currentView
- Vector members = (Vector) server.getAttribute(getCacheObjectName(),
+ Vector members = (Vector) server.getAttribute(getCacheObjectName(),
"Members");
if (members != null)
currentView = new HashSet(members);
}
-
+
private void endTransaction()
{
- try
+ try
{
if(tm.getTransaction().getStatus() != Status.STATUS_MARKED_ROLLBACK)
{
tm.commit();
- }
+ }
else
{
tm.rollback();
}
- }
- catch (Exception e)
+ }
+ catch (Exception e)
{
log.error(e);
throw new NestedRuntimeException("TreeCacheSSOClusterManager.endTransaction(): ", e);
@@ -1140,7 +1141,7 @@
}
return treeCacheAvailable;
}
-
+
private boolean checkTreeCacheAvailable()
{
boolean avail = isTreeCacheAvailable(false);
@@ -1159,12 +1160,12 @@
{
// Ensure we have a transaction manager and a cluster-wide unique address
configureFromCache();
-
+
// If the SSO region is inactive, activate it
activateCacheRegion();
-
+
registerAsTreeCacheListener();
-
+
log.debug("Successfully integrated with cache service " + cacheObjectName);
}
@@ -1172,7 +1173,7 @@
/**
* If we are sharing a cache with HttpSession replication, the SSO
* region may not be active, so here we ensure it is.
- *
+ *
* @throws Exception
*/
private void activateCacheRegion() throws Exception
@@ -1198,7 +1199,7 @@
catch (MBeanException e)
{
Exception cause = e.getTargetException();
- if (cause != null
+ if (cause != null
&& "org.jboss.cache.RegionNotEmptyException".equals(cause.getClass().getName()))
{
log.debug(SSO + " region already active", cause);
@@ -1253,9 +1254,9 @@
new Object[]{fqn, GRAVITATE_OPTION},
REMOVE_SIGNATURE);
}
-
+
private void initThreadPool()
- {
+ {
if (threadPoolName != null)
{
try
@@ -1267,14 +1268,14 @@
}
catch (Exception e)
{
- log.info("Unable to access ThreadPool at " + threadPoolName +
+ log.info("Unable to access ThreadPool at " + threadPoolName +
" -- will use individual threads for cleanup work");
log.debug("Failure to access ThreadPool due to: " + e);
}
}
else
{
- log.debug("No ThreadPool configured -- will use individual threads for cleanup work");
+ log.debug("No ThreadPool configured -- will use individual threads for cleanup work");
}
}
@@ -1298,11 +1299,11 @@
String password)
{
SSOCredentials data = new SSOCredentials(authType, username, password);
-
+
// Add this SSO to our list of in-process local adds so
// this.nodeModified() will ignore the addition
beingLocallyAdded.set(ssoId);
-
+
try
{
putInTreeCache(getCredentialsFqn(ssoId), data, false);
@@ -1347,7 +1348,28 @@
setMissingCacheErrorLogged(true);
}
}
-
+
+ /**
+ * Creates a SessionAddressId which includes the host and context in
+ * addition to the session id itself. These fields could not be added
+ * directly to SessionAddress as that would have broken backwards
+ * compatibility. See JBPAPP-4473 for more information.
+ */
+ private String getSessionAddressId(Session session)
+ {
+ Container context = session.getManager().getContainer();
+ String contextName = context.getName();
+ Container host = context.getParent();
+ String hostName = host.getName();
+
+ StringBuilder builder = new StringBuilder(hostName);
+ builder.append('_');
+ builder.append(contextName);
+ builder.append('_');
+ builder.append(session.getId());
+ return builder.toString();
+ }
+
private static boolean cleanDeadMembers(Set sessionSet, Set currentMembers)
{
boolean changed = false;
@@ -1381,7 +1403,7 @@
{
/** The serialVersionUID */
private static final long serialVersionUID = 5704877226920571663L;
-
+
private String authType = null;
private String password = null;
private String username = null;
@@ -1433,15 +1455,15 @@
}
} // end SSOCredentials
-
+
static class SessionAddress implements Serializable
{
/** The serialVersionUID */
private static final long serialVersionUID = -3702932999380140004L;
-
+
Serializable address;
String sessionId;
-
+
SessionAddress(String sessionId, Serializable address)
{
this.sessionId = sessionId;
@@ -1452,13 +1474,13 @@
{
if (this == obj)
return true;
-
+
if (!(obj instanceof SessionAddress))
return false;
-
+
SessionAddress other = (SessionAddress) obj;
-
- return (sessionId.equals(other.sessionId)
+
+ return (sessionId.equals(other.sessionId)
&& address.equals(other.address));
}
@@ -1467,36 +1489,36 @@
int total = (19 * 43) + sessionId.hashCode();
return ((total * 43) + address.hashCode());
}
-
-
+
+
}
/**
- * Runnable that's run when the removal of a node from the cluster has been detected.
+ * Runnable that's run when the removal of a node from the cluster has been detected.
* Removes any SessionAddress objects associated with dead members from the
* session set of each SSO. Operates locally only so each node can independently clean
* its SSOs without concern about replication lock conflicts.
*/
private class DeadMemberCleaner implements Runnable
- {
+ {
public void run()
{
synchronized (cleanupMutex)
{
try
- {
+ {
// Ensure we have a TransactionManager
if (tm == null)
configureFromCache();
-
+
Set ids = getSSOIds();
// Copy off the currentView
Set members = new HashSet(currentView);
for (Iterator iter = ids.iterator(); iter.hasNext();)
{
- cleanDeadMembersFromSSO((String) iter.next(), members);
+ cleanDeadMembersFromSSO((String) iter.next(), members);
}
-
+
// We've cleaned up; no need for other threads to help
checkForInvalidAddresses = false;
}
@@ -1506,7 +1528,7 @@
}
}
}
-
+
private void cleanDeadMembersFromSSO(String ssoId, Set currentMembers)
{
Fqn fqn = getSessionsFqn(ssoId);
@@ -1519,20 +1541,20 @@
if(doTx)
tm.begin();
-
+
Set sessions = getSessionSet(fqn, false, true);
if (sessions != null && sessions.size() > 0)
{
boolean changed = cleanDeadMembers(sessions, currentMembers);
-
+
if (changed)
- {
+ {
if (sessions.size() == 0)
{
ssoValve.notifySSOEmpty(ssoId);
}
-
- // Don't bother with the local-onlyput; we have a lock on the node
+
+ // Don't bother with the local-onlyput; we have a lock on the node
// from the get and the cached data is a ref to the set we just changed
//putInTreeCache(fqn, sessions, true);
}
@@ -1554,7 +1576,7 @@
{
if (doTx)
endTransaction();
- }
+ }
}
}
More information about the jboss-cvs-commits
mailing list