[jboss-cvs] JBossAS SVN: r77077 - in trunk: 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
Thu Aug 14 14:50:47 EDT 2008


Author: bstansberry at jboss.com
Date: 2008-08-14 14:50:47 -0400 (Thu, 14 Aug 2008)
New Revision: 77077

Modified:
   trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/TreeCacheSSOClusterManagerUnitTestCase.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/sso/TreeCacheSSOClusterManager.java
Log:
[JBAS-5609] Handle multiple sessions with the same session id but different managers

Modified: trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/TreeCacheSSOClusterManagerUnitTestCase.java
===================================================================
--- trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/TreeCacheSSOClusterManagerUnitTestCase.java	2008-08-14 15:37:04 UTC (rev 77076)
+++ trunk/testsuite/src/main/org/jboss/test/cluster/defaultcfg/simpleweb/test/TreeCacheSSOClusterManagerUnitTestCase.java	2008-08-14 18:50:47 UTC (rev 77077)
@@ -30,6 +30,7 @@
 import org.apache.catalina.LifecycleException;
 import org.apache.catalina.Manager;
 import org.apache.catalina.Session;
+import org.apache.catalina.core.StandardContext;
 import org.apache.catalina.session.StandardManager;
 import org.apache.catalina.session.StandardSession;
 import org.jboss.cache.Cache;
@@ -53,6 +54,8 @@
 import org.jboss.test.JBossTestCase;
 import org.jboss.test.cluster.testutil.DelegatingMockCache;
 import org.jboss.test.cluster.testutil.MockTransactionManagerLookup;
+import org.jboss.test.cluster.web.mocks.MockEngine;
+import org.jboss.test.cluster.web.mocks.MockHost;
 import org.jboss.util.threadpool.BasicThreadPool;
 import org.jboss.web.tomcat.service.sso.ClusteredSingleSignOn;
 import org.jboss.web.tomcat.service.sso.TreeCacheSSOClusterManager;
@@ -151,11 +154,11 @@
          // Create an SSO that will have two sessions from local valve
          localSSOManager.register("1", "FORM", "Brian", "password");
          
-         Manager localSessMgr1 = new StandardManager();
+         Manager localSessMgr1 = getSessionManager("A");
          Session sess1 = new MockSession(localSessMgr1, "1");
          localSSOManager.addSession("1", sess1);
          
-         Manager localSessMgr2 = new StandardManager();
+         Manager localSessMgr2 = getSessionManager("B");
          Session sess2 = new MockSession(localSessMgr2, "2");
          localSSOManager.addSession("1", sess2);
          
@@ -209,11 +212,11 @@
          // Create an SSO that will have two sessions from local valve
          localSSOManager.register("1", "FORM", "Brian", "password");
          
-         Manager localSessMgr1 = new StandardManager();
+         Manager localSessMgr1 = getSessionManager("A");
          Session sess1 = new MockSession(localSessMgr1, "1");
          localSSOManager.addSession("1", sess1);
          
-         Manager localSessMgr2 = new StandardManager();
+         Manager localSessMgr2 = getSessionManager("B");
          Session sess2 = new MockSession(localSessMgr2, "2");
          localSSOManager.addSession("1", sess2);
          
@@ -265,11 +268,11 @@
       // Create an SSO that will have two sessions from local valve
       localSSOManager.register("1", "FORM", "Brian", "password");
       
-      Manager localSessMgr1 = new StandardManager();
+      Manager localSessMgr1 = getSessionManager("A");
       Session sess1 = new MockSession(localSessMgr1, "1");
       localSSOManager.addSession("1", sess1);
       
-      Manager localSessMgr2 = new StandardManager();
+      Manager localSessMgr2 = getSessionManager("B");
       Session sess2 = new MockSession(localSessMgr2, "2");
       localSSOManager.addSession("1", sess2);
       
@@ -400,11 +403,11 @@
       // Create an SSO that will have sessions from both valves
       localSSOManager.register("1", "FORM", "Brian", "password");
       
-      Manager localSessMgr1 = new StandardManager();
+      Manager localSessMgr1 = getSessionManager("A");
       Session sess1 = new MockSession(localSessMgr1, "1");
       localSSOManager.addSession("1", sess1);
       
-      Manager remoteSessMgr1 = new StandardManager();
+      Manager remoteSessMgr1 = getSessionManager("B");
       Session sess2 = new MockSession(remoteSessMgr1, "2");
       remoteSSOManager.addSession("1", sess2);
       
@@ -412,38 +415,52 @@
       // Create another SSO with sessions only from remote
       remoteSSOManager.register("2", "FORM", "Brian", "password");
       
-      Manager remoteSessMgr2 = new StandardManager();
+      Manager remoteSessMgr2 = getSessionManager("C");
       Session sess3 = new MockSession(remoteSessMgr2, "3");
       remoteSSOManager.addSession("2", sess3);
       
-      Manager remoteSessMgr3 = new StandardManager();
+      Manager remoteSessMgr3 = getSessionManager("D");
       Session sess4 = new MockSession(remoteSessMgr3, "4");
       remoteSSOManager.addSession("2", sess4);
       
       
       // Create a third SSO that will have sessions from both valves
+      // with the same session id
       localSSOManager.register("3", "FORM", "Brian", "password");
       
-      Manager localSessMgr2 = new StandardManager();
+      Manager localSessMgr2 = getSessionManager("E");
       Session sess5 = new MockSession(localSessMgr2, "5");
       localSSOManager.addSession("3", sess5);
       
-      Manager remoteSessMgr4 = new StandardManager();
-      Session sess6 = new MockSession(remoteSessMgr4, "6");
+      Manager remoteSessMgr4 = getSessionManager("E");
+      Session sess6 = new MockSession(remoteSessMgr4, "5");
       remoteSSOManager.addSession("3", sess6);
       
       
       // Create a fourth SSO that will have two sessions from local valve
       localSSOManager.register("4", "FORM", "Brian", "password");
       
-      Manager localSessMgr3 = new StandardManager();
+      Manager localSessMgr3 = getSessionManager("F");
       Session sess7 = new MockSession(localSessMgr3, "7");
       localSSOManager.addSession("4", sess7);
       
-      Manager localSessMgr4 = new StandardManager();
+      Manager localSessMgr4 = getSessionManager("G");
       Session sess8 = new MockSession(localSessMgr4, "8");
       localSSOManager.addSession("4", sess8);
       
+      
+      // Create a fifth SSO with sessions only from remote, same session id
+      // but different managers
+      remoteSSOManager.register("5", "FORM", "Brian", "password");
+      
+      Manager remoteSessMgr5 = getSessionManager("H");
+      Session sess9 = new MockSession(remoteSessMgr5, "9");
+      remoteSSOManager.addSession("5", sess9);
+      
+      Manager remoteSessMgr6 = getSessionManager("I");
+      Session sess10 = new MockSession(remoteSessMgr6, "9");
+      remoteSSOManager.addSession("5", sess10);
+      
       // Confirm that data is cached properly
       assertEquals("SSO 1 has correct number of sessions", 2, localSSOManager.getSessionCount("1"));
       assertEquals("SSO 1 has correct number of sessions", 2, remoteSSOManager.getSessionCount("1"));
@@ -453,6 +470,8 @@
       assertEquals("SSO 3 has correct number of sessions", 2, remoteSSOManager.getSessionCount("3"));
       assertEquals("SSO 4 has correct number of sessions", 2, localSSOManager.getSessionCount("4"));
       assertEquals("SSO 4 has correct number of sessions", 2, remoteSSOManager.getSessionCount("4"));
+      assertEquals("SSO 5 has correct number of sessions", 2, localSSOManager.getSessionCount("5"));
+      assertEquals("SSO 5 has correct number of sessions", 2, remoteSSOManager.getSessionCount("5"));
       
       // Put in a new view with REMOTE_ADDRESS dead
       ViewId viewId = new ViewId(LOCAL_ADDRESS, 1);
@@ -473,8 +492,55 @@
       assertEquals("SSO 2 has correct number of sessions", 0, localSSOManager.getSessionCount("2"));
       assertEquals("SSO 3 has correct number of sessions", 1, localSSOManager.getSessionCount("3"));
       assertEquals("SSO 4 has correct number of sessions", 2, localSSOManager.getSessionCount("4"));
+      assertEquals("SSO 5 has correct number of sessions", 0, localSSOManager.getSessionCount("5"));
    }
    
+   /**
+    * Test for JBAS-5609 -- confirm that if sessions from different managers
+    * but with the same session id are registered, the removal of one leaves
+    * the SSO in the proper state.
+    */
+   public void testSameSessionId() throws Exception
+   {
+      CacheManager cacheManager = getCacheManager();
+      // Register a cache
+      Cache<Object, Object> delegate = new DefaultCacheFactory<Object, Object>().createCache(false);
+      MockTreeCache cache = new MockTreeCache(delegate);
+      // JBAS-4097 -- don't use a TransactionManagerLookup that will
+      // bind DummyTransactionManager into JNDI, as that will screw
+      // up other tests
+      cache.getConfiguration().getRuntimeConfig().setTransactionManager(new BatchModeTransactionManager());
+      
+      cacheManager.registerCache(cache, ClusteredSingleSignOn.DEFAULT_CACHE_NAME);
+      
+      // Build up an SSO infrastructure based on LOCAL_ADDRESS  
+      TreeCacheSSOClusterManager localSSOManager = new TreeCacheSSOClusterManager(mbeanServer);
+      localSSOManager.setCacheName(ClusteredSingleSignOn.DEFAULT_CACHE_NAME);
+      
+      MockSSOValve localValve = new MockSSOValve();
+      localValve.setClusterManager(localSSOManager);
+      localSSOManager.setSingleSignOnValve(localValve);
+      localSSOManager.start();
+      
+      
+      // Create an SSO that will have sessions from both valves
+      localSSOManager.register("1", "FORM", "Brian", "password");
+      
+      Manager localSessMgr1 = getSessionManager("A");
+      Session sess1 = new MockSession(localSessMgr1, "1");
+      localSSOManager.addSession("1", sess1);
+      
+      Manager localSessMgr2 = getSessionManager("B");
+      Session sess2 = new MockSession(localSessMgr2, "1");
+      localSSOManager.addSession("1", sess2);
+      
+      assertEquals(2, localSSOManager.getSessionCount("1"));
+      
+      localSSOManager.removeSession("1", sess2);
+      
+      assertEquals(1, localSSOManager.getSessionCount("1"));
+   }
+   
    private CacheManager getCacheManager() throws Exception
    {
       if (cacheManager == null)
@@ -487,7 +553,22 @@
       return cacheManager;
    }
    
+   private Manager getSessionManager(String contextName)
+   {
+      StandardManager mgr = new StandardManager();
+      MockEngine engine = new MockEngine();
+      MockHost host = new MockHost();
+      engine.addChild(host);
+      host.setName("localhost");
+      StandardContext container = new StandardContext();
+      container.setName(contextName);
+      host.addChild(container);
+      container.setManager(mgr);
+      
+      return mgr;
+   }
    
+   
    static class MockTreeCache extends DelegatingMockCache
    {
       private IpAddress ourAddress = LOCAL_ADDRESS;
@@ -555,6 +636,13 @@
       {
          return ourId;
       }
+
+      @Override
+      public String getIdInternal()
+      {
+         return ourId;
+      }      
+      
    }
 
 }

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/sso/TreeCacheSSOClusterManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/sso/TreeCacheSSOClusterManager.java	2008-08-14 15:37:04 UTC (rev 77076)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/sso/TreeCacheSSOClusterManager.java	2008-08-14 18:50:47 UTC (rev 77077)
@@ -37,6 +37,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;
@@ -326,7 +327,7 @@
          if(doTx)
             tm.begin();
          
-         putInTreeCache(fqn, session.getId(), null);
+         putInTreeCache(fqn, new FullyQualifiedSessionId(session), null);
       }
       catch (Exception e)
       {
@@ -537,9 +538,10 @@
 
          if(doTx)
             tm.begin();
-         
+
+         FullyQualifiedSessionId fqsi = new FullyQualifiedSessionId(session);
          Set keys = getSessionKeys(ssoId);
-         if (keys.contains(session.getId()))
+         if (keys.contains(fqsi))
          {
             if (keys.size() == 1)
             {
@@ -551,7 +553,7 @@
             else
             {
                // Simple removal of one our local sessions
-               removeFromTreeCache(fqn, session.getId());
+               removeFromTreeCache(fqn, fqsi);
             }
          }
       }
@@ -1553,7 +1555,88 @@
       }
 
    } // end SSOCredentials
+   
+   public static class FullyQualifiedSessionId implements Serializable
+   {
+      /** The serialVersionUID */
+      private static final long serialVersionUID = 6081884018218825708L;
+      
+      private final String hostName;
+      private final String contextName;
+      private final String sessionId;
+      
+      public FullyQualifiedSessionId(Session session)
+      {
+         this.sessionId = session.getIdInternal();
+         Container context = session.getManager().getContainer();
+         this.contextName = context.getName(); 
+         Container host = context.getParent();
+         this.hostName = host.getName();       
+      }
+      
+      /**
+       * Get the contextPath.
+       * 
+       * @return the contextPath.
+       */
+      public String getContextName()
+      {
+         return contextName;
+      }
+      /**
+       * Get the hostName.
+       * 
+       * @return the hostName.
+       */
+      public String getHostName()
+      {
+         return hostName;
+      }
+      /**
+       * Get the sessionId.
+       * 
+       * @return the sessionId.
+       */
+      public String getSessionId()
+      {
+         return sessionId;
+      }
 
+      @Override
+      public boolean equals(Object obj)
+      {
+         if (this == obj)
+            return true;
+         
+         if (obj instanceof FullyQualifiedSessionId)
+         {
+            FullyQualifiedSessionId other = (FullyQualifiedSessionId) obj;
+            return (hostName.equals(other.hostName) 
+                      && contextName.equals(other.contextName) 
+                      && sessionId.equals(other.sessionId));
+         }
+         
+         return false;
+      }
+
+      @Override
+      public int hashCode()
+      {
+         int result = 17;
+         result += 29 * hostName.hashCode();
+         result += 29 * contextName.hashCode();
+         result += 29 * sessionId.hashCode();
+         return result;
+      }
+
+      @Override
+      public String toString()
+      {
+         return hostName + "/" + contextName + "/" + sessionId;
+      }
+      
+   }
+
    /**
     * 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




More information about the jboss-cvs-commits mailing list