Author: markt
Date: Fri Dec 19 13:55:24 2014
New Revision: 1646721

URL: http://svn.apache.org/r1646721
Log:
Refactor to replace reverse map with dedicated session listener that
contains a reference to the SSO ID.
This refactoring is in support of the fix for BZ 57338.

Added:
    
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnListener.java
Modified:
    tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java
    tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnEntry.java
    
tomcat/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java?rev=1646721&r1=1646720&r2=1646721&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOn.java Fri 
Dec 19 13:55:24 2014
@@ -31,7 +31,6 @@ import org.apache.catalina.LifecycleExce
 import org.apache.catalina.Manager;
 import org.apache.catalina.Realm;
 import org.apache.catalina.Session;
-import org.apache.catalina.SessionEvent;
 import org.apache.catalina.SessionListener;
 import org.apache.catalina.connector.Request;
 import org.apache.catalina.connector.Response;
@@ -57,7 +56,7 @@ import org.apache.tomcat.util.res.String
  *
  * @author Craig R. McClanahan
  */
-public class SingleSignOn extends ValveBase implements SessionListener {
+public class SingleSignOn extends ValveBase {
 
     private static final StringManager sm = 
StringManager.getManager(SingleSignOn.class);
 
@@ -90,13 +89,6 @@ public class SingleSignOn extends ValveB
     private boolean requireReauthentication = false;
 
     /**
-     * The cache of single sign on identifiers, keyed by the Session that is
-     * associated with them.
-     */
-    protected Map<SingleSignOnSessionKey,String> reverse = new 
ConcurrentHashMap<>();
-
-
-    /**
      * Optional SSO cookie domain.
      */
     private String cookieDomain;
@@ -196,55 +188,6 @@ public class SingleSignOn extends ValveB
     }
 
 
-    // ------------------------------------------------ SessionListener Methods
-
-    /**
-     * Acknowledge the occurrence of the specified event.
-     *
-     * @param event SessionEvent that has occurred
-     */
-    @Override
-    public void sessionEvent(SessionEvent event) {
-
-        if (!getState().isAvailable()) {
-            return;
-        }
-
-        // We only care about session destroyed events
-        if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType())) {
-            return;
-        }
-
-        // Look up the single session id associated with this session (if any)
-        Session session = event.getSession();
-        if (containerLog.isDebugEnabled()) {
-            containerLog.debug("Process session destroyed on " + session);
-        }
-
-        String ssoId = null;
-        ssoId = reverse.get(new SingleSignOnSessionKey(session));
-        if (ssoId == null) {
-            return;
-        }
-
-        // Was the session destroyed as the result of a timeout or context 
stop?
-        // If so, we'll just remove the expired session from the SSO. If the
-        // session was logged out, we'll log out of all session associated with
-        // the SSO.
-        if (((session.getMaxInactiveInterval() > 0)
-            && (System.currentTimeMillis() - 
session.getThisAccessedTimeInternal() >=
-                session.getMaxInactiveInterval() * 1000))
-            || (!session.getManager().getContext().getState().isAvailable())) {
-            removeSession(ssoId, session);
-        } else {
-            // The session was logged out.
-            // Deregister this single session id, invalidating
-            // associated sessions
-            deregister(ssoId);
-        }
-    }
-
-
     // ---------------------------------------------------------- Valve Methods
 
     /**
@@ -349,6 +292,43 @@ public class SingleSignOn extends ValveB
     // ------------------------------------------------------ Protected Methods
 
     /**
+     * Process a session destroyed event by removing references to that session
+     * from the caches and - if the session destruction is the result of a
+     * logout - destroy the associated SSO session.
+     *
+     * @param ssoId   The ID of the SSO session which which the destroyed
+     *                session was associated
+     * @param session The session that has been destroyed
+     */
+    public void sessionDestroyed(String ssoId, Session session) {
+
+        if (!getState().isAvailable()) {
+            return;
+        }
+
+        if (containerLog.isDebugEnabled()) {
+            containerLog.debug("Process session destroyed on " + session);
+        }
+
+        // Was the session destroyed as the result of a timeout or context 
stop?
+        // If so, we'll just remove the expired session from the SSO. If the
+        // session was logged out, we'll log out of all session associated with
+        // the SSO.
+        if (((session.getMaxInactiveInterval() > 0)
+            && (System.currentTimeMillis() - 
session.getThisAccessedTimeInternal() >=
+                session.getMaxInactiveInterval() * 1000))
+            || (!session.getManager().getContext().getState().isAvailable())) {
+            removeSession(ssoId, session);
+        } else {
+            // The session was logged out.
+            // Deregister this single session id, invalidating
+            // associated sessions
+            deregister(ssoId);
+        }
+    }
+
+
+    /**
      * Associate the specified single sign on identifier with the
      * specified Session.
      *
@@ -368,8 +348,7 @@ public class SingleSignOn extends ValveB
         if (sso == null) {
             return false;
         } else {
-            sso.addSession(this, session);
-            reverse.put(new SingleSignOnSessionKey(session), ssoId);
+            sso.addSession(this, ssoId, session);
             return true;
         }
     }
@@ -399,8 +378,6 @@ public class SingleSignOn extends ValveB
             if (containerLog.isTraceEnabled()) {
                 containerLog.trace(" Invalidating session " + ssoKey);
             }
-            // Remove from reverse cache first to avoid recursion
-            reverse.remove(ssoKey);
             // Invalidate this session
             expire(ssoKey);
         }
@@ -586,9 +563,6 @@ public class SingleSignOn extends ValveB
         // Remove the inactive session from SingleSignOnEntry
         entry.removeSession(session);
 
-        // Remove the inactive session from the 'reverse' Map.
-        reverse.remove(new SingleSignOnSessionKey(session));
-
         // If there are not sessions left in the SingleSignOnEntry,
         // deregister the entry.
         if (entry.findSessions().size() == 0) {
@@ -597,6 +571,11 @@ public class SingleSignOn extends ValveB
     }
 
 
+    protected SessionListener getSessionListener(String ssoId) {
+        return new SingleSignOnListener(ssoId);
+    }
+
+
     @Override
     protected synchronized void startInternal() throws LifecycleException {
         Container c = getContainer();

Modified: 
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnEntry.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnEntry.java?rev=1646721&r1=1646720&r2=1646721&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnEntry.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnEntry.java 
Fri Dec 19 13:55:24 2014
@@ -87,12 +87,12 @@ public class SingleSignOnEntry implement
      *                  the SSO session.
      * @param session   The <code>Session</code> being associated with the SSO.
      */
-    public void addSession(SingleSignOn sso, Session session) {
+    public void addSession(SingleSignOn sso, String ssoId, Session session) {
         SingleSignOnSessionKey key = new SingleSignOnSessionKey(session);
         SingleSignOnSessionKey currentKey = sessionKeys.putIfAbsent(key, key);
         if (currentKey == null) {
             // Session not previously added
-            session.addSessionListener(sso);
+            session.addSessionListener(sso.getSessionListener(ssoId));
         }
     }
 

Added: 
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnListener.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnListener.java?rev=1646721&view=auto
==============================================================================
--- 
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnListener.java 
(added)
+++ 
tomcat/trunk/java/org/apache/catalina/authenticator/SingleSignOnListener.java 
Fri Dec 19 13:55:24 2014
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.authenticator;
+
+import java.io.Serializable;
+
+import org.apache.catalina.Authenticator;
+import org.apache.catalina.Context;
+import org.apache.catalina.Manager;
+import org.apache.catalina.Session;
+import org.apache.catalina.SessionEvent;
+import org.apache.catalina.SessionListener;
+
+public class SingleSignOnListener implements SessionListener, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private final String ssoId;
+
+    public SingleSignOnListener(String ssoId) {
+        this.ssoId = ssoId;
+    }
+
+
+    @Override
+    public void sessionEvent(SessionEvent event) {
+        if (!Session.SESSION_DESTROYED_EVENT.equals(event.getType())) {
+            return;
+        }
+
+        Session session = event.getSession();
+        Manager manager = session.getManager();
+        if (manager == null) {
+            return;
+        }
+        Context context = manager.getContext();
+        if (context == null) {
+            return;
+        }
+        Authenticator authenticator = context.getAuthenticator();
+        if (!(authenticator instanceof AuthenticatorBase)) {
+            return;
+        }
+        SingleSignOn sso = ((AuthenticatorBase) authenticator).sso;
+        if (sso == null) {
+            return;
+        }
+        sso.sessionDestroyed(ssoId, session);
+    }
+}

Modified: 
tomcat/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java?rev=1646721&r1=1646720&r2=1646721&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java 
(original)
+++ 
tomcat/trunk/java/org/apache/catalina/ha/authenticator/ClusterSingleSignOn.java 
Fri Dec 19 13:55:24 2014
@@ -24,7 +24,6 @@ import org.apache.catalina.LifecycleExce
 import org.apache.catalina.Session;
 import org.apache.catalina.authenticator.SingleSignOn;
 import org.apache.catalina.authenticator.SingleSignOnEntry;
-import org.apache.catalina.authenticator.SingleSignOnSessionKey;
 import org.apache.catalina.ha.CatalinaCluster;
 import org.apache.catalina.ha.ClusterValve;
 import org.apache.catalina.tribes.Channel;
@@ -157,12 +156,6 @@ public class ClusterSingleSignOn extends
                     cls, terminateOnStartFailure);
             cache.setChannelSendOptions(mapSendOptions);
             this.cache = cache;
-
-            ReplicatedMap<SingleSignOnSessionKey,String> reverse = new 
ReplicatedMap<>(
-                    this, cluster.getChannel(), rpcTimeout, 
cluster.getClusterName() + "-SSO-reverse",
-                    cls, terminateOnStartFailure);
-            reverse.setChannelSendOptions(mapSendOptions);
-            this.reverse = reverse;
         } catch (Throwable t) {
             ExceptionUtils.handleThrowable(t);
             throw new LifecycleException(
@@ -187,7 +180,6 @@ public class ClusterSingleSignOn extends
 
         if (getCluster() != null) {
             ((ReplicatedMap<?,?>) cache).breakdown();
-            ((ReplicatedMap<?,?>) reverse).breakdown();
         }
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to