Author: markt Date: Fri Jan 15 17:40:18 2016 New Revision: 1724863 URL: http://svn.apache.org/viewvc?rev=1724863&view=rev Log: Refactoring Make the session attribute distribution / filtering more consistent across the various Manager and Session implementation. Differentiate between - whether or not it is possible for an attribute to be distributed - Session.isAttributeDistributable() - whether or not the Manager wants and attribute to be distributed - Manager.willAttributeDistribute
Modified: tomcat/trunk/java/org/apache/catalina/Manager.java tomcat/trunk/java/org/apache/catalina/Session.java tomcat/trunk/java/org/apache/catalina/ha/session/ClusterManagerBase.java tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java tomcat/trunk/java/org/apache/catalina/manager/DummyProxySession.java tomcat/trunk/java/org/apache/catalina/session/Constants.java tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java tomcat/trunk/java/org/apache/catalina/session/StandardSession.java tomcat/trunk/java/org/apache/catalina/session/StoreBase.java Modified: tomcat/trunk/java/org/apache/catalina/Manager.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Manager.java?rev=1724863&r1=1724862&r2=1724863&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/Manager.java (original) +++ tomcat/trunk/java/org/apache/catalina/Manager.java Fri Jan 15 17:40:18 2016 @@ -370,4 +370,18 @@ public interface Manager { * a method that executes periodic tasks, such as expiring sessions etc. */ public void backgroundProcess(); + + + /** + * Would the Manager distribute the given session attribute? Manager + * implementations may provide additional configuration options to control + * which attributes are distributable. + * + * @param name The attribute name + * @param value The attribute value + * + * @return {@code true} if the Manager would distribute the given attribute + * otherwise {@code false} + */ + public boolean willAttributeDistribute(String name, Object value); } Modified: tomcat/trunk/java/org/apache/catalina/Session.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Session.java?rev=1724863&r1=1724862&r2=1724863&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/Session.java (original) +++ tomcat/trunk/java/org/apache/catalina/Session.java Fri Jan 15 17:40:18 2016 @@ -356,4 +356,23 @@ public interface Session { boolean notifySessionListeners, boolean notifyContainerListeners); + /** + * Does the session implementation support the distributing of the given + * attribute? If the Manager is marked as distributable, then this method + * must be used to check attributes before adding them to a session and + * an {@link IllegalArgumentException} thrown if the proposed attribute is + * not distributable. + * <p> + * Note that the {@link Manager} implementation may further restrict which + * attributes are distributed but a {@link Manager} level restriction should + * not trigger an {@link IllegalArgumentException} in + * {@link HttpSession#setAttribute(String, Object)} + * + * @param name The attribute name + * @param value The attribute value + * + * @return {@code true} if distribution is supported, otherwise {@code + * false} + */ + public boolean isAttributeDistributable(String name, Object value); } Modified: tomcat/trunk/java/org/apache/catalina/ha/session/ClusterManagerBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/session/ClusterManagerBase.java?rev=1724863&r1=1724862&r2=1724863&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/ha/session/ClusterManagerBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/ha/session/ClusterManagerBase.java Fri Jan 15 17:40:18 2016 @@ -138,14 +138,25 @@ public abstract class ClusterManagerBase * * @param name The attribute name * @return <code>true</code> if the attribute should be distributed + * + * @deprecated Use {@link #willAttributeDistribute(String, Object)}. Will be + * removed in Tomcat 9.0.x */ + @Deprecated public boolean willAttributeDistribute(String name) { + return willAttributeDistribute(name, null); + } + + + @Override + public boolean willAttributeDistribute(String name, Object value) { if (sessionAttributePattern == null) { return true; } return sessionAttributePattern.matcher(name).matches(); } + public static ClassLoader[] getClassLoaders(Context context) { ClassLoader tccl = Thread.currentThread().getContextClassLoader(); Loader loader = context.getLoader(); Modified: tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java?rev=1724863&r1=1724862&r2=1724863&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java (original) +++ tomcat/trunk/java/org/apache/catalina/ha/session/DeltaSession.java Fri Jan 15 17:40:18 2016 @@ -610,42 +610,11 @@ public class DeltaSession extends Standa return deltaRequest; } + // ------------------------------------------------- HttpSession Properties // ----------------------------------------------HttpSession Public Methods - - /** - * Check whether the Object can be distributed. - * The object is always distributable, if the cluster manager - * decides to never distribute it. - * @param name The name of the attribute to check - * @param value The value of the attribute to check - * @return true if the attribute is distributable, false otherwise - */ - @Override - protected boolean isAttributeDistributable(String name, Object value) { - if (manager instanceof ClusterManagerBase && - !((ClusterManagerBase)manager).willAttributeDistribute(name)) - return true; - return super.isAttributeDistributable(name, value); - } - - /** - * Exclude attributes from replication. - * @param name the attribute's name - * @return true if attribute should not be replicated - */ - @Override - protected boolean exclude(String name) { - - if (super.exclude(name)) - return true; - if (manager instanceof ClusterManagerBase) - return !((ClusterManagerBase)manager).willAttributeDistribute(name); - return false; - } - /** * Remove the object bound with the specified name from this session. If the * session does not have an object bound with this name, this method does @@ -713,7 +682,7 @@ public class DeltaSession extends Standa lock(); try { super.setAttribute(name,value, notify); - if (addDeltaRequest && deltaRequest != null && !exclude(name)) { + if (addDeltaRequest && deltaRequest != null && !exclude(name, value)) { deltaRequest.setAttribute(name, value); } } finally { @@ -863,9 +832,8 @@ public class DeltaSession extends Standa for (int i = 0; i < keys.length; i++) { Object value = null; value = attributes.get(keys[i]); - if (value == null || exclude(keys[i])) - continue; - else if (value instanceof Serializable) { + if (value != null && !exclude(keys[i], value) && + isAttributeDistributable(keys[i], value)) { saveNames.add(keys[i]); saveValues.add(value); } @@ -908,7 +876,7 @@ public class DeltaSession extends Standa if (value == null) return; super.removeAttributeInternal(name,notify); - if (addDeltaRequest && deltaRequest != null && !exclude(name)) { + if (addDeltaRequest && deltaRequest != null && !exclude(name, null)) { deltaRequest.removeAttribute(name); } Modified: tomcat/trunk/java/org/apache/catalina/manager/DummyProxySession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/DummyProxySession.java?rev=1724863&r1=1724862&r2=1724863&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/manager/DummyProxySession.java (original) +++ tomcat/trunk/java/org/apache/catalina/manager/DummyProxySession.java Fri Jan 15 17:40:18 2016 @@ -214,4 +214,9 @@ public class DummyProxySession implement boolean notifySessionListeners, boolean notifyContainerListeners) { // NOOP } + + @Override + public boolean isAttributeDistributable(String name, Object value) { + return false; + } } Modified: tomcat/trunk/java/org/apache/catalina/session/Constants.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/Constants.java?rev=1724863&r1=1724862&r2=1724863&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/session/Constants.java (original) +++ tomcat/trunk/java/org/apache/catalina/session/Constants.java Fri Jan 15 17:40:18 2016 @@ -14,9 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package org.apache.catalina.session; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; -package org.apache.catalina.session; +import org.apache.catalina.Globals; /** * Manifest constants for the <code>org.apache.catalina.session</code> @@ -27,6 +31,17 @@ package org.apache.catalina.session; public class Constants { - public static final String Package = "org.apache.catalina.session"; - + /** + * Set of session attribute names used internally by Tomcat that should + * always be removed from the session before it is persisted, replicated or + * equivalent. + */ + public static final Set<String> excludedAttributeNames; + + static { + Set<String> names = new HashSet<>(); + names.add(Globals.SUBJECT_ATTR); + names.add(Globals.GSS_CREDENTIAL_ATTR); + excludedAttributeNames = Collections.unmodifiableSet(names); + } } Modified: tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java?rev=1724863&r1=1724862&r2=1724863&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java Fri Jan 15 17:40:18 2016 @@ -191,8 +191,7 @@ public abstract class ManagerBase extend /** * The string manager for this package. */ - protected static final StringManager sm = - StringManager.getManager(Constants.Package); + protected static final StringManager sm = StringManager.getManager(ManagerBase.class); /** * The property change support for this component. @@ -773,6 +772,17 @@ public abstract class ManagerBase extend } + /** + * {@inheritDoc} + * <p> + * This implementation always returns {@code true} + */ + @Override + public boolean willAttributeDistribute(String name, Object value) { + return true; + } + + // ------------------------------------------------------ Protected Methods Modified: tomcat/trunk/java/org/apache/catalina/session/StandardSession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/StandardSession.java?rev=1724863&r1=1724862&r2=1724863&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/session/StandardSession.java (original) +++ tomcat/trunk/java/org/apache/catalina/session/StandardSession.java Fri Jan 15 17:40:18 2016 @@ -162,7 +162,11 @@ public class StandardSession implements /** * Set of attribute names which are not allowed to be persisted. + * + * @deprecated Use {@link Constants#excludedAttributeNames} instead. Will be + * removed in Tomcat 9. */ + @Deprecated protected static final String[] excludedAttributes = { Globals.SUBJECT_ATTR, Globals.GSS_CREDENTIAL_ATTR @@ -247,8 +251,7 @@ public class StandardSession implements /** * The string manager for this package. */ - protected static final StringManager sm = - StringManager.getManager(Constants.Package); + protected static final StringManager sm = StringManager.getManager(StandardSession.class); /** @@ -1463,13 +1466,15 @@ public class StandardSession implements } // Validate our current state - if (!isValidInternal()) + if (!isValidInternal()) { throw new IllegalStateException(sm.getString( "standardSession.setAttribute.ise", getIdInternal())); + } if ((manager != null) && manager.getDistributable() && - !isAttributeDistributable(name, value)) - throw new IllegalArgumentException - (sm.getString("standardSession.setAttribute.iae", name)); + !isAttributeDistributable(name, value) && !exclude(name, value)) { + throw new IllegalArgumentException(sm.getString( + "standardSession.setAttribute.iae", name)); + } // Construct an event with the new value HttpSessionBindingEvent event = null; @@ -1571,15 +1576,14 @@ public class StandardSession implements } /** - * Check whether the Object can be distributed. This implementation - * simply checks for serializability. Derived classes might use other - * distribution technology not based on serialization and can extend - * this check. - * @param name The name of the attribute to check - * @param value The value of the attribute to check - * @return true if the attribute is distributable, false otherwise + * {@inheritDoc} + * <p> + * This implementation simply checks the value for serializability. + * Sub-classes might use other distribution technology not based on + * serialization and can override this check. */ - protected boolean isAttributeDistributable(String name, Object value) { + @Override + public boolean isAttributeDistributable(String name, Object value) { return value instanceof Serializable; } @@ -1723,15 +1727,40 @@ public class StandardSession implements * @param name the attribute's name * @return <code>true</code> if the specified attribute should be * excluded from serialization + * + * @deprecated Use {@link #exclude(String, Object)}. Will be removed in + * Tomcat 9.0.x. */ + @Deprecated protected boolean exclude(String name){ + return exclude(name, null); + } - for (int i = 0; i < excludedAttributes.length; i++) { - if (name.equalsIgnoreCase(excludedAttributes[i])) - return true; - } - return false; + /** + * Should the given session attribute be excluded? This implementation + * checks:</p> + * <ul> + * <li>{@link Constants#excludedAttributeNames}</li> + * <li>{@link Manager#willAttributeDistribute(String, Object)}</li> + * </ul> + * Note: This method deliberately does not check + * {@link #isAttributeDistributable(String, Object)} which is + * deliberately separate to support the checks required in + * {@link #setAttribute(String, Object, boolean)} + * + * @param name The attribute name + * @param value The attribute value + * + * @return {@code true} if the attribute should be excluded from + * distribution, otherwise {@false} + */ + protected boolean exclude(String name, Object value) { + if (Constants.excludedAttributeNames.contains(name)) { + return true; + } + // Last check so use a short-cut + return !getManager().willAttributeDistribute(name, value); } Modified: tomcat/trunk/java/org/apache/catalina/session/StoreBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/StoreBase.java?rev=1724863&r1=1724862&r2=1724863&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/session/StoreBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/session/StoreBase.java Fri Jan 15 17:40:18 2016 @@ -51,7 +51,7 @@ public abstract class StoreBase extends /** * The string manager for this package. */ - protected static final StringManager sm = StringManager.getManager(Constants.Package); + protected static final StringManager sm = StringManager.getManager(StoreBase.class); /** * The Manager with which this Store is associated. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org