[Jboss-cvs] JBossAS SVN: r56603 - in trunk/tomcat: . src/main/org/jboss/web/tomcat/tc5 src/main/org/jboss/web/tomcat/tc5/session src/main/org/jboss/web/tomcat/tc5/sso src/main/org/jboss/web/tomcat/tc6 src/main/org/jboss/web/tomcat/tc6/sso
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Sep 6 09:57:32 EDT 2006
Author: remy.maucherat at jboss.com
Date: 2006-09-06 09:57:20 -0400 (Wed, 06 Sep 2006)
New Revision: 56603
Removed:
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/DeployerConfig.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/JvmRouteFilter.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/StandardService.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/StatusServlet.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/Tomcat5.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/Tomcat5MBean.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/TomcatDeployer.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebAppClassLoader.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebAppLoader.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebCtxLoader.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/AbstractJBossManager.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/AttributeBasedClusteredSession.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/BatchReplicationClusteredSessionValve.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/CacheListener.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSession.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSessionValve.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteringNotSupportedException.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/FieldBasedClusteredSession.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/InstantSnapshotManager.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/IntervalSnapshotManager.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheCluster.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheClusterMBean.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheClusteredSession.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManagerMBean.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheService.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheWrapper.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManager.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManagerMBean.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JvmRouteValve.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalSessionActivity.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalStrings.properties
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalStrings_ja.properties
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionBasedClusteredSession.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionIDGenerator.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SnapshotManager.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/Util.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/ClusteredSingleSignOn.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/SSOClusterManager.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/SingleSignOnEntry.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/TreeCacheSSOClusterManager.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/mbeans-descriptors.xml
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/sso/TreeCacheSSOClusterManager.java~
Modified:
trunk/tomcat/build.xml
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/StandardService.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/StatusServlet.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/Tomcat6.java
Log:
- Switch to the JBoss Web version of the TC 6 binaries.
- Remove the TC 5 code (which uses older APIs).
- Remove usage of modeler (now much lighter weight, package renamed and merged into the main JAR).
Modified: trunk/tomcat/build.xml
===================================================================
--- trunk/tomcat/build.xml 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/build.xml 2006-09-06 13:57:20 UTC (rev 56603)
@@ -58,7 +58,6 @@
<path refid="dom4j.dom4j.classpath"/>
<path refid="oswego.concurrent.classpath"/>
<path refid="jgroups.jgroups.classpath"/>
- <path refid="apache.modeler.classpath"/>
<path refid="jboss.jbossxb.classpath"/>
<path refid="jboss.serialization.classpath"/>
</path>
@@ -120,7 +119,7 @@
<path id="javac.tomcat.classpath">
<pathelement path="${classpath}"/>
<pathelement path="${local.classpath}"/>
- <path refid="apache.tomcat.classpath"/>
+ <path refid="jboss.web.classpath"/>
<path refid="thirdparty.classpath"/>
</path>
@@ -224,15 +223,12 @@
tofile="${build.deploy}/jbossweb-tomcat6.sar/sso-channel.xml" />
-->
<copy todir="${build.deploy}/jbossweb-tomcat6.sar">
- <fileset dir="${apache.tomcat.lib}">
+ <fileset dir="${jboss.web.lib}">
<include name="*.jar"/>
</fileset>
</copy>
<copy todir="${build.deploy}/jbossweb-tomcat6.sar"
- file="${apache.modeler.lib}/commons-modeler.jar" />
-
- <copy todir="${build.deploy}/jbossweb-tomcat6.sar"
file="${sun.jstl.lib}/jstl.jar" />
<mkdir dir="${build.deploy}/jbossweb-tomcat6.sar/jsf-libs"/>
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/DeployerConfig.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/DeployerConfig.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/DeployerConfig.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,366 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5;
-
-import javax.management.ObjectName;
-
-import org.jboss.security.plugins.AuthorizationManagerServiceMBean;
-import org.jboss.security.plugins.JaasSecurityManagerServiceMBean;
-
-/**
- * The tomcat war deployer configuration passed in from the web container.
- *
- * @author Scott.Stark at jboss.org
- * @version $Revision$
- */
-public class DeployerConfig
-{
- /**
- * The tomcat sar class loader
- */
- private ClassLoader serviceClassLoader;
- /**
- * The domain used for the tomcat mbeans
- */
- private String catalinaDomain = "Catalina";
-
- /**
- * The fully qualified name of the class that will be used for session
- * management if <tt>distributable</tt> is set to true.
- */
- private String managerClass = "org.jboss.web.tomcat.tc5.session.JBossManager";
-
- /**
- * JMX Object name of the TreeCache MBean. Used by JBossCacheManager
- */
- private String cacheName = "jboss.cache:service=TreeCache";
-
- /**
- * The web context class to create
- */
- private String contextClassName;
- /**
- * The parent class loader first model flag
- */
- private boolean java2ClassLoadingCompliance = false;
- /**
- * A flag indicating if war archives should be unpacked
- */
- private boolean unpackWars = true;
- /**
- * If true, ejb-links that don't resolve don't cause an error
- * (fallback to jndi-name)
- */
- private boolean lenientEjbLink = false;
- /**
- * The tomcat service JMX object name
- */
- private ObjectName serviceName;
- /**
- * The catalina debug level
- */
- private int debugLevel;
- /**
- * A flag indicating if the JBoss UCL should be used
- */
- private boolean useJBossWebLoader = true;
- /**
- * A flag indicating if the working dir for a war deployment should be
- * delete when the war is undeployed.
- */
- private boolean deleteWorkDirs = true;
- /**
- * Which snapshot mode should be used in clustered environment?
- * Default: instant
- */
- private String snapshotMode = "instant"; // instant or interval
- /**
- * With IntervalSnapshotManager use this interval (in ms) for snapshotting
- */
- private int snapshotInterval = 1000;
-
- /**
- * Should the clustering code use caching or not?
- */
- private boolean useLocalCache;
-
- /**
- * Whether to use MOD_JK(2) for sticky session combined with JvmRoute. If set to true,
- * it will insert a JvmRouteFilter to intercept every request and replace the JvmRoute
- * if it detects a failover.
- */
- private boolean useJK = false;
-
- /**
- * Get the request attribute name under which the JAAS Subject is store
- */
- private String subjectAttributeName = null;
- /**
- * The default security-domain name to use
- */
- private String defaultSecurityDomain;
- /** Package names that should be ignored for class loading */
- private String[] filteredPackages;
-
- /**
- * Flag indicating whether web-app specific context xmls may set the privileged flag.
- */
- private boolean allowSelfPrivilegedWebApps = false;
- /** The service used to flush authentication cache on session invalidation. */
- private JaasSecurityManagerServiceMBean secMgrService;
-
- /** Service used to register policies */
- private AuthorizationManagerServiceMBean authorizationMgrService;
-
- public ClassLoader getServiceClassLoader()
- {
- return serviceClassLoader;
- }
-
- public void setServiceClassLoader(ClassLoader serviceClassLoader)
- {
- this.serviceClassLoader = serviceClassLoader;
- }
-
- public String getManagerClass()
- {
- return managerClass;
- }
-
- public void setManagerClass(String managerClass)
- {
- this.managerClass = managerClass;
- }
-
- public String getCacheName()
- {
- return cacheName;
- }
-
- public void setCacheName(String cacheName)
- {
- this.cacheName = cacheName;
- }
-
- public String getCatalinaDomain()
- {
- return catalinaDomain;
- }
-
- public void setCatalinaDomain(String catalinaDomain)
- {
- this.catalinaDomain = catalinaDomain;
- }
-
- public String getContextClassName()
- {
- return contextClassName;
- }
-
- public void setContextClassName(String contextClassName)
- {
- this.contextClassName = contextClassName;
- }
-
- public boolean isJava2ClassLoadingCompliance()
- {
- return java2ClassLoadingCompliance;
- }
-
- public void setJava2ClassLoadingCompliance(boolean java2ClassLoadingCompliance)
- {
- this.java2ClassLoadingCompliance = java2ClassLoadingCompliance;
- }
-
- public boolean isUnpackWars()
- {
- return unpackWars;
- }
-
- public void setUnpackWars(boolean unpackWars)
- {
- this.unpackWars = unpackWars;
- }
-
- public boolean isLenientEjbLink()
- {
- return lenientEjbLink;
- }
-
- public void setLenientEjbLink(boolean lenientEjbLink)
- {
- this.lenientEjbLink = lenientEjbLink;
- }
-
- public ObjectName getServiceName()
- {
- return serviceName;
- }
-
- public void setServiceName(ObjectName serviceName)
- {
- this.serviceName = serviceName;
- }
-
- public int getDebugLevel()
- {
- return debugLevel;
- }
-
- public void setDebugLevel(int debugLevel)
- {
- this.debugLevel = debugLevel;
- }
-
- public boolean isUseJBossWebLoader()
- {
- return useJBossWebLoader;
- }
-
- public void setUseJBossWebLoader(boolean useJBossWebLoader)
- {
- this.useJBossWebLoader = useJBossWebLoader;
- }
-
- public boolean isDeleteWorkDirs()
- {
- return deleteWorkDirs;
- }
-
- public void setDeleteWorkDirs(boolean deleteWorkDirs)
- {
- this.deleteWorkDirs = deleteWorkDirs;
- }
-
- public String getSnapshotMode()
- {
- return snapshotMode;
- }
-
- public void setSnapshotMode(String snapshotMode)
- {
- this.snapshotMode = snapshotMode;
- }
-
- public int getSnapshotInterval()
- {
- return snapshotInterval;
- }
-
- public void setSnapshotInterval(int snapshotInterval)
- {
- this.snapshotInterval = snapshotInterval;
- }
-
- public boolean isUseLocalCache()
- {
- return useLocalCache;
- }
-
- public void setUseLocalCache(boolean useLocalCache)
- {
- this.useLocalCache = useLocalCache;
- }
-
- public boolean isUseJK()
- {
- return useJK;
- }
-
- public void setUseJK(boolean useJK)
- {
- this.useJK = useJK;
- }
-
- public String getSubjectAttributeName()
- {
- return subjectAttributeName;
- }
-
- public void setSubjectAttributeName(String subjectAttributeName)
- {
- this.subjectAttributeName = subjectAttributeName;
- }
-
- /**
- * Get the default security domain implementation to use if a war
- * does not declare a security-domain.
- *
- * @return jndi name of the security domain binding to use.
- * @jmx:managed-attribute
- */
- public String getDefaultSecurityDomain()
- {
- return defaultSecurityDomain;
- }
-
- /**
- * Set the default security domain implementation to use if a war
- * does not declare a security-domain.
- *
- * @param defaultSecurityDomain - jndi name of the security domain binding
- * to use.
- * @jmx:managed-attribute
- */
- public void setDefaultSecurityDomain(String defaultSecurityDomain)
- {
- this.defaultSecurityDomain = defaultSecurityDomain;
- }
-
- public boolean isAllowSelfPrivilegedWebApps()
- {
- return allowSelfPrivilegedWebApps;
- }
-
- public void setAllowSelfPrivilegedWebApps(boolean allowSelfPrivilegedWebApps)
- {
- this.allowSelfPrivilegedWebApps = allowSelfPrivilegedWebApps;
- }
-
- public AuthorizationManagerServiceMBean getAuthorizationManagerService()
- {
- return authorizationMgrService;
- }
-
- public void setAuthorizationManagerService(AuthorizationManagerServiceMBean authorizationMgrService)
- {
- this.authorizationMgrService = authorizationMgrService;
- }
-
- public JaasSecurityManagerServiceMBean getSecurityManagerService()
- {
- return secMgrService;
- }
- public void setSecurityManagerService(JaasSecurityManagerServiceMBean mgr)
- {
- this.secMgrService = mgr;
- }
-
- public String[] getFilteredPackages()
- {
- return filteredPackages;
- }
- public void setFilteredPackages(String[] filteredPackages)
- {
- this.filteredPackages = filteredPackages;
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/JvmRouteFilter.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/JvmRouteFilter.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/JvmRouteFilter.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,204 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5;
-
-import java.io.IOException;
-import java.util.Enumeration;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import org.apache.catalina.Session;
-import org.jboss.logging.Logger;
-import org.jboss.util.NestedRuntimeException;
-import org.jboss.web.tomcat.tc5.session.AbstractJBossManager;
-
-/**
- * Web request filter to specifically handle Tomcat jvmRoute using mod_jk(2)
- * module. We assume that the session is set by cookie only for now, i.e., no
- * support of that from URL. Furthermore, the session id has a format of
- * id.jvmRoute where jvmRoute is used by JK module to determine sticky session
- * during load balancing.
- *
- * @author Ben Wang
- * @author Marco Antonioni
- * @version $Revision$
- * @deprecated 4.0.3
- */
-public class JvmRouteFilter
- implements Filter
-{
- protected AbstractJBossManager manager_;
- protected static Logger log_ = Logger.getLogger(JvmRouteFilter.class);
-
- public void init(FilterConfig filterConfig) throws ServletException
- {
- if (log_.isDebugEnabled())
- {
- ServletContext sc = filterConfig.getServletContext();
- Enumeration names = sc.getAttributeNames();
- while (names.hasMoreElements())
- {
- String name = (String) names.nextElement();
- Object value = sc.getAttribute(name);
- log_.debug("name=" + name + ", value.className: [" + value.getClass().getName() + "] value.toString: [" + value.toString() + "]");
- }
- }
- manager_ = (AbstractJBossManager) filterConfig.getServletContext().getAttribute("AbstractJBossManager");
- if (manager_ == null)
- {
- throw new RuntimeException("JvmRouteFilter.init(): No AbstractJBossManager found for clustering support.");
- }
-
- if (log_.isDebugEnabled())
- log_.debug("JvmRouteFilter.init(): initializing JvmRouteFilter");
- }
-
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException
- {
- // Check if request and response is valid
- if (!(request instanceof HttpServletRequest && response instanceof HttpServletResponse))
- {
- // Don't know how to handle. There is a mistake.
- throw new RuntimeException("JvmRouteFilter.doFilter(): Not a http request and response type.");
- }
-
- // get session id
- HttpServletRequest req = (HttpServletRequest) request;
- HttpServletResponse res = (HttpServletResponse) response;
- HttpSession session = req.getSession(false);
- if (session != null)
- {
- String sessionId = session.getId();
-
- // Obtain JvmRoute
- String jvmRoute = manager_.getJvmRoute();
- if (log_.isDebugEnabled())
- {
- log_.debug("doFilter(): check if need to re-route based on JvmRoute. Session id: " +
- sessionId + " jvmRoute: " + jvmRoute);
- }
-
- if (jvmRoute == null)
- {
- throw new RuntimeException("JvmRouteFilter.doFilter(): Tomcat JvmRoute is null. " +
- "Need to assign a value in Tomcat server.xml for load balancing.");
- }
-
- // Check if incoming session id has JvmRoute appended. If not, append it.
- // TODO. We handle only get session id by cookie only
- if (req.isRequestedSessionIdFromURL())
- {
- // Warning but do nothing
- log_.error("JvmRouteFilter.doFilter(): Can't handle clustering where session id is from URL. Will skip.");
- }
- else
- {
- handleJvmRoute(sessionId, jvmRoute, res);
- }
- }
- chain.doFilter(request, response);
- }
-
- protected void handleJvmRoute(String sessionId, String jvmRoute, HttpServletResponse response)
- {
- // get requested jvmRoute.
- // TODO. The current format is assumed to be id.jvmRoute. Can be generalized later.
- String requestedJvmRoute = null;
- int ind = sessionId.indexOf(".");
- if (ind > 0)
- {
- requestedJvmRoute = sessionId.substring(sessionId.indexOf(".") + 1, sessionId.length());
- }
-
- String sid = sessionId;
- if (requestedJvmRoute == null)
- {
- // If this filter is turned on, we assume we have an appendix of jvmRoute. So this request is new.
- sid = sessionId + "." + jvmRoute;
- manager_.setNewSessionCookie(sid, response);
- }
- else if (requestedJvmRoute.equals(jvmRoute))
- {
- return; // Nothing more needs to be done.
- }
- else
- {
- // We just have a failover since jvmRoute does not match. We will replace the old one with the new one.
- if (log_.isDebugEnabled())
- {
- log_.debug("handleJvmRoute(): We have detected a failover with differen jvmRoute." +
- " old one: " + requestedJvmRoute + " new one: " + jvmRoute + ". Will reset the session id.");
- }
- int index = sessionId.indexOf(".");
- if (index > 0)
- {
- String base = sessionId.substring(0, sessionId.indexOf("."));
- sid = base + "." + jvmRoute;
- }
- else
- {
- throw new RuntimeException("JvmRouteFilter.handleJvmRoute(): session id doesn't JvmRoute.");
- }
-
- manager_.setNewSessionCookie(sid, response);
- // Change the sessionId with the new one using local jvmRoute
- Session catalinaSession = null;
- try
- {
- catalinaSession = manager_.findSession(sessionId);
- // change session id with the new one using local jvmRoute and update cluster if needed.
- if( catalinaSession != null )
- {
- catalinaSession.setId(sid);
- if (log_.isDebugEnabled())
- {
- log_.debug("handleJvmRoute(): changed catalina session to= [" + sid + "] old one= [" + sessionId + "]");
- }
- }
- }
- catch (IOException e)
- {
- if (log_.isDebugEnabled())
- {
- log_.debug("handleJvmRoute(): manager_.findSession() unable to find session= [" + sessionId + "]", e);
- }
- throw new NestedRuntimeException("JvmRouteFilter.handleJvmRoute(): cannot find session [" + sessionId + "]", e);
- }
- }
- }
-
-
- public void destroy()
- {
- manager_ = null;
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/StandardService.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/StandardService.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/StandardService.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,749 +0,0 @@
-/*
- * Copyright 1999-2002,2004 The Apache Software Foundation.
- *
- * Licensed 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.
- */
-/*
- * JBoss, the OpenSource WebOS
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.web.tomcat.tc5;
-
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import javax.management.MBeanRegistration;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-import org.apache.catalina.Container;
-import org.apache.catalina.Engine;
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.Server;
-import org.apache.catalina.Service;
-import org.apache.catalina.ServerFactory;
-import org.apache.catalina.connector.Connector;
-import org.apache.catalina.core.Constants;
-import org.apache.catalina.core.ContainerBase;
-import org.apache.catalina.util.LifecycleSupport;
-import org.apache.catalina.util.StringManager;
-import org.apache.commons.modeler.Registry;
-import org.jboss.logging.Logger;
-
-
-/**
- * Standard implementation of the <code>Service</code> interface. The
- * associated Container is generally an instance of Engine, but this is
- * not required.
- * <p/>
- * This version does not start the connectors in the start method so that
- * all web apps may be completely deployed before enabling the transport
- * layer.
- *
- * @author Craig R. McClanahan
- * @author Scott.Stark at jboss.org
- * @version $Revision$
- */
-public class StandardService
- implements Lifecycle, Service, MBeanRegistration
-{
- private static Logger log = Logger.getLogger(StandardService.class);
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * The set of Connectors associated with this Service.
- */
- private Connector connectors[] = new Connector[0];
-
-
- /**
- * The Container associated with this Service.
- */
- private Container container = null;
-
-
- /**
- * The debugging detail level for this component.
- */
- private int debug = 0;
-
-
- /**
- * Descriptive information about this component implementation.
- */
- private static final String info =
- "org.jboss.web.tomcat.tc5.StandardService/1.0";
-
-
- /**
- * Has this component been initialized?
- */
- private boolean initialized = false;
-
-
- /**
- * The name of this service.
- */
- private String name = null;
-
-
- /**
- * The lifecycle event support for this component.
- */
- private LifecycleSupport lifecycle = new LifecycleSupport(this);
-
-
- /**
- * The string manager for this package.
- */
- private static final StringManager sm =
- StringManager.getManager(Constants.Package);
-
- /**
- * The <code>Server</code> that owns this Service, if any.
- */
- private Server server = null;
-
- /**
- * Has this component been started?
- */
- private boolean started = false;
-
-
- /**
- * The property change support for this component.
- */
- protected PropertyChangeSupport support = new PropertyChangeSupport(this);
-
-
- // ------------------------------------------------------------- Properties
-
-
- /**
- * Return the <code>Container</code> that handles requests for all
- * <code>Connectors</code> associated with this Service.
- */
- public Container getContainer()
- {
-
- return (this.container);
-
- }
-
-
- /**
- * Set the <code>Container</code> that handles requests for all
- * <code>Connectors</code> associated with this Service.
- *
- * @param container The new Container
- */
- public void setContainer(Container container)
- {
-
- Container oldContainer = this.container;
- if ((oldContainer != null) && (oldContainer instanceof Engine))
- ((Engine) oldContainer).setService(null);
- this.container = container;
- if ((this.container != null) && (this.container instanceof Engine))
- ((Engine) this.container).setService(this);
- if (started && (this.container != null) &&
- (this.container instanceof Lifecycle))
- {
- try
- {
- ((Lifecycle) this.container).start();
- }
- catch (LifecycleException e)
- {
- ;
- }
- }
- synchronized (connectors)
- {
- for (int i = 0; i < connectors.length; i++)
- connectors[i].setContainer(this.container);
- }
- if (started && (oldContainer != null) &&
- (oldContainer instanceof Lifecycle))
- {
- try
- {
- ((Lifecycle) oldContainer).stop();
- }
- catch (LifecycleException e)
- {
- ;
- }
- }
-
- // Report this property change to interested listeners
- support.firePropertyChange("container", oldContainer, this.container);
-
- }
-
- public ObjectName getContainerName()
- {
- if (container instanceof ContainerBase)
- {
- return ((ContainerBase) container).getJmxName();
- }
- return null;
- }
-
-
- /**
- * Return the debugging detail level of this component.
- */
- public int getDebug()
- {
-
- return (this.debug);
-
- }
-
-
- /**
- * Set the debugging detail level of this component.
- *
- * @param debug The new debugging detail level
- */
- public void setDebug(int debug)
- {
-
- this.debug = debug;
-
- }
-
-
- /**
- * Return descriptive information about this Service implementation and
- * the corresponding version number, in the format
- * <code><description>/<version></code>.
- */
- public String getInfo()
- {
-
- return (info);
-
- }
-
-
- /**
- * Return the name of this Service.
- */
- public String getName()
- {
-
- return (this.name);
-
- }
-
-
- /**
- * Set the name of this Service.
- *
- * @param name The new service name
- */
- public void setName(String name)
- {
-
- this.name = name;
-
- }
-
-
- /**
- * Return the <code>Server</code> with which we are associated (if any).
- */
- public Server getServer()
- {
-
- return (this.server);
-
- }
-
-
- /**
- * Set the <code>Server</code> with which we are associated (if any).
- *
- * @param server The server that owns this Service
- */
- public void setServer(Server server)
- {
-
- this.server = server;
-
- }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Add a new Connector to the set of defined Connectors, and associate it
- * with this Service's Container.
- *
- * @param connector The Connector to be added
- */
- public void addConnector(Connector connector)
- {
-
- synchronized (connectors)
- {
- connector.setContainer(this.container);
- connector.setService(this);
- Connector results[] = new Connector[connectors.length + 1];
- System.arraycopy(connectors, 0, results, 0, connectors.length);
- results[connectors.length] = connector;
- connectors = results;
-
- if (initialized)
- {
- try
- {
- connector.initialize();
- }
- catch (LifecycleException e)
- {
- e.printStackTrace(System.err);
- }
- }
-
- if (started && (connector instanceof Lifecycle))
- {
- try
- {
- ((Lifecycle) connector).start();
- }
- catch (LifecycleException e)
- {
- ;
- }
- }
-
- // Report this property change to interested listeners
- support.firePropertyChange("connector", null, connector);
- }
-
- }
-
- public ObjectName[] getConnectorNames()
- {
- ObjectName results[] = new ObjectName[connectors.length];
- for (int i = 0; i < results.length; i++)
- {
- // if it's a coyote connector
- //if( connectors[i] instanceof CoyoteConnector ) {
- // results[i]=((CoyoteConnector)connectors[i]).getJmxName();
- //}
- }
- return results;
- }
-
-
- /**
- * Add a property change listener to this component.
- *
- * @param listener The listener to add
- */
- public void addPropertyChangeListener(PropertyChangeListener listener)
- {
-
- support.addPropertyChangeListener(listener);
-
- }
-
-
- /**
- * Find and return the set of Connectors associated with this Service.
- */
- public Connector[] findConnectors()
- {
-
- return (connectors);
-
- }
-
-
- /**
- * Remove the specified Connector from the set associated from this
- * Service. The removed Connector will also be disassociated from our
- * Container.
- *
- * @param connector The Connector to be removed
- */
- public void removeConnector(Connector connector)
- {
-
- synchronized (connectors)
- {
- int j = -1;
- for (int i = 0; i < connectors.length; i++)
- {
- if (connector == connectors[i])
- {
- j = i;
- break;
- }
- }
- if (j < 0)
- return;
- if (started && (connectors[j] instanceof Lifecycle))
- {
- try
- {
- ((Lifecycle) connectors[j]).stop();
- }
- catch (LifecycleException e)
- {
- ;
- }
- }
- connectors[j].setContainer(null);
- connector.setService(null);
- int k = 0;
- Connector results[] = new Connector[connectors.length - 1];
- for (int i = 0; i < connectors.length; i++)
- {
- if (i != j)
- results[k++] = connectors[i];
- }
- connectors = results;
-
- // Report this property change to interested listeners
- support.firePropertyChange("connector", connector, null);
- }
-
- }
-
-
- /**
- * Remove a property change listener from this component.
- *
- * @param listener The listener to remove
- */
- public void removePropertyChangeListener(PropertyChangeListener listener)
- {
-
- support.removePropertyChangeListener(listener);
-
- }
-
-
- /**
- * Return a String representation of this component.
- */
- public String toString()
- {
-
- StringBuffer sb = new StringBuffer("StandardService[");
- sb.append(getName());
- sb.append("]");
- return (sb.toString());
-
- }
-
-
- // ------------------------------------------------------ Lifecycle Methods
-
-
- /**
- * Add a LifecycleEvent listener to this component.
- *
- * @param listener The listener to add
- */
- public void addLifecycleListener(LifecycleListener listener)
- {
-
- lifecycle.addLifecycleListener(listener);
-
- }
-
-
- /**
- * Get the lifecycle listeners associated with this lifecycle. If this
- * Lifecycle has no listeners registered, a zero-length array is returned.
- */
- public LifecycleListener[] findLifecycleListeners()
- {
-
- return lifecycle.findLifecycleListeners();
-
- }
-
-
- /**
- * Remove a LifecycleEvent listener from this component.
- *
- * @param listener The listener to remove
- */
- public void removeLifecycleListener(LifecycleListener listener)
- {
-
- lifecycle.removeLifecycleListener(listener);
-
- }
-
-
- /**
- * Prepare for the beginning of active use of the public methods of this
- * component. This method should be called before any of the public
- * methods of this component are utilized. It should also send a
- * LifecycleEvent of type START_EVENT to any registered listeners.
- *
- * @throws LifecycleException if this component detects a fatal error
- * that prevents this component from being used
- */
- public void start() throws LifecycleException
- {
-
- // Validate and update our current component state
- if (started)
- {
- log.info(sm.getString("standardService.start.started"));
- }
-
- if (!initialized)
- init();
-
- // Notify our interested LifecycleListeners
- lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
-
- log.info(sm.getString("standardService.start.name", this.name));
- lifecycle.fireLifecycleEvent(START_EVENT, null);
- started = true;
-
- // Start our defined Container first
- if (container != null)
- {
- synchronized (container)
- {
- if (container instanceof Lifecycle)
- {
- ((Lifecycle) container).start();
- }
- }
- }
-
- /* Start our defined Connectors second
- synchronized (connectors) {
- for (int i = 0; i < connectors.length; i++) {
- if (connectors[i] instanceof Lifecycle)
- ((Lifecycle) connectors[i]).start();
- }
- }
-*/
- // Notify our interested LifecycleListeners
- lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
-
- }
-
-
- /**
- * Gracefully terminate the active use of the public methods of this
- * component. This method should be the last one called on a given
- * instance of this component. It should also send a LifecycleEvent
- * of type STOP_EVENT to any registered listeners.
- *
- * @throws LifecycleException if this component detects a fatal error
- * that needs to be reported
- */
- public void stop() throws LifecycleException
- {
-
- // Validate and update our current component state
- if (!started)
- {
- return;
- }
-
- // Notify our interested LifecycleListeners
- lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
-
- // Stop our defined Connectors first
- synchronized (connectors)
- {
- for (int i = 0; i < connectors.length; i++)
- {
- connectors[i].pause();
- }
- }
-
- // Heuristic: Sleep for a while to ensure pause of the connector
- try
- {
- Thread.sleep(1000);
- }
- catch (InterruptedException e)
- {
- // Ignore
- }
-
- lifecycle.fireLifecycleEvent(STOP_EVENT, null);
-
- log.info
- (sm.getString("standardService.stop.name", this.name));
- started = false;
-
- // Stop our defined Container second
- if (container != null)
- {
- synchronized (container)
- {
- if (container instanceof Lifecycle)
- {
- ((Lifecycle) container).stop();
- }
- }
- }
-
- // Stop our defined Connectors first
- synchronized (connectors)
- {
- for (int i = 0; i < connectors.length; i++)
- {
- if (connectors[i] instanceof Lifecycle)
- ((Lifecycle) connectors[i]).stop();
- }
- }
-
- if (oname == controller)
- {
- // we registered ourself on init().
- // That should be the typical case - this object is just for
- // backward compat, nobody should bother to load it explicitely
- Registry.getRegistry(null, null).unregisterComponent(oname);
- }
-
-
- // Notify our interested LifecycleListeners
- lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
-
- }
-
-
- /**
- * Invoke a pre-startup initialization. This is used to allow connectors
- * to bind to restricted ports under Unix operating environments.
- */
- public void initialize()
- throws LifecycleException
- {
- // Service shouldn't be used with embeded, so it doesn't matter
- if (initialized)
- {
- log.info(sm.getString("standardService.initialize.initialized"));
- return;
- }
- initialized = true;
-
- if (oname == null)
- {
- try
- {
- // Hack - Server should be deprecated...
- Container engine = this.getContainer();
- domain = engine.getName();
- oname = new ObjectName(domain + ":type=Service,serviceName=" + name);
- this.controller = oname;
- Registry.getRegistry(null, null)
- .registerComponent(this, oname, null);
- }
- catch (Exception e)
- {
- log.error("Error registering ", e);
- }
-
-
- }
- if (server == null)
- {
- // Register with the server
- // HACK: ServerFactory should be removed...
-
- ServerFactory.getServer().addService(this);
- }
-
-
- // Initialize our defined Connectors
- synchronized (connectors)
- {
- for (int i = 0; i < connectors.length; i++)
- {
- connectors[i].initialize();
- }
- }
- }
-
- public void destroy() throws LifecycleException
- {
- if (started) stop();
- // unregister should be here probably
- }
-
- public void init()
- {
- try
- {
- initialize();
- }
- catch (Throwable t)
- {
- t.printStackTrace();
- }
- }
-
- protected String type;
- protected String domain;
- protected String suffix;
- protected ObjectName oname;
- protected ObjectName controller;
- protected MBeanServer mserver;
-
- public ObjectName getObjectName()
- {
- return oname;
- }
-
- public String getDomain()
- {
- return domain;
- }
-
- public ObjectName preRegister(MBeanServer server,
- ObjectName name) throws Exception
- {
- oname = name;
- mserver = server;
- domain = name.getDomain();
- return name;
- }
-
- public void postRegister(Boolean registrationDone)
- {
- }
-
- public void preDeregister() throws Exception
- {
- }
-
- public void postDeregister()
- {
- }
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/StatusServlet.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/StatusServlet.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/StatusServlet.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,388 +0,0 @@
-/*
- * Copyright 1999-2001,2004 The Apache Software Foundation.
- *
- * Licensed 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.jboss.web.tomcat.tc5;
-
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.Vector;
-
-import javax.management.MBeanServer;
-import javax.management.MBeanServerNotification;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.modeler.Registry;
-
-import org.apache.catalina.util.ServerInfo;
-import org.apache.catalina.util.StringManager;
-import org.apache.catalina.manager.Constants;
-import org.apache.catalina.manager.StatusTransformer;
-
-/**
- * This servlet will display a complete status of the HTTP/1.1 connector.
- *
- * @author Remy Maucherat
- * @version $Revision$ $Date$
- */
-
-public class StatusServlet
- extends HttpServlet implements NotificationListener
-{
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * The debugging detail level for this servlet.
- */
- private int debug = 0;
-
-
- /**
- * MBean server.
- */
- protected MBeanServer mBeanServer = null;
-
-
- /**
- * Vector of protocol handlers object names.
- */
- protected Vector protocolHandlers = new Vector();
-
-
- /**
- * Vector of thread pools object names.
- */
- protected Vector threadPools = new Vector();
-
-
- /**
- * Vector of request processors object names.
- */
- protected Vector requestProcessors = new Vector();
-
-
- /**
- * Vector of global request processors object names.
- */
- protected Vector globalRequestProcessors = new Vector();
-
-
- /**
- * The string manager for this package.
- */
- protected static StringManager sm =
- StringManager.getManager(Constants.Package);
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * Initialize this servlet.
- */
- public void init() throws ServletException
- {
-
- // Retrieve the MBean server
- mBeanServer = Registry.getServer();
-
- // Set our properties from the initialization parameters
- String value = null;
- try
- {
- value = getServletConfig().getInitParameter("debug");
- debug = Integer.parseInt(value);
- }
- catch (Throwable t)
- {
- ;
- }
-
- try
- {
-
- // Query protocol handlers
- String onStr = "*:type=ProtocolHandler,*";
- ObjectName objectName = new ObjectName(onStr);
- Set set = mBeanServer.queryMBeans(objectName, null);
- Iterator iterator = set.iterator();
- while (iterator.hasNext())
- {
- ObjectInstance oi = (ObjectInstance) iterator.next();
- protocolHandlers.addElement(oi.getObjectName());
- }
-
- // Query Thread Pools
- onStr = "*:type=ThreadPool,*";
- objectName = new ObjectName(onStr);
- set = mBeanServer.queryMBeans(objectName, null);
- iterator = set.iterator();
- while (iterator.hasNext())
- {
- ObjectInstance oi = (ObjectInstance) iterator.next();
- threadPools.addElement(oi.getObjectName());
- }
-
- // Query Global Request Processors
- onStr = "*:type=GlobalRequestProcessor,*";
- objectName = new ObjectName(onStr);
- set = mBeanServer.queryMBeans(objectName, null);
- iterator = set.iterator();
- while (iterator.hasNext())
- {
- ObjectInstance oi = (ObjectInstance) iterator.next();
- globalRequestProcessors.addElement(oi.getObjectName());
- }
-
- // Query Request Processors
- onStr = "*:type=RequestProcessor,*";
- objectName = new ObjectName(onStr);
- set = mBeanServer.queryMBeans(objectName, null);
- iterator = set.iterator();
- while (iterator.hasNext())
- {
- ObjectInstance oi = (ObjectInstance) iterator.next();
- requestProcessors.addElement(oi.getObjectName());
- }
-
- // Register with MBean server
- onStr = "JMImplementation:type=MBeanServerDelegate";
- objectName = new ObjectName(onStr);
- mBeanServer.addNotificationListener(objectName, this, null, null);
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
- }
-
-
- /**
- * Finalize this servlet.
- */
- public void destroy()
- {
-
- ; // No actions necessary
-
- }
-
-
- /**
- * Process a GET request for the specified resource.
- *
- * @param request The servlet request we are processing
- * @param response The servlet response we are creating
- * @throws IOException if an input/output error occurs
- * @throws ServletException if a servlet-specified error occurs
- */
- public void doGet(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
-
- // mode is flag for HTML or XML output
- int mode = 0;
- // if ?XML=true, set the mode to XML
- if ("true".equals(request.getParameter("XML")))
- {
- mode = 1;
- }
- StatusTransformer.setContentType(response, mode);
-
- PrintWriter writer = response.getWriter();
-
- boolean completeStatus = false;
- if ("true".equals(request.getParameter("full")))
- {
- completeStatus = true;
- }
-
- // use StatusTransformer to output status
- if (mode == 0)
- {
- // HTML Header Section
- writer.print(HTML_HEADER);
- }
- else if (mode == 1)
- {
- writer.write(Constants.XML_DECLARATION);
- writer.write
- (Constants.XML_STYLE);
- writer.write("<status>");
- }
-
- try
- {
-
- // Display virtual machine statistics
- StatusTransformer.writeVMState(writer, mode);
-
- Enumeration enumeration = threadPools.elements();
- while (enumeration.hasMoreElements())
- {
- ObjectName objectName = (ObjectName) enumeration.nextElement();
- String name = objectName.getKeyProperty("name");
- // use StatusTransformer to output status
- StatusTransformer.writeConnectorState
- (writer, objectName,
- name, mBeanServer, globalRequestProcessors,
- requestProcessors, mode);
- }
-
- if (completeStatus)
- {
- // Note: Retrieving the full status is much slower
- // use StatusTransformer to output status
- StatusTransformer.writeDetailedState
- (writer, mBeanServer, mode);
- }
-
- }
- catch (Exception e)
- {
- throw new ServletException(e);
- }
-
- if (mode == 0)
- {
- writer.print(HTML_FOOTER);
- }
- else if (mode == 1)
- {
- writer.write("</status>");
- }
-
- }
-
- // ------------------------------------------- NotificationListener Methods
-
-
- public void handleNotification(Notification notification,
- java.lang.Object handback)
- {
-
- if (notification instanceof MBeanServerNotification)
- {
- ObjectName objectName =
- ((MBeanServerNotification) notification).getMBeanName();
- if (notification.getType().equals
- (MBeanServerNotification.REGISTRATION_NOTIFICATION))
- {
- String type = objectName.getKeyProperty("type");
- if (type != null)
- {
- if (type.equals("ProtocolHandler"))
- {
- protocolHandlers.addElement(objectName);
- }
- else if (type.equals("ThreadPool"))
- {
- threadPools.addElement(objectName);
- }
- else if (type.equals("GlobalRequestProcessor"))
- {
- globalRequestProcessors.addElement(objectName);
- }
- else if (type.equals("RequestProcessor"))
- {
- requestProcessors.addElement(objectName);
- }
- }
- }
- else if (notification.getType().equals
- (MBeanServerNotification.UNREGISTRATION_NOTIFICATION))
- {
- String type = objectName.getKeyProperty("type");
- if (type != null)
- {
- if (type.equals("ProtocolHandler"))
- {
- protocolHandlers.removeElement(objectName);
- }
- else if (type.equals("ThreadPool"))
- {
- threadPools.removeElement(objectName);
- }
- else if (type.equals("GlobalRequestProcessor"))
- {
- globalRequestProcessors.removeElement(objectName);
- }
- else if (type.equals("RequestProcessor"))
- {
- requestProcessors.removeElement(objectName);
- }
- }
- String j2eeType = objectName.getKeyProperty("j2eeType");
- if (j2eeType != null)
- {
-
- }
- }
- }
-
- }
-
-
- // ------------------------------------------------------- Private Constats
-
-
- private static final String HTML_HEADER =
- "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"
- + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
- + "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
- + "<head>"
- + "<title>Tomcat Status</title>"
- + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />"
- + "<link rel=\"StyleSheet\" href=\"jboss.css\" type=\"text/css\"/>"
- + "</head>"
- + "<body>"
- + "<!-- header begin -->"
- + "<a href=\"http://www.jboss.org\">"
- + "<img src=\"logo.gif\" alt=\"JBoss\" id=\"logo\" width=\"226\" height=\"105\" />"
- + "</a>"
- + "<div id=\"header\"> </div>"
- + "<div id=\"navigation_bar\">"
- + "</div>"
- + "<!-- header end -->";
-
- private static final String HTML_FOOTER =
- "<!-- footer begin -->"
- + "<div id=\"footer\">"
- + "<div id=\"credits\">JBoss™ Application Server</div>"
- + "<div id=\"footer_bar\"> </div>"
- + "</div>"
- + "<!-- footer end -->"
- + "</body>"
- + "</html>";
-
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/Tomcat5.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/Tomcat5.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/Tomcat5.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,623 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5;
-
-import java.io.File;
-import java.util.Iterator;
-import java.util.Properties;
-
-import javax.management.Attribute;
-import javax.management.MBeanServer;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.security.jacc.PolicyContext;
-
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.connector.Connector;
-import org.apache.commons.modeler.Registry;
-import org.jboss.deployment.DeploymentInfo;
-import org.jboss.deployment.SubDeployerExt;
-import org.jboss.mx.util.MBeanProxyExt;
-import org.jboss.security.plugins.AuthorizationManagerServiceMBean;
-import org.jboss.security.plugins.JaasSecurityManagerServiceMBean;
-import org.jboss.system.ServiceControllerMBean;
-import org.jboss.system.server.Server;
-import org.jboss.system.server.ServerImplMBean;
-import org.jboss.web.AbstractWebContainer;
-import org.jboss.web.AbstractWebDeployer;
-import org.jboss.web.tomcat.security.HttpServletRequestPolicyContextHandler;
-import org.jboss.web.tomcat.tc5.session.SessionIDGenerator;
-
-
-/**
- * An implementation of the AbstractWebContainer for the Jakarta Tomcat5
- * servlet container. It has no code dependency on tomcat - only the new JMX
- * model is used.
- * <p/>
- * Tomcat5 is organized as a set of mbeans - just like jboss.
- *
- * @author Scott.Stark at jboss.org
- * @author Costin Manolache
- * @author Wonne.Keysers at realsoftware.be
- * @author Dimitris.Andreadis at jboss.org
- * @version $Revision$
- * @see org.jboss.web.AbstractWebContainer
- */
-public class Tomcat5 extends AbstractWebContainer
- implements Tomcat5MBean, NotificationListener
-{
- // Constants -----------------------------------------------------
- public static final String NAME = "Tomcat5";
-
- /**
- * Default value for property <code>cacheName</code>. This name will be used by JBossCache exclusively
- * for Tomcat clustering, e.g., session and sso replication.
- */
- public static final String DEFAULT_CACHE_NAME =
- "jboss.cache:service=TomcatClusteringCache";
-
- // XXX We could make this configurable - so it can support other containers
- // that provide JMX-based deployment.
- private String contextClassName =
- "org.apache.catalina.core.StandardContext";
-
- /**
- * Configurable map of tomcat authenticators
- * Keyed in by the http auth method that gets
- * plugged into the Context Config and then into the StandardContext
- */
- private Properties authenticators = null;
-
- /**
- * Domain for tomcat5 mbeans
- */
- private String catalinaDomain = "Catalina";
-
- /**
- * ObjectName of a shared TreeCache used for clustered session replication
- * and clustered single-sign-on
- */
- private String cacheName = DEFAULT_CACHE_NAME;
-
- /**
- * The fully qualified name of the class that will be used for session
- * management if <tt>distributable</tt> is set to true.
- */
- protected String managerClass = "org.jboss.web.tomcat.tc5.session.JBossCacheManager";
-
- /**
- * With IntervalSnapshotManager use this interval (in ms)
- * for snapshotting
- */
- private int snapshotInterval = 1000;
-
- /**
- * Which snapshot mode should be used in clustered environment?
- * Default: instant
- */
- private String snapshotMode = "instant"; // instant or interval
-
- /**
- * Should the clustering code use a local cache for the sessions?
- */
- private boolean useLocalCache = true;
-
- /**
- * Whether we are using Apache MOD_JK(2) module or not
- */
- private boolean useJK = false;
-
- /**
- * A flag indicating if the JBoss Loader should be used
- */
- private boolean useJBossWebLoader = true;
-
- /**
- * The server xml configuration file name
- */
- private String serverConfigFile = "server.xml";
-
- /**
- * Get the request attribute name under which the JAAS Subject is store
- */
- private String subjectAttributeName = null;
-
- /**
- * Flag indicating whether web-app specific context xmls may set the privileged flag.
- */
- private boolean allowSelfPrivilegedWebApps = false;
-
- /** The service used to flush authentication cache on session invalidation. */
- private JaasSecurityManagerServiceMBean secMgrService;
-
- /** Authorization Manager Service that is used to register xacml policies */
- private AuthorizationManagerServiceMBean authorizationMgrService;
-
- /** */
- private String[] filteredPackages;
-
- /** Hold a proxy reference to myself, used when registering to MainDeployer */
- private SubDeployerExt thisProxy;
-
- public Tomcat5()
- {
- }
-
- public String getName()
- {
- return NAME;
- }
-
-
- public String getManagerClass()
- {
- return managerClass;
- }
-
- public void setManagerClass(String managerClass)
- {
- this.managerClass = managerClass;
- }
-
-
- public String getDomain()
- {
- return this.catalinaDomain;
- }
-
- public Properties getAuthenticators()
- {
- return this.authenticators;
- }
-
- public void setAuthenticators(Properties prop)
- {
- this.authenticators = prop;
- log.debug("Passed set of authenticators=" + prop);
- }
-
- /**
- * The most important atteribute - defines the managed domain.
- * A catalina instance (engine) corresponds to a JMX domain, that's
- * how we know where to deploy webapps.
- *
- * @param catalinaDomain the domain portion of the JMX ObjectNames
- */
- public void setDomain(String catalinaDomain)
- {
- this.catalinaDomain = catalinaDomain;
- }
-
- public void setContextMBeanCode(String className)
- {
- this.contextClassName = className;
- }
-
- public String getContextMBeanCode()
- {
- return contextClassName;
- }
-
- /**
- * Set the snapshot interval in milliseconds for snapshot mode = interval
- */
- public void setSnapshotInterval(int interval)
- {
- this.snapshotInterval = interval;
- }
-
- /**
- * Get the snapshot interval
- */
- public int getSnapshotInterval()
- {
- return this.snapshotInterval;
- }
-
- /**
- * Set the snapshot mode. Currently supported: instant or interval
- */
- public void setSnapshotMode(String mode)
- {
- this.snapshotMode = mode;
- }
-
- /**
- * Get the snapshot mode
- */
- public String getSnapshotMode()
- {
- return this.snapshotMode;
- }
-
- /**
- * Gets the JMX object name of a shared TreeCache to be used for clustered
- * single-sign-on.
- *
- * @see #DEFAULT_CACHE_NAME
- * @see org.jboss.web.tomcat.tc5.sso.TreeCacheSSOClusterManager
- */
- public String getCacheName()
- {
- return cacheName;
- }
-
- /**
- * Gets the JMX object name of a shared TreeCache to be used for clustered
- * single-sign-on.
- * <p/>
- * <b>NOTE:</b> TreeCache must be deployed before this service.
- *
- * @see #DEFAULT_CACHE_NAME
- * @see org.jboss.web.tomcat.tc5.sso.TreeCacheSSOClusterManager
- */
- public void setCacheName(String cacheName)
- {
- this.cacheName = cacheName;
- }
-
- public boolean isUseLocalCache()
- {
- return useLocalCache;
- }
-
- public void setUseLocalCache(boolean useLocalCache)
- {
- this.useLocalCache = useLocalCache;
- }
-
- public boolean isUseJK()
- {
- return useJK;
- }
-
- public void setUseJK(boolean useJK)
- {
- this.useJK = useJK;
- }
-
- /**
- * The SessionIdAlphabet is the set of characters used to create a session Id
- */
- public void setSessionIdAlphabet(String sessionIdAlphabet)
- {
- SessionIDGenerator.getInstance().setSessionIdAlphabet(sessionIdAlphabet);
- }
-
- /**
- * The SessionIdAlphabet is the set of characters used to create a session Id
- */
- public String getSessionIdAlphabet()
- {
- return SessionIDGenerator.getInstance().getSessionIdAlphabet();
- }
-
- public boolean getUseJBossWebLoader()
- {
- return useJBossWebLoader;
- }
-
- public void setUseJBossWebLoader(boolean flag)
- {
- this.useJBossWebLoader = flag;
- }
-
- public String getConfigFile()
- {
- return serverConfigFile;
- }
-
- public void setConfigFile(String configFile)
- {
- this.serverConfigFile = configFile;
- }
-
- public String getSubjectAttributeName()
- {
- return this.subjectAttributeName;
- }
-
- public void setSubjectAttributeName(String name)
- {
- this.subjectAttributeName = name;
- }
-
- public boolean isAllowSelfPrivilegedWebApps()
- {
- return allowSelfPrivilegedWebApps;
- }
-
- public void setAllowSelfPrivilegedWebApps(boolean allowSelfPrivilegedWebApps)
- {
- this.allowSelfPrivilegedWebApps = allowSelfPrivilegedWebApps;
- }
-
- public void setAuthorizationManagerService(AuthorizationManagerServiceMBean mgr)
- {
- this.authorizationMgrService = mgr;
- }
-
- public void setSecurityManagerService(JaasSecurityManagerServiceMBean mgr)
- {
- this.secMgrService = mgr;
- }
-
- public String[] getFilteredPackages()
- {
- return filteredPackages;
- }
- public void setFilteredPackages(String[] pkgs)
- {
- this.filteredPackages = pkgs;
- }
-
- public void startService()
- throws Exception
- {
-
- System.setProperty("catalina.ext.dirs",
- (System.getProperty("jboss.server.home.dir")
- + File.separator + "lib"));
-
- String objectNameS = catalinaDomain + ":type=server";
- ObjectName objectName = new ObjectName(objectNameS);
-
- // Set the modeler Registry MBeanServer to the that of the tomcat service
- Registry.getRegistry().setMBeanServer(server);
-
- server.createMBean("org.apache.commons.modeler.BaseModelMBean",
- objectName,
- new Object[]{"org.apache.catalina.startup.Catalina"},
- new String[]{"java.lang.String"});
-
- server.setAttribute(objectName, new Attribute
- ("catalinaHome",
- System.getProperty("jboss.server.home.dir")));
- server.setAttribute(objectName, new Attribute
- ("configFile", serverConfigFile));
- server.setAttribute(objectName, new Attribute
- ("useNaming", new Boolean(false)));
- server.setAttribute(objectName, new Attribute
- ("useShutdownHook", new Boolean(false)));
- server.setAttribute(objectName, new Attribute
- ("await", new Boolean(false)));
- server.setAttribute(objectName, new Attribute
- ("redirectStreams", new Boolean(false)));
-
- server.invoke(objectName, "create", new Object[]{},
- new String[]{});
-
- server.invoke(objectName, "start", new Object[]{},
- new String[]{});
-
- // Configure any SingleSignOn valves
-
- ObjectName ssoQuery = new ObjectName(catalinaDomain + ":type=Valve,*");
- Iterator iterator = server.queryMBeans(ssoQuery, null).iterator();
- while (iterator.hasNext())
- {
- ObjectName ssoObjectName =
- ((ObjectInstance) iterator.next()).getObjectName();
- String name = ssoObjectName.getKeyProperty("name");
-
- /* Ensure that the SingleSignOn valve requires that each
- request be reauthenticated to the security mgr. Should not
- be neccessary now that we cache the principal in the session.
- if ((name != null) && (name.indexOf("SingleSignOn") >= 0))
- {
- log.info("Turning on reauthentication of each request on " +
- ssoObjectName);
- server.setAttribute(ssoObjectName, new Attribute
- ("requireReauthentication", Boolean.TRUE));
- }
- */
-
- // If the valve is a ClusteredSingleSignOn and we have a shared
- // TreeCache configured, configure the valve to use the shared one
- if (cacheName != null && "ClusteredSingleSignOn".equals(name))
- {
- String tcName = (String) server.getAttribute(ssoObjectName,
- "treeCacheName");
- tcName = (tcName != null ? tcName : DEFAULT_CACHE_NAME);
- ObjectName ssoCacheName = new ObjectName(tcName);
- // Only override if the valve's cacheName property was not
- // explicitly set in server.xml to a non-default value
- if (ssoCacheName.equals(new ObjectName(DEFAULT_CACHE_NAME)))
- {
- log.info("Setting the cache name to " + cacheName +
- " on " + ssoObjectName);
- server.setAttribute(ssoObjectName,
- new Attribute("treeCacheName", cacheName));
- }
- }
- }
-
- // Register the web container JACC PolicyContextHandlers
- HttpServletRequestPolicyContextHandler handler = new HttpServletRequestPolicyContextHandler();
- PolicyContext.registerHandler(HttpServletRequestPolicyContextHandler.WEB_REQUEST_KEY,
- handler, false);
-
- // The ServiceController used to control web app startup dependencies
- serviceController = (ServiceControllerMBean)
- MBeanProxyExt.create(ServiceControllerMBean.class, ServiceControllerMBean.OBJECT_NAME, server);
-
- // make a proxy to myself, so that calls from the MainDeployer
- // can go through the MBeanServer, so interceptors can be added
- thisProxy = (SubDeployerExt)
- MBeanProxyExt.create(SubDeployerExt.class, super.getServiceName(), super.getServer());
-
- // Register with the main deployer
- mainDeployer.addDeployer(thisProxy);
-
- // If we are hot-deployed *after* the overall server is started
- // we'll never receive Server.START_NOTIFICATION_TYPE, so check
- // with the Server and start the connectors immediately, if this is the case.
- // Otherwise register to receive the server start-up notification.
- Boolean started = (Boolean)server.getAttribute(ServerImplMBean.OBJECT_NAME, "Started");
- if (started.booleanValue() == true)
- {
- log.debug("Server '" + ServerImplMBean.OBJECT_NAME +
- "' already started, starting connectors now");
-
- startConnectors();
- }
- else
- {
- // Register for notification of the overall server startup
- log.debug("Server '" + ServerImplMBean.OBJECT_NAME +
- "' not started, registering for start-up notification");
-
- server.addNotificationListener(ServerImplMBean.OBJECT_NAME, this, null, null);
- }
- }
-
-
- public void stopService()
- throws Exception
- {
-
- String objectNameS = catalinaDomain + ":type=server";
- ObjectName objectName = new ObjectName(objectNameS);
-
- server.invoke(objectName, "stop", new Object[]{},
- new String[]{});
-
- server.invoke(objectName, "destroy", new Object[]{},
- new String[]{});
-
- server.unregisterMBean(objectName);
-
- MBeanServer server2 = server;
-
- // deregister with MainDeployer
- mainDeployer.removeDeployer(thisProxy);
-
- // Unregister any remaining jboss.web or Catalina MBeans
- ObjectName queryObjectName = new ObjectName
- (catalinaDomain + ":*");
- Iterator iterator =
- server2.queryMBeans(queryObjectName, null).iterator();
- while (iterator.hasNext())
- {
- ObjectInstance oi = (ObjectInstance) iterator.next();
- ObjectName toRemove = oi.getObjectName();
- // Exception: Don't unregister the service right now
- if (!"WebServer".equals(toRemove.getKeyProperty("service")))
- {
- if (server2.isRegistered(toRemove))
- {
- server2.unregisterMBean(toRemove);
- }
- }
- }
- queryObjectName = new ObjectName("Catalina:*");
- iterator = server2.queryMBeans(queryObjectName, null).iterator();
- while (iterator.hasNext())
- {
- ObjectInstance oi = (ObjectInstance) iterator.next();
- ObjectName name = oi.getObjectName();
- server2.unregisterMBean(name);
- }
-
- }
-
- public void startConnectors() throws Exception
- {
- ObjectName service = new ObjectName(catalinaDomain + ":type=Service,serviceName=jboss.web");
- Object[] args = {};
- String[] sig = {};
- Connector[] connectors = (Connector[]) server.invoke(service,
- "findConnectors", args, sig);
- for (int n = 0; n < connectors.length; n++)
- {
- Lifecycle lc = (Lifecycle) connectors[n];
- lc.start();
- }
- // Notify listeners that connectors have started processing requests
- sendNotification(new Notification(TOMCAT_CONNECTORS_STARTED,
- this, getNextNotificationSequenceNumber()));
- }
-
- public void stopConnectors() throws Exception
- {
- ObjectName service = new ObjectName(catalinaDomain + ":type=Service,serviceName=jboss.web");
- Object[] args = {};
- String[] sig = {};
- Connector[] connectors = (Connector[]) server.invoke(service,
- "findConnectors", args, sig);
- for (int n = 0; n < connectors.length; n++)
- {
- Lifecycle lc = (Lifecycle) connectors[n];
- lc.stop();
- }
- }
-
- public void handleNotification(Notification msg, Object handback)
- {
- String type = msg.getType();
- if (type.equals(Server.START_NOTIFICATION_TYPE))
- {
- log.debug("Saw " + type + " notification, starting connectors");
- try
- {
- startConnectors();
- }
- catch (Exception e)
- {
- log.warn("Failed to startConnectors", e);
- }
- }
- }
-
- public AbstractWebDeployer getDeployer(DeploymentInfo di) throws Exception
- {
- ClassLoader loader = di.ucl;
- Class deployerClass = loader.loadClass("org.jboss.web.tomcat.tc5.TomcatDeployer");
- AbstractWebDeployer deployer = (AbstractWebDeployer) deployerClass.newInstance();
- DeployerConfig config = new DeployerConfig();
- config.setDefaultSecurityDomain(this.defaultSecurityDomain);
- config.setSubjectAttributeName(this.subjectAttributeName);
- config.setServiceClassLoader(getClass().getClassLoader());
- config.setManagerClass(this.managerClass);
- config.setJava2ClassLoadingCompliance(this.java2ClassLoadingCompliance);
- config.setUnpackWars(this.unpackWars);
- config.setLenientEjbLink(this.lenientEjbLink);
- config.setCatalinaDomain(catalinaDomain);
- config.setContextClassName(contextClassName);
- config.setServiceName(serviceName);
- config.setSnapshotInterval(this.snapshotInterval);
- config.setSnapshotMode(this.snapshotMode);
- config.setUseLocalCache(this.useLocalCache);
- config.setUseJK(this.useJK);
- config.setSubjectAttributeName(this.subjectAttributeName);
- config.setUseJBossWebLoader(this.useJBossWebLoader);
- config.setAllowSelfPrivilegedWebApps(this.allowSelfPrivilegedWebApps);
- config.setAuthorizationManagerService(this.authorizationMgrService);
- config.setSecurityManagerService(this.secMgrService);
- config.setFilteredPackages(filteredPackages);
- deployer.setServer(server);
- deployer.init(config);
- return deployer;
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/Tomcat5MBean.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/Tomcat5MBean.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/Tomcat5MBean.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,216 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5;
-
-import org.jboss.web.AbstractWebContainerMBean;
-import org.jboss.security.plugins.JaasSecurityManagerServiceMBean;
-
-/**
- * An implementation of the AbstractWebContainer for the Jakarta Tomcat5
- * servlet container. It has no code dependency on tomcat - only the new JMX
- * model is used.
- * <p/>
- * Tomcat5 is organized as a set of mbeans - just like jboss.
- *
- * @author Scott.Stark at jboss.org
- * @author Costin Manolache
- * @version $Revision$
- * @see AbstractWebContainerMBean
- */
-public interface Tomcat5MBean extends AbstractWebContainerMBean
-{
- /** JMX notification type to signal after-start connector event */
- public final String TOMCAT_CONNECTORS_STARTED = "jboss.tomcat.connectors.started";
-
- /**
- * @return the jmx domain for the tomcat management mbeans
- */
- public String getDomain();
-
- /**
- * The most important attribute - defines the managed domain.
- * A catalina instance (engine) corresponds to a JMX domain, that's
- * how we know where to deploy webapps.
- *
- * @param domainName the jmx domain under which tc registers
- */
- public void setDomain(String domainName);
-
- /**
- * Set the snapshot mode in a clustered environment
- */
- public void setSnapshotMode(String mode);
-
- /**
- * Get the snapshot mode in a clustered environment
- */
- public String getSnapshotMode();
-
- /**
- * Set the snapshot interval in ms for the interval snapshot mode
- */
- public void setSnapshotInterval(int interval);
-
- /**
- * Get the snapshot interval
- */
- public int getSnapshotInterval();
-
- /**
- * Get the clustering code cache behaviour
- */
- public boolean isUseLocalCache();
-
- /**
- * Set the clustering code cache behaviour
- */
- public void setUseLocalCache(boolean useLocalCache);
-
- /**
- * Get the clustering code failover behaviour whether MOD_JK(2) is used or not.
- */
- public boolean isUseJK();
-
- /**
- * Set the clustering code failover behaviour whether MOD_JK(2) is used or not.
- */
- public void setUseJK(boolean useJK);
-
- /**
- * The SessionIdAlphabet is the set of characters used to create a session Id
- */
- public void setSessionIdAlphabet(String sessionIdAlphabet);
-
- /**
- * The SessionIdAlphabet is the set of characters used to create a session Id
- */
- public String getSessionIdAlphabet();
-
- /**
- * Gets the JMX object name of a shared TreeCache to be used for clustered
- * single-sign-on.
- *
- * @see org.jboss.web.tomcat.tc5.sso.TreeCacheSSOClusterManager
- */
- public String getCacheName();
-
- /**
- * Gets the JMX object name of a shared TreeCache to be used for clustered
- * single-sign-on.
- * <p/>
- * <b>NOTE:</b> TreeCache must be deployed before this service.
- *
- * @see org.jboss.web.tomcat.tc5.sso.TreeCacheSSOClusterManager
- */
- public void setCacheName(String cacheName);
-
- /**
- * Get the JBoss UCL use flag
- */
- public boolean getUseJBossWebLoader();
-
- /**
- * Set the JBoss UCL use flag
- */
- public void setUseJBossWebLoader(boolean flag);
-
- public String getManagerClass();
-
- public void setManagerClass(String managerClass);
-
- /** */
- public String getContextMBeanCode();
-
- /** */
- public void setContextMBeanCode(String className);
-
- /**
- * Get the name of the external tomcat server configuration file.
- *
- * @return the config file name, server.xml for example
- */
- public String getConfigFile();
-
- /**
- * Set the name of the external tomcat server configuration file.
- *
- * @param configFile - the config file name, server.xml for example
- */
- public void setConfigFile(String configFile);
-
- /**
- * Get the request attribute name under which the JAAS Subject is store
- */
- public String getSubjectAttributeName();
-
- /**
- * Set the request attribute name under which the JAAS Subject will be
- * stored when running with a security mgr that supports JAAS. If this is
- * empty then the Subject will not be store in the request.
- *
- * @param name the HttpServletRequest attribute name to store the Subject
- */
- public void setSubjectAttributeName(String name);
-
- /**
- * Start all connectors of the Domain + ":type=Service,serviceName=jboss.web"
- * service.
- *
- * @throws Exception
- */
- public void startConnectors() throws Exception;
-
- /**
- * Stop all connectors of the Domain + ":type=Service,serviceName=jboss.web"
- * service.
- *
- * @throws Exception
- */
- public void stopConnectors() throws Exception;
-
- /**
- * Get whether web-apps are able to control the privileged flag
- */
- public boolean isAllowSelfPrivilegedWebApps();
-
- /**
- * Set whether web-apps are able to control the privileged flag
- */
- public void setAllowSelfPrivilegedWebApps(boolean flag);
-
- /** Set the SecurityManagerService binding. This is used to flush any
- * associated authentication cache on session invalidation.
- * @param mgr the JaasSecurityManagerServiceMBean
- */
- public void setSecurityManagerService(JaasSecurityManagerServiceMBean mgr);
-
- /**
- *
- * @return
- */
- public String[] getFilteredPackages();
- /**
- *
- * @param pkgs
- */
- public void setFilteredPackages(String[] pkgs);
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/TomcatDeployer.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/TomcatDeployer.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/TomcatDeployer.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,617 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5;
-
-import org.apache.catalina.Loader;
-import org.jboss.deployment.DeploymentException;
-import org.jboss.deployment.DeploymentInfo;
-import org.jboss.metadata.WebMetaData;
-import org.jboss.security.AuthorizationManager;
-import org.jboss.security.authorization.PolicyRegistration;
-import org.jboss.security.plugins.AuthorizationManagerServiceMBean;
-import org.jboss.web.AbstractWebContainer;
-import org.jboss.web.AbstractWebDeployer;
-import org.jboss.web.WebApplication;
-import org.jboss.web.tomcat.security.JaccContextValve;
-import org.jboss.web.tomcat.security.SecurityAssociationValve;
-import org.jboss.web.tomcat.security.RunAsListener;
-import org.jboss.web.tomcat.tc5.session.AbstractJBossManager;
-import org.jboss.web.tomcat.tc5.session.ClusteringNotSupportedException;
-import org.jboss.web.tomcat.tc5.session.JBossCacheManager;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.security.CodeSource;
-import java.security.cert.Certificate;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-import javax.management.Attribute;
-import javax.management.JMException;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-
-/**
- * The tomcat web application deployer
- *
- * @author Scott.Stark at jboss.org
- * @author Costin Manolache
- * @version $Revision$
- */
-public class TomcatDeployer extends AbstractWebDeployer
-{
- /**
- * The name of the war level context configuration descriptor
- */
- private static final String CONTEXT_CONFIG_FILE = "WEB-INF/context.xml";
-
- /**
- * Optional XACML Policy File
- */
- private static final String XACML_POLICY_FILE = "WEB-INF/xacml-policy.xml";
-
- private DeployerConfig config;
- private String[] javaVMs =
- {" jboss.management.local:J2EEServer=Local,j2eeType=JVM,name=localhost"};
- private String serverName = "jboss";
- private HashMap vhostToHostNames = new HashMap();
-
- public void init(Object containerConfig) throws Exception
- {
- this.config = (DeployerConfig)containerConfig;
- super.setJava2ClassLoadingCompliance(config.isJava2ClassLoadingCompliance());
- super.setUnpackWars(config.isUnpackWars());
- super.setLenientEjbLink(config.isLenientEjbLink());
- super.setDefaultSecurityDomain(config.getDefaultSecurityDomain());
- }
-
- /**
- * Perform the tomcat specific deployment steps.
- */
- protected void performDeploy(WebApplication appInfo, String warUrl,
- AbstractWebContainer.WebDescriptorParser webAppParser)
- throws Exception
- {
- WebMetaData metaData = appInfo.getMetaData();
- String hostName = null;
- // Get any jboss-web/virtual-hosts
- Iterator vhostNames = metaData.getVirtualHosts();
- // Map the virtual hosts onto the configured hosts
- Iterator hostNames = mapVirtualHosts(vhostNames);
- if (hostNames.hasNext())
- {
- hostName = hostNames.next().toString();
- }
- performDeployInternal(hostName, appInfo, warUrl, webAppParser);
- while (hostNames.hasNext())
- {
- String additionalHostName = hostNames.next().toString();
- performDeployInternal(additionalHostName, appInfo, warUrl, webAppParser);
- }
- }
-
- protected void performDeployInternal(String hostName,
- WebApplication appInfo, String warUrl,
- AbstractWebContainer.WebDescriptorParser webAppParser)
- throws Exception
- {
-
- WebMetaData metaData = appInfo.getMetaData();
- String ctxPath = metaData.getContextRoot();
- if (ctxPath.equals("/") || ctxPath.equals("/ROOT") || ctxPath.equals(""))
- {
- log.debug("deploy root context=" + ctxPath);
- ctxPath = "/";
- metaData.setContextRoot(ctxPath);
- }
-
- log.info("deploy, ctxPath=" + ctxPath + ", warUrl=" + shortWarUrlFromServerHome(warUrl));
-
- URL url = new URL(warUrl);
-
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- /* If we are using the jboss class loader we need to augment its path
- to include the WEB-INF/{lib,classes} dirs or else scoped class loading
- does not see the war level overrides. The call to setWarURL adds these
- paths to the deployment UCL.
- */
- Loader webLoader = null;
- if (config.isUseJBossWebLoader())
- {
- WebCtxLoader jbossLoader = new WebCtxLoader(loader);
- jbossLoader.setWarURL(url);
- webLoader = jbossLoader;
- }
- else
- {
- String[] pkgs = config.getFilteredPackages();
- WebAppLoader jbossLoader = new WebAppLoader(loader, pkgs);
- jbossLoader.setDelegate(getJava2ClassLoadingCompliance());
- webLoader = jbossLoader;
- }
-
- // We need to establish the JNDI ENC prior to the start
- // of the web container so that init on startup servlets are able
- // to interact with their ENC. We hook into the context lifecycle
- // events to be notified of the start of the
- // context as this occurs before the servlets are started.
- if (appInfo.getAppData() == null)
- webAppParser.parseWebAppDescriptors(loader, appInfo.getMetaData());
-
- appInfo.setName(url.getPath());
- appInfo.setClassLoader(loader);
- appInfo.setURL(url);
-
- String objectNameS = config.getCatalinaDomain()
- + ":j2eeType=WebModule,name=//" +
- ((hostName == null) ? "localhost" : hostName)
- + ctxPath + ",J2EEApplication=none,J2EEServer=none";
-
- ObjectName objectName = new ObjectName(objectNameS);
-
- if (server.isRegistered(objectName))
- {
- log.debug("Already exists, destroying " + objectName);
- server.invoke(objectName, "destroy", new Object[]{},
- new String[]{});
- }
-
- server.createMBean("org.apache.commons.modeler.BaseModelMBean",
- objectName, new Object[]{config.getContextClassName()},
- new String[]{"java.lang.String"});
-
-
- // Find and set config file on the context
- // If WAR is packed, expand config file to temp folder
- String ctxConfig = null;
- try
- {
- ctxConfig = findConfig(url);
- }
- catch (IOException e)
- {
- log.debug("No " + CONTEXT_CONFIG_FILE + " in " + url, e);
- }
-
- server.setAttribute(objectName, new Attribute("docBase", url.getFile()));
-
- server.setAttribute(objectName, new Attribute("configFile", ctxConfig));
-
- server.setAttribute(objectName, new Attribute
- ("defaultContextXml", "context.xml"));
- server.setAttribute(objectName, new Attribute
- ("defaultWebXml", "conf/web.xml"));
-
- server.setAttribute(objectName, new Attribute("javaVMs", javaVMs));
-
- server.setAttribute(objectName, new Attribute("server", serverName));
-
- server.setAttribute(objectName, new Attribute
- ("saveConfig", Boolean.FALSE));
-
- if (webLoader != null)
- {
- server.setAttribute(objectName, new Attribute
- ("loader", webLoader));
- }
- else
- {
- server.setAttribute(objectName, new Attribute
- ("parentClassLoader", loader));
- }
-
- server.setAttribute(objectName, new Attribute
- ("delegate", new Boolean(getJava2ClassLoadingCompliance())));
-
- String[] jspCP = getCompileClasspath(loader);
- StringBuffer classpath = new StringBuffer();
- for (int u = 0; u < jspCP.length; u++)
- {
- String repository = jspCP[u];
- if (repository == null)
- continue;
- if (repository.startsWith("file://"))
- repository = repository.substring(7);
- else if (repository.startsWith("file:"))
- repository = repository.substring(5);
- else
- continue;
- if (repository == null)
- continue;
- // ok it is a file. Make sure that is is a directory or jar file
- File fp = new File(repository);
- if (!fp.isDirectory())
- {
- // if it is not a directory, try to open it as a zipfile.
- try
- {
- // avoid opening .xml files
- if (fp.getName().toLowerCase().endsWith(".xml"))
- continue;
-
- ZipFile zip = new ZipFile(fp);
- zip.close();
- }
- catch (IOException e)
- {
- continue;
- }
-
- }
- if (u > 0)
- classpath.append(File.pathSeparator);
- classpath.append(repository);
- }
-
- server.setAttribute(objectName, new Attribute
- ("compilerClasspath", classpath.toString()));
-
- // Set the session cookies flag according to metadata
- switch (metaData.getSessionCookies())
- {
- case WebMetaData.SESSION_COOKIES_ENABLED:
- server.setAttribute(objectName, new Attribute
- ("cookies", new Boolean(true)));
- log.debug("Enabling session cookies");
- break;
- case WebMetaData.SESSION_COOKIES_DISABLED:
- server.setAttribute(objectName, new Attribute
- ("cookies", new Boolean(false)));
- log.debug("Disabling session cookies");
- break;
- default:
- log.debug("Using session cookies default setting");
- }
-
- // Add a valve to estalish the JACC context before authorization valves
- Certificate[] certs = null;
- CodeSource cs = new CodeSource(url, certs);
- JaccContextValve jaccValve = new JaccContextValve(metaData.getJaccContextID(), cs);
- server.invoke(objectName, "addValve",
- new Object[]{jaccValve},
- new String[]{"org.apache.catalina.Valve"}
- );
-
- // Pass the metadata to the RunAsListener via a thread local
- RunAsListener.metaDataLocal.set(metaData);
- try
- {
- // Init the container; this will also start it
- server.invoke(objectName, "init", new Object[]{}, new String[]{});
- }
- finally
- {
- RunAsListener.metaDataLocal.set(null);
- }
-
- // make the context class loader known to the WebMetaData, ws4ee needs it
- // to instanciate service endpoint pojos that live in this webapp
- Loader ctxLoader = (Loader)server.getAttribute(objectName, "loader");
- metaData.setContextLoader(ctxLoader.getClassLoader());
-
- // Clustering
- if (metaData.getDistributable())
- {
- // Try to initate clustering, fallback to standard if no clustering is available
- try
- {
- AbstractJBossManager manager = null;
- String managerClassName = config.getManagerClass();
- Class managerClass = Thread.currentThread().getContextClassLoader().loadClass(managerClassName);
- manager = (AbstractJBossManager) managerClass.newInstance();
- String name = "//" + ((hostName == null) ? "localhost" : hostName) + ctxPath;
- manager.init(name, metaData, config.isUseJK(), config.isUseLocalCache());
-
- if (manager instanceof JBossCacheManager)
- {
- String snapshotMode = config.getSnapshotMode();
- int snapshotInterval = config.getSnapshotInterval();
- JBossCacheManager jbcm = (JBossCacheManager) manager;
- jbcm.setSnapshotMode(snapshotMode);
- jbcm.setSnapshotInterval(snapshotInterval);
- }
-
- server.setAttribute(objectName, new Attribute("manager", manager));
-
- log.debug("Enabled clustering support for ctxPath=" + ctxPath);
- }
- catch (ClusteringNotSupportedException e)
- {
- log.error("Failed to setup clustering, clustering disabled", e);
- }
- catch(Throwable t)
- {
- log.error("Failed to setup clustering, clustering disabled. Exception: ", t);
- }
- }
-
- /* Add security association valve after the authorization
- valves so that the authenticated user may be associated with the
- request thread/session.
- */
- SecurityAssociationValve valve = new SecurityAssociationValve(metaData,
- config.getSecurityManagerService());
- valve.setSubjectAttributeName(config.getSubjectAttributeName());
- server.invoke(objectName, "addValve",
- new Object[]{valve},
- new String[]{"org.apache.catalina.Valve"});
-
- // Retrieve the state, and throw an exception in case of a failure
- Integer state = (Integer) server.getAttribute(objectName, "state");
- if (state.intValue() != 1)
- {
- throw new DeploymentException("URL " + warUrl + " deployment failed");
- }
-
- appInfo.setAppData(objectName);
-
- // Create mbeans for the servlets
- DeploymentInfo di = webAppParser.getDeploymentInfo();
- di.deployedObject = objectName;
- ObjectName servletQuery = new ObjectName
- (config.getCatalinaDomain() + ":j2eeType=Servlet,WebModule="
- + objectName.getKeyProperty("name") + ",*");
- Iterator iterator = server.queryMBeans(servletQuery, null).iterator();
- while (iterator.hasNext())
- {
- di.mbeans.add(((ObjectInstance)iterator.next()).getObjectName());
- }
-
- if(metaData.getSecurityDomain() != null)
- {
- String secDomain = getUnprefixedSecurityDomain(metaData.getSecurityDomain());
- //Associate the Context Id with the Security Domain
- String contextID = metaData.getJaccContextID();
- mapSecurityDomain(secDomain, contextID);
-
- //Check if xacml policy is available
- URL xacmlPolicyFile = null;
- try
- {
- xacmlPolicyFile = this.findXACMLFile(url);
- if(xacmlPolicyFile != null)
- {
- AuthorizationManagerServiceMBean authzmgrService = config.getAuthorizationManagerService();
- if(authzmgrService == null)
- throw new IllegalStateException("AuthorizationManagerService not configured in Tomcat5");
- AuthorizationManager authzmgr= authzmgrService.getAuthorizationManager(secDomain);
- if(authzmgr instanceof PolicyRegistration)
- {
- PolicyRegistration xam = (PolicyRegistration)authzmgr;
- xam.registerPolicy(contextID,xacmlPolicyFile);
- }
- }
- }
- catch(IOException ioe)
- {
- //Ignore
- }
- }
-
- log.debug("Initialized: " + appInfo + " " + objectName);
- }
-
-
- /**
- * Called as part of the undeploy() method template to ask the
- * subclass for perform the web container specific undeployment steps.
- */
- protected void performUndeploy(String warUrl, WebApplication appInfo)
- throws Exception
- {
- if (appInfo == null)
- {
- log.debug("performUndeploy, no WebApplication found for URL "
- + warUrl);
- return;
- }
-
- log.info("undeploy, ctxPath=" + appInfo.getMetaData().getContextRoot()
- + ", warUrl=" + shortWarUrlFromServerHome(warUrl));
-
- WebMetaData metaData = appInfo.getMetaData();
- String hostName = null;
- Iterator hostNames = metaData.getVirtualHosts();
- if (hostNames.hasNext())
- {
- hostName = hostNames.next().toString();
- }
- performUndeployInternal(hostName, warUrl, appInfo);
- while (hostNames.hasNext())
- {
- String additionalHostName = hostNames.next().toString();
- performUndeployInternal(additionalHostName, warUrl, appInfo);
- }
-
- }
-
- protected void performUndeployInternal(String hostName, String warUrl,
- WebApplication appInfo)
- throws Exception
- {
-
- WebMetaData metaData = appInfo.getMetaData();
- String ctxPath = metaData.getContextRoot();
-
- // If the server is gone, all apps were stopped already
- if (server == null)
- return;
-
- ObjectName objectName = new ObjectName(config.getCatalinaDomain()
- + ":j2eeType=WebModule,name=//" +
- ((hostName == null) ? "localhost" : hostName)
- + ctxPath + ",J2EEApplication=none,J2EEServer=none");
-
- if (server.isRegistered(objectName))
- {
- // Contexts should be stopped by the host already
- server.invoke(objectName, "destroy", new Object[]{},
- new String[]{});
- }
-
- }
-
- /**
- * Resolve the input virtual host names to the names of the configured Hosts
- * @param vhostNames Iterator<String> for the jboss-web/virtual-host elements
- * @return Iterator<String> of the unique Host names
- * @throws Exception
- */
- protected synchronized Iterator mapVirtualHosts(Iterator vhostNames)
- throws Exception
- {
- if (vhostToHostNames.size() == 0)
- {
- // Query the configured Host mbeans
- String hostQuery = config.getCatalinaDomain() + ":type=Host,*";
- ObjectName query = new ObjectName(hostQuery);
- Set hosts = server.queryNames(query, null);
- Iterator iter = hosts.iterator();
- while (iter.hasNext())
- {
- ObjectName host = (ObjectName)iter.next();
- String name = host.getKeyProperty("host");
- if (name != null)
- {
- vhostToHostNames.put(name, name);
- String[] aliases = (String[])
- server.invoke(host, "findAliases", null, null);
- int count = aliases != null ? aliases.length : 0;
- for (int n = 0; n < count; n++)
- {
- vhostToHostNames.put(aliases[n], name);
- }
- }
- }
- }
-
- // Map the virtual host names to the hosts
- HashSet hosts = new HashSet();
- while (vhostNames.hasNext())
- {
- String vhost = (String)vhostNames.next();
- String host = (String)vhostToHostNames.get(vhost);
- if (host == null)
- {
- log.warn("Failed to map vhost: " + vhost);
- // This will cause a new host to be created
- host = vhost;
- }
- hosts.add(host);
- }
- return hosts.iterator();
- }
-
- private String findConfig(URL warURL) throws IOException
- {
- String result = null;
- // See if the warUrl is a dir or a file
- File warFile = new File(warURL.getFile());
- if (warURL.getProtocol().equals("file") && warFile.isDirectory() == true)
- {
- File webDD = new File(warFile, CONTEXT_CONFIG_FILE);
- if (webDD.exists() == true) result = webDD.getAbsolutePath();
- }
- else
- {
- ZipFile zipFile = new ZipFile(warFile);
- ZipEntry entry = zipFile.getEntry(CONTEXT_CONFIG_FILE);
- if (entry != null)
- {
- InputStream zipIS = zipFile.getInputStream(entry);
- byte[] buffer = new byte[512];
- int bytes;
- result = warFile.getAbsolutePath() + "-context.xml";
- FileOutputStream fos = new FileOutputStream(result);
- while ((bytes = zipIS.read(buffer)) > 0)
- {
- fos.write(buffer, 0, bytes);
- }
- zipIS.close();
- fos.close();
- }
- zipFile.close();
- }
- return result;
- }
-
- private URL findXACMLFile(URL warURL) throws IOException
- {
- URL result = null;
- // See if the warUrl is a dir or a file
- File warFile = new File(warURL.getFile());
- if (warURL.getProtocol().equals("file") && warFile.isDirectory() == true)
- {
- File webDD = new File(warFile, XACML_POLICY_FILE);
- if (webDD.exists() == true)
- result = webDD.toURL();
- }
- return result;
- }
-
- private String shortWarUrlFromServerHome(String warUrl)
- {
- String serverHomeUrl = System.getProperty(org.jboss.system.server.ServerConfig.SERVER_HOME_URL);
-
- if (warUrl == null || serverHomeUrl == null)
- return warUrl;
-
- if (warUrl.startsWith(serverHomeUrl))
- return ".../" + warUrl.substring(serverHomeUrl.length());
- else
- return warUrl;
- }
-
- protected void mapSecurityDomain(String securityDomain, String contextId)
- {
- //Register the context id with the authentication service
- ObjectName oname = null;
- try
- {
- oname = new ObjectName("jboss.security:service=JASPISecurityManager");
- server.invoke(oname,"registerSecurityDomain", new Object[]{securityDomain,contextId},
- new String[]{"java.lang.String", "java.lang.String"} );
- }catch(JMException me)
- {
- log.error("mapSecurityDomain::" + me.getLocalizedMessage());
- }
- }
-
- private String getUnprefixedSecurityDomain(String securityDomain)
- {
- String result = "";
- if(securityDomain.startsWith("java:/jaas"))
- result = securityDomain.substring("java:/jaas/".length());
- else
- if(securityDomain.startsWith("java:/jbsx"))
- result = securityDomain.substring("java:/jbsx/".length());
- return result;
-
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebAppClassLoader.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebAppClassLoader.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebAppClassLoader.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,88 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5;
-
-import org.apache.catalina.loader.WebappClassLoader;
-import org.jboss.logging.Logger;
-
-/**
- * Subclass the tomcat web app class loader to override the filter method
- * to exclude classes which cannot be override by the web app due to their
- * use in the tomcat web container/integration.
- *
- * @author Scott.Stark at jboss.org
- * @version $Revision$
- */
-public class WebAppClassLoader extends WebappClassLoader
-{
- static Logger log = Logger.getLogger(WebAppClassLoader.class);
- private String[] filteredPackages = {
- "org.apache.commons.logging"
- };
-
- public WebAppClassLoader()
- {
- }
-
- public WebAppClassLoader(ClassLoader parent)
- {
- super(parent);
- }
-
- public String[] getFilteredPackages()
- {
- return filteredPackages;
- }
- public void setFilteredPackages(String[] pkgs)
- {
- this.filteredPackages = pkgs;
- }
-
- /**
- * Overriden to filter out classes in the packages listed in the
- * filteredPackages settings.
- *
- * @param name
- * @return true if the class should be loaded from the parent class loader,
- * false if it can be loaded from this class loader.
- */
- protected boolean filter(String name)
- {
- boolean excludeClass = super.filter(name);
- if( excludeClass == false )
- {
- // Check class against our filtered packages
- int length = filteredPackages != null ? filteredPackages.length : 0;
- for(int n = 0; n < length; n ++)
- {
- String pkg = filteredPackages[n];
- if( name.startsWith(pkg) )
- {
- excludeClass = true;
- break;
- }
- }
- }
- log.trace("filter name="+name+", exclude="+excludeClass);
- return excludeClass;
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebAppLoader.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebAppLoader.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebAppLoader.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,68 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5;
-
-import org.apache.catalina.loader.WebappLoader;
-import org.apache.catalina.LifecycleException;
-
-/**
- * Override the tomcat WebappLoader to set the default class loader to the
- * WebAppClassLoader and pass the filtered packages to the WebAppClassLoader.
- *
- * @author Scott.Stark at jboss.org
- * @version $Revision$
- */
-public class WebAppLoader extends WebappLoader
-{
- private String[] filteredPackages = {
- "org.apache.commons.logging"
- };
-
- public WebAppLoader()
- {
- super();
- setLoaderClass(WebAppClassLoader.class.getName());
- }
-
- public WebAppLoader(ClassLoader parent, String[] filteredPackages)
- {
- super(parent);
- setLoaderClass(WebAppClassLoader.class.getName());
- this.filteredPackages = filteredPackages;
- }
-
- /**
- * Override to apply the filteredPackages to the jboss WebAppClassLoader
- *
- * @throws LifecycleException
- */
- public void start() throws LifecycleException
- {
- super.start();
- ClassLoader loader = getClassLoader();
- if( loader instanceof WebAppClassLoader )
- {
- WebAppClassLoader webLoader = (WebAppClassLoader) loader;
- webLoader.setFilteredPackages(filteredPackages);
- }
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebCtxLoader.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebCtxLoader.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/WebCtxLoader.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,320 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt 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.web.tomcat.tc5;
-
-import java.beans.PropertyChangeListener;
-import java.io.File;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-
-import javax.servlet.ServletContext;
-
-import org.apache.catalina.Container;
-import org.apache.catalina.Context;
-import org.apache.catalina.Globals;
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.Loader;
-import org.apache.naming.resources.DirContextURLStreamHandler;
-import org.jboss.mx.loading.RepositoryClassLoader;
-
-/**
- * Initial version of a JBoss implementation of the Tomcat Loader.
- *
- * @author Scott.Stark at jboss.org
- * @version $Revision$
- */
-public class WebCtxLoader
- implements Lifecycle, Loader
-{
- /**
- * The ClassLoader used to scope the ENC
- */
- protected ClassLoader encLoader;
- /**
- * The ClassLoader returned from getClassLoader
- */
- protected ENCLoader ctxLoader;
- /**
- * The war UCL used to load the war classes
- */
- protected RepositoryClassLoader delegate;
- protected Container webContainer;
- protected URL warURL;
-
- /**
- * The set of repositories associated with this class loader.
- */
- private ArrayList repositories = new ArrayList();
-
- /**
- * Create a WebCtxLoader given the ENC scoping class loader.
- *
- * @param encLoader
- */
- WebCtxLoader(ClassLoader encLoader)
- {
- this.encLoader = encLoader;
- this.ctxLoader = new ENCLoader(encLoader);
- ClassLoader parent = encLoader;
- while ((parent instanceof RepositoryClassLoader) == false && parent != null)
- parent = parent.getParent();
- this.delegate = (RepositoryClassLoader) parent;
- }
-
- public void setWarURL(URL warURL) throws MalformedURLException
- {
- this.warURL = warURL;
- String path = warURL.getFile();
- File classesDir = new File(path, "WEB-INF/classes");
- if (classesDir.exists())
- {
- delegate.addURL(classesDir.toURL());
- ctxLoader.addURLInternal(classesDir.toURL());
- }
- File libDir = new File(path, "WEB-INF/lib");
- if (libDir.exists())
- {
- File[] jars = libDir.listFiles();
- int length = jars != null ? jars.length : 0;
- for (int j = 0; j < length; j++)
- {
- File jar = jars[j];
- if(jar.getAbsolutePath().endsWith(".jar"))
- {
- delegate.addURL(jar.toURL());
- ctxLoader.addURLInternal(jar.toURL());
- }
- }
- }
- }
-
- public void addLifecycleListener(LifecycleListener listener)
- {
- }
-
- public LifecycleListener[] findLifecycleListeners()
- {
- return new LifecycleListener[0];
- }
-
- public void removeLifecycleListener(LifecycleListener listener)
- {
- }
-
- public void start() throws LifecycleException
- {
- // ctxLoader is set upon construction and nullified during stop
- if (this.ctxLoader == null)
- throw new LifecycleException("WebCtxLoader cannot be restarted");
-
- setClassPath();
- ServletContext servletContext = ((Context) webContainer).getServletContext();
- if (servletContext == null)
- return;
- }
-
- public void stop() throws LifecycleException
- {
- // Remove the ctxLoader mapping kept by the DirContextURLStreamHandler
- DirContextURLStreamHandler.unbind(ctxLoader);
- org.apache.commons.logging.LogFactory.release(ctxLoader);
- org.apache.commons.logging.LogFactory.release(encLoader);
- this.encLoader = null;
- this.ctxLoader = null;
- this.delegate = null;
- this.repositories.clear();
- this.warURL = null;
- this.webContainer = null;
- }
-
- public void backgroundProcess()
- {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- /**
- * We must pass the wrapped encLoader as tomcat needs to see a unique
- * class loader that is distinct from the thread context class loader seen
- * to be in effect when the web app is started. This is due to how it
- * binds contexts using the DirContextURLStreamHandler class.
- *
- * @return The ENC scoping class loader
- * @see org.apache.naming.resources.DirContextURLStreamHandler
- */
- public ClassLoader getClassLoader()
- {
- return ctxLoader;
- }
-
- public Container getContainer()
- {
- return webContainer;
- }
-
- public void setContainer(Container container)
- {
- webContainer = container;
-
- }
-
- public boolean getDelegate()
- {
- return false;
- }
-
- public void setDelegate(boolean delegate)
- {
- }
-
- public String getInfo()
- {
- return null;
- }
-
- public boolean getReloadable()
- {
- return false;
- }
-
- public void setReloadable(boolean reloadable)
- {
- }
-
- public void addPropertyChangeListener(PropertyChangeListener listener)
- {
- }
-
- public void addRepository(String repository)
- {
- if (repositories.contains(repository) == true)
- return;
- repositories.add(repository);
- setClassPath();
- }
-
- public String[] findRepositories()
- {
- String[] tmp = new String[repositories.size()];
- repositories.toArray(tmp);
- return tmp;
- }
-
- public boolean modified()
- {
- return false;
- }
-
- public void removePropertyChangeListener(PropertyChangeListener listener)
- {
- }
-
- /**
- * Set the appropriate context attribute for our class path. This
- * is required only because Jasper depends on it.
- */
- private void setClassPath()
- {
- // Validate our current state information
- if (!(webContainer instanceof Context))
- return;
- ServletContext servletContext = ((Context) webContainer).getServletContext();
- if (servletContext == null)
- return;
-
- try
- {
- Method method =
- webContainer.getClass().getMethod("getCompilerClasspath", null);
- Object baseClasspath = method.invoke(webContainer, null);
- if (baseClasspath != null)
- {
- servletContext.setAttribute(Globals.CLASS_PATH_ATTR,
- baseClasspath.toString());
- return;
- }
- }
- catch (Exception e)
- {
- // Ignore
- e.printStackTrace();
- }
-
- StringBuffer classpath = new StringBuffer();
-
- // Assemble the class path information from our repositories
- for (int i = 0; i < repositories.size(); i++)
- {
- String repository = repositories.get(i).toString();
- if (repository.startsWith("file://"))
- repository = repository.substring(7);
- else if (repository.startsWith("file:"))
- repository = repository.substring(5);
- else if (repository.startsWith("jndi:"))
- repository = servletContext.getRealPath(repository.substring(5));
- else
- continue;
- if (repository == null)
- continue;
- if (i > 0)
- classpath.append(File.pathSeparator);
- classpath.append(repository);
- }
-
- // Store the assembled class path as a servlet context attribute
- servletContext.setAttribute(Globals.CLASS_PATH_ATTR,
- classpath.toString());
-
- }
-
- /**
- * A trival extension of URLClassLoader that uses an empty URL[] as its
- * classpath so that all work is delegated to its parent.
- */
- static class ENCLoader extends URLClassLoader
- {
- private URL[] urllist = new URL[0];
-
- ENCLoader(ClassLoader parent)
- {
- super(new URL[0], parent);
- }
-
- void addURLInternal(URL url)
- {
- URL[] result = new URL[urllist.length + 1];
- for (int i = 0; i < urllist.length; i++)
- result[i] = urllist[i];
- result[urllist.length] = url;
- urllist = result;
- }
-
- public URL[] getURLs()
- {
- return urllist;
- }
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/AbstractJBossManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/AbstractJBossManager.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/AbstractJBossManager.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,85 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.catalina.Session;
-import org.apache.catalina.Manager;
-import org.jboss.metadata.WebMetaData;
-
-/** Common interface for the http session replication managers.
- *
- * @author Scott.Stark at jboss.org
- * @version $Revision$
- */
-public interface AbstractJBossManager extends Manager
-{
- /** Initialize the manager with the web metadata and
- * @param name
- * @param webMetaData
- * @param useJK
- * @param useLocalCache
- * @throws ClusteringNotSupportedException
- */
- public void init(String name, WebMetaData webMetaData, boolean useJK,
- boolean useLocalCache)
- throws ClusteringNotSupportedException;
-
- /** The session invalidation policy. One of:
- SESSION_INVALIDATE_ACCESS =0;
- SESSION_INVALIDATE_SET_AND_GET =1;
- SESSION_INVALIDATE_SET_AND_NON_PRIMITIVE_GET =2;
- SESSION_INVALIDATE_SET =3;
- * @return the invalidation policy constant
- */
- public int getInvalidateSessionPolicy();
-
- /**
- * Retrieve the JvmRoute for the enclosing Engine.
- *
- * @return the JvmRoute or null.
- */
- public String getJvmRoute();
-
- /**
- * Sets a new cookie for the given session id and response
- *
- * @param sessionId The session id
- */
- public void setNewSessionCookie(String sessionId, HttpServletResponse response);
-
- /**
- * Remove the active session locally from the manager without replicating to the cluster. This can be
- * useful when the session is exipred, for example, where there is not need to propagate the expiration.
- *
- * @param session
- */
- public void removeLocal(Session session);
-
- /**
- * Store the modified session.
- *
- * @param session
- */
- public boolean storeSession(Session session);
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/AttributeBasedClusteredSession.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/AttributeBasedClusteredSession.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/AttributeBasedClusteredSession.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,269 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Implementation of a clustered session for the JBossCacheManager. The replication granularity
- * level is attribute based; that is, we replicate only the dirty attributes.
- * We use JBossCache for our internal, deplicated data store.
- * The internal structure is like in JBossCache:
- * <pre>
- * /JSESSION
- * /hostname
- * /web_app_path (path + session id is unique)
- * /id Map(id, session)
- * (VERSION_KEY, version) // Used for version tracking. version is an Integer.
- * /ATTRIBUTE Map(attr_key, value)
- * </pre>
- * <p/>
- * Note that the isolation level of the cache dictates the
- * concurrency behavior. Also note that session and its associated attribtues are stored in different nodes.
- * This will be ok since cache will take care of concurrency. When replicating, we will need to replicate both
- * session and its attributes.</p>
- *
- * @author Ben Wang
- * @author Brian Stansberry
- *
- * @version $Revision$
- */
-class AttributeBasedClusteredSession
- extends JBossCacheClusteredSession
-{
- static final long serialVersionUID = -5625209785550936713L;
- /**
- * Descriptive information describing this Session implementation.
- */
- protected static final String info = "AttributeBasedClusteredSession/1.0";
-
- // Transient map to store attr changes for replication.
- private transient Map attrModifiedMap_ = new HashMap();
- // Note that the removed attr is intentionally stored in a map
- // instead of a Set so it is faster to lookup and remove.
- private transient Map attrRemovedMap_ = new HashMap();
- private static final int REMOVE = 0; // Used to track attribute changes
- private static final int MODIFY = 1;
- // TODO why isn't the superclass field sufficient?
- private transient Map attributes_ = Collections.synchronizedMap(new HashMap());
-
- public AttributeBasedClusteredSession(JBossCacheManager manager)
- {
- super(manager);
- }
-
- // ----------------------------------------------- Overridden Public Methods
-
-
- /**
- * Override the superclass to additionally reset this class' fields.
- * <p>
- * <strong>NOTE:</strong> It is not anticipated that this method will be
- * called on a ClusteredSession, but we are overriding the method to be
- * thorough.
- * </p>
- */
- public void recycle()
- {
- super.recycle();
-
- attributes_.clear();
- clearAttrChangedMaps();
- }
-
- /**
- * Return a string representation of this object.
- */
- public String toString()
- {
-
- StringBuffer sb = new StringBuffer();
- sb.append("AttributeBasedClusteredSession[");
- sb.append(super.toString());
- sb.append("]");
- return (sb.toString());
-
- }
-
- /**
- * Overrides the superclass version to read in the attributes.
- */
- public synchronized void processSessionRepl()
- {
- // Replicate the metadata first. Note this will be lightweight since many
- // of the fields are transient and the attribute map isn't included.
- if (log.isTraceEnabled())
- {
- log.trace("processSessionRepl(): session is dirty. Will increment " +
- "version from: " + getVersion() + " and replicate.");
- }
- this.incrementVersion();
- proxy_.putSession(realId, this);
-
- // Go thru the attribute change list
-
- if (getSessionAttributesDirty())
- {
- // Go thru the modified attr list first
- Set set = attrModifiedMap_.keySet();
- Iterator it = set.iterator();
- while (it.hasNext())
- {
- Object key = it.next();
- proxy_.putAttribute(realId, (String) key, attrModifiedMap_.get(key));
- }
-
- // Go thru the remove attr list
- set = attrRemovedMap_.keySet();
- it = set.iterator();
- while (it.hasNext())
- {
- Object key = it.next();
- proxy_.removeAttribute(realId, (String) key);
- }
-
- clearAttrChangedMaps();
- }
-
- sessionAttributesDirty = false;
- sessionMetadataDirty = false;
-
- updateLastReplicated();
- }
-
- public void removeMyself()
- {
- // This is a shortcut to remove session and it's child attributes.
- proxy_.removeSession(realId);
- }
-
- public void removeMyselfLocal()
- {
- // Need to evict attribute first before session to clean up everything.
- // BRIAN -- the attributes *are* already evicted, but we leave the
- // removeAttributesLocal call here in order to evict the ATTRIBUTE node.
- // Otherwise empty nodes for the session root and child ATTRIBUTE will
- // remain in the tree and screw up our list of session names.
- proxy_.removeAttributesLocal(realId);
- proxy_.removeSessionLocal(realId);
- }
-
- // ------------------------------------------------ JBoss internal abstract method
-
- /**
- * Populate the attributes stored in the distributed store to local transient ones.
- */
- protected void populateAttributes()
- {
- Map map = proxy_.getAttributes(realId);
-
- // Preserve any local attributes that were excluded from replication
- Map excluded = removeExcludedAttributes(attributes_);
- if (excluded != null)
- map.putAll(excluded);
-
- attributes_ = Collections.synchronizedMap(map);
- attrModifiedMap_.clear();
- attrRemovedMap_.clear();
- }
-
- protected Object getJBossInternalAttribute(String name)
- {
- Object result = attributes_.get(name);
-
- // Do dirty check even if result is null, as w/ SET_AND_GET null
- // still makes us dirty (ensures timely replication w/o using ACCESS)
- if (isGetDirty(result) && !replicationExcludes.contains(name))
- {
- attributeChanged(name, result, MODIFY);
- }
-
- return result;
- }
-
- protected Object removeJBossInternalAttribute(String name,
- boolean localCall,
- boolean localOnly)
- {
- Object result = attributes_.remove(name);
- if (localCall && !replicationExcludes.contains(name))
- attributeChanged(name, result, REMOVE);
- return result;
- }
-
- protected Map getJBossInternalAttributes()
- {
- return attributes_;
- }
-
- protected Set getJBossInternalKeys()
- {
- return attributes_.keySet();
- }
-
- /**
- * Method inherited from Tomcat. Return zero-length based string if not found.
- */
- protected String[] keys()
- {
- return ((String[]) getJBossInternalKeys().toArray(EMPTY_ARRAY));
- }
-
- protected Object setJBossInternalAttribute(String key, Object value)
- {
- Object old = attributes_.put(key, value);
- if (!replicationExcludes.contains(key))
- attributeChanged(key, value, MODIFY);
- return old;
- }
-
- protected synchronized void attributeChanged(Object key, Object value, int op)
- {
- if (op == MODIFY)
- {
- if (attrRemovedMap_.containsKey(key))
- {
- attrRemovedMap_.remove(key);
- }
- attrModifiedMap_.put(key, value);
- }
- else if (op == REMOVE)
- {
- if (attrModifiedMap_.containsKey(key))
- {
- attrModifiedMap_.remove(key);
- }
- attrRemovedMap_.put(key, value);
- }
- sessionAttributesDirty();
- }
-
- protected synchronized void clearAttrChangedMaps()
- {
- attrRemovedMap_.clear();
- attrModifiedMap_.clear();
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/BatchReplicationClusteredSessionValve.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/BatchReplicationClusteredSessionValve.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/BatchReplicationClusteredSessionValve.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,154 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.io.IOException;
-import javax.servlet.ServletException;
-import javax.transaction.TransactionManager;
-
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.connector.Request;
-import org.apache.catalina.connector.Response;
-import org.apache.catalina.util.LifecycleSupport;
-import org.apache.catalina.valves.ValveBase;
-import org.jboss.logging.Logger;
-
-/**
- * This Valve handles batch replication mode. It uses the cache tm to performa batch replication.
- *
- * @author Ben Wang
- * @version $Revision$
- */
-public class BatchReplicationClusteredSessionValve extends ValveBase implements Lifecycle
-{
- private static Logger log_ = Logger.getLogger(BatchReplicationClusteredSessionValve.class);
-
- // The info string for this Valve
- private static final String info = "BatchReplicationClusteredSessionValve/1.0";
-
- // Valve-lifecycle_ helper object
- protected LifecycleSupport support = new LifecycleSupport(this);
-
- // store the request and response object for parts of the clustering code that
- // have no direct access to this objects
- protected static ThreadLocal requestThreadLocal = new ThreadLocal();
- protected static ThreadLocal responseThreadLocal = new ThreadLocal();
-
- protected JBossCacheManager manager_;
-
- /**
- * Create a new Valve.
- *
- */
- public BatchReplicationClusteredSessionValve(AbstractJBossManager manager)
- {
- super();
- manager_ = (JBossCacheManager)manager;
- }
-
- /**
- * Get information about this Valve.
- */
- public String getInfo()
- {
- return info;
- }
-
- /**
- * Valve-chain handler method.
- * This method gets called when the request goes through the Valve-chain. Our session replication mechanism replicates the
- * session after request got through the servlet code.
- *
- * @param request The request object associated with this request.
- * @param response The response object associated with this request.
- */
- public void invoke(Request request, Response response) throws IOException, ServletException
- {
- // Note: we use specfically the tm in cache.
- TransactionManager tm = manager_.getCacheService().getTransactionManager();
- if(tm == null)
- {
- throw new RuntimeException("BatchReplicationClusteredSessionValve.invoke(): Obtain null tm");
- }
-
- // Before we start a tx, get the session. If this is a failover
- // situation, this will cause data gravitation, which will occur
- // thus outside of the scope of the tx we are about to start.
- // JBossCacheManager will ensure the gravitation is in its own tx
- request.getSession(false);
-
- // Start a new transaction, we need transaction so all the replication are sent in batch.
- try
- {
- tm.begin();
- // let the servlet invocation go through
- getNext().invoke(request, response);
- if(log_.isDebugEnabled())
- {
- log_.debug("Ready to commit batch replication for field level granularity");
- }
- tm.commit();
- }
- catch (Exception e)
- {
- try
- {
- tm.rollback();
- }
- catch (Exception exn)
- {
- exn.printStackTrace();
- }
- // We will need to alert Tomcat of this exception.
- throw new RuntimeException("JBossCacheManager.processSessionRepl(): failed to replicate session.", e);
- }
- }
-
- // Lifecylce-interface
- public void addLifecycleListener(LifecycleListener listener)
- {
- support.addLifecycleListener(listener);
- }
-
- public void removeLifecycleListener(LifecycleListener listener)
- {
- support.removeLifecycleListener(listener);
- }
-
- public LifecycleListener[] findLifecycleListeners()
- {
- return support.findLifecycleListeners();
- }
-
- public void start() throws LifecycleException
- {
- support.fireLifecycleEvent(START_EVENT, this);
- }
-
- public void stop() throws LifecycleException
- {
- support.fireLifecycleEvent(STOP_EVENT, this);
- }
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/CacheListener.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/CacheListener.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/CacheListener.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,276 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import org.jboss.cache.Fqn;
-import org.jboss.cache.TreeCache;
-import org.jboss.cache.AbstractTreeCacheListener;
-import org.jboss.logging.Logger;
-import org.jboss.metadata.WebMetaData;
-import org.jgroups.View;
-
-
-public class CacheListener extends AbstractTreeCacheListener
-{
- // Element within an FQN that is the session id
- private static final int SESSION_ID_FQN_INDEX = 3;
- // Size of an Fqn that points to the root of a session
- private static final int SESSION_FQN_SIZE = SESSION_ID_FQN_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;
- // Size of an Fqn that points to the root of a session
- private static final int POJO_KEY_FQN_SIZE = POJO_KEY_FQN_INDEX + 1;
- // The root of the buddy backup subtree
- private static final String BUDDY_BACKUP = "_BUDDY_BACKUP_";
-
- protected static Logger log_ = Logger.getLogger(CacheListener.class);
- protected JBossCacheWrapper cacheWrapper_;
- protected JBossCacheManager manager_;
- protected Fqn subtreeRoot_;
- protected boolean fieldBased_;
-
- CacheListener(JBossCacheWrapper wrapper, JBossCacheManager manager, Fqn subtreeRoot)
- {
- cacheWrapper_ = wrapper;
- manager_ = manager;
- subtreeRoot_ = subtreeRoot;
- fieldBased_ = manager_.getReplicationGranularity() == WebMetaData.REPLICATION_GRANULARITY_FIELD;
- }
-
- /**
- * If this event is emitted by myself or is not for the web app
- * I'm managing, then we can skip.
- * @param fqn
- * @return
- */
- protected boolean needToHandle(Fqn fqn)
- {
- return (LocalSessionActivity.isLocallyActive(getIdFromFqn(fqn)) == false
- && fqn.isChildOf(subtreeRoot_));
- }
-
- // --------------- TreeCacheListener methods ------------------------------------
-
- public void nodeCreated(Fqn fqn)
- {
- // No-op
- }
-
- public void nodeRemoved(Fqn fqn)
- {
- ParsedBuddyFqn pfqn = new ParsedBuddyFqn(fqn);
- fqn = pfqn.noBuddy;
- if (fqn == null)
- return;
-
- if (fqn.size() == POJO_KEY_FQN_SIZE)
- {
- // Potential removal of a Pojo where we need to unregister
- // as an Observer.
- if (fieldBased_
- && needToHandle(fqn)
- && JBossCacheService.ATTRIBUTE.equals(fqn.get(POJO_ATTRIBUTE_FQN_INDEX)))
- {
- String sessId = getIdFromFqn(fqn);
- FieldBasedClusteredSession session =
- (FieldBasedClusteredSession) manager_.findLocalSession(sessId);
- if (session != null)
- {
- String attrKey = (String) fqn.get(POJO_KEY_FQN_INDEX);
- boolean localCall = false; // call is due to remote event
- boolean localOnly = true; // don't call back into cache
- boolean notify = false; // SRV.10.7 gives us leeway
- // not to notify listeners,
- // which is safer
- synchronized (session)
- {
- session.removeAttributeInternal(attrKey, localCall, localOnly, notify);
- }
- if (log_.isTraceEnabled())
- log_.trace("nodeRemoved: removed attribute " + attrKey);
- }
- }
- }
- else if(fqn.size() == SESSION_FQN_SIZE && needToHandle(fqn))
- {
- // A session has been invalidated from another node;
- // need to inform manager
- String sessId = getIdFromFqn(fqn);
- manager_.processRemoteInvalidation(sessId);
- }
- }
-
- /**
- * Called when a node is loaded into memory via the CacheLoader. This is not the same
- * as {@link #nodeCreated(Fqn)}.
- */
- public void nodeLoaded(Fqn fqn)
- {
- }
-
- public void nodeModified(Fqn fqn)
- {
- nodeDirty(fqn);
- }
-
- protected void nodeDirty(Fqn fqn)
- {
- // Parse the Fqn so we if it has a buddy backup region in it
- // we can just deal with the part below that
- ParsedBuddyFqn pfqn = new ParsedBuddyFqn(fqn);
- Fqn noBuddy = pfqn.noBuddy;
-
- // Check if we need to handle this event. If this is from myself or not for
- // my webapp, then I should skip it.
- // We only deal with events for the root node of a session,
- // so skip all others
- if(noBuddy == null || noBuddy.size() != SESSION_FQN_SIZE || !needToHandle(noBuddy)) return;
-
- // Query if we have version value. Use the full Fqn, not just the
- // "no buddy" part.
- // If we have a version value, we compare the version. Invalidate if necessary.
- Integer version = (Integer)cacheWrapper_.get(fqn, JBossCacheService.VERSION_KEY);
- if(version != null)
- {
- String realId = getIdFromFqn(noBuddy);
-
- ClusteredSession session = manager_.findLocalSession(realId);
- if (session == null)
- {
- // Notify the manager that an unloaded session has been updated
- manager_.unloadedSessionChanged(realId, pfqn.owner);
- }
- else if (session.isNewData(version.intValue()))
- {
- // Need to invalidate the loaded session
- session.setOutdatedVersion(version.intValue());
- if(log_.isTraceEnabled())
- {
- log_.trace("nodeDirty(): session in-memory data is " +
- "invalidated with id: " + realId + " and version: " +
- version.intValue());
- }
- }
- else
- {
- log_.warn("Possible concurrency problem: Replicated version id " +
- version + " matches in-memory version for session " + realId);
- }
- }
- else
- {
- log_.warn("No VERSION_KEY attribute found in " + fqn);
- }
- }
-
- public void nodeVisited(Fqn fqn)
- {
- // no-op
- }
-
- public void cacheStarted(TreeCache cache)
- {
- // TODO will need to synchronize this with local sessions
- }
-
- public void cacheStopped(TreeCache cache)
- {
- // TODO will need to synchronize this with local sessions
- }
-
- public void viewChange(View new_view)
- {
- // We don't care for this event.
- }
-
- public void nodeEvicted(Fqn fqn)
- {
- // We don't care for this event.
- }
-
- public void nodeActivate(Fqn fqn, boolean pre)
- {
- //no-op
- // we don't need to handle node activation notification since the session manager will do upon
- // loading the session from the distrubted store.
- }
-
- public void nodePassivate(Fqn fqn, boolean pre)
- {
- // Parse the Fqn so if it has a buddy backup region in it
- // we can just deal with the part below that
- ParsedBuddyFqn pfqn = new ParsedBuddyFqn(fqn);
- Fqn noBuddy = pfqn.noBuddy;
-
- // Check if we need to handle this event. If this is from myself or not for
- // my webapp, then I should skip it.
- // We only deal with events for the root node of a session,
- // so skip all others
- if(noBuddy == null || noBuddy.size() != SESSION_FQN_SIZE || !needToHandle(noBuddy)) return;
-
- if(pre)
- {
- // A session has been passivated on another node;
- // need to inform the manager
- String realId = getIdFromFqn(noBuddy);
- // process the session passivation
- manager_.processSessionPassivation(realId, pfqn.owner);
- }
-
- }
-
- protected String getIdFromFqn(Fqn fqn)
- {
- return (String)fqn.get(SESSION_ID_FQN_INDEX);
- }
-
- private class ParsedBuddyFqn
- {
- Fqn raw;
- Fqn noBuddy;
- String owner;
-
- ParsedBuddyFqn(Fqn raw)
- {
- this.raw = raw;
- if (raw != null)
- {
- if (BUDDY_BACKUP.equals(raw.get(0)))
- {
- if (raw.size() > 2)
- {
- owner = (String) raw.get(1);
- noBuddy = raw.getFqnChild(2, raw.size());
- if (log_.isTraceEnabled())
- log_.trace(raw + " parsed to " + noBuddy + " with owner " + owner);
- }
- }
- else
- {
- noBuddy = raw;
- }
- }
- }
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSession.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSession.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSession.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,1393 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.beans.PropertyChangeSupport;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.Serializable;
-import java.security.Principal;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.servlet.http.HttpSessionActivationListener;
-import javax.servlet.http.HttpSessionAttributeListener;
-import javax.servlet.http.HttpSessionBindingEvent;
-import javax.servlet.http.HttpSessionBindingListener;
-import javax.servlet.http.HttpSessionEvent;
-import javax.servlet.http.HttpSessionListener;
-
-import org.apache.catalina.Context;
-import org.apache.catalina.Globals;
-import org.apache.catalina.Session;
-import org.apache.catalina.session.StandardSession;
-import org.apache.catalina.util.Enumerator;
-import org.apache.catalina.util.StringManager;
-import org.jboss.logging.Logger;
-import org.jboss.metadata.WebMetaData;
-
-/**
- * Abstract base class for session clustering based on StandardSession. Different session
- * replication strategy can be implemented such as session- or attribute-based ones.
- *
- * @author Ben Wang
- * @author Brian Stansberry
- *
- * @version $Revision$
- */
-abstract class ClusteredSession
- extends StandardSession
- implements Externalizable
-{
- private static final long serialVersionUID = -758573655613558722L;
- protected static Logger log = Logger.getLogger(ClusteredSession.class);
-
- // ----------------------------------------------------- Instance Variables
- /**
- * Descriptive information describing this Session implementation.
- */
- protected static final String info = "ClusteredSession/1.0";
-
- /**
- * Set of attribute names which are not allowed to be replicated/persisted.
- */
- protected static final String[] excludedAttributes = {
- Globals.SUBJECT_ATTR
- };
-
- /**
- * Set containing all members of {@link #excludedAttributes}.
- */
- protected static final Set replicationExcludes;
- static
- {
- HashSet set = new HashSet();
- for (int i = 0; i < excludedAttributes.length; i++)
- {
- set.add(excludedAttributes[i]);
- }
- replicationExcludes = Collections.unmodifiableSet(set);
- }
-
- protected int invalidationPolicy;
-
- /**
- * If true, means the local in-memory session data contains
- * changes that have not been published to the distributed cache.
- *
- * @deprecated not used
- */
- protected transient boolean isSessionModifiedSinceLastSave;
-
- /**
- * If true, means the local in-memory session data contains metadata
- * changes that have not been published to the distributed cache.
- */
- protected transient boolean sessionMetadataDirty;
-
- /**
- * If true, means the local in-memory session data contains attribute
- * changes that have not been published to the distributed cache.
- */
- protected transient boolean sessionAttributesDirty;
-
- /**
- * The last version that was passed to {@link #setOutdatedVersion} or
- * <code>0</code> if <code>setIsOutdated(false)</code> was subsequently called.
- */
- protected transient int outdatedVersion;
-
- /**
- * The last time {@link #setIsOutdated setIsOutdated(true)} was called or
- * <code>0</code> if <code>setIsOutdated(false)</code> was subsequently called.
- */
- protected transient long outdatedTime;
-
- /**
- * Version number to track cache invalidation. If any new version number is
- * greater than this one, it means the data it holds is newer than this one.
- */
- protected int version;
-
- /**
- * The session's id with any jvmRoute removed.
- */
- protected transient String realId;
-
- /**
- * Whether JK is being used, in which case our realId will
- * not match our id
- */
- private transient boolean useJK;
-
- /**
- * Timestamp when we were last replicated.
- */
- protected transient long lastReplicated;
-
- protected transient int maxUnreplicatedFactor = 80;
-
- protected transient long maxUnreplicatedInterval;
-
- protected transient Boolean hasActivationListener;
-
- /**
- * The string manager for this package.
- */
- protected static StringManager sm =
- StringManager.getManager(ClusteredSession.class.getPackage().getName());
-
- /**
- * Create a new ClusteredSession.
- *
- * @param manager the session's manager
- *
- * @deprecated use {@link ClusteredSession(AbstractJBossManager, boolean)}
- */
- protected ClusteredSession(AbstractJBossManager manager)
- {
- this(manager, false);
- }
-
- protected ClusteredSession(AbstractJBossManager manager, boolean useJK)
- {
- super(manager);
- invalidationPolicy = manager.getInvalidateSessionPolicy();
- this.useJK = useJK;
- calcMaxUnreplicatedInterval();
- }
-
- /**
- * Check to see if the session data is still valid. Outdated here means
- * that the in-memory data is not in sync with one in the data store.
- *
- * @return
- */
- public boolean isOutdated()
- {
- return thisAccessedTime < outdatedTime;
- }
-
- /**
- * Marks this session as outdated or up-to-date vis-a-vis the distributed
- * cache.
- *
- * @param outdated
- *
- * @deprecated use {@link #setOutdatedVersion(int)} and {@link #clearOutdated()}
- */
- public void setIsOutdated(boolean outdated)
- {
- if (outdated)
- outdatedTime = System.currentTimeMillis();
- else
- clearOutdated();
- }
-
- public void setOutdatedVersion(int version)
- {
- this.outdatedVersion = version;
- outdatedTime = System.currentTimeMillis();
- }
-
- public void clearOutdated()
- {
- // Only overwrite the access time if access() hasn't been called
- // since setOutdatedVersion() was called
- if (outdatedTime > thisAccessedTime)
- {
- lastAccessedTime = thisAccessedTime;
- thisAccessedTime = outdatedTime;
- }
- outdatedTime = 0;
-
- // Only overwrite the version if the outdated version is greater
- // Otherwise when we first unmarshal a session that has been
- // replicated many times, we will reset the version to 0
- if (outdatedVersion > version)
- version = outdatedVersion;
-
- outdatedVersion = 0;
- }
-
- public void updateAccessTimeFromOutdatedTime()
- {
- if (outdatedTime > thisAccessedTime)
- {
- lastAccessedTime = thisAccessedTime;
- thisAccessedTime = outdatedTime;
- }
- outdatedTime = 0;
- }
-
- /**
- * Gets the session id with any appended jvmRoute info removed.
- *
- * @see #getUseJK()
- */
- public String getRealId()
- {
- return realId;
- }
-
- private void parseRealId(String sessionId)
- {
- String newId = null;
- if (useJK)
- newId = Util.getRealId(sessionId);
- else
- newId = sessionId;
-
- // realId is used in a lot of map lookups, so only replace it
- // if the new id is actually different -- preserve object identity
- if (!newId.equals(realId))
- realId = newId;
- }
-
- /**
- * This is called specifically for failover case using mod_jk where the new
- * session has this node name in there. As a result, it is safe to just
- * replace the id since the backend store is using the "real" id
- * without the node name.
- *
- * @param id
- */
- public void resetIdWithRouteInfo(String id)
- {
- this.id = id;
- parseRealId(id);
- }
-
- public boolean getUseJK()
- {
- return useJK;
- }
-
- /**
- * Check to see if the input version number is greater than I am. If it is,
- * it means we will need to invalidate the in-memory cache.
- * @param version
- * @return
- */
- public boolean isNewData(int version)
- {
- return (this.version < version);
- }
-
- public int getVersion()
- {
- return version;
- }
-
- public void setVersion(int version)
- {
- this.version = version;
- }
-
- /**
- * There are couple ways to generate this version number.
- * But we will stick with the simple one of incrementing for now.
- *
- * @return the new version
- */
- public int incrementVersion()
- {
- return version++;
- }
-
- /**
- * Gets the maximum percentage of the <code>maxInactiveInterval</code>
- * beyond which a session should be replicated upon access even if it
- * isn't dirty. Used to ensure that even a read-only session gets
- * replicated before it expires, so that it isn't removed from other
- * nodes.
- *
- * @return an int between 1 and 100, or -1 if replicating on access is
- * disabled
- */
- public int getMaxUnreplicatedFactor()
- {
- return maxUnreplicatedFactor;
- }
-
- /**
- * Sets the maximum percentage of the <code>maxInactiveInterval</code>
- * beyond which a session should be replicated upon access even if it
- * isn't dirty. Used to ensure that even a read-only session gets
- * replicated before it expires, so that it isn't removed from other
- * nodes.
- *
- * @param maxUnreplicatedFactor an int between 1 and 100, or -1 to
- * disable replicating on access
- *
- * @throws IllegalArgumentException if the factor isn't -1 or between
- * 1 and 100
- */
- public void setMaxUnreplicatedFactor(int factor)
- {
- if ((factor != -1 && factor < 1) || factor > 100)
- throw new IllegalArgumentException("Invalid factor " + factor +
- " -- must be between 1 and 100 or -1");
- this.maxUnreplicatedFactor = factor;
- calcMaxUnreplicatedInterval();
- }
-
-
- /**
- * Overrides the superclass to calculate
- * {@link #getMaxUnreplicatedInterval() maxUnreplicatedInterval}.
- */
- public void setMaxInactiveInterval(int interval)
- {
- super.setMaxInactiveInterval(interval);
- calcMaxUnreplicatedInterval();
- sessionMetadataDirty();
- }
-
- /**
- * Gets the time {@link #updateLastReplicated()} was last called, or
- * <code>0</code> if it has never been called.
- */
- public long getLastReplicated()
- {
- return lastReplicated;
- }
-
- /**
- * Sets the {@link #getLastReplicated() lastReplicated} field to
- * the current time.
- */
- public void updateLastReplicated()
- {
- lastReplicated = System.currentTimeMillis();
- }
-
- public long getMaxUnreplicatedInterval()
- {
- return maxUnreplicatedInterval;
- }
-
- public boolean getExceedsMaxUnreplicatedInterval()
- {
- boolean result = false;
-
- if (maxUnreplicatedInterval > 0) // -1 means ignore; 0 means expire now
- {
- result = ((System.currentTimeMillis() - lastReplicated) >= maxUnreplicatedInterval);
- }
-
- return result;
- }
-
- private void calcMaxUnreplicatedInterval()
- {
- if (maxInactiveInterval < 0 || maxUnreplicatedFactor < 0)
- maxUnreplicatedInterval = -1;
- else
- maxUnreplicatedInterval = maxInactiveInterval * maxUnreplicatedFactor / 100;
- }
-
- /**
- * This is called after loading a session to initialize the transient values.
- *
- * @param manager
- */
- public abstract void initAfterLoad(AbstractJBossManager manager);
-
- /**
- * Propogate session to the internal store.
- */
- public abstract void processSessionRepl();
-
- /**
- * Remove myself from the internal store.
- */
- public abstract void removeMyself();
-
- /**
- * Remove myself from the <t>local</t> internal store.
- */
- public abstract void removeMyselfLocal();
-
-
- // ----------------------------------------------- Overridden Public Methods
-
- public void access()
- {
- super.access();
-
- if (invalidationPolicy == WebMetaData.SESSION_INVALIDATE_ACCESS)
- {
- this.sessionMetadataDirty();
- }
- }
-
- public Object getAttribute(String name)
- {
-
- if (!isValid())
- throw new IllegalStateException
- (sm.getString("clusteredSession.getAttribute.ise"));
-
- return getAttributeInternal(name);
- }
-
- public Enumeration getAttributeNames()
- {
- if (!isValid())
- throw new IllegalStateException
- (sm.getString("clusteredSession.getAttributeNames.ise"));
-
- return (new Enumerator(getAttributesInternal().keySet(), true));
- }
-
- public void setAttribute(String name, Object value)
- {
- // Name cannot be null
- if (name == null)
- throw new IllegalArgumentException
- (sm.getString("clusteredSession.setAttribute.namenull"));
-
- // Null value is the same as removeAttribute()
- if (value == null)
- {
- removeAttribute(name);
- return;
- }
-
- // Validate our current state
- if (!isValid())
- throw new IllegalStateException
- (sm.getString("clusteredSession.setAttribute.ise"));
- if ((manager != null) && manager.getDistributable() &&
- !(canAttributeBeReplicated(value)))
- throw new IllegalArgumentException
- (sm.getString("clusteredSession.setAttribute.iae"));
-
- // Construct an event with the new value
- HttpSessionBindingEvent event = null;
-
- // Call the valueBound() method if necessary
- if (value instanceof HttpSessionBindingListener)
- {
- event = new HttpSessionBindingEvent(getSession(), name, value);
- try
- {
- ((HttpSessionBindingListener) value).valueBound(event);
- }
- catch (Throwable t)
- {
- manager.getContainer().getLogger().error(sm.getString("standardSession.bindingEvent"), t);
- }
- }
-
- // Replace or add this attribute
- Object unbound = setInternalAttribute(name, value);
-
- // Call the valueUnbound() method if necessary
- if ((unbound != null) && (unbound != value) &&
- (unbound instanceof HttpSessionBindingListener))
- {
- try
- {
- ((HttpSessionBindingListener) unbound).valueUnbound
- (new HttpSessionBindingEvent(getSession(), name));
- }
- catch (Throwable t)
- {
- manager.getContainer().getLogger().error(sm.getString("standardSession.bindingEvent"), t);
- }
- }
-
- // Notify interested application event listeners
- Context context = (Context) manager.getContainer();
- Object listeners[] = context.getApplicationEventListeners();
- if (listeners == null)
- return;
- for (int i = 0; i < listeners.length; i++)
- {
- if (!(listeners[i] instanceof HttpSessionAttributeListener))
- continue;
- HttpSessionAttributeListener listener =
- (HttpSessionAttributeListener) listeners[i];
- try
- {
- if (unbound != null)
- {
- fireContainerEvent(context,
- "beforeSessionAttributeReplaced",
- listener);
- if (event == null)
- {
- event = new HttpSessionBindingEvent
- (getSession(), name, unbound);
- }
- listener.attributeReplaced(event);
- fireContainerEvent(context,
- "afterSessionAttributeReplaced",
- listener);
- }
- else
- {
- fireContainerEvent(context,
- "beforeSessionAttributeAdded",
- listener);
- if (event == null)
- {
- event = new HttpSessionBindingEvent
- (getSession(), name, value);
- }
- listener.attributeAdded(event);
- fireContainerEvent(context,
- "afterSessionAttributeAdded",
- listener);
- }
- }
- catch (Throwable t)
- {
- try
- {
- if (unbound != null)
- {
- fireContainerEvent(context,
- "afterSessionAttributeReplaced",
- listener);
- }
- else
- {
- fireContainerEvent(context,
- "afterSessionAttributeAdded",
- listener);
- }
- }
- catch (Exception e)
- {
- ;
- }
- manager.getContainer().getLogger().error(sm.getString("standardSession.attributeEvent"), t);
- }
- }
- }
-
-
- /**
- * Returns whether the attribute's type is one that can be replicated.
- *
- * @param attribute the attribute
- * @return <code>true</code> if <code>attribute</code> is <code>null</code>,
- * <code>Serializable</code> or an array of primitives.
- */
- protected boolean canAttributeBeReplicated(Object attribute)
- {
- if (attribute instanceof Serializable || attribute == null)
- return true;
- Class clazz = attribute.getClass().getComponentType();
- return (clazz != null && clazz.isPrimitive());
- }
-
- /**
- * Invalidates this session and unbinds any objects bound to it.
- * Overridden here to remove across the cluster instead of just expiring.
- *
- * @exception IllegalStateException if this method is called on
- * an invalidated session
- */
- public void invalidate()
- {
- if (!isValid())
- throw new IllegalStateException(sm.getString("clusteredSession.invalidate.ise"));
-
- // Cause this session to expire globally
- boolean notify = true;
- boolean localCall = true;
- boolean localOnly = false;
- expire(notify, localCall, localOnly);
- }
-
-
- /**
- * Overrides the {@link StandardSession#isValid() superclass method}
- * to call {@ #isValid(boolean) isValid(true)}.
- */
- public boolean isValid()
- {
- return isValid(true);
- }
-
- /**
- * Returns whether the current session is still valid, but
- * only calls {@link #expire(boolean)} for timed-out sessions
- * if <code>expireIfInvalid</code> is <code>true</code>.
- *
- * @param expireIfInvalid <code>true</code> if sessions that have
- * been timed out should be expired
- */
- public boolean isValid(boolean expireIfInvalid)
- {
- if (this.expiring)
- {
- return true;
- }
-
- if (!this.isValid)
- {
- return false;
- }
-
- if (maxInactiveInterval >= 0)
- {
- long timeNow = System.currentTimeMillis();
- int timeIdle = (int) ((timeNow - thisAccessedTime) / 1000L);
- if (timeIdle >= maxInactiveInterval)
- {
- if (expireIfInvalid)
- expire(true);
- else
- return false;
- }
- }
-
- return (this.isValid);
-
- }
-
- /**
- * Expires the session, but in such a way that other cluster nodes
- * are unaware of the expiration.
- *
- * @param notify
- */
- public void expire(boolean notify)
- {
- boolean localCall = true;
- boolean localOnly = true;
- expire(notify, localCall, localOnly);
- }
-
- /**
- * Expires the session, notifying listeners and possibly the manager.
- * <p>
- * <strong>NOTE:</strong> The manager will only be notified of the expiration
- * if <code>localCall</code> is <code>true</code>; otherwise it is the
- * responsibility of the caller to notify the manager that the session is
- * expired. (In the case of JBossCacheManager, it is the manager itself
- * that makes such a call, so it of course is aware).
- * </p>
- *
- * @param notify whether servlet spec listeners should be notified
- * @param localCall <code>true</code> if this call originated due to local
- * activity (such as a session invalidation in user code
- * or an expiration by the local background processing
- * thread); <code>false</code> if the expiration
- * originated due to some kind of event notification
- * from the cluster.
- * @param localOnly <code>true</code> if the expiration should not be
- * announced to the cluster, <code>false</code> if other
- * cluster nodes should be made aware of the expiration.
- * Only meaningful if <code>localCall</code> is
- * <code>true</code>.
- */
- public void expire(boolean notify, boolean localCall, boolean localOnly)
- {
- if (log.isDebugEnabled())
- {
- log.debug("The session has expired with id: " + id +
- " -- is it local? " + localOnly);
- }
-
- // If another thread is already doing this, stop
- if (expiring)
- return;
-
- synchronized (this)
- {
- // If we had a race to this sync block, another thread may
- // have already completed expiration. If so, don't do it again
- if (!isValid)
- return;
-
- if (manager == null)
- return;
-
- expiring = true;
-
- // Notify interested application event listeners
- // FIXME - Assumes we call listeners in reverse order
- Context context = (Context) manager.getContainer();
- Object listeners[] = context.getApplicationLifecycleListeners();
- if (notify && (listeners != null))
- {
- HttpSessionEvent event =
- new HttpSessionEvent(getSession());
- for (int i = 0; i < listeners.length; i++)
- {
- int j = (listeners.length - 1) - i;
- if (!(listeners[j] instanceof HttpSessionListener))
- continue;
- HttpSessionListener listener =
- (HttpSessionListener) listeners[j];
- try
- {
- fireContainerEvent(context,
- "beforeSessionDestroyed",
- listener);
- listener.sessionDestroyed(event);
- fireContainerEvent(context,
- "afterSessionDestroyed",
- listener);
- }
- catch (Throwable t)
- {
- try
- {
- fireContainerEvent(context,
- "afterSessionDestroyed",
- listener);
- }
- catch (Exception e)
- {
- ;
- }
- manager.getContainer().getLogger().error(sm.getString("standardSession.sessionEvent"), t);
- }
- }
- }
-
- // Notify interested session event listeners.
- if (notify)
- {
- fireSessionEvent(Session.SESSION_DESTROYED_EVENT, null);
- }
-
- // JBAS-1360 -- Unbind any objects associated with this session
- String keys[] = keys();
- for (int i = 0; i < keys.length; i++)
- removeAttributeInternal(keys[i], localCall, localOnly, notify);
-
- // Remove this session from our manager's active sessions
- removeFromManager(localCall, localOnly);
-
- // We have completed expire of this session
- setValid(false);
- expiring = false;
- }
-
- }
-
- /**
- * Advise our manager to remove this expired session.
- *
- * @param localCall whether this call originated from local activity
- * or from a remote invalidation. In this default
- * implementation, this parameter is ignored.
- * @param localOnly whether the rest of the cluster should be made aware
- * of the removal
- */
- protected void removeFromManager(boolean localCall, boolean localOnly)
- {
- if(localOnly)
- {
- ((AbstractJBossManager) manager).removeLocal(this);
- }
- else
- {
- manager.remove(this);
- }
- }
-
- public void passivate()
- {
- // Notify interested session event listeners
- fireSessionEvent(Session.SESSION_PASSIVATED_EVENT, null);
-
- if (hasActivationListener != Boolean.FALSE)
- {
- boolean hasListener = false;
-
- // Notify ActivationListeners
- HttpSessionEvent event = null;
- String keys[] = keys();
- Map attrs = getAttributesInternal();
- for (int i = 0; i < keys.length; i++)
- {
- Object attribute = attrs.get(keys[i]);
- if (attribute instanceof HttpSessionActivationListener)
- {
- hasListener = true;
-
- if (event == null)
- event = new HttpSessionEvent(getSession());
- try
- {
- ((HttpSessionActivationListener)attribute).sessionWillPassivate(event);
- }
- catch (Throwable t)
- {
- manager.getContainer().getLogger().error
- (sm.getString("clusteredSession.attributeEvent"), t);
- }
- }
- }
-
- hasActivationListener = hasListener ? Boolean.TRUE : Boolean.FALSE;
- }
- }
-
- public void activate()
- {
- // Notify interested session event listeners
- fireSessionEvent(Session.SESSION_ACTIVATED_EVENT, null);
-
- if (hasActivationListener != Boolean.FALSE)
- {
- // Notify ActivationListeners
-
- boolean hasListener = false;
-
- HttpSessionEvent event = null;
- String keys[] = keys();
- Map attrs = getAttributesInternal();
- for (int i = 0; i < keys.length; i++)
- {
- Object attribute = attrs.get(keys[i]);
- if (attribute instanceof HttpSessionActivationListener)
- {
- hasListener = true;
- if (event == null)
- event = new HttpSessionEvent(getSession());
- try
- {
- ((HttpSessionActivationListener)attribute).sessionDidActivate(event);
- }
- catch (Throwable t)
- {
- manager.getContainer().getLogger().error
- (sm.getString("clusteredSession.attributeEvent"), t);
- }
- }
- }
-
- hasActivationListener = hasListener ? Boolean.TRUE : Boolean.FALSE;
- }
- }
-
- // TODO uncomment when work on JBAS-1900 is completed
-// public void removeNote(String name)
-// {
-// // FormAuthenticator removes the username and password because
-// // it assumes they are not needed if the Principal is cached,
-// // but they are needed if the session fails over, so ignore
-// // the removal request.
-// // TODO discuss this on Tomcat dev list to see if a better
-// // way of handling this can be found
-// if (Constants.SESS_USERNAME_NOTE.equals(name)
-// || Constants.SESS_PASSWORD_NOTE.equals(name))
-// {
-// if (log.isDebugEnabled())
-// {
-// log.debug("removeNote(): ignoring removal of note " + name);
-// }
-// }
-// else
-// {
-// super.removeNote(name);
-// }
-//
-// }
-
- // TODO uncomment when work on JBAS-1900 is completed
-// public void setNote(String name, Object value)
-// {
-// super.setNote(name, value);
-//
-// if (Constants.SESS_USERNAME_NOTE.equals(name)
-// || Constants.SESS_PASSWORD_NOTE.equals(name))
-// {
-// sessionIsDirty();
-// }
-// }
-
- /**
- * Override the superclass to additionally reset this class' fields.
- * <p>
- * <strong>NOTE:</strong> It is not anticipated that this method will be
- * called on a ClusteredSession, but we are overriding the method to be
- * thorough.
- * </p>
- */
- public void recycle()
- {
- super.recycle();
-
- // Fields that the superclass isn't clearing
- listeners.clear();
- support = new PropertyChangeSupport(this);
-
- invalidationPolicy = 0;
- outdatedTime = 0;
- outdatedVersion = 0;
- sessionAttributesDirty = false;
- sessionMetadataDirty = false;
- realId = null;
- useJK = false;
- version = 0;
- hasActivationListener = null;
- lastReplicated = 0;
- maxUnreplicatedFactor = 80;
- calcMaxUnreplicatedInterval();
- }
-
- /**
- * Set the creation time for this session. This method is called by the
- * Manager when an existing Session instance is reused.
- *
- * @param time The new creation time
- */
- public void setCreationTime(long time)
- {
- super.setCreationTime(time);
- sessionMetadataDirty();
- }
-
- /**
- * Overrides the superclass method to also set the
- * {@link #getRealId() realId} property.
- */
- public void setId(String id)
- {
- // Parse the real id first, as super.setId() calls add(),
- // which depends on having the real id
- parseRealId(id);
- super.setId(id);
- }
-
- /**
- * Set the authenticated Principal that is associated with this Session.
- * This provides an <code>Authenticator</code> with a means to cache a
- * previously authenticated Principal, and avoid potentially expensive
- * <code>Realm.authenticate()</code> calls on every request.
- *
- * @param principal The new Principal, or <code>null</code> if none
- */
- public void setPrincipal(Principal principal)
- {
-
- Principal oldPrincipal = this.principal;
- this.principal = principal;
- support.firePropertyChange("principal", oldPrincipal, this.principal);
-
- if ((oldPrincipal != null && !oldPrincipal.equals(principal)) ||
- (oldPrincipal == null && principal != null))
- sessionMetadataDirty();
-
- }
-
- public void setNew(boolean isNew)
- {
- super.setNew(isNew);
- sessionMetadataDirty();
- }
-
- public void setValid(boolean isValid)
- {
- super.setValid(isValid);
- sessionMetadataDirty();
- }
-
- public String toString()
- {
- StringBuffer buf = new StringBuffer();
- buf.append("id: " +id).append(" lastAccessedTime: " +lastAccessedTime).append(
- " version: " +version).append(" lastOutdated: " + outdatedTime);
-
- return buf.toString();
- }
-
- // --------------------------------------------------------- Externalizable
-
- /**
- * Reads all non-transient state from the ObjectOutput <i>except
- * the attribute map</i>. Subclasses that wish the attribute map
- * to be read should override this method and
- * {@link #writeExternal(ObjectOutput) writeExternal()}.
- *
- * <p>
- * This method is deliberately public so it can be used to reset
- * the internal state of a session object using serialized
- * contents replicated from another JVM via JBossCache.
- * </p>
- *
- * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
- */
- public void readExternal(ObjectInput in)
- throws IOException, ClassNotFoundException
- {
- synchronized (this)
- {
- // From StandardSession
- id = in.readUTF();
- creationTime = in.readLong();
- lastAccessedTime = in.readLong();
- maxInactiveInterval = in.readInt();
- isNew = in.readBoolean();
- isValid = in.readBoolean();
- thisAccessedTime = in.readLong();
-
- // From ClusteredSession
- invalidationPolicy = in.readInt();
- version = in.readInt();
-
- // Get our id without any jvmRoute appended
- parseRealId(id);
-
- // We no longer know if we have an activationListener
- hasActivationListener = null;
-
- // TODO uncomment when work on JBAS-1900 is completed
-// // Session notes -- for FORM auth apps, allow replicated session
-// // to be used without requiring a new login
-// // We use the superclass set/removeNote calls here to bypass
-// // the custom logic we've added
-// String username = (String) in.readObject();
-// if (username != null)
-// {
-// super.setNote(Constants.SESS_USERNAME_NOTE, username);
-// }
-// else
-// {
-// super.removeNote(Constants.SESS_USERNAME_NOTE);
-// }
-// String password = (String) in.readObject();
-// if (password != null)
-// {
-// super.setNote(Constants.SESS_PASSWORD_NOTE, password);
-// }
-// else
-// {
-// super.removeNote(Constants.SESS_PASSWORD_NOTE);
-// }
- }
- }
-
-
- /**
- * Writes all non-transient state to the ObjectOutput <i>except
- * the attribute map</i>. Subclasses that wish the attribute map
- * to be written should override this method and append it.
- *
- * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
- */
- public void writeExternal(ObjectOutput out)
- throws IOException
- {
- synchronized (this)
- {
- // From StandardSession
- out.writeUTF(id);
- out.writeLong(creationTime);
- out.writeLong(lastAccessedTime);
- out.writeInt(maxInactiveInterval);
- out.writeBoolean(isNew);
- out.writeBoolean(isValid);
- out.writeLong(thisAccessedTime);
-
- // From ClusteredSession
- out.writeInt(invalidationPolicy);
- out.writeInt(version);
-
- // TODO uncomment when work on JBAS-1900 is completed
-// // Session notes -- for FORM auth apps, allow replicated session
-// // to be used without requiring a new login
-// String username = (String) getNote(Constants. SESS_USERNAME_NOTE);
-// log.debug(Constants.SESS_USERNAME_NOTE + " = " + username);
-// out.writeObject(username);
-// String password = (String) getNote(Constants.SESS_PASSWORD_NOTE);
-// log.debug(Constants.SESS_PASSWORD_NOTE + " = " + password);
-// out.writeObject(password);
- }
- }
-
- // ----------------------------------------------------- Protected Methods
-
- /**
- * Removes any attribute whose name is found in {@link #excludedAttributes}
- * from <code>attributes</code> and returns a Map of all such attributes.
- *
- * @param attributes source map from which excluded attributes are to be
- * removed.
- *
- * @return Map that contains any attributes removed from
- * <code>attributes</code>, or <code>null</code> if no attributes
- * were removed.
- */
- protected static Map removeExcludedAttributes(Map attributes)
- {
- Map excluded = null;
- for (int i = 0; i < excludedAttributes.length; i++) {
- Object attr = attributes.remove(excludedAttributes[i]);
- if (attr != null)
- {
- if (log.isTraceEnabled())
- {
- log.trace("Excluding attribute " + excludedAttributes[i] +
- " from replication");
- }
- if (excluded == null)
- {
- excluded = new HashMap();
- }
- excluded.put(excludedAttributes[i], attr);
- }
- }
-
- return excluded;
- }
-
- // -------------------------------------- Internal protected method override
-
- /**
- * Method inherited from Tomcat. Return zero-length based string if not found.
- */
- protected String[] keys()
- {
- return ((String[]) getAttributesInternal().keySet().toArray(EMPTY_ARRAY));
- }
-
- /**
- * Called by super.removeAttribute().
- *
- * @param name the attribute name
- * @param notify <code>true</code> if listeners should be notified
- */
- protected void removeAttributeInternal(String name, boolean notify)
- {
- boolean localCall = true;
- boolean localOnly = false;
- removeAttributeInternal(name, localCall, localOnly, notify);
- }
-
- /**
- * Remove the attribute from the local cache and possibly the distributed
- * cache, plus notify any listeners
- *
- * @param name the attribute name
- * @param localCall <code>true</code> if this call originated from local
- * activity (e.g. a removeAttribute() in the webapp or a
- * local session invalidation/expiration),
- * <code>false</code> if it originated due to an remote
- * event in the distributed cache.
- * @param localOnly <code>true</code> if the removal should not be
- * replicated around the cluster
- * @param notify <code>true</code> if listeners should be notified
- */
- protected void removeAttributeInternal(String name,
- boolean localCall,
- boolean localOnly,
- boolean notify)
- {
- // Remove this attribute from our collection
- Object value = removeAttributeInternal(name, localCall, localOnly);
-
- // Do we need to do valueUnbound() and attributeRemoved() notification?
- if (!notify || (value == null))
- {
- return;
- }
-
- // Call the valueUnbound() method if necessary
- HttpSessionBindingEvent event = null;
- if (value instanceof HttpSessionBindingListener)
- {
- event = new HttpSessionBindingEvent(getSession(), name, value);
- ((HttpSessionBindingListener) value).valueUnbound(event);
- }
-
- // Notify interested application event listeners
- Context context = (Context) manager.getContainer();
- Object listeners[] = context.getApplicationEventListeners();
- if (listeners == null)
- return;
- for (int i = 0; i < listeners.length; i++)
- {
- if (!(listeners[i] instanceof HttpSessionAttributeListener))
- continue;
- HttpSessionAttributeListener listener =
- (HttpSessionAttributeListener) listeners[i];
- try
- {
- fireContainerEvent(context,
- "beforeSessionAttributeRemoved",
- listener);
- if (event == null)
- {
- event = new HttpSessionBindingEvent
- (getSession(), name, value);
- }
- listener.attributeRemoved(event);
- fireContainerEvent(context,
- "afterSessionAttributeRemoved",
- listener);
- }
- catch (Throwable t)
- {
- try
- {
- fireContainerEvent(context,
- "afterSessionAttributeRemoved",
- listener);
- }
- catch (Exception e)
- {
- ;
- }
- manager.getContainer().getLogger().error(sm.getString("standardSession.attributeEvent"), t);
- }
- }
-
- }
-
- /**
- * Exists in this class solely to act as an API-compatible bridge to the
- * deprecated {@link #removeJBossInternalAttribute(String)}.
- * JBossCacheClusteredSession subclasses will override this to call their
- * own methods that make use of localCall and localOnly
- *
- * @param name
- * @param localCall
- * @param localOnly
- * @return
- *
- * @deprecated will be replaced by removeJBossInternalAttribute(String, boolean, boolean)
- */
- protected Object removeAttributeInternal(String name,
- boolean localCall,
- boolean localOnly)
- {
- return removeJBossInternalAttribute(name);
- }
-
- protected Object getAttributeInternal(String name)
- {
- return getJBossInternalAttribute(name);
- }
-
- protected Map getAttributesInternal()
- {
- return getJBossInternalAttributes();
- }
-
- protected Object setInternalAttribute(String name, Object value)
- {
- if (value instanceof HttpSessionActivationListener)
- hasActivationListener = Boolean.TRUE;
-
- return setJBossInternalAttribute(name, value);
- }
-
- // ------------------------------------------ JBoss internal abstract method
-
- protected abstract Object getJBossInternalAttribute(String name);
-
- /** @deprecated will be replaced by removeJBossInternalAttribute(String, boolean, boolean) */
- protected abstract Object removeJBossInternalAttribute(String name);
-
- protected abstract Map getJBossInternalAttributes();
-
- protected abstract Object setJBossInternalAttribute(String name, Object value);
-
- // ------------------------------------------------ Session Package Methods
-
- protected void sessionAttributesDirty()
- {
- sessionAttributesDirty = true;
- }
-
- protected boolean getSessionAttributesDirty()
- {
- return sessionAttributesDirty;
- }
-
- protected void sessionMetadataDirty()
- {
- sessionMetadataDirty = true;
- }
-
- protected boolean getSessionMetadataDirty()
- {
- return sessionMetadataDirty;
- }
-
- /**
- * Calls {@link #sessionAttributesDirty()} and
- * {@link #sessionMetadataDirty()}.
- *
- * @deprecated use one of the more fine-grained methods.
- */
- protected void sessionDirty()
- {
- sessionAttributesDirty();
- sessionMetadataDirty();
- }
-
- public boolean isSessionDirty()
- {
- return sessionAttributesDirty || sessionMetadataDirty;
- }
-
- public boolean getReplicateSessionBody()
- {
- return sessionMetadataDirty || getExceedsMaxUnreplicatedInterval();
- }
-
- protected boolean isGetDirty(Object attribute)
- {
- boolean result = false;
- switch (invalidationPolicy)
- {
- case (WebMetaData.SESSION_INVALIDATE_SET_AND_GET):
- result = true;
- break;
- case (WebMetaData.SESSION_INVALIDATE_SET_AND_NON_PRIMITIVE_GET):
- result = isMutable(attribute);
- break;
- default:
- // result is false
- }
- return result;
- }
-
- protected boolean isMutable(Object attribute)
- {
- return attribute != null &&
- !(attribute instanceof String ||
- attribute instanceof Number ||
- attribute instanceof Character ||
- attribute instanceof Boolean);
- }
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSessionValve.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSessionValve.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteredSessionValve.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,146 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.io.IOException;
-import javax.servlet.http.HttpSession;
-import javax.servlet.ServletException;
-
-import org.apache.catalina.*;
-import org.apache.catalina.connector.Request;
-import org.apache.catalina.connector.Response;
-import org.apache.catalina.util.LifecycleSupport;
-import org.apache.catalina.valves.ValveBase;
-
-/**
- * This Valve detects all sessions that were used in a request. All sessions are given to a snapshot
- * manager that handles the distribution of modified sessions.
- * <p/>
- * TOMCAT 4.1.12 UPDATE: Added findLifecycleListeners() to comply with the latest
- * Lifecycle interface.
- *
- * @author Thomas Peuss <jboss at peuss.de>
- * @version $Revision$
- */
-public class ClusteredSessionValve extends ValveBase implements Lifecycle
-{
- // The info string for this Valve
- private static final String info = "ClusteredSessionValve/1.0";
-
- // The SnapshotManager that is associated with this Valve
- protected SnapshotManager snapshot;
-
- // Valve-lifecycle_ helper object
- protected LifecycleSupport support = new LifecycleSupport(this);
-
- // store the request and response object for parts of the clustering code that
- // have no direct access to this objects
- protected static final ThreadLocal requestThreadLocal = new ThreadLocal();
- protected static final ThreadLocal responseThreadLocal = new ThreadLocal();
- // Manager may store a ref to session id's it has handled here
- protected static final ThreadLocal sessionIdThreadLocal = new ThreadLocal();
-
- /**
- * Create a new Valve.
- *
- * @param snapshot The SnapshotManager associated with this Valve
- */
- public ClusteredSessionValve(SnapshotManager snapshot)
- {
- super();
- this.snapshot = snapshot;
- }
-
- /**
- * Get information about this Valve.
- */
- public String getInfo()
- {
- return info;
- }
-
- /**
- * Valve-chain handler method.
- * This method gets called when the request goes through the Valve-chain. Our session replication mechanism replicates the
- * session after request got through the servlet code.
- *
- * @param request The request object associated with this request.
- * @param response The response object associated with this request.
- */
- public void invoke(Request request, Response response) throws IOException, ServletException
- {
- // Store the request and response object for the clustering code that has no direct access to
- // this objects
- requestThreadLocal.set(request);
- responseThreadLocal.set(response);
-
- // let the servlet invocation go through
- getNext().invoke(request, response);
-
- // --> We are now after the servlet invocation
-
- // Get the session
- HttpSession session = request.getSession(false);
-
- if (session != null && session.getId() != null)
- {
- // tell the snapshot manager that this session was modified
- snapshot.snapshot(session.getId());
- }
-
- // don't leak references to the request and response objects
- requestThreadLocal.set(null);
- responseThreadLocal.set(null);
-
- // If JBossCacheManager stored a ref to a session id, we need to clear it
- sessionIdThreadLocal.set(null);
- }
-
- // Lifecylce-interface
- public void addLifecycleListener(LifecycleListener listener)
- {
- support.addLifecycleListener(listener);
- }
-
- public void removeLifecycleListener(LifecycleListener listener)
- {
- support.removeLifecycleListener(listener);
- }
-
- public LifecycleListener[] findLifecycleListeners()
- {
- return support.findLifecycleListeners();
- }
-
- public void start() throws LifecycleException
- {
- snapshot.start();
- support.fireLifecycleEvent(START_EVENT, this);
- }
-
- public void stop() throws LifecycleException
- {
- support.fireLifecycleEvent(STOP_EVENT, this);
- snapshot.stop();
- }
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteringNotSupportedException.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteringNotSupportedException.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/ClusteringNotSupportedException.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,38 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-
-/**
- * This exception is thrown when the clustered HTTPSession-service
- * is not found
- *
- * @author Thomas Peuss <jboss at peuss.de>
- * @version $Revision$
- */
-public class ClusteringNotSupportedException extends Exception
-{
- public ClusteringNotSupportedException(String message)
- {
- super(message);
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/FieldBasedClusteredSession.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/FieldBasedClusteredSession.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/FieldBasedClusteredSession.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,363 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import org.jboss.aspects.patterns.observable.Observer;
-import org.jboss.aspects.patterns.observable.Subject;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.servlet.http.HttpSessionActivationListener;
-
-/**
- * <p>
- * Implementation of a clustered session for JBossCacheManager. The replication granularity
- * level is field based; that is, we replicate only the dirty field in a POJO that is part of
- * a session attribute. E.g., once a user do setAttribute("pojo", pojo), pojo will be monitored
- * automatically for field changes and accessing. It offers couple of advantages:
- * <ul>
- * <li>pojo.setName(), for example, will only replicate the name field in the pojo. And thus is more efficient.</li>
- * <li>If pojo has a complex object graph, we will handle that automtically providing that the
- * children object is also aspectized.</li>
- * </ul>
- * Note that in current version, all the attributes and its associated childre graph objects are
- * required to be aspectized. That is, you can't simply declare them as Serializable. This is restricted
- * because of the marshalling/unmarshalling issue.</p>
- *
- * <p>We use JBossCache for our internal, replicated data store.
- * The internal structure is like in JBossCache:
- * <pre>
- * /JSESSION
- * /hostname
- * /web_app_path (path + session id is unique)
- * /id Map(id, session)
- * (VERSION, version)
- * /ATTRIBUTE Map(can be empty)
- * /pojo Map(field name, field value) (pojo naming is by field.getName())
- *
- * </pre>
- * <p/>
- *
- * @author Ben Wang
- * @author Brian Stansberry
- *
- * @version $Revision$
- */
-class FieldBasedClusteredSession
- extends JBossCacheClusteredSession implements Observer
-{
- /** The serialVersionUID */
- private static final long serialVersionUID = 8347544395334247623L;
-
- /**
- * Descriptive information describing this Session implementation.
- */
- protected static final String info = "FieldBasedClusteredSession/1.0";
-
- protected transient Map attributes_ = Collections.synchronizedMap(new HashMap());
-
- public FieldBasedClusteredSession(JBossCacheManager manager)
- {
- super(manager);
- }
-
- // ----------------------------------------------- Overridden Public Methods
-
-
- /**
- * Override the superclass to additionally reset this class' fields.
- * <p>
- * <strong>NOTE:</strong> It is not anticipated that this method will be
- * called on a ClusteredSession, but we are overriding the method to be
- * thorough.
- * </p>
- */
- public void recycle()
- {
- super.recycle();
-
- attributes_.clear();
- }
-
- /**
- * Return a string representation of this object.
- */
- public String toString()
- {
-
- StringBuffer sb = new StringBuffer();
- sb.append("FieldBasedClusteredSession[");
- sb.append(super.toString());
- sb.append("]");
- return (sb.toString());
-
- }
-
- // The superclass version of processSessionRepl is fine; it will remove
- // the session metadata, and any attribute changes have been picked up
- // for replication as they were made; no need to do anything here
-// public synchronized void processSessionRepl()
-// {
-// super.processSessionRepl();
-// }
-
- public void removeMyself()
- {
- // This is a shortcut to remove session and it's child attributes.
- // Note that there is no need to remove attribute first since caller
- // will do that already.
- proxy_.removeSession(realId);
- }
-
- public void removeMyselfLocal()
- {
- // Need to evict attribute first before session to clean up everything.
- // Note that there is no need to remove attributes first since caller
- // will do that already.
- // BRIAN -- the attributes *are* already evicted, but we leave the
- // removePojosLocal call here in order to evict the ATTRIBUTE node.
- // Otherwise empty nodes for the session root and child ATTRIBUTE will
- // remain in the tree and screw up our list of session names.
- proxy_.removePojosLocal(realId);
- proxy_.removeSessionLocal(realId);
- }
-
- // ------------------------------------------------ JBoss internal abstract method
-
- /**
- * Populate the attributes stored in the distributed store to the local
- * transient map. Add ourself as an Observer to newly found attributes and
- * remove ourself as an Observer to existing attributes that are no longer
- * in the distributed store.
- */
- protected void populateAttributes()
- {
- // Preserve any local attributes that were excluded from replication
- Map excluded = removeExcludedAttributes(attributes_);
-
- Set keys = proxy_.getPojoKeys(realId);
- Set oldKeys = new HashSet(attributes_.keySet());
-
- // Since we are going to touch each attribute, might as well
- // check if we have any HttpSessionActivationListener
- boolean hasListener = false;
-
- if (keys != null)
- {
- oldKeys.removeAll(keys); // only keys that no longer exist are left
-
- for (Iterator it = keys.iterator(); it.hasNext(); )
- {
- String name = (String) it.next();
-
- Object oldAttrib = null;
- Object newAttrib = proxy_.getPojo(realId, name);
- if (newAttrib != null)
- {
- oldAttrib = attributes_.put(name, newAttrib);
-
- if (oldAttrib != newAttrib)
- {
- // Need to observe this pojo as well
- // for any modification events.
- proxy_.addObserver(this, newAttrib);
-
- // Stop observing the old pojo
- proxy_.removeObserver(this, oldAttrib); // null pojo OK :)
- }
-
- // Check if we have a listener
- if (newAttrib instanceof HttpSessionActivationListener)
- hasListener = true;
- }
- else
- {
- // This shouldn't happen -- if we had a key, newAttrib s/b not null
-
- oldAttrib = attributes_.remove(name);
- // Stop observing this pojo
- proxy_.removeObserver(this, oldAttrib); // null pojo OK :)
-
- }
- }
- }
-
- hasActivationListener = hasListener ? Boolean.TRUE : Boolean.FALSE;
-
- // Cycle through remaining old keys and remove them
- // and also remove ourself as Observer
- for (Iterator it = oldKeys.iterator(); it.hasNext(); )
- {
- Object oldAttrib = attributes_.remove(it.next());
- proxy_.removeObserver(this, oldAttrib);
- }
-
- // Restore any excluded attributes
- if (excluded != null)
- attributes.putAll(excluded);
- }
-
- protected Object getJBossInternalAttribute(String name)
- {
- // Check the local map first.
- Object result = attributes_.get(name);
-
- // NOTE -- we no longer check with the store. Attributes are only
- // loaded from store during populateAttributes() call at beginning
- // of request when we notice we are outdated.
-
- // Do dirty check even if result is null, as w/ SET_AND_GET null
- // still makes us dirty (ensures timely replication w/o using ACCESS)
- if (isGetDirty(result))
- {
- sessionAttributesDirty();
- }
-
- return result;
- }
-
- /**
- * Overrides the superclass to treat classes implementing Subject
- * as "immutable", since as an Observer we will detect any changes
- * to those types.
- */
- protected boolean isMutable(Object attribute)
- {
- boolean pojo = (attribute instanceof Subject);
- boolean mutable = (!pojo && super.isMutable(attribute));
- return mutable;
- }
-
- protected Object removeJBossInternalAttribute(String name, boolean localCall, boolean localOnly)
- {
- // Remove it from the underlying store
- if (localCall && !replicationExcludes.contains(name))
- {
- if (localOnly)
- proxy_.removePojoLocal(realId, name);
- else
- proxy_.removePojo(realId, name);
-
- sessionAttributesDirty();
- }
- Object result = attributes_.remove(name);
- if(result == null)
- {
- log.warn("removeJBossInternalAttribute(): null value to remove with key: "+ name);
- return null;
- }
- proxy_.removeObserver(this, result);
-
- return result;
- }
-
- protected Map getJBossInternalAttributes()
- {
- return attributes_;
- }
-
- protected Set getJBossInternalKeys()
- {
- return attributes_.keySet();
- }
-
- /**
- * Method inherited from Tomcat. Return zero-length based string if not found.
- */
- protected String[] keys()
- {
- return ((String[]) getJBossInternalKeys().toArray(EMPTY_ARRAY));
- }
-
- /**
- * Overrides the superclass to allow instrumented classes and
- * non-serializable Collections and Maps.
- */
- protected boolean canAttributeBeReplicated(Object attribute)
- {
- return (Util.checkPojoType(attribute));
- }
-
- /**
- * This is the hook for setAttribute. Note that in this FieldBasedClusteredSession using aop,
- * user should not call setAttribute call too often since this will re-connect the attribute with the internal
- * cache (and this is expensive).
- * @param key
- * @param value
- * @return Object
- */
- protected Object setJBossInternalAttribute(String key, Object value)
- {
- Object oldVal = null;
- if (!replicationExcludes.contains(key))
- {
- oldVal = proxy_.setPojo(realId, key, value);
- if(oldVal != null)
- { // We are done with the old one.
- proxy_.removeObserver(this, oldVal);
- }
-
- if(value != null)
- {
- // Special case for Collection classes.
- if( value instanceof Map || value instanceof List || value instanceof Set)
- {
- // We need to obtain the proxy first.
- value = proxy_.getPojo(realId, key);
- }
-
- // Need to use obj since it can return as a proxy.
- proxy_.addObserver(this, value);
- }
-
- // Only mark session dirty if we can replicate the attribute
- sessionAttributesDirty();
- }
-
- // Still need to put it in the map to track locally.
- oldVal = attributes_.put(key, value);
-
- return oldVal;
- }
-
- /**
- * Call back handler for the aop Subject/Observer pattern.
- * We subscribe to the event of field write and mark ourself dirty.
- *
- * @param subject the object we are Observing
- */
- public void fireChange(Subject subject)
- {
- // Currently we don't care who is modified, we will simply mark session is dirty for replication purpose.
- if(log.isTraceEnabled())
- {
- log.trace("fireChange(): subject has changed: " +subject);
- }
- sessionAttributesDirty();
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/InstantSnapshotManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/InstantSnapshotManager.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/InstantSnapshotManager.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,67 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import org.apache.catalina.Session;
-import org.jboss.logging.Logger;
-
-/**
- * A concrete implementation of the snapshot manager interface
- * that does instant replication of a modified session
- *
- * @author Thomas Peuss <jboss at peuss.de>
- * @version $Revision$
- */
-public class InstantSnapshotManager extends SnapshotManager
-{
- static Logger log = Logger.getLogger(InstantSnapshotManager.class);
-
- public InstantSnapshotManager(AbstractJBossManager manager, String path)
- {
- super(manager, path);
- }
-
- /**
- * Instant replication of the modified session
- */
- public void snapshot(String id)
- {
- try
- {
- // find the session that has been modified
- Session session = manager.findSession(id);
- manager.storeSession(session);
- }
- catch (Exception e)
- {
- log.warn("Failed to replicate sessionID:" + id, e);
- }
- }
-
- public void start()
- {
- }
-
- public void stop()
- {
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/IntervalSnapshotManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/IntervalSnapshotManager.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/IntervalSnapshotManager.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,190 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.util.HashMap;
-import java.util.Iterator;
-
-import org.apache.catalina.Context;
-import org.apache.catalina.Session;
-import org.jboss.logging.Logger;
-
-/**
- * A snapshot manager that collects all modified sessions over a given
- * period of time and distributes them en bloc.
- *
- * @author Thomas Peuss <jboss at peuss.de>
- * @version $Revision$
- */
-public class IntervalSnapshotManager extends SnapshotManager implements Runnable
-{
- static Logger log = Logger.getLogger(IntervalSnapshotManager.class);
-
- // the interval in ms
- protected int interval = 1000;
-
- // the modified sessions
- protected HashMap sessions = new HashMap();
-
- // the distribute thread
- protected Thread thread = null;
-
- // has the thread finished?
- protected boolean threadDone = false;
-
- public IntervalSnapshotManager(AbstractJBossManager manager, String path)
- {
- super(manager, path);
- }
-
- public IntervalSnapshotManager(AbstractJBossManager manager, String path, int interval)
- {
- super(manager, path);
- this.interval = interval;
- }
-
- /**
- * Store the modified session in a hashmap for the distributor thread
- */
- public void snapshot(String id)
- {
- try
- {
- Session session = (Session) manager.findSession(id);
- synchronized (sessions)
- {
- sessions.put(id, session);
- }
- }
- catch (Exception e)
- {
- log.warn("Failed to replicate sessionID:" + id, e);
- }
- }
-
- /**
- * Distribute all modified sessions
- */
- protected void processSessions()
- {
- HashMap copy = new HashMap(sessions.size());
-
- synchronized (sessions)
- {
- copy.putAll(sessions);
- sessions.clear();
- }
- Iterator iter = copy.values().iterator();
-
- // distribute all modified sessions using default replication type
- while (iter.hasNext())
- {
- Session session = (Session) iter.next();
- manager.storeSession(session);
- }
- copy.clear();
- }
-
- /**
- * Start the snapshot manager
- */
- public void start()
- {
- startThread();
- }
-
- /**
- * Stop the snapshot manager
- */
- public void stop()
- {
- stopThread();
- synchronized (sessions)
- {
- sessions.clear();
- }
- }
-
- /**
- * Start the distributor thread
- */
- protected void startThread()
- {
- if (thread != null)
- {
- return;
- }
-
- thread = new Thread(this, "ClusteredSessionDistributor[" + contextPath + "]");
- thread.setDaemon(true);
- thread.setContextClassLoader(manager.getContainer().getLoader().getClassLoader());
- threadDone = false;
- thread.start();
- }
-
- /**
- * Stop the distributor thread
- */
- protected void stopThread()
- {
- if (thread == null)
- {
- return;
- }
- threadDone = true;
- thread.interrupt();
- try
- {
- thread.join();
- }
- catch (InterruptedException e)
- {
- }
- thread = null;
- }
-
- /**
- * Little Thread - sleep awhile...
- */
- protected void threadSleep()
- {
- try
- {
- Thread.sleep(interval);
- }
- catch (InterruptedException e)
- {
- }
- }
-
- /**
- * Thread-loop
- */
- public void run()
- {
- while (!threadDone)
- {
- threadSleep();
- processSessions();
- }
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheCluster.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheCluster.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheCluster.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,949 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.ObjectName;
-
-import org.apache.catalina.Container;
-import org.apache.catalina.Engine;
-import org.apache.catalina.Host;
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.Manager;
-import org.apache.catalina.core.ContainerBase;
-import org.apache.catalina.util.LifecycleSupport;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.BatchModeTransactionManagerLookup;
-import org.jboss.cache.PropertyConfigurator;
-import org.jboss.cache.aop.PojoCache;
-import org.jboss.cache.aop.PojoCacheMBean;
-import org.jboss.mx.util.MBeanProxyExt;
-import org.jboss.mx.util.MBeanServerLocator;
-import org.jboss.web.tomcat.tc5.Tomcat5;
-
-/**
- * A Tomcat <code>Cluster</code> implementation that uses a JBoss
- * <code>TreeCache</code> to support intra-cluster session replication.
- * <p>
- * This class registers a <code>TreeCache</code> in JMX, making it
- * available to other users who wish to replicate data within the cluster.
- * </p>
- *
- * @author Brian Stansberry
- * @version $Revision$
- */
-public class JBossCacheCluster
- implements JBossCacheClusterMBean, Lifecycle
-{
- // ------------------------------------------------------- Static Fields
-
- protected static final String info = "JBossCacheCluster/2.1";
-
- public static Log log = LogFactory.getLog(JBossCacheCluster.class);
-
- public static final String DEFAULT_CLUSTER_NAME = "Tomcat-Cluster";
-
- /** TreeCache's isolation level */
- public static final String DEFAULT_ISOLATION_LEVEL = "REPEATABLE_READ";
-
- /** TreeCache's cache mode */
- public static final String DEFAULT_CACHE_MODE = "REPL_ASYNC";
-
- /** TreeCache's lock aquisition timeout */
- public static final long DEFAULT_LOCK_TIMEOUT = 15000;
-
- /** TransactionManagerLookup implementation that the TreeCache should use. */
- public static final String DEFAULT_TM_LOOKUP =
- BatchModeTransactionManagerLookup.class.getName();
-
- public static final String DEFAULT_CACHE_CONFIG_PATH = "conf/cluster-cache.xml";
-
- // ------------------------------------------------------- Instance Fields
-
- /** Parent container of this cluster. */
- private Container container = null;
-
- /** Our JMX Server. */
- private MBeanServer mserver = null;
-
- /** Name under which we are registered in JMX */
- private ObjectName objectName = null;
-
- /** Are we started? */
- private boolean started = false;
-
- /** The lifecycle event support for this component. */
- private LifecycleSupport lifecycle = new LifecycleSupport(this);
-
- /** Our tree cache */
- private PojoCacheMBean treeCache = null;
-
- /** Name under which our TreeCache is registered in JMX */
- private String treeCacheObjectName = Tomcat5.DEFAULT_CACHE_NAME;
-
- /** Did we create the tree cache, or was it already registered in JMX? */
- private boolean treeCacheLocal = false;
-
- /** Name of the tree cache's JGroups channel */
- private String clusterName = null;
-
- /** File name, URL or String to use to configure JGroups. */
- private String cacheConfigPath = null;
-
- /**
- * Implementation of Manager to instantiate when
- * createManager() is called.
- */
- private String managerClassName = JBossCacheManager.class.getName();
-
- /** Does the Engine in which we are running use mod_jk? */
- private boolean useJK = false;
-
- /** Whether our Managers should use a local cache. */
- private boolean useLocalCache = false;
-
- /**
- * Default replication trigger to assign to our
- * Managers that haven't had this property set.
- */
- private String defaultReplicationTrigger = null;
-
- /**
- * Default replication granularity to assign to our Managers
- * that haven't had this property set.
- */
- private String defaultReplicationGranularity = null;
-
- /**
- * JBossCacheManager's snapshot mode.
- */
- private String snapshotMode = null;
-
- /**
- * JBossCacheManager's snapshot interval.
- */
- private int snapshotInterval = 0;
-
- /** Whether we use batch mode replication for field level granularity */
- private boolean replicationFieldBatchMode;
-
- // ---------------------------------------------------------- Constructors
-
- /**
- * Default constructor.
- */
- public JBossCacheCluster()
- {
- super();
- }
-
- // ------------------------------------------------------------ Properties
-
- /**
- * Gets a String representation of the JMX <code>ObjectName</code> under
- * which our <code>TreeCache</code> is registered.
- * <p>
- * If this property is not explicitly set, the <code>TreeCache</code> will
- * be registered under
- * @{@link Tomcat5.DEFAULT_CACHE_NAME the default name used in
- * embedded JBoss/Tomcat}.
- * </p>
- *
- * @jmx.managed-attribute
- */
- public String getCacheObjectName()
- {
- return treeCacheObjectName;
- }
-
- /**
- * Sets the JMX <code>ObjectName</code> under which our
- * <code>TreeCache</code> is registered, if already created, or under
- * which it should be registered if this object creates it.
- *
- * @jmx.managed-attribute
- */
- public void setCacheObjectName(String objectName)
- {
- this.treeCacheObjectName = objectName;
- }
-
- /**
- * Sets the name of the <code>TreeCache</code>'s JGroups channel.
- * <p>
- * This property is ignored if a <code>TreeCache</code> is already
- * registered under the provided
- * {@link #setCacheObjectName cache object name}.
- * </p>
- *
- * @jmx.managed-attribute
- */
- public void setClusterName(String clusterName)
- {
- this.clusterName = clusterName;
- }
-
- /**
- * Gets the filesystem path, which can either be absolute or a path
- * relative to <code>$CATALINA_BASE</code>, where a
- * a JBossCache configuration file can be found.
- *
- * @return a path, either absolute or relative to
- * <code>$CATALINA_BASE</code>. Will return
- * <code>null</code> if no such path was configured.
- *
- * @jmx.managed-attribute
- */
- public String getCacheConfigPath()
- {
- return cacheConfigPath;
- }
-
- /**
- * Sets the filesystem path, which can either be absolute or a path
- * relative to <code>$CATALINA_BASE</code>, where a
- * a JBossCache configuration file can be found.
- * <p>
- * This property is ignored if a <code>TreeCache</code> is already
- * registered under the provided
- * {@link #setCacheObjectName cache object name}.
- * </p>
- *
- * @param cacheConfigPath a path, absolute or relative to
- * <code>$CATALINA_BASE</code>,
- * pointing to a JBossCache configuration file.
- *
- * @jmx.managed-attribute
- */
- public void setCacheConfigPath(String cacheConfigPath)
- {
- this.cacheConfigPath = cacheConfigPath;
- }
-
- /**
- * Gets the name of the implementation of Manager to instantiate when
- * createManager() is called.
- *
- * @jmx.managed-attribute
- */
- public String getManagerClassName()
- {
- return managerClassName;
- }
-
- /**
- * Sets the name of the implementation of Manager to instantiate when
- * createManager() is called.
- * <p>
- * This should be {@link JBossCacheManager} (the default) or a subclass
- * of it.
- * </p>
- *
- * @jmx.managed-attribute
- */
- public void setManagerClassName(String managerClassName)
- {
- this.managerClassName = managerClassName;
- }
-
- /**
- * Gets whether the <code>Engine</code> in which we are running
- * uses <code>mod_jk</code>.
- *
- * @jmx.managed-attribute
- */
- public boolean isUseJK()
- {
- return useJK;
- }
-
- /**
- * Sets whether the <code>Engine</code> in which we are running
- * uses <code>mod_jk</code>.
- *
- * @jmx.managed-attribute
- */
- public void setUseJK(boolean useJK)
- {
- this.useJK = useJK;
- }
-
- /**
- * Gets the <code>JBossCacheManager</code>'s <code>useLocalCache</code>
- * property.
- *
- * @jmx.managed-attribute
- */
- public boolean isUseLocalCache()
- {
- return useLocalCache;
- }
-
- /**
- * Sets the <code>JBossCacheManager</code>'s <code>useLocalCache</code>
- * property.
- *
- * @jmx.managed-attribute
- */
- public void setUseLocalCache(boolean useLocalCache)
- {
- this.useLocalCache = useLocalCache;
- }
-
- /**
- * Gets the default granularity of session data replicated across the
- * cluster; i.e. whether the entire session should be replicated when
- * replication is triggered, or only modified attributes.
- * <p>
- * The value of this property is applied to <code>Manager</code> instances
- * that did not have an equivalent property explicitly set in
- * <code>context.xml</code> or <code>server.xml</code>.
- * </p>
- *
- * @jmx.managed-attribute
- */
- public String getDefaultReplicationGranularity()
- {
- return defaultReplicationGranularity;
- }
-
- /**
- * Sets the granularity of session data replicated across the cluster.
- * Valid values are:
- * <ul>
- * <li>SESSION</li>
- * <li>ATTRIBUTE</li>
- * <li>FIELD</li>
- * </ul>
- * @jmx.managed-attribute
- */
- public void setDefaultReplicationGranularity(
- String defaultReplicationGranularity)
- {
- this.defaultReplicationGranularity = defaultReplicationGranularity;
- }
-
- /**
- * Gets the type of operations on a <code>HttpSession</code> that
- * trigger replication.
- * <p>
- * The value of this property is applied to <code>Manager</code> instances
- * that did not have an equivalent property explicitly set in
- * <code>context.xml</code> or <code>server.xml</code>.
- * </p>
- *
- * @jmx.managed-attribute
- */
- public String getDefaultReplicationTrigger()
- {
- return defaultReplicationTrigger;
- }
-
- /**
- * Sets the type of operations on a <code>HttpSession</code> that
- * trigger replication. Valid values are:
- * <ul>
- * <li>SET_AND_GET</li>
- * <li>SET_AND_NON_PRIMITIVE_GET</li>
- * <li>SET</li>
- * </ul>
- *
- * @jmx.managed-attribute
- */
- public void setDefaultReplicationTrigger(String defaultTrigger)
- {
- this.defaultReplicationTrigger = defaultTrigger;
- }
-
- /**
- * Gets whether Managers should use batch mode replication.
- * Only meaningful if replication granularity is set to <code>FIELD</code>.
- *
- * @jmx.managed-attribute
- */
- public boolean getDefaultReplicationFieldBatchMode()
- {
- return replicationFieldBatchMode;
- }
-
- /**
- * Sets whether Managers should use batch mode replication.
- * Only meaningful if replication granularity is set to <code>FIELD</code>.
- *
- * @jmx.managed-attribute
- */
- public void setDefaultReplicationFieldBatchMode(boolean replicationFieldBatchMode)
- {
- this.replicationFieldBatchMode = replicationFieldBatchMode;
- }
-
- /**
- * Gets when sessions are replicated to the other nodes.
- * The default value, "instant", synchronously replicates changes
- * to the other nodes. In this case, the "SnapshotInterval" attribute
- * is not used.
- * The "interval" mode, in association with the "SnapshotInterval"
- * attribute, indicates that Tomcat will only replicate modified
- * sessions every "SnapshotInterval" miliseconds at most.
- *
- * @see #getSnapshotInterval()
- *
- * @jmx.managed-attribute
- */
- public String getSnapshotMode()
- {
- return snapshotMode;
- }
-
- /**
- * Sets when sessions are replicated to the other nodes. Valid values are:
- * <ul>
- * <li>instant</li>
- * <li>interval</li>
- * </ul>
- *
- * @jmx.managed-attribute
- */
- public void setSnapshotMode(String snapshotMode)
- {
- this.snapshotMode = snapshotMode;
- }
-
- /**
- * Gets how often session changes should be replicated to other nodes.
- * Only relevant if property {@link #getSnapshotMode() snapshotMode} is
- * set to <code>interval</code>.
- *
- * @return the number of milliseconds between session replications.
- *
- * @jmx.managed-attribute
- */
- public int getSnapshotInterval()
- {
- return snapshotInterval;
- }
-
- /**
- * Sets how often session changes should be replicated to other nodes.
- *
- * @param snapshotInterval the number of milliseconds between
- * session replications.
- * @jmx.managed-attribute
- */
- public void setSnapshotInterval(int snapshotInterval)
- {
- this.snapshotInterval = snapshotInterval;
- }
-
- // ---------------------------------------------------------------- Cluster
-
- /**
- * Gets the name of the <code>TreeCache</code>'s JGroups channel.
- *
- * @see org.apache.catalina.Cluster#getClusterName()
- */
- public String getClusterName()
- {
- return clusterName;
- }
-
- /* (non-javadoc)
- * @see org.apache.catalina.Cluster#getContainer()
- */
- public Container getContainer()
- {
- return container;
- }
-
- /* (non-javadoc)
- * @see org.apache.catalina.Cluster#setContainer()
- */
- public void setContainer(Container container)
- {
- this.container = container;
- }
-
- /**
- * @see org.apache.catalina.Cluster#getInfo()
- *
- * @jmx.managed-attribute access="read-only"
- */
- public String getInfo()
- {
- return info;
- }
-
- /**
- * @see org.apache.catalina.Cluster#createManager(java.lang.String)
- */
- public Manager createManager(String name)
- {
- if (log.isDebugEnabled())
- log.debug("Creating ClusterManager for context " + name
- + " using class " + getManagerClassName());
- Manager manager = null;
- try
- {
- manager = (Manager) getClass().getClassLoader().loadClass(
- getManagerClassName()).newInstance();
- }
- catch (Exception x)
- {
- log.error("Unable to load class for replication manager", x);
- manager = new JBossCacheManager();
- }
- finally
- {
- manager.setDistributable(true);
- }
-
- if (manager instanceof JBossCacheManager)
- {
- configureManager((JBossCacheManager) manager);
- }
-
- return manager;
- }
-
- /**
- * Does nothing; tracking the status of other members of the cluster is
- * provided by the JGroups layer.
- *
- * @see org.apache.catalina.Cluster#backgroundProcess()
- */
- public void backgroundProcess()
- {
- ; // no-op
- }
-
- // --------------------------------------------- Deprecated Cluster Methods
-
- /**
- * Returns <code>null</code>; method is deprecated.
- *
- * @return <code>null</code>, always.
- *
- * @see org.apache.catalina.Cluster#getProtocol()
- */
- public String getProtocol()
- {
- return null;
- }
-
- /**
- * Does nothing; method is deprecated.
- *
- * @see org.apache.catalina.Cluster#setProtocol(java.lang.String)
- */
- public void setProtocol(String protocol)
- {
- ; // no-op
- }
-
- /**
- * Does nothing; method is deprecated.
- *
- * @see org.apache.catalina.Cluster#startContext(java.lang.String)
- */
- public void startContext(String contextPath) throws IOException
- {
- ; // no-op
- }
-
- /**
- * Does nothing; method is deprecated.
- *
- * @see org.apache.catalina.Cluster#installContext(java.lang.String, java.net.URL)
- */
- public void installContext(String contextPath, URL war)
- {
- ; // no-op
- }
-
- /**
- * Does nothing; method is deprecated.
- *
- * @see org.apache.catalina.Cluster#stop(java.lang.String)
- */
- public void stop(String contextPath) throws IOException
- {
- ; // no-op
- }
-
- // --------------------------------------------------------- Public Methods
-
- /**
- * Sets the cluster-wide properties of a <code>Manager</code> to
- * match those of this cluster. Does not override
- * <code>Manager</code>-specific properties with cluster-wide defaults
- * if the <code>Manager</code>-specfic properties have already been set.
- */
- public void configureManager(JBossCacheManager manager)
- {
- manager.setSnapshotMode(snapshotMode);
- manager.setSnapshotInterval(snapshotInterval);
- manager.setUseJK(useJK);
- manager.setUseLocalCache(useLocalCache);
- manager.setCacheObjectNameString(treeCacheObjectName);
-
- // Only set replication attributes if they were not
- // already set via a <Manager> element in an XML config file
-
- if (manager.getReplicationGranularityString() == null)
- {
- manager.setReplicationGranularityString(defaultReplicationGranularity);
- }
-
- if (manager.getReplicationTriggerString() == null)
- {
- manager.setReplicationTriggerString(defaultReplicationTrigger);
- }
-
- if (manager.isReplicationFieldBatchMode() == null)
- {
- manager.setReplicationFieldBatchMode(replicationFieldBatchMode);
- }
- }
-
- // --------------------------------------------------------------- Lifecyle
-
- /**
- * Finds or creates a {@link TreeCache}; if created, starts the
- * cache and registers it with our JMX server.
- *
- * @see org.apache.catalina.Lifecycle#start()
- */
- public void start() throws LifecycleException
- {
- if (started)
- {
- throw new LifecycleException("Cluster already started");
- }
-
- // Notify our interested LifecycleListeners
- lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, this);
-
- try
- {
- // Tell the JBoss MBeanServerLocator utility
- // that Tomcat's MBean server is 'jboss'
- MBeanServerLocator.setJBoss(getMBeanServer());
-
- // Initialize the tree cache
- PojoCacheMBean cache = getTreeCache();
-
- if (treeCacheLocal)
- {
- cache.createService();
- cache.startService();
- }
-
- registerMBeans();
-
- started = true;
-
- // Notify our interested LifecycleListeners
- lifecycle.fireLifecycleEvent(AFTER_START_EVENT, this);
-
- }
- catch (LifecycleException e)
- {
- throw e;
- }
- catch (Exception e)
- {
- log.error("Unable to start cluster.", e);
- throw new LifecycleException(e);
- }
- }
-
- /**
- * If this object created its own {@link TreeCache}, stops it
- * and unregisters it with JMX.
- *
- * @see org.apache.catalina.Lifecycle#stop()
- */
- public void stop() throws LifecycleException
- {
- if (!started)
- {
- throw new IllegalStateException("Cluster not started");
- }
-
- // Notify our interested LifecycleListeners
- lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, this);
-
- if (treeCacheLocal)
- {
- treeCache.stopService();
- treeCache.destroyService();
- }
-
- started = false;
- // Notify our interested LifecycleListeners
- lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, this);
-
- unregisterMBeans();
- }
-
- /* (non-javadoc)
- * @see org.apache.catalina.Lifecycle#addLifecycleListener()
- */
- public void addLifecycleListener(LifecycleListener listener)
- {
- lifecycle.addLifecycleListener(listener);
- }
-
- /* (non-javadoc)
- * @see org.apache.catalina.Lifecycle#findLifecycleListeners()
- */
- public LifecycleListener[] findLifecycleListeners()
- {
- return lifecycle.findLifecycleListeners();
- }
-
- /* (non-javadoc)
- * @see org.apache.catalina.Lifecycle#removeLifecycleListener()
- */
- public void removeLifecycleListener(LifecycleListener listener)
- {
- lifecycle.removeLifecycleListener(listener);
- }
-
- // -------------------------------------------------------- Private Methods
-
- /**
- * Gets our TreeCache, either from a local reference or the JMX
- * server. If one is not found, creates and configures it.
- */
- private PojoCacheMBean getTreeCache() throws Exception
- {
- if (treeCache == null) {
-
- MBeanServer server = getMBeanServer();
- ObjectName objName = new ObjectName(treeCacheObjectName);
- if (server.isRegistered(objName))
- {
- // Get a proxy to the existing TreeCache
- treeCache = (PojoCacheMBean)
- MBeanProxyExt.create(PojoCacheMBean.class, objName);
- }
- else
- {
- // Create our own tree cache
- treeCache = new PojoCache();
-
- // See if there is an XML descriptor file to configure the cache
- InputStream configIS = getCacheConfigStream();
-
- if (configIS != null)
- {
- PropertyConfigurator config = new PropertyConfigurator();
- config.configure(treeCache, configIS);
- try
- {
- configIS.close();
- }
- catch (IOException io)
- {
- // ignore
- }
-
- if (clusterName != null)
- {
- // Override the XML config with the name provided in
- // server.xml. Method setClusterName is specified in the
- // Cluster interface, otherwise we would not do this
- treeCache.setClusterName(clusterName);
- }
- }
- else
- {
- // User did not try to configure the cache.
- // Configure it using defaults. Only exception
- // is the clusterName, which user can specify in server.xml.
- String channelName = (clusterName == null) ? DEFAULT_CLUSTER_NAME
- : clusterName;
- treeCache.setClusterName(channelName);
- treeCache.setIsolationLevel(DEFAULT_ISOLATION_LEVEL);
- treeCache.setCacheMode(DEFAULT_CACHE_MODE);
- treeCache.setLockAcquisitionTimeout(DEFAULT_LOCK_TIMEOUT);
- treeCache.setTransactionManagerLookupClass(DEFAULT_TM_LOOKUP);
- }
-
- treeCacheLocal = true;
- }
- }
- return treeCache;
- }
-
-
-
- private InputStream getCacheConfigStream() throws FileNotFoundException
- {
- boolean useDefault = (this.cacheConfigPath == null);
- String path = (useDefault) ? DEFAULT_CACHE_CONFIG_PATH : cacheConfigPath;
- // See if clusterProperties points to a file relative
- // to $CATALINA_BASE
- File file = new File(path);
- if (!file.isAbsolute())
- {
- file = new File(System.getProperty("catalina.base"), path);
- }
-
- try
- {
- return new FileInputStream(file);
- }
- catch (FileNotFoundException fnf)
- {
- if (useDefault)
- {
- // Not a problem, just means user did not try to
- // configure the cache. Return null and let the cache
- // be configured from defaults.
- return null;
- }
- else
- {
- // User provided config was invalid; throw the exception
- log.error("No tree cache config file found at " +
- file.getAbsolutePath());
- throw fnf;
- }
- }
- }
-
- /**
- * Registers this object and the tree cache (if we created it) with JMX.
- */
- private void registerMBeans()
- {
- try
- {
- MBeanServer server = getMBeanServer();
-
- String domain;
- if (container instanceof ContainerBase)
- {
- domain = ((ContainerBase) container).getDomain();
- }
- else
- {
- domain = server.getDefaultDomain();
- }
-
- String name = ":type=Cluster";
- if (container instanceof Host) {
- name += ",host=" + container.getName();
- }
- else if (container instanceof Engine)
- {
- name += ",engine=" + container.getName();
- }
-
- ObjectName clusterName = new ObjectName(domain + name);
-
- if (server.isRegistered(clusterName))
- {
- log.warn("MBean " + clusterName + " already registered");
- }
- else
- {
- this.objectName = clusterName;
- server.registerMBean(this, objectName);
- }
-
- if (treeCacheLocal)
- {
- // Register the treeCache
- ObjectName treeCacheName = new ObjectName(treeCacheObjectName);
- server.registerMBean(getTreeCache(), treeCacheName);
- }
-
- }
- catch (Exception ex)
- {
- log.error(ex.getMessage(), ex);
- }
- }
-
- /**
- * Unregisters this object and the tree cache (if we created it) with JMX.
- */
- private void unregisterMBeans()
- {
- if (mserver != null)
- {
- try
- {
- if (objectName != null) {
- mserver.unregisterMBean(objectName);
- }
- if (treeCacheLocal)
- {
- mserver.unregisterMBean(new ObjectName(treeCacheObjectName));
- }
- }
- catch (Exception e)
- {
- log.error(e);
- }
- }
- }
-
- /**
- * Get the current Catalina MBean Server.
- *
- * @return
- * @throws Exception
- */
- private MBeanServer getMBeanServer() throws Exception
- {
- if (mserver == null)
- {
- ArrayList servers = MBeanServerFactory.findMBeanServer(null);
- if (servers.size() > 0)
- {
- mserver = (MBeanServer) servers.get(0);
- }
- else
- {
- mserver = MBeanServerFactory.createMBeanServer();
- }
- }
- return mserver;
- }
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheClusterMBean.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheClusterMBean.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheClusterMBean.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,80 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import org.apache.catalina.Cluster;
-import org.apache.catalina.LifecycleException;
-
-/**
- * The MBean interface for the JBossCacheCluster.
- *
- * @see org.jboss.web.tomcat.tc5.JBossCacheCluster
- *
- * @author Brian Stansberry
- * @version $Revision$
- */
-public interface JBossCacheClusterMBean extends Cluster
-{
- public abstract boolean isUseJK();
-
- public abstract void setUseJK(boolean useJK);
-
- public abstract boolean isUseLocalCache();
-
- public abstract void setUseLocalCache(boolean useLocalCache);
-
- public abstract String getManagerClassName();
-
- public abstract void setManagerClassName(String managerClassName);
-
- public abstract String getDefaultReplicationGranularity();
-
- public abstract void setDefaultReplicationGranularity(String defaultGran);
-
- public abstract String getDefaultReplicationTrigger();
-
- public abstract void setDefaultReplicationTrigger(String defaultTrigger);
-
- public boolean getDefaultReplicationFieldBatchMode();
-
- public void setDefaultReplicationFieldBatchMode(boolean replicationFieldBatchMode);
-
- public abstract int getSnapshotInterval();
-
- public abstract void setSnapshotInterval(int snapshotInterval);
-
- public abstract String getSnapshotMode();
-
- public abstract void setSnapshotMode(String snapshotMode);
-
- public abstract String getCacheObjectName();
-
- public abstract void setCacheObjectName(String objectName);
-
- public abstract void start() throws LifecycleException;
-
- /**
- * Does nothing.
- */
- public abstract void stop() throws LifecycleException;
-
-}
\ No newline at end of file
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheClusteredSession.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheClusteredSession.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheClusteredSession.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,160 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-/**
- * Common superclass of ClusteredSession types that use JBossCache
- * as their distributed cache.
- *
- * @author Brian Stansberry
- *
- * @version $Revision$
- */
-public abstract class JBossCacheClusteredSession extends ClusteredSession
-{
- /**
- * Our proxy to the cache.
- */
- protected transient JBossCacheService proxy_;
-
- /**
- * Create a new JBossCacheClusteredSession.
- *
- * @param manager
- * @param useJK
- */
- public JBossCacheClusteredSession(JBossCacheManager manager)
- {
- super(manager, manager.getUseJK());
- establishProxy();
- }
-
- /**
- * Initialize fields marked as transient after loading this session
- * from the distributed store
- *
- * @param manager the manager for this session
- */
- public void initAfterLoad(AbstractJBossManager manager)
- {
- // Our manager and proxy may have been lost if we were recycled,
- // so reestablish them
- setManager(manager);
- establishProxy();
-
- // Since attribute map is may be transient, we may need to populate it
- // from the underlying store.
- populateAttributes();
-
- // Notify all attributes of type HttpSessionActivationListener (SRV 7.7.2)
- this.activate();
-
- // We are no longer outdated vis a vis distributed cache
- clearOutdated();
- }
-
- /**
- * Gets a reference to the JBossCacheService.
- */
- protected void establishProxy()
- {
- if (proxy_ == null)
- {
- proxy_ = ((JBossCacheManager) manager).getCacheService();
-
- // still null???
- if (proxy_ == null)
- {
- throw new RuntimeException("JBossCacheClusteredSession: Cache service is null.");
- }
- }
- }
-
- protected abstract void populateAttributes();
-
- /**
- * Override the superclass to additionally reset this class' fields.
- * <p>
- * <strong>NOTE:</strong> It is not anticipated that this method will be
- * called on a ClusteredSession, but we are overriding the method to be
- * thorough.
- * </p>
- */
- public void recycle()
- {
- super.recycle();
-
- proxy_ = null;
- }
-
- /**
- * Increment our version and place ourself in the cache.
- */
- public synchronized void processSessionRepl()
- {
- // Replicate the session.
- if (log.isDebugEnabled())
- {
- log.debug("processSessionRepl(): session is dirty. Will increment " +
- "version from: " + getVersion() + " and replicate.");
- }
- this.incrementVersion();
- proxy_.putSession(realId, this);
-
- sessionAttributesDirty = false;
- sessionMetadataDirty = false;
-
- updateLastReplicated();
- }
-
- /**
- * Overrides the superclass impl by doing nothing if <code>localCall</code>
- * is <code>false</code>. The JBossCacheManager will already be aware of
- * a remote invalidation and will handle removal itself.
- */
- protected void removeFromManager(boolean localCall, boolean localOnly)
- {
- if (localCall)
- {
- super.removeFromManager(localCall, localOnly);
- }
- }
-
-
- protected Object removeAttributeInternal(String name, boolean localCall, boolean localOnly)
- {
- return removeJBossInternalAttribute(name, localCall, localOnly);
- }
-
- protected Object removeJBossInternalAttribute(String name)
- {
- throw new UnsupportedOperationException("removeJBossInternalAttribute(String) " +
- "is not supported by JBossCacheClusteredSession; use " +
- "removeJBossInternalAttribute(String, boolean, boolean");
- }
-
- protected abstract Object removeJBossInternalAttribute(String name,
- boolean localCall,
- boolean localOnly);
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManager.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,1817 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.transaction.Status;
-import javax.transaction.TransactionManager;
-import javax.transaction.RollbackException;
-
-import org.apache.catalina.Context;
-import org.apache.catalina.Host;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.Session;
-import org.apache.catalina.Valve;
-import org.apache.catalina.core.ContainerBase;
-import org.jboss.cache.CacheException;
-import org.jboss.metadata.WebMetaData;
-import org.jboss.mx.util.MBeanServerLocator;
-import org.jboss.web.tomcat.tc5.Tomcat5;
-
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-
-/**
- * Implementation of a clustered session manager for
- * catalina using JBossCache replication.
- *
- * @author Ben Wang
- * @author Brian Stansberry
- * @author Hany Mesha
- */
-public class JBossCacheManager
- extends JBossManager
- implements JBossCacheManagerMBean
-{
-
- /**
- * Informational name for this Catalina component
- */
- static final String info_ = "JBossCacheManager/1.0";
-
- // -- Class attributes ---------------------------------
-
- /**
- * The transaction manager.
- */
- protected TransactionManager tm;
-
- /**
- * Proxy-object for the JBossCacheService
- */
- private JBossCacheService proxy_;
-
- /**
- * Id/timestamp of sessions in cache that we haven't loaded
- */
- private Map unloadedSessions_ = new ConcurrentHashMap();
-
- /** Our TreeCache's ObjectName */
- private String cacheObjectNameString_ = Tomcat5.DEFAULT_CACHE_NAME;
-
- /**
- * If set to true, will add a JvmRouteFilter to the request.
- */
- protected boolean useJK_ = false;
-
- /** Are we running embedded in JBoss? */
- private boolean embedded_ = false;
-
- /** Our JMX Server */
- private MBeanServer mserver_ = null;
-
- /** Our ClusteredSessionValve's snapshot mode. */
- private String snapshotMode_ = null;
-
- /** Our ClusteredSessionValve's snapshot interval. */
- private int snapshotInterval_ = 0;
-
- /** String form of invalidateSessionPolicy_ */
- private String replTriggerString_ = null;
-
- /** String form of replGranularityString_ */
- private String replGranularityString_ = null;
-
- /**
- * Whether we use batch mode replication for field level granularity.
- * We store this in a Boolean rather than a primitive so JBossCacheCluster
- * can determine if this was set via a <Manager> element.
- */
- private Boolean replicationFieldBatchMode_;
-
- // ---------------------------------------------------------- Constructors
-
- public JBossCacheManager()
- {
- super();
- }
-
- /**
- * Initializes this Manager when running in embedded mode.
- * <p>
- * <strong>NOTE:</strong> This method should not be called when
- * running unembedded.
- * </p>
- */
- public void init(String name, WebMetaData webMetaData,
- boolean useJK, boolean useLocalCache)
- throws ClusteringNotSupportedException
- {
- super.init(name, webMetaData, useJK, useLocalCache);
- this.useJK_ = useJK;
- this.replicationFieldBatchMode_ =
- webMetaData.getReplicationFieldBatchMode() ? Boolean.TRUE : Boolean.FALSE;
- try
- {
- proxy_ = new JBossCacheService(cacheObjectNameString_);
- }
- catch (Throwable t)
- {
- String str = "JBossCacheService to Tomcat clustering not found";
- log_.error(str, t);
- throw new ClusteringNotSupportedException(str);
- }
-
- // Confirm our replication granularity is compatible with the cache
- validateFieldMarshalling();
-
- embedded_ = true;
- }
-
- // ------------------------------------------------------------- Properties
-
- /**
- * Gets the <code>JBossCacheService</code> through which we interact
- * with the <code>TreeCache</code>.
- */
- public JBossCacheService getCacheService()
- {
- return proxy_;
- }
-
- /**
- * Gets a String representation of the JMX <code>ObjectName</code> under
- * which our <code>TreeCache</code> is registered.
- */
- public String getCacheObjectNameString()
- {
- return cacheObjectNameString_;
- }
-
- /**
- * Sets the JMX <code>ObjectName</code> under which our
- * <code>TreeCache</code> is registered.
- */
- public void setCacheObjectNameString(String treeCacheObjectName)
- {
- this.cacheObjectNameString_ = treeCacheObjectName;
- }
-
- /**
- * Gets when sessions are replicated to the other nodes.
- * The default value, "instant", synchronously replicates changes
- * to the other nodes. In this case, the "SnapshotInterval" attribute
- * is not used.
- * The "interval" mode, in association with the "SnapshotInterval"
- * attribute, indicates that Tomcat will only replicate modified
- * sessions every "SnapshotInterval" miliseconds at most.
- *
- * @see #getSnapshotInterval()
- */
- public String getSnapshotMode()
- {
- return snapshotMode_;
- }
-
- /**
- * Sets when sessions are replicated to the other nodes. Valid values are:
- * <ul>
- * <li>instant</li>
- * <li>interval</li>
- * </ul>
- */
- public void setSnapshotMode(String snapshotMode)
- {
- this.snapshotMode_ = snapshotMode;
- }
-
- /**
- * Gets how often session changes should be replicated to other nodes.
- * Only relevant if property {@link #getSnapshotMode() snapshotMode} is
- * set to <code>interval</code>.
- *
- * @return the number of milliseconds between session replications.
- */
- public int getSnapshotInterval()
- {
- return snapshotInterval_;
- }
-
- /**
- * Sets how often session changes should be replicated to other nodes.
- *
- * @param snapshotInterval the number of milliseconds between
- * session replications.
- */
- public void setSnapshotInterval(int snapshotInterval)
- {
- this.snapshotInterval_ = snapshotInterval;
- }
-
- /**
- * Gets whether the <code>Engine</code> in which we are running
- * uses <code>mod_jk</code>.
- */
- public boolean getUseJK()
- {
- return useJK_;
- }
-
- /**
- * Sets whether the <code>Engine</code> in which we are running
- * uses <code>mod_jk</code>.
- */
- public void setUseJK(boolean useJK)
- {
- this.useJK_ = useJK;
- }
-
- /**
- * Returns the replication granularity expressed as an int.
- *
- * @see WebMetaData#REPLICATION_GRANULARITY_ATTRIBUTE
- * @see WebMetaData#REPLICATION_GRANULARITY_FIELD
- * @see WebMetaData#REPLICATION_GRANULARITY_SESSION
- */
- public int getReplicationGranularity()
- {
- return replicationGranularity_;
- }
-
- /**
- * Gets the granularity of session data replicated across the
- * cluster; i.e. whether the entire session should be replicated when
- * replication is triggered, only modified attributes, or only
- * modified fields of attributes.
- */
- public String getReplicationGranularityString()
- {
- // Only lazy-set this if we are started;
- // otherwise screws up standalone TC integration!!
- if (started_ && this.replGranularityString_ == null)
- {
- switch (this.replicationGranularity_)
- {
- case WebMetaData.REPLICATION_GRANULARITY_ATTRIBUTE:
- this.replGranularityString_ = "ATTRIBUTE";
- break;
- case WebMetaData.REPLICATION_GRANULARITY_SESSION:
- this.replGranularityString_ = "SESSION";
- break;
- case WebMetaData.REPLICATION_GRANULARITY_FIELD:
- this.replGranularityString_ = "FIELD";
- }
- }
- return replGranularityString_;
- }
-
- /**
- * Sets the granularity of session data replicated across the cluster.
- * Valid values are:
- * <ul>
- * <li>SESSION</li>
- * <li>ATTRIBUTE</li>
- * <li>FIELD</li>
- * </ul>
- */
- public void setReplicationGranularityString(String granularity)
- {
- this.replGranularityString_ = granularity;
- }
-
- /**
- * Gets the type of operations on a <code>HttpSession</code> that
- * trigger replication.
- */
- public String getReplicationTriggerString()
- {
- // Only lazy-set this if we are started;
- // otherwise screws up standalone TC integration!!
- if (started_ && this.replTriggerString_ == null)
- {
- switch (this.invalidateSessionPolicy_)
- {
- case WebMetaData.SESSION_INVALIDATE_SET:
- this.replTriggerString_ = "SET";
- break;
- case WebMetaData.SESSION_INVALIDATE_SET_AND_GET:
- this.replTriggerString_ = "SET_AND_GET";
- break;
- case WebMetaData.SESSION_INVALIDATE_SET_AND_NON_PRIMITIVE_GET:
- this.replTriggerString_ = "SET_AND_NON_PRIMITIVE_GET";
- }
- }
- return this.replTriggerString_;
- }
-
- /**
- * Sets the type of operations on a <code>HttpSession</code> that
- * trigger replication. Valid values are:
- * <ul>
- * <li>SET_AND_GET</li>
- * <li>SET_AND_NON_PRIMITIVE_GET</li>
- * <li>SET</li>
- * </ul>
- */
- public void setReplicationTriggerString(String trigger)
- {
- this.replTriggerString_ = trigger;
- }
-
- /**
- * Gets whether, if replication granularity is set to <code>FIELD</code>,
- * replication should be done in batch mode. Ignored if field-level
- * granularity is not used.
- */
- public Boolean isReplicationFieldBatchMode()
- {
- return replicationFieldBatchMode_;
- }
-
- /**
- * Sets whether, if replication granularity is set to <code>FIELD</code>,
- * replication should be done in batch mode. Ignored if field-level
- * granularity is not used.
- */
- public void setReplicationFieldBatchMode(boolean replicationFieldBatchMode)
- {
- this.replicationFieldBatchMode_ = Boolean.valueOf(replicationFieldBatchMode);
- }
-
- public void setUseLocalCache(boolean useLocalCache)
- {
- this.useLocalCache_ = useLocalCache;
- }
-
- // JBossCacheManagerMBean-methods -------------------------------------
-
- public void expireSession(String sessionId)
- {
- Session session = findSession(sessionId);
- if (session != null)
- session.expire();
- }
-
- public String getLastAccessedTime(String sessionId)
- {
- Session session = findSession(sessionId);
- if(session == null) {
- log_.debug("getLastAccessedTime(): Session " + sessionId +
- " not found");
- return "";
- }
- return new Date(session.getLastAccessedTime()).toString();
- }
-
- public Object getSessionAttribute(String sessionId, String key)
- {
- ClusteredSession session = (ClusteredSession) findSession(sessionId);
- return (session == null) ? null : session.getAttribute(key);
- }
-
- public String getSessionAttributeString(String sessionId, String key)
- {
- Object attr = getSessionAttribute(sessionId, key);
- return (attr == null) ? null : attr.toString();
- }
-
- public String listLocalSessionIds()
- {
- return reportSessionIds(sessions_.keySet());
- }
-
- public String listSessionIds()
- {
- Set ids = new HashSet(sessions_.keySet());
- ids.addAll(unloadedSessions_.keySet());
- return reportSessionIds(ids);
- }
-
- private String reportSessionIds(Set ids)
- {
- StringBuffer sb = new StringBuffer();
- boolean added = false;
- for (Iterator it = ids.iterator(); it.hasNext(); )
- {
- if (added)
- {
- sb.append(',');
- }
- else
- {
- added = true;
- }
-
- sb.append(it.next());
- }
- return sb.toString();
- }
-
- // Manager-methods -------------------------------------
-
- /**
- * Start this Manager
- *
- * @throws org.apache.catalina.LifecycleException
- *
- */
- public void start() throws LifecycleException
- {
- if (embedded_)
- {
- startEmbedded();
- }
- else
- {
- startUnembedded();
- }
- }
-
- public void stop() throws LifecycleException
- {
- if (!started_)
- {
- throw new IllegalStateException("Manager not started");
- }
-
- if (log_.isDebugEnabled())
- log_.debug("Stopping");
-
- resetStats();
-
- // Notify our interested LifecycleListeners
- lifecycle_.fireLifecycleEvent(BEFORE_STOP_EVENT, this);
-
- clearSessions();
-
- proxy_.stop();
- tm = null;
-
- started_ = false;
-
- // Notify our interested LifecycleListeners
- lifecycle_.fireLifecycleEvent(AFTER_STOP_EVENT, this);
-
- try
- {
- unregisterMBeans();
- }
- catch (Exception e)
- {
- log_.error("Could not unregister ManagerMBean from MBeanServer", e);
- }
- }
-
- /**
- * Clear the underlying cache store and also pojo that has the observers.
- */
- protected void clearSessions()
- {
- // First, the sessions we have actively loaded
- ClusteredSession[] sessions = findLocalSessions();
- for(int i=0; i < sessions.length; i++)
- {
- ClusteredSession ses = sessions[i];
- // JBCLUSTER-15
- // if session passivation is enabled, passivate sessions instead of expiring them which means
- // they'll be available to the manager for activation after a restart.
- if (log_.isTraceEnabled())
- {
- log_.trace("clearSessions(): clear session by expiring or passivating: " + ses);
- }
- boolean notify = true;
- boolean localCall = true;
- boolean localOnly = true;
- try
- {
- if(isPassivationEnabled() && ses.isValid())
- {
-
- processSessionPassivation(ses.getRealId(), this.getContainer().getParent().getName());
- }
- else
- {
- ses.expire(notify, localCall, localOnly);
- }
-
- }
- catch (Throwable t)
- {
- log_.warn("clearSessions(): Caught exception expiring or passivating session " +
- ses.getIdInternal(), t);
- }
- finally
- {
- // Guard against leaking memory if anything is holding a
- // ref to the session by clearing its internal state
- ses.recycle();
- }
- }
-
- // Next, the local copy of the distributed cache
- Map unloaded = new HashMap(unloadedSessions_);
- Set keys = unloaded.keySet();
- for (Iterator it = keys.iterator(); it.hasNext(); )
- {
- String realId = (String) it.next();
- proxy_.removeSessionLocal(realId);
- unloadedSessions_.remove(realId);
- }
- }
-
- /**
- * Create a new session with a generated id.
- */
- public Session createSession()
- {
- return createSession(null);
- }
-
- /**
- * Create a new session.
- *
- * @param sessionId the id to use, or <code>null</code> if we should
- * generate a new id
- *
- * @return the session
- *
- * @throws IllegalStateException if the current number of active sessions
- * exceeds the maximum number allowed
- */
- public Session createSession(String sessionId)
- {
- if (log_.isTraceEnabled())
- {
- log_.trace("createSession: active sessions = " + activeCounter_ + " and max allowed sessions = " + maxActive_);
- }
- log_.info("createSession: active sessions = " + activeCounter_ + " and max allowed sessions = " + maxActive_);
- // We check here for maxActive instead of in add(). add() gets called
- // when we load an already existing session from the distributed cache
- // (e.g. in a failover) and we don't want to fail in that situation.
-
- // JBCLUSTER-15
- // first check if passivation is enabled and reached the max allowed sessions,
- /// then try to expire/passivate sessions to free memory
- if(maxActive_ != -1 && activeCounter_ >= maxActive_ && isPassivationEnabled())
- {
- processExpires();
- }
- // maxActive_ -1 is unlimited
- if (maxActive_ != -1 && activeCounter_ >= maxActive_)
- {
- // Exceeds limit. We need to reject it.
- rejectedCounter_++;
- // Catalina api does not specify what happens
- // but we will throw a runtime exception for now.
- String msgEnd = (sessionId == null) ? "" : " id " + sessionId;
- throw new IllegalStateException("JBossCacheManager.createSession(): number of " +
- "active sessions exceeds the maximum limit: " +
- maxActive_ + " when trying to add session" + msgEnd);
- }
-
- ClusteredSession session = createEmptyClusteredSession();
-
- session.setNew(true);
- session.setCreationTime(System.currentTimeMillis());
- session.setMaxInactiveInterval(this.maxInactiveInterval_);
- session.setValid(true);
-
- if (sessionId == null)
- {
- sessionId = this.getNextId();
-
- // We are using mod_jk for load balancing. Append the JvmRoute.
- if (useJK_)
- {
- if (log_.isDebugEnabled())
- {
- log_.debug("createSession(): useJK is true. Will append JvmRoute: " + this.getJvmRoute());
- }
- sessionId += "." + this.getJvmRoute();
- }
- }
-
- session.setId(sessionId); // Setting the id leads to a call to add()
-
- if (log_.isDebugEnabled())
- {
- log_.debug("Created a ClusteredSession with id: " + sessionId);
- }
-
- createdCounter_++;
- return session;
- }
-
- public boolean storeSession(Session baseSession)
- {
- boolean stored = false;
- if(baseSession != null)
- {
- ClusteredSession session = (ClusteredSession) baseSession;
-
- synchronized (session)
- {
- if (log_.isDebugEnabled())
- {
- log_.debug("check to see if needs to store and replicate " +
- "session with id " + session.getIdInternal());
- }
-
- if (session.isValid() &&
- (session.isSessionDirty() || session.getExceedsMaxUnreplicatedInterval()))
- {
- String realId = session.getRealId();
-
- // Notify all session attributes that they get serialized (SRV 7.7.2)
- long begin = System.currentTimeMillis();
- session.passivate();
- long elapsed = System.currentTimeMillis() - begin;
- stats_.updatePassivationStats(realId, elapsed);
-
- // Do the actual replication
- begin = System.currentTimeMillis();
- processSessionRepl(session);
- elapsed = System.currentTimeMillis() - begin;
- stored = true;
- stats_.updateReplicationStats(realId, elapsed);
- }
- }
- }
-
- return stored;
- }
-
- public void add(Session session)
- {
- if (session == null)
- return;
-
- if (!(session instanceof ClusteredSession))
- {
- throw new IllegalArgumentException("You can only add instances of " +
- "type ClusteredSession to this Manager. Session class name: " +
- session.getClass().getName());
- }
-
-// add((ClusteredSession) session, true);
- add((ClusteredSession) session, false);
- }
-
- /**
- * Adds the given session to the collection of those being managed by this
- * Manager.
- *
- * @param session the session. Cannot be <code>null</code>.
- * @param replicate whether the session should be replicated
- *
- * @throws NullPointerException if <code>session</code> is <code>null</code>.
- */
- private void add(ClusteredSession session, boolean replicate)
- {
- if (!session.isValid())
- {
- log_.error("Cannot add session with id=" + session.getIdInternal() +
- " because it is invalid");
- return;
- }
-
- String realId = session.getRealId();
- Object existing = sessions_.put(realId, session);
- unloadedSessions_.remove(realId);
-
- if (!session.equals(existing))
- {
- if (replicate)
- {
- storeSession(session);
- }
-
- activeCounter_++;
- if (activeCounter_ > maxActiveCounter_)
- maxActiveCounter_++;
-
- if (log_.isDebugEnabled())
- {
- log_.debug("Session with id=" + session.getIdInternal() + " added. " +
- "Current active sessions " + activeCounter_);
- }
- }
- }
-
- // Satisfy the Manager interface. Internally we use
- // createEmptyClusteredSession to avoid a cast
- public Session createEmptySession()
- {
- return createEmptyClusteredSession();
- }
-
- private ClusteredSession createEmptyClusteredSession()
- {
- if (log_.isDebugEnabled())
- {
- log_.debug("Creating an empty ClusteredSession");
- }
-
- ClusteredSession session = null;
- switch (replicationGranularity_)
- {
- case (WebMetaData.REPLICATION_GRANULARITY_ATTRIBUTE):
- session = new AttributeBasedClusteredSession(this);
- break;
- case (WebMetaData.REPLICATION_GRANULARITY_FIELD):
- session = new FieldBasedClusteredSession(this);
- break;
- default:
- session = new SessionBasedClusteredSession(this);
- break;
- }
- return session;
- }
-
- /**
- * Attempts to find the session in the collection of those being managed
- * locally, and if not found there, in the distributed cache of sessions.
- * <p>
- * If a session is found in the distributed cache, it is added to the
- * collection of those being managed locally.
- * </p>
- *
- * @param id the session id, which may include an appended jvmRoute
- *
- * @return the session, or <code>null</code> if no such session could
- * be found
- */
- public Session findSession(String id)
- {
- String realId = getRealId(id);
- // Find it from the local store first
- ClusteredSession session = findLocalSession(realId);
-
- // If we didn't find it locally, only check the distributed cache
- // if we haven't previously handled this session id on this request.
- // If we handled it previously but it's no longer local, that means
- // it's been invalidated. If we request an invalidated session from
- // the distributed cache, it will be missing from the local cache but
- // may still exist on other nodes (i.e. if the invalidation hasn't
- // replicated yet because we are running in a tx). With buddy replication,
- // asking the local cache for the session will cause the out-of-date
- // session from the other nodes to be gravitated, thus resuscitating
- // the session.
- if (session == null
- && !realId.equals(ClusteredSessionValve.sessionIdThreadLocal.get()))
- {
- session = loadSession(realId);
- if (session != null)
- {
- add(session);
- // TODO should we advise of a new session?
- //tellNew();
- }
- }
- else if (session != null && session.isOutdated())
- {
- // Need to update it from the cache
- loadSession(realId);
- }
-
- if (session != null)
- ClusteredSessionValve.sessionIdThreadLocal.set(realId);
-
- return session;
- }
-
- /**
- * Return the sessions. Note that this will return not only the local
- * in-memory sessions, but also any sessions that are in the distributed
- * cache but have not previously been accessed on this server. Invoking
- * this method will bring all such sessions into local memory and can
- * potentially be quite expensive.
- *
- * <p>
- * Note also that when sessions are loaded from the distributed cache, no
- * check is made as to whether the number of local sessions will thereafter
- * exceed the maximum number allowed on this server.
- * </p>
- *
- * @return an array of all the sessions
- */
- public Session[] findSessions()
- {
- // Need to load all the unloaded sessions
- if(unloadedSessions_.size() > 0)
- {
- // Make a thread-safe copy of the new id list to work with
- Set ids = new HashSet(unloadedSessions_.keySet());
-
- if(log_.isDebugEnabled()) {
- log_.debug("findSessions: loading sessions from distributed cache: " + ids);
- }
-
- for(Iterator it = ids.iterator(); it.hasNext();) {
- loadSession((String) it.next());
- }
- }
-
- // All sessions are now "local" so just return the local sessions
- return findLocalSessions();
- }
-
- /**
- * Returns all the sessions that are being actively managed by this manager.
- * This includes those that were created on this server, those that were
- * brought into local management by a call to
- * {@link #findLocalSession(String)} as well as all sessions brought into
- * local management by a call to {@link #findSessions()}.
- */
- public ClusteredSession[] findLocalSessions()
- {
- Collection coll = sessions_.values();
- ClusteredSession[] sess = new ClusteredSession[coll.size()];
- sess = (ClusteredSession[]) coll.toArray(sess);
- return sess;
- }
-
- /**
- * Returns the given session if it is being actively managed by this manager.
- * An actively managed session is on that was either created on this server,
- * brought into local management by a call to
- * {@link #findLocalSession(String)} or brought into local management by a
- * call to {@link #findSessions()}.
- *
- * @param realId the session id, with any trailing jvmRoute removed.
- *
- * @see #getRealId(String)
- */
- public ClusteredSession findLocalSession(String realId)
- {
- ClusteredSession session = (ClusteredSession) sessions_.get(realId);
- return session;
- }
-
- /**
- * Removes the session from this Manager's collection of actively managed
- * sessions. Also removes the session from the distributed cache, both
- * on this server and on all other server to which this one replicates.
- */
- public void remove(Session session)
- {
- ClusteredSession clusterSess = (ClusteredSession) session;
- synchronized (clusterSess)
- {
- String realId = clusterSess.getRealId();
- if (realId == null)
- return;
-
- if (log_.isDebugEnabled())
- {
- log_.debug("Removing session from store with id: " + realId);
- }
-
- try {
- // Ignore any cache notifications that our own work generates
- LocalSessionActivity.startLocalActivity(realId);
- clusterSess.removeMyself();
- }
- finally {
- LocalSessionActivity.finishLocalActivity();
- }
-
- sessions_.remove(realId);
- stats_.removeStats(realId);
- }
- activeCounter_--;
- }
-
- /**
- * Removes the session from this Manager's collection of actively managed
- * sessions. Also removes the session from this server's copy of the
- * distributed cache (but does not remove it from other servers'
- * distributed cache).
- */
- public void removeLocal(Session session)
- {
- ClusteredSession clusterSess = (ClusteredSession) session;
- synchronized (clusterSess)
- {
- String realId = clusterSess.getRealId();
- if (realId == null) return;
-
- if (log_.isDebugEnabled())
- {
- log_.debug("Removing session from local store with id: " + realId);
- }
- clusterSess.removeMyselfLocal();
- sessions_.remove(realId);
- stats_.removeStats(realId);
- }
-
- // Update counters.
- // It's a bit ad-hoc to do it here. But since we currently call
- // this when session expires ...
- expiredCounter_++;
- activeCounter_--;
- }
-
- /**
- * Loads a session from the distributed store. If an existing session with
- * the id is already under local management, that session's internal state
- * will be updated from the distributed store. Otherwise a new session
- * will be created and added to the collection of those sessions under
- * local management.
- *
- * @param realId id of the session-id with any jvmRoute removed
- *
- * @return the session or <code>null</code> if the session cannot be found
- * in the distributed store
- */
- protected ClusteredSession loadSession(String realId)
- {
- if (realId == null)
- {
- return null;
- }
-
- long begin = System.currentTimeMillis();
- boolean mustAdd = false;
- ClusteredSession session = (ClusteredSession) sessions_.get(realId);
- if (session == null)
- {
- // This is either the first time we've seen this session on this
- // server, or we previously expired it and have since gotten
- // a replication message from another server
- mustAdd = true;
- session = createEmptyClusteredSession();
- }
-
- synchronized (session)
- {
- boolean doTx = false;
- try
- {
- // We need transaction so any data gravitation replication
- // is sent in batch.
- // Don't do anything if there is already transaction context
- // associated with this thread.
- if(tm.getTransaction() == null)
- doTx = true;
-
- if(doTx)
- tm.begin();
-
- // Ignore cache notifications we may generate for this
- // session if data gravitation occurs.
- LocalSessionActivity.startLocalActivity(realId);
-
- session = proxy_.loadSession(realId, session);
- }
- catch (Exception ex)
- {
- try
- {
-// if(doTx)
- // Let's set it no matter what.
- tm.setRollbackOnly();
- }
- catch (Exception exn)
- {
- exn.printStackTrace();
- }
- // We will need to alert Tomcat of this exception.
- if (ex instanceof RuntimeException)
- throw (RuntimeException) ex;
-
- throw new RuntimeException("loadSession(): failed to load session " +
- realId, ex);
- }
- finally
- {
- try {
- if(doTx)
- endTransaction(realId);
- }
- finally {
- LocalSessionActivity.finishLocalActivity();
- }
- }
-
- if (session != null)
- {
- // Need to initialize.
- session.initAfterLoad(this);
- if (mustAdd)
- add(session, false); // don't replicate
- long elapsed = System.currentTimeMillis() - begin;
- stats_.updateLoadStats(realId, elapsed);
-
- if (log_.isDebugEnabled())
- {
- log_.debug("loadSession(): id= " + realId + ", session=" + session);
- }
- }
- else if (log_.isDebugEnabled())
- {
- log_.debug("loadSession(): session " + realId +
- " not found in distributed cache");
- }
- }
-
- return session;
- }
-
- /**
- * Places the current session contents in the distributed cache and
- * replicates them to the cluster
- *
- * @param session the session. Cannot be <code>null</code>.
- */
- protected void processSessionRepl(ClusteredSession session)
- {
- // If we are using SESSION granularity, we don't want to initiate a TX
- // for a single put
- boolean notSession = (replicationGranularity_ != WebMetaData.REPLICATION_GRANULARITY_SESSION);
- boolean doTx = false;
- String realId = session.getRealId();
- try
- {
- // We need transaction so all the replication are sent in batch.
- // Don't do anything if there is already transaction context
- // associated with this thread.
- if(notSession && tm.getTransaction() == null)
- doTx = true;
-
- if(doTx)
- tm.begin();
-
- // Tell the proxy to ignore cache notifications we are about
- // to generate for this session. We have to do this
- // at this level because we don't want to resume handling
- // notifications until any compensating changes resulting
- // from a tx rollback are done.
- LocalSessionActivity.startLocalActivity(realId);
-
- session.processSessionRepl();
- }
- catch (Exception ex)
- {
- if (log_.isDebugEnabled())
- log_.debug("processSessionRepl(): failed with exception", ex);
-
- try
- {
-// if(doTx)
- // Let's set it no matter what.
- tm.setRollbackOnly();
- }
- catch (Exception exn)
- {
- exn.printStackTrace();
- }
-
- // We will need to alert Tomcat of this exception.
- if (ex instanceof RuntimeException)
- throw (RuntimeException) ex;
-
- throw new RuntimeException("JBossCacheManager.processSessionRepl(): " +
- "failed to replicate session.", ex);
- }
- finally
- {
- try {
- if(doTx)
- endTransaction(session.getId());
- }
- finally {
- LocalSessionActivity.finishLocalActivity();
- }
- }
- }
-
- protected void endTransaction(String id)
- {
- if (tm == null)
- {
- log_.warn("JBossCacheManager.endTransaction(): tm is null for id: " +id);
- return;
- }
-
-
- try
- {
- if(tm.getTransaction().getStatus() != Status.STATUS_MARKED_ROLLBACK)
- {
- tm.commit();
- }
- else
- {
- log_.info("JBossCacheManager.endTransaction(): rolling back tx for id: " +id);
- tm.rollback();
- }
- }
- catch (RollbackException re)
- {
- // Do nothing here since cache may rollback automatically.
- log_.warn("JBossCacheManager.endTransaction(): rolling back transaction with exception: " +re);
- }
- catch (Exception e)
- {
- throw new RuntimeException("JBossCacheManager.endTransaction(): Exception for id: " +id, e);
- }
- }
-
- /**
- * Goes through all sessions and look if they have expired.
- * Note this overrides the method in JBossManager.
- */
- protected void processExpires()
- {
- if (maxInactiveInterval_ < 0)
- {
- return;
- }
-
- if (log_.isTraceEnabled())
- {
- log_.trace("processExpires():max active sessions = " + maxActive_);
- log_.trace("processExpires(): passivation mode = " + isPassivationEnabled());
- log_.trace("processExpires(): Looking for sessions that have expired ...");
- }
-
- log_.info("prcessExpires():current sessions map size = " + sessions_.size() + ", max active sessions = " + maxActive_ + " and passivation mode = " + isPassivationEnabled());
- try
- {
- // First, handle the sessions we are actively managing
- Session sessions[] = findLocalSessions();
-
- for (int i = 0; i < sessions.length; ++i)
- {
- try
- {
- ClusteredSession session = (ClusteredSession) sessions[i];
- if(session == null)
- {
- log_.warn("processExpires(): processing null session at index " +i);
- continue;
- }
-
- // JBAS-2403. Check for outdated sessions where we think
- // the local copy has timed out. If found, refresh the
- // session from the cache in case that might change the timeout
- if (session.isOutdated() && !(session.isValid(false)))
- {
- // JBAS-2792 don't assign the result of loadSession to session
- // just update the object from the cache or fall through if
- // the session has been removed from the cache
- loadSession(session.getRealId());
- }
-
- // Do a normal invalidation check that will expire any
- // sessions that have timed out
- // DON'T SYNCHRONIZE on session here -- isValid() and
- // expire() are meant to be multi-threaded and synchronize
- // properly internally; synchronizing externally can lead
- // to deadlocks!!
- if (!session.isValid()) continue;
-
- // JBCLUSTER-15
- if (log_.isTraceEnabled())
- {
- log_.trace("processExpires(): Checking passivation for session " + session.getId());
- }
- // now that we have valid session, see if we need to
- // passivate it based on the configurable passivation min and max Idle time
- if (isPassivationEnabled())
- {
- long timeNow = System.currentTimeMillis();
- int timeIdle = (int) ((timeNow - session.getLastAccessedTimeInternal()) / 1000L);
- // if maxIdle time configured, means that we need to passivate sessions that have
- // exceeded the max allowed idle time
- if (passivationMaxIdleTime_ >= 0 && timeIdle > passivationMaxIdleTime_)
- {
- if(log_.isTraceEnabled())
- {
- log_.trace("JBossCacheManager.processExpires() passivating session " + session.getRealId());
- }
- processSessionPassivation(session.getRealId(), this.getContainer().getParent().getName());
- }
- // If the session didn't exceed the passivationMaxIdleTime_, See
- // if the number of sessions managed by this manager greater than the max allowed
- // active sessions, passivate the session if it exceed passivationMinIdleTime_
- else if (maxActive_ > 0 && passivationMinIdleTime_ > 0 && sessions_.size()> maxActive_)
- {
- if(timeIdle > passivationMinIdleTime_)
- {
- if(log_.isTraceEnabled())
- {
- log_.debug("JBossCacheManager.processExpires() passivating session " + session.getRealId());
- }
- processSessionPassivation(session.getRealId(), this.getContainer().getParent().getName());
- }
- }
- }
-
- }
- catch (Exception ex)
- {
- log_.error("processExpires(): failed expiring " +
- sessions[i].getIdInternal() + " with exception: " +
- ex, ex);
- }
- }
-
- // Next, handle any unloaded sessions that are stale
-
- long now = System.currentTimeMillis();
- Map unloaded = new HashMap(unloadedSessions_);
- Set entries = unloaded.entrySet();
- for (Iterator it = entries.iterator(); it.hasNext(); )
- {
- Map.Entry entry = (Map.Entry) it.next();
- OwnedSessionUpdate osu = (OwnedSessionUpdate) entry.getValue();
- int elapsed = (int) ((now - osu.updateTime) / 1000L);
- if (elapsed >= maxInactiveInterval_)
- {
- String realId = (String) entry.getKey();
- try
- {
- proxy_.removeSessionLocal(realId, osu.owner);
- unloadedSessions_.remove(realId);
- }
-
- // JBClUSTER-15
- // we don't need to worry about session passivation here, since the
- // method processSessionPassivation() takes care of unloadedSessions_ map
- // when it's receives a notification of passivation event happened in the
- // distributed store from the CacheListener
- catch (Exception ex)
- {
- log_.error("processExpire(): failed removing unloaded session " +
- realId + " with exception: " +
- ex, ex);
- }
- }
- }
- }
- catch (Exception ex)
- {
- log_.error("processExpires: failed with exception: " + ex, ex);
- }
- }
-
- public void processRemoteInvalidation(String realId)
- {
- // Remove the session from our local map
- ClusteredSession session = (ClusteredSession) sessions_.remove(realId);
- if (session == null)
- {
- // We weren't managing the session anyway. But remove it
- // from the list of cached sessions we haven't loaded
- unloadedSessions_.remove(realId);
- }
- else
- {
- // Expire the session
- // DON'T SYNCHRONIZE ON SESSION HERE -- isValid() and
- // expire() are meant to be multi-threaded and synchronize
- // properly internally; synchronizing externally can lead
- // to deadlocks!!
- boolean notify = false; // Don't notify listeners. SRV.10.7
- // allows this, and sending notifications
- // leads to all sorts of issues; e.g.
- // circular calls with ClusteredSSO
- boolean localCall = false; // this call originated from the cache;
- // we have already removed session
- boolean localOnly = true; // Don't pass attr removals to cache
- session.expire(notify, localCall, localOnly);
-
- // Remove any stats for this session
- stats_.removeStats(realId);
-
- // Update counter.
- activeCounter_--;
- }
- }
-
- public void processSessionPassivation(String realId, String dataOwner)
- {
- // get the session from the local map
- ClusteredSession session = findLocalSession(realId);
- // only remove actively managed session and add to the unloaded sessions
- // if it's already unloaded session (session == null) don't do anything,
- // the evict notification will tell the server that has the session to remove it.
- if (session != null)
- {
- synchronized (session)
- {
- if (log_.isTraceEnabled())
- {
- log_.trace("Passivating session with id: " + realId);
- }
-
- try {
- // Tell the proxy to ignore cache notifications we are about
- // to generate for this session.
- LocalSessionActivity.startLocalActivity(realId);
- session.passivate();
- proxy_.evictSession(realId);
- }
- finally {
- LocalSessionActivity.finishLocalActivity();
- }
-
- Object obj = unloadedSessions_.put(realId,
- new OwnedSessionUpdate(dataOwner, session.getLastAccessedTime()));
- if (log_.isTraceEnabled())
- {
- if (obj == null)
- {
- log_.trace("New session " + realId + " added to unloaded session map");
- }
- else
- {
- log_.trace("Updated timestamp for unloaded session " + realId);
- }
- }
- sessions_.remove(realId);
- stats_.removeStats(realId);
- }
- activeCounter_--;
- }
- }
-
- /**
- * Gets the session id with any jvmRoute removed.
- *
- * @param id a session id with or without an appended jvmRoute.
- * Cannot be <code>null</code>.
- */
- protected String getRealId(String id)
- {
- return (useJK_ ? Util.getRealId(id) : id);
- }
-
- /**
- * Callback from the CacheListener to notify us that a session
- * we haven't loaded has been changed.
- *
- * @param realId the session id, without any trailing jvmRoute
- * @param dataOwner the owner of the session. Can be <code>null</code> if
- * the owner is unknown.
- */
- protected void unloadedSessionChanged(String realId, String dataOwner)
- {
- Object obj = unloadedSessions_.put(realId,
- new OwnedSessionUpdate(dataOwner, System.currentTimeMillis()));
- if (log_.isTraceEnabled())
- {
- if (obj == null)
- {
- log_.trace("New session " + realId + " added to unloaded session map");
- }
- else
- {
- log_.trace("Updated timestamp for unloaded session " + realId);
- }
- }
- }
-
- /**
- * Returns true if the passivation mode is set to true in JBoss-web.xml and JBoss Cache passivation
- * has been enabled with proper configured cache loader. Otherwise, it returns false
- *
- * @return
- */
- protected boolean isPassivationEnabled()
- {
- return (passivationMode_ && proxy_.isCachePassivationEnabled());
- }
- // ---------------------------------------------------- Lifecyle Unembedded
-
- /**
- * Start this Manager when running embedded in JBoss AS.
- *
- * @throws org.apache.catalina.LifecycleException
- */
- private void startEmbedded() throws LifecycleException
- {
- super.start();
-
- // Start the JBossCacheService
- // Will need to pass the classloader that is associated with this
- //web app so de-serialization will work correctly.
- ClassLoader tcl = super.getContainer().getLoader().getClassLoader();
-
- proxy_.start(tcl, this);
-
- tm = proxy_.getTransactionManager();
- if(tm == null)
- {
- throw new LifecycleException("JBossCacheManager.start(): Obtain null tm");
- }
-
- try
- {
- initializeUnloadedSessions();
-
- // Add SnapshotValve and, if needed, JvmRouteValve and batch repl valve
- installValves();
-
- if (log_.isDebugEnabled())
- {
- log_.debug("start(): JBossCacheService started");
- }
- }
- catch (Exception e)
- {
- log_.error("Unable to start manager.", e);
- throw new LifecycleException(e);
- }
- }
-
- // ----------------------------------------------- Lifecyle When Unembedded
-
- /**
- * Start this Manager when running in standalone Tomcat.
- */
- private void startUnembedded() throws LifecycleException
- {
- if (started_)
- {
- return;
- }
-
- if (log_.isInfoEnabled())
- {
- log_.info("Manager is about to start");
- }
-
- // Notify our interested LifecycleListeners
- lifecycle_.fireLifecycleEvent(BEFORE_START_EVENT, this);
-
- if (snapshotMode_ == null)
- {
- // We were not instantiated by a JBossCacheCluster, so we need to
- // find one and let it configure our cluster-wide properties
- try
- {
- JBossCacheCluster cluster = (JBossCacheCluster) container_.getCluster();
- cluster.configureManager(this);
- }
- catch (ClassCastException e)
- {
- String msg = "Cluster is not an instance of JBossCacheCluster";
- log_.error(msg, e);
- throw new LifecycleException(msg, e);
- }
- }
-
- // Validate attributes
-
- if ("SET_AND_GET".equalsIgnoreCase(replTriggerString_))
- this.invalidateSessionPolicy_ = WebMetaData.SESSION_INVALIDATE_SET_AND_GET;
- else if ("SET_AND_NON_PRIMITIVE_GET".equalsIgnoreCase(replTriggerString_))
- this.invalidateSessionPolicy_ = WebMetaData.SESSION_INVALIDATE_SET_AND_NON_PRIMITIVE_GET;
- else if ("SET".equalsIgnoreCase(replTriggerString_))
- this.invalidateSessionPolicy_ = WebMetaData.SESSION_INVALIDATE_SET;
- else
- throw new LifecycleException("replication-trigger value set to a " +
- "non-valid value: '" +
- replTriggerString_ +
- "' (should be ['SET_AND_GET', " +
- "'SET_AND_NON_PRIMITIVE_GET', 'SET'])");
-
- if ("SESSION".equalsIgnoreCase(replGranularityString_))
- this.replicationGranularity_ = WebMetaData.REPLICATION_GRANULARITY_SESSION;
- else if ("ATTRIBUTE".equalsIgnoreCase(replGranularityString_))
- this.replicationGranularity_ = WebMetaData.REPLICATION_GRANULARITY_ATTRIBUTE;
- else if ("FIELD".equalsIgnoreCase(replGranularityString_))
- this.replicationGranularity_ = WebMetaData.REPLICATION_GRANULARITY_FIELD;
- else
- throw new LifecycleException("replication-granularity value set to " +
- "a non-valid value: '" +
- replGranularityString_ +
- "' (should be ['SESSION', " +
- "'ATTRIBUTE' or 'FIELD'])");
-
- // Create the JBossCacheService
- try
- {
- proxy_ = new JBossCacheService(cacheObjectNameString_);
-
- // Confirm our replication granularity is compatible with the cache
- validateFieldMarshalling();
-
- // We need to pass the classloader that is associated with this
- // web app so de-serialization will work correctly.
- ClassLoader cl = container_.getLoader().getClassLoader();
- proxy_.start(cl, this);
- }
- catch (ClusteringNotSupportedException e)
- {
- throw new LifecycleException(e.getMessage(), e);
- }
- catch (Throwable t)
- {
- String str = "JBossCacheService to Tomcat clustering not found";
- log_.error(str);
- throw new LifecycleException(str, t);
- }
-
- tm = proxy_.getTransactionManager();
- if(tm == null)
- {
- throw new LifecycleException("JBossCacheManager.start(): Obtain null tm");
- }
-
- try
- {
- initializeUnloadedSessions();
-
- // Add SnapshotValve and, if needed, JvmRouteValve and batch repl valve
- installValves();
-
- started_ = true;
-
- // Notify our interested LifecycleListeners
- lifecycle_.fireLifecycleEvent(AFTER_START_EVENT, this);
-
- if (log_.isDebugEnabled())
- {
- log_.debug("start(): JBossCacheService started");
- }
- }
- catch (Exception e)
- {
- log_.error("Unable to start manager.", e);
- throw new LifecycleException(e);
- }
-
- try
- {
- registerMBeans();
- }
- catch (Exception e)
- {
- log_.error("Could not register ManagerMBean with MBeanServer", e);
- }
- }
-
- /**
- * Register this Manager with JMX.
- */
- private void registerMBeans()
- {
- try
- {
- MBeanServer server = getMBeanServer();
-
- String domain;
- if (container_ instanceof ContainerBase)
- {
- domain = ((ContainerBase) container_).getDomain();
- }
- else
- {
- domain = server.getDefaultDomain();
- }
- String hostName = ((Host) container_.getParent()).getName();
- hostName = (hostName == null) ? "localhost" : hostName;
- ObjectName clusterName = new ObjectName(domain
- + ":service=ClusterManager,WebModule=//" + hostName
- + ((Context) container_).getPath());
-
- if (server.isRegistered(clusterName))
- {
- log_.warn("MBean " + clusterName + " already registered");
- return;
- }
-
- objectName_ = clusterName;
- server.registerMBean(this, clusterName);
-
- }
- catch (Exception ex)
- {
- log_.error(ex.getMessage(), ex);
- }
- }
-
- /**
- * Unregister this Manager from the JMX server.
- */
- private void unregisterMBeans()
- {
- if (mserver_ != null)
- {
- try
- {
- mserver_.unregisterMBean(objectName_);
- }
- catch (Exception e)
- {
- log_.error(e);
- }
- }
- }
-
- /**
- * Get the current MBean Server.
- *
- * @return
- * @throws Exception
- */
- private MBeanServer getMBeanServer() throws Exception
- {
- if (mserver_ == null)
- {
- mserver_ = MBeanServerLocator.locateJBoss();
- }
- return (mserver_);
- }
-
- /**
- * Gets the ids of all sessions in the distributed cache and adds
- * them to the unloaded sessions map, with the current time as the
- * last replication time. This means these sessions may not be
- * evicted from the cache for a period well beyond when they would
- * normally expire, but this is a necessary tradeoff to avoid
- * deserializing them all to check their lastAccessedTime.
- */
- private void initializeUnloadedSessions() throws CacheException
- {
- Map sessions = proxy_.getSessionIds();
- if (sessions != null)
- {
- long now = System.currentTimeMillis();
- for (Iterator it = sessions.entrySet().iterator(); it.hasNext(); )
- {
- Map.Entry entry = (Entry) it.next();
- unloadedSessions_.put(entry.getKey(),
- new OwnedSessionUpdate((String) entry.getValue(), now));
- }
- }
- }
-
- /**
- * Instantiate a SnapshotManager and ClusteredSessionValve and add
- * the valve to our parent Context's pipeline.
- * Add a JvmRouteValve and BatchReplicationClusteredSessionValve if needed.
- *
- */
- private void installValves()
- {
- if (useJK_)
- {
- log_.info("We are using mod_jk(2) for load-balancing. " +
- "Will add JvmRouteValve.");
-
- installContextValve(new JvmRouteValve(this));
- }
-
- // Add batch replication valve if needed.
- if (replicationGranularity_ == WebMetaData.REPLICATION_GRANULARITY_FIELD &&
- Boolean.TRUE.equals(replicationFieldBatchMode_))
- {
- Valve batchValve = new BatchReplicationClusteredSessionValve(this);
- log_.debug("Adding BatchReplicationClusteredSessionValve for batch replication.");
- installContextValve(batchValve);
- }
- // Choose the snapshot manager
- String ctxPath = ((Context) container_).getPath();
- SnapshotManager snap = null;
- if ("instant".equals(snapshotMode_) || replicationGranularity_
- == WebMetaData.REPLICATION_GRANULARITY_FIELD)
- {
- snap = new InstantSnapshotManager(this, ctxPath);
- }
- else if ("interval".equals(snapshotMode_))
- {
- snap = new IntervalSnapshotManager(this, ctxPath, snapshotInterval_);
- }
- else
- {
- log_.error("Snapshot mode must be 'instant' or 'interval' - " +
- "using 'instant'");
- snap = new InstantSnapshotManager(this, ctxPath);
- }
-
- // Add the session snapshot valve to the Context
- ClusteredSessionValve valve = new ClusteredSessionValve(snap);
- installContextValve(valve);
- }
-
- private void installContextValve(Valve valve)
- {
- boolean installed = false;
-
- // In embedded mode, install the valve via JMX to be consistent
- // with the way the overall context is created in TomcatDeployer.
- // We can't do this in unembedded mode because we are called
- // before our Context is registered with the MBean server
- if (embedded_ && getContextObjectName() != null) {
- try
- {
- getMBeanServer().invoke(getContextObjectName(), "addValve",
- new Object[]{valve},
- new String[]{"org.apache.catalina.Valve"});
- installed = true;
- }
- catch (Exception e)
- {
- // JBAS-2422. If the context is restarted via JMX, the above
- // JMX call will fail as the context will not be registered
- // when it's made. So we catch the exception and fall back
- // to adding the valve directly.
- // TODO consider skipping adding via JMX and just do it directly
- if (log_.isDebugEnabled())
- log_.debug("Caught exception installing valve to Context", e);
- }
- }
-
- if (!installed)
- {
- // If possible install via the ContainerBase.addValve() API.
- if (container_ instanceof ContainerBase)
- {
- ((ContainerBase) container_).addValve(valve);
- }
- else
- {
- // No choice; have to add it to the context's pipeline
- container_.getPipeline().addValve(valve);
- }
- }
- }
-
- /**
- * If we are using FIELD granularity, checks that the TreeCache
- * supports marshalling.
- *
- * @throws ClusteringNotSupportedException if not
- */
- private void validateFieldMarshalling() throws ClusteringNotSupportedException
- {
- if (replicationGranularity_ == WebMetaData.REPLICATION_GRANULARITY_FIELD
- && !proxy_.isMarshallingAvailable())
- {
- throw new ClusteringNotSupportedException("replication-granularity value is set to " +
- "'FIELD' but is not supported by the cache service configuration. " +
- "Must set 'UseRegionBasedMarshalling' to 'true' in the tc5-cluster-service.xml");
- }
- }
-
- private ObjectName getContextObjectName()
- {
- String oname = container_.getObjectName();
- try
- {
- return (oname == null) ? null : new ObjectName(oname);
- }
- catch (MalformedObjectNameException e)
- {
- log_.warn("Error creating object name from string " + oname, e);
- return null;
- }
- }
-
-
- private class OwnedSessionUpdate
- {
- String owner;
- long updateTime;
-
- OwnedSessionUpdate(String owner, long updateTime)
- {
- this.owner = owner;
- this.updateTime = updateTime;
- }
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManagerMBean.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManagerMBean.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheManagerMBean.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,107 +0,0 @@
-package org.jboss.web.tomcat.tc5.session;
-
-public interface JBossCacheManagerMBean extends JBossManagerMBean
-{
- /**
- * Gets the value of the attribute with the given key from the given
- * session. If the session is in the distributed store but hasn't been
- * loaded on this node, invoking this method will cause it to be loaded.
- *
- * @param sessionId the id of the session
- * @param key the attribute key
- * @return the value, or <code>null</code> if the session or
- * key does not exist.
- */
- Object getSessionAttribute(String sessionId, String key);
-
- /**
- * Same as <code>getSessionAttribute(sessionId, key).toString()</code>.
- *
- */
- String getSessionAttributeString(String sessionId, String key);
-
- /**
- * Expires the given session. If the session is in the distributed store
- * but hasn't been loaded on this node, invoking this method will cause it
- * to be loaded.
- *
- * @param sessionId the id of the session
- */
- void expireSession(String sessionId);
-
- /**
- * Gets the last time the given session was accessed on this node.
- * Information about sessions stored in the distributed store but never
- * accessed on this node will not be made available.
- *
- * @param sessionId
- * @return the last accessed time, or <code>null</code> if the session
- * has expired or has never been accessed on this node.
- */
- String getLastAccessedTime(String sessionId);
-
- /**
- * Gets the JMX ObjectName of the distributed session cache as a string.
- */
- String getCacheObjectNameString();
-
- /**
- * Gets the replication granularity.
- *
- * @return SESSION, ATTRIBUTE or FIELD, or <code>null</code> if this
- * has not yet been configured.
- */
- String getReplicationGranularityString();
-
- /**
- * Gets the replication trigger.
- *
- * @return SET, SET_AND_GET, SET_AND_NON_PRIMITIVE_GET or <code>null</code>
- * if this has not yet been configured.
- */
- String getReplicationTriggerString();
-
- /**
- * Gets whether batching of field granularity changes will be done. Only
- * relevant with replication granularity FIELD.
- *
- * @return <code>true</code> if per-request batching will be done,
- * <code>false</code> if not, <code>null</code> if not configured
- */
- Boolean isReplicationFieldBatchMode();
-
- /**
- * Gets whether JK is being used and special handling of a jvmRoute
- * portion of session ids is needed.
- */
- boolean getUseJK();
-
- /**
- * Gets the snapshot mode.
- *
- * @return "instant" or "interval"
- */
- String getSnapshotMode();
-
- /**
- * Gets the number of milliseconds between replications if "interval" mode
- * is used.
- */
- int getSnapshotInterval();
-
- /**
- * Lists all session ids known to this manager, including those in the
- * distributed store that have not been accessed on this node.
- *
- * @return a comma-separated list of session ids
- */
- String listSessionIds();
-
- /**
- * Lists all session ids known to this manager, excluding those in the
- * distributed store that have not been accessed on this node.
- *
- * @return a comma-separated list of session ids
- */
- String listLocalSessionIds();
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheService.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheService.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheService.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,1142 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.StringTokenizer;
-import java.util.WeakHashMap;
-
-import javax.management.ObjectName;
-import javax.transaction.TransactionManager;
-
-import org.apache.catalina.Context;
-import org.jboss.aspects.patterns.observable.Observer;
-import org.jboss.aspects.patterns.observable.Subject;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.aop.PojoCacheMBean;
-import org.jboss.cache.transaction.BatchModeTransactionManager;
-import org.jboss.invocation.MarshalledValue;
-import org.jboss.invocation.MarshalledValueInputStream;
-import org.jboss.invocation.MarshalledValueOutputStream;
-import org.jboss.logging.Logger;
-import org.jboss.mx.util.MBeanProxyExt;
-
-/**
- * A wrapper class to JBossCache. This is currently needed to handle various operations such as
- * <ul>
- * <li>Using MarshalledValue to replace Serializable used inside different web app class loader context.</li>
- * <li>Stripping out any id string after ".". This is to handle the JK failover properly with
- * Tomcat JvmRoute.</li>
- * <li>Cache exception retry.</li>
- * <li>Helper APIS.</li>
- * </ul>
- */
-public class JBossCacheService
-{
- // Types that are considered "primitive".
- private static final Set immediates =
- new HashSet(Arrays.asList(new Object[]{
- String.class,
- Boolean.class,
- Double.class,
- Float.class,
- Integer.class,
- Long.class,
- Short.class,
- Character.class,
- Boolean.TYPE,
- Double.TYPE,
- Float.TYPE,
- Integer.TYPE,
- Long.TYPE,
- Short.TYPE,
- Character.TYPE,
- Class.class}));
-
- protected static Logger log_ = Logger.getLogger(JBossCacheService.class);
- public static final String BUDDY_BACKUP = "_BUDDY_BACKUP_";
- public static final Fqn BUDDY_BACKUP_FQN = new Fqn("_BUDDY_BACKUP_");
- public static final String SESSION = "JSESSION";
- public static final String ATTRIBUTE = "ATTRIBUTE";
- public static final String KEY = "ATRR_KEY";
- // Needed for cache invalidation
- static final String VERSION_KEY = "VERSION";
- static final String FQN_DELIMITER = "/";
-
- private PojoCacheMBean proxy_;
- private ObjectName cacheServiceName_;
-
- // name of webapp's virtual host(JBAS-2194).
- // Idea is host_name + web_app_path + session id is a unique combo.
- private String hostName_;
- // web app path (JBAS-1367 and JBAS-2194).
- // Idea is host_name + web_app_path + session id is a unique combo.
- private String webAppPath_;
- private TransactionManager tm;
-
- // Class loader for this web app.
- private ClassLoader tcl_;
- private JBossCacheManager manager_;
- private CacheListener cacheListener_;
- private JBossCacheWrapper cacheWrapper_;
-
- // Do we have to marshall attributes ourself or can we let
- // the TreeCache do it?
- private boolean useTreeCacheMarshalling_ = false;
-
- private WeakHashMap typeMap = new WeakHashMap();
-
- public JBossCacheService(String treeCacheObjectName) throws ClusteringNotSupportedException
- {
- // Find JBossCacheService
- try
- {
- cacheServiceName_ = new ObjectName(treeCacheObjectName);
- // Create Proxy-Object for this service
- proxy_ = (PojoCacheMBean) MBeanProxyExt.create(PojoCacheMBean.class,
- cacheServiceName_);
- if (proxy_ == null)
- {
- throw new RuntimeException("JBossCacheService: locate null TomcatCacheMbean");
- }
-
- cacheWrapper_ = new JBossCacheWrapper(proxy_);
-
- useTreeCacheMarshalling_ = proxy_.getUseRegionBasedMarshalling();
- }
- catch (Throwable e)
- {
- String str = cacheServiceName_ + " service to Tomcat clustering not found";
- log_.error(str);
- throw new ClusteringNotSupportedException(str);
- }
- }
-
- public void start(ClassLoader tcl, JBossCacheManager manager)
- {
- tcl_ = tcl;
- manager_ = manager;
-
- Context webapp = (Context) manager_.getContainer();
- String path = webapp.getName();
- if( path.length() == 0 || path.equals("/")) {
- // If this is root.
- webAppPath_ = "ROOT";
- } else if ( path.startsWith("/") ) {
- webAppPath_ = path.substring(1);
- } else {
- webAppPath_ = path;
- }
- log_.debug("Old and new web app path are: " +path + ", " +webAppPath_);
-
- String host = webapp.getParent().getName();
- if( host == null || host.length() == 0) {
- hostName_ = "localhost";
- }else {
- hostName_ = host;
- }
- log_.debug("Old and new virtual host name are: " + host + ", " + hostName_);
-
-
- // Construct the fqn
- Object[] objs = new Object[]{SESSION, hostName_, webAppPath_};
- Fqn pathFqn = new Fqn( objs );
-
- cacheListener_ = new CacheListener(cacheWrapper_, manager_, pathFqn);
- proxy_.addTreeCacheListener(cacheListener_);
-
- // register the tcl and bring over the state for the webapp
- String fqnStr = pathFqn.toString();
- try {
- if(useTreeCacheMarshalling_)
- {
- log_.debug("UseMarshalling is true. We will register the fqn: " +
- fqnStr + " with class loader" +tcl_ +
- " and activate the webapp's Region");
- proxy_.registerClassLoader(fqnStr, tcl_);
- proxy_.activateRegion(fqnStr);
- }
- } catch (Exception ex)
- {
- throw new RuntimeException("Can't register class loader", ex);
- }
-
- // We require the cache tm to be BatchModeTransactionManager now.
- tm = proxy_.getTransactionManager();
- if( ! (tm instanceof BatchModeTransactionManager) )
- {
- throw new RuntimeException("JBossCacheService.start(): JBossCacheAop transaction manager is not type BatchModeTransactionManager." +
- " Please check the tc5-cluster-service.xml TransactionManagerClassLookup field.");
- }
-
- if(isCachePassivationEnabled())
- {
- log_.info("JBossCacheService.start(): JBossCache passivation is enabled");
- }
- else
- {
- log_.info("JBossCacheService.start(): JBossCache passivation is disabled");
- }
- }
-
- public void stop()
- {
- proxy_.removeTreeCacheListener(cacheListener_);
-
- // Construct the fqn
- Object[] objs = new Object[]{SESSION, hostName_, webAppPath_};
- Fqn pathFqn = new Fqn( objs );
-
- String fqnStr = pathFqn.toString();
- if(useTreeCacheMarshalling_)
- {
- log_.debug("UseMarshalling is true. We will inactivate the fqn: " +
- fqnStr + " and un-register its classloader");
-
- try {
- proxy_.inactivateRegion(fqnStr);
- proxy_.unregisterClassLoader(fqnStr);
- }
- catch (Exception e)
- {
- log_.error("Exception during inactivation of webapp region " + fqnStr +
- " or un-registration of its class loader", e);
- }
- }
-
- // remove session data
- cacheWrapper_.removeLocalSubtree(pathFqn);
- }
-
- /**
- * Get specfically the BatchModeTransactionManager.
- */
- public TransactionManager getTransactionManager()
- {
- return tm;
- }
-
- /**
- * Gets whether TreeCache-based marshalling is available
- */
- public boolean isMarshallingAvailable()
- {
- return useTreeCacheMarshalling_;
- }
-
- /**
- * Loads any serialized data in the cache into the given session
- * using its <code>readExternal</code> method.
- *
- * @return the session passed as <code>toLoad</code>, or
- * <code>null</code> if the cache had no data stored
- * under the given session id.
- */
- public ClusteredSession loadSession(String realId, ClusteredSession toLoad)
- {
- Fqn fqn = getSessionFqn(realId);
- Object sessionData = cacheWrapper_.get(fqn, realId, true);
-
- if (sessionData == null) {
- // Requested session is no longer in the cache; return null
- return null;
- }
-
- boolean firstLoad = (toLoad.getVersion() == 0);
-
-// if (useTreeCacheMarshalling_)
-// {
-// toLoad.update((ClusteredSession) sessionData);
-// }
-// else
-// {
- byte[] sessionBytes = (byte[]) sessionData;
-
- // Swap in/out the webapp classloader so we can deserialize
- // attributes whose classes are only available to the webapp
- ClassLoader prevTCL = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(tcl_);
- try
- {
- ByteArrayInputStream bais = new ByteArrayInputStream(sessionBytes);
- // Use MarshalledValueInputStream instead of superclass ObjectInputStream
- // or else there are problems finding classes with scoped loaders
- MarshalledValueInputStream input = new MarshalledValueInputStream(bais);
- toLoad.readExternal(input);
- input.close();
- }
- catch (Exception e)
- {
- log_.error("loadSession(): id: " + realId + "exception occurred during serialization: " +e);
- return null;
- }
- finally {
- Thread.currentThread().setContextClassLoader(prevTCL);
- }
-// }
-
- // The internal version of the serialized session may be less than the
- // real one due to not replicating metadata. If our listener hasn't
- // been keeping the outdatedVersion of the session up to date because
- // the session has never been loaded into the JBCManager cache, we
- // need to fix the version
- if (firstLoad)
- {
- Integer ver = (Integer) cacheWrapper_.get(fqn, VERSION_KEY);
- if (ver != null)
- toLoad.setVersion(ver.intValue());
- }
-
- return toLoad;
- }
-
- public void putSession(String realId, ClusteredSession session)
- {
- Fqn fqn = getSessionFqn(realId);
-
- if (session.getReplicateSessionBody())
- {
- Map map = new HashMap();
-// if (useTreeCacheMarshalling_)
-// map.put(realId, session);
-// else
- map.put(realId, externalizeSession(session));
- // Put in (VERSION_KEY, version) after the real put for cache invalidation
- map.put(VERSION_KEY, new Integer(session.getVersion()));
- cacheWrapper_.put(fqn, map);
- }
- else
- {
- // Invalidate the remote caches
- cacheWrapper_.put(fqn, VERSION_KEY, new Integer(session.getVersion()));
- }
- }
-
- public void removeSession(String realId)
- {
- Fqn fqn = getSessionFqn(realId);
- if (log_.isDebugEnabled())
- {
- log_.debug("Remove session from distributed store. Fqn: " + fqn);
- }
- //Object obj = getUnMarshalledValue(cacheWrapper_.remove(fqn, realId));
- cacheWrapper_.remove(fqn, realId);
- // This needs to go after object removal to support correct cache invalidation.
-// _remove(fqn, VERSION_KEY);
- // Let just remove the whole thing (including the fqn)
- cacheWrapper_.remove(fqn);
- //return obj;
- }
-
- public void removeSessionLocal(String realId)
- {
- Fqn fqn = getSessionFqn(realId);
- if (log_.isDebugEnabled())
- {
- log_.debug("Remove session from my own distributed store only. Fqn: " + fqn);
- }
- cacheWrapper_.removeLocalSubtree(fqn);
- }
-
- public void removeSessionLocal(String realId, String dataOwner)
- {
- if (dataOwner == null)
- {
- removeSessionLocal(realId);
- }
- else
- {
- Fqn fqn = getSessionFqn(realId, dataOwner);
- if (log_.isDebugEnabled())
- {
- log_.debug("Remove session from my own distributed store only. Fqn: " + fqn);
- }
- cacheWrapper_.removeLocalSubtree(fqn);
- }
- }
-
- public void evictSession(String realId)
- {
- Fqn fqn = getSessionFqn(realId);
- if(log_.isDebugEnabled())
- {
- log_.debug("JBossCacheService.evictSession(): evicting session from my distributed store");
- }
- cacheWrapper_.evictSubtree(fqn);
-
- }
-
- public boolean exists(String realId)
- {
- Fqn fqn = getSessionFqn(realId);
- return proxy_.exists(fqn);
- }
-
- public Object getAttribute(String realId, String key)
- {
- Fqn fqn = getAttributeFqn(realId);
- return getUnMarshalledValue(cacheWrapper_.get(fqn, key));
- }
-
- public void putAttribute(String realId, String key, Object value)
- {
- Fqn fqn = getAttributeFqn(realId);
- cacheWrapper_.put(fqn, key, getMarshalledValue(value));
- }
-
- public void putAttribute(String realId, Map map)
- {
- // Duplicate the map with marshalled values
- Map marshalled = new HashMap(map.size());
- Set entries = map.entrySet();
- for (Iterator it = entries.iterator(); it.hasNext(); )
- {
- Map.Entry entry = (Map.Entry) it.next();
- marshalled.put(entry.getKey(), getMarshalledValue(entry.getValue()));
- }
-
- Fqn fqn = getAttributeFqn(realId);
- cacheWrapper_.put(fqn, marshalled);
-
- }
-
- public void removeAttributes(String realId)
- {
- Fqn fqn = getAttributeFqn(realId);
- cacheWrapper_.remove(fqn);
- }
-
- public Object removeAttribute(String realId, String key)
- {
- Fqn fqn = getAttributeFqn(realId);
- if (log_.isTraceEnabled())
- {
- log_.trace("Remove attribute from distributed store. Fqn: " + fqn + " key: " + key);
- }
- return getUnMarshalledValue(cacheWrapper_.remove(fqn, key));
- }
-
- public void removeAttributesLocal(String realId)
- {
- Fqn fqn = getAttributeFqn(realId);
- if (log_.isDebugEnabled())
- {
- log_.debug("Remove attributes from my own distributed store only. Fqn: " + fqn);
- }
- cacheWrapper_.removeLocal(fqn);
- }
-
- /**
- * Obtain the keys associated with this fqn. Note that it is not the fqn children.
- *
- */
- public Set getAttributeKeys(String realId)
- {
- Set keys = null;
- Fqn fqn = getAttributeFqn(realId);
- try
- {
- keys = proxy_.getKeys(fqn);
- }
- catch (CacheException e)
- {
- log_.error("getAttributeKeys(): Exception getting keys for session " + realId, e);
- }
-
- return keys;
- }
-
- /**
- * Return all attributes associated with this session id.
- *
- * @param realId the session id with any jvmRoute removed
- * @return the attributes, or any empty Map if none are found.
- */
- public Map getAttributes(String realId)
- {
- if (realId == null || realId.length() == 0) return new HashMap();
-
- Map map = new HashMap();
- Set set = getAttributeKeys(realId);
- if(set != null)
- {
- for (Iterator it = set.iterator(); it.hasNext();)
- {
- String key = (String) it.next();
- Object value = getAttribute(realId, key);
- map.put(key, value);
- }
- }
- return map;
- }
-
- /**
- * Gets the ids of all sessions in the underlying cache.
- *
- * @return Set containing all of the session ids of sessions in the cache
- * (with any jvmRoute removed) or <code>null</code> if there
- * are no sessions in the cache.
- */
- public Map getSessionIds() throws CacheException
- {
- Map result = new HashMap();
- Set owners = proxy_.getChildrenNames(BUDDY_BACKUP_FQN);
- if (owners != null)
- {
- for (Iterator it = owners.iterator(); it.hasNext();)
- {
- Object owner = it.next();
- Set ids = proxy_.getChildrenNames(getWebappFqn(owner));
- storeSessionOwners(ids, owner, result);
- }
- }
- storeSessionOwners(proxy_.getChildrenNames(getWebappFqn()), null, result);
-
- return result;
- }
-
- private void storeSessionOwners(Set ids, Object owner, Map map)
- {
- if (ids != null)
- {
- for (Iterator it = ids.iterator(); it.hasNext();)
- {
- map.put(it.next(), owner);
- }
- }
- }
-
- /**
- * store the pojo instance in the cache. Note that this is for the aop cache.
- * THe pojo needs to be "aspectized".
- *
- * @param realId the session id with any jvmRoute removed
- * @param key the attribute key
- * @param pojo
- */
- public Object setPojo(String realId, String key, Object pojo)
- {
- // TODO This actually redundant here -- its already in
- // FieldBasedClusteredSession
- if( !Util.checkPojoType(pojo) )
- {
- throw new RuntimeException("setPojo: pojo is not an instance of Advised. Need to declare it in aop: "
- +pojo.toString());
- }
-
- if(log_.isTraceEnabled())
- {
- log_.trace("setPojo(): session id: " + realId + " key: " + key +
- " object: " + pojo.toString());
- }
- // Construct the fqn.
- Fqn fqn = getFieldFqn(realId, key);
- try {
- // Ignore any cache notifications that our own work generates
- LocalSessionActivity.startLocalActivity(realId);
- return proxy_.putObject(fqn, pojo);
- } catch (CacheException e) {
- throw new RuntimeException("JBossCacheService: exception occurred in cache setPojo ... ", e);
- }
- finally {
- LocalSessionActivity.finishLocalActivity();
- }
- }
-
- /**
- * Remove pojo from the underlying cache store.
- * @param realId the session id with any jvmRoute removed
- * @param key the attribute key
- * @return pojo that just removed. Null if there none.
- */
- public Object removePojo(String realId, String key)
- {
- if(log_.isTraceEnabled())
- {
- log_.trace("removePojo(): session id: " +realId + " key: " +key);
- }
- // Construct the fqn.
- Fqn fqn = getFieldFqn(realId, key);
- try {
- // Ignore any cache notifications that our own work generates
- LocalSessionActivity.startLocalActivity(realId);
- return proxy_.removeObject(fqn);
- } catch (CacheException e) {
- throw new RuntimeException("JBossCacheService: exception occurred in cache removePojo ... ", e);
- }
- finally {
- LocalSessionActivity.finishLocalActivity();
- }
- }
-
- /**
- * Remove all the pojos from the underlying cache store locally
- * without replication.
- *
- * @param realId the session id with any jvmRoute removed
- */
- public void removePojosLocal(String realId)
- {
- if(log_.isDebugEnabled())
- {
- log_.debug("removePojoLocal(): session id: " +realId);
- }
- // Construct the fqn.
- Fqn fqn = getAttributeFqn(realId);
- try {
- // Ignore any cache notifications that our own work generates
- LocalSessionActivity.startLocalActivity(realId);
- cacheWrapper_.removeLocalSubtree(fqn);
- }
- finally {
- LocalSessionActivity.finishLocalActivity();
- }
- }
-
- /**
- * Remove all the pojos from the underlying cache store locally
- * without replication.
- *
- * @param realId the session id with any jvmRoute removed
- */
- public void removePojoLocal(String realId, String key)
- {
- if(log_.isTraceEnabled())
- {
- log_.trace("removePojoLocal(): session id: " + realId + " key: " +key);
- }
- // Construct the fqn.
- Fqn fqn = getFieldFqn(realId, key);
- try {
- // Ignore any cache notifications that our own work generates
- LocalSessionActivity.startLocalActivity(realId);
- cacheWrapper_.removeLocalSubtree(fqn);
- }
- finally {
- LocalSessionActivity.finishLocalActivity();
- }
- }
-
- public Set getPojoKeys(String realId)
- {
- Set keys = null;
- Fqn fqn = getAttributeFqn(realId);
- try
- {
- keys = proxy_.getChildrenNames(fqn);
- }
- catch (CacheException e)
- {
- log_.error("getPojoKeys(): Exception getting keys for session " + realId, e);
- }
-
- return keys;
- }
-
-
- /**
- *
- * @param realId the session id with any jvmRoute removed
- * @param key the attribute key
- * @return Pojo that is associated with the attribute
- */
- public Object getPojo(String realId, String key)
- {
- if(log_.isTraceEnabled())
- {
- log_.trace("getPojo(): session id: " +realId + " key: " +key);
- }
- // Construct the fqn.
- Fqn fqn = getFieldFqn(realId, key);
-
- try
- {
- return proxy_.getObject(fqn);
- }
- catch (CacheException e)
- {
- throw new RuntimeException("JBossCacheService: exception occurred in cache getPojo ... ", e);
- }
- }
-
- /**
- * Recursively adds session as observer to the pojo graph. Assumes the
- * whole object graph has Subject "introduction" declared. If a portion
- * of the graph isn't a Subject, the recursion does not continue below
- * that part of the graph.
- *
- * @param session the session
- * @param pojo the pojo. Can be <code>null</code>.
- */
- public void addObserver(Observer session, Object pojo)
- {
- addObserver(session, pojo, new Stack());
- }
-
- private void addObserver(Observer session, Object pojo, Stack stack)
- {
- if ( pojo instanceof Collection )
- {
- Collection col = (Collection)pojo;
- for (Iterator i = col.iterator(); i.hasNext();) {
- Object obj = i.next();
- // If not a managed pojo, will return anyway
- addObserver(session, obj, stack);
- }
-
- return;
- }
- else if (pojo instanceof Map)
- {
- Map map = (Map)pojo;
- for (Iterator i = map.keySet().iterator(); i.hasNext();) {
- Object key = i.next();
- Object value = map.get(key);
-
- // Walk thru key and value
- addObserver(session, key, stack);
- addObserver(session, value, stack);
- }
-
- return;
- }
-
- // BRIAN 3/14 changed this from checking Advised to checking Subject
- // since that is what we cast to below
- if(! (pojo instanceof Subject) )
- {
- return; // No need to add observer since it is primitive.
- }
-
- Subject subject = (Subject)pojo;
- subject.addObserver(session);
-
- if(log_.isTraceEnabled())
- {
- log_.trace("addObserver(): session: " +session + " pojo name: " +pojo.getClass().getName());
- }
-
- // Examine each field of the type and its superclasses to see if
- // we need to add the observer to the pojo held by that field
- // Traverse recursively
-
- // First identify and cache the names of all the class'
- // non-immediate fields
- Class type = pojo.getClass();
- Set complexFields = (Set) typeMap.get(type);
- if (complexFields == null)
- {
- complexFields = parseComplexFields(type);
- typeMap.put(type, complexFields);
- }
-
- // Store a ref to the pojo on the stack to avoid cyclic additions
- stack.push(pojo);
-
- for (Iterator iter = complexFields.iterator(); iter.hasNext();)
- {
- String fieldName = (String) iter.next();
- Class curType = type;
- while (curType != null)
- {
- try
- {
- Field field = curType.getDeclaredField(fieldName);
- boolean accessible = field.isAccessible();
- Object value = null;
- try
- {
- field.setAccessible(true);
-
- value=field.get(pojo);
- // Continue recursively unless we've already handled this value
- if (value != null && !stack.contains(value))
- addObserver(session, value, stack);
- break;
- }
- catch(IllegalAccessException e)
- {
- throw new RuntimeException("field access failed", e);
- }
- finally
- {
- field.setAccessible(accessible);
- }
- }
- catch (NoSuchFieldException e)
- {
- // Check if the field is declared in a superclass
- curType = curType.getSuperclass();
- if (curType == null)
- throw new RuntimeException("Field " + fieldName +
- " does not exist", e);
- }
- }
- }
-
- stack.pop();
- }
-
- /**
- * Recursively removes session as observer to the pojo graph. Assumes the
- * whole object graph has Subject "introduction" declared. If a portion
- * of the graph isn't a Subject, the recursion does not continue below
- * that part of the graph.
- *
- * @param session the session
- * @param pojo the pojo to stop observing. Can be <code>null</code>.
- */
- public void removeObserver(Observer session, Object pojo)
- {
- removeObserver(session, pojo, new Stack());
- }
-
- private void removeObserver(Observer session, Object pojo, Stack stack)
- {
- if ( pojo instanceof Collection )
- {
- Collection col = (Collection)pojo;
- for (Iterator i = col.iterator(); i.hasNext();) {
- Object obj = i.next();
- // If not a managed pojo, will return anyway
- removeObserver(session, obj, stack);
- }
-
- return;
- }
- else if (pojo instanceof Map)
- {
- Map map = (Map)pojo;
- for (Iterator i = map.keySet().iterator(); i.hasNext();) {
- Object key = i.next();
- Object value = map.get(key);
-
- // Walk thru key and value
- removeObserver(session, key, stack);
- removeObserver(session, value, stack);
- }
-
- return;
- }
- // BRIAN 3/14 changed this from checking Advised to checking Subject
- // since that is what we cast to below
- if(! (pojo instanceof Subject) )
- {
- return; // No need to add observer since it is primitive.
- }
-
- Subject subject = (Subject)pojo;
- subject.removeObserver(session);
- if(log_.isTraceEnabled())
- {
- log_.trace("removeObserver(): session: " +session + " pojo name: " +pojo.getClass().getName());
- }
-
- // Examine each field of the type and its superclasses to see if
- // we need to remove the observer from the pojo held by that field
- // Traverse recursively
-
- // First identify and cache the names of all the class'
- // non-immediate fields
- Class type = pojo.getClass();
- Set complexFields = (Set) typeMap.get(type);
- if (complexFields == null)
- {
- complexFields = parseComplexFields(type);
- typeMap.put(type, complexFields);
- }
-
- // Store a ref to the pojo on the stack to avoid cyclic additions
- stack.push(pojo);
-
- for (Iterator iter = complexFields.iterator(); iter.hasNext();)
- {
- String fieldName = (String) iter.next();
- Class curType = type;
- while (curType != null)
- {
- try
- {
- Field field = curType.getDeclaredField(fieldName);
- boolean accessible = field.isAccessible();
- Object value = null;
- try
- {
- field.setAccessible(true);
-
- value=field.get(pojo);
- // Continue recursively unless we've already handled this value
- if (value != null && !stack.contains(value))
- removeObserver(session, value, stack);
- break;
- }
- catch(IllegalAccessException e)
- {
- throw new RuntimeException("field access failed", e);
- }
- finally
- {
- field.setAccessible(accessible);
- }
- }
- catch (NoSuchFieldException e)
- {
- // Check if the field is declared in a superclass
- curType = curType.getSuperclass();
- if (curType == null)
- throw new RuntimeException("Field " + fieldName +
- " does not exist", e);
- }
- }
- }
-
- stack.pop();
- }
-
- public boolean isCachePassivationEnabled()
- {
- if(proxy_.getCacheLoader() != null)
- {
- return (proxy_.getCacheLoaderPassivation() &&
- !proxy_.getCacheLoaderShared());
- }
- else
- {
- return false;
- }
- }
- private Fqn getFieldFqn(String id, String key)
- {
- // /SESSION/id/ATTR/key
- // Guard against string with delimiter.
- List list = new ArrayList();
- list.add(SESSION);
- list.add(hostName_);
- list.add(webAppPath_);
- list.add(id);
- list.add(ATTRIBUTE);
- breakKeys(key, list);
- return new Fqn(list);
- }
-
- private void breakKeys(String key, List list)
- {
- StringTokenizer token = new StringTokenizer(key, FQN_DELIMITER);
- while(token.hasMoreTokens())
- {
- list.add(token.nextToken());
- }
- }
-
- private Fqn getWebappFqn()
- {
- // /SESSION/hostname/webAppPath
- Object[] objs = new Object[]{SESSION, hostName_, webAppPath_};
- return new Fqn(objs);
- }
-
- private Fqn getWebappFqn(Object dataOwner)
- {
- if (dataOwner == null)
- return getWebappFqn();
-
- // /SESSION/hostname/webAppPath
- Object[] objs = new Object[]{BUDDY_BACKUP, dataOwner, SESSION, hostName_, webAppPath_};
- return new Fqn(objs);
- }
-
- private Fqn getSessionFqn(String id)
- {
- // /SESSION/hostname/webAppPath/id
- Object[] objs = new Object[]{SESSION, hostName_, webAppPath_, id};
- return new Fqn(objs);
- }
-
- private Fqn getSessionFqn(String id, String dataOwner)
- {
- // /_BUDDY_BACKUP_/dataOwner/SESSION/hostname/webAppPath/id
- Object[] objs = new Object[]{BUDDY_BACKUP, dataOwner, SESSION, hostName_, webAppPath_, id};
- return new Fqn(objs);
- }
-
- private Fqn getAttributeFqn(String id)
- {
- // /SESSION/hostName/webAppPath/id/ATTR
- Object[] objs = new Object[]{SESSION, hostName_, webAppPath_, id, ATTRIBUTE};
- return new Fqn(objs);
- }
-
- private Object getMarshalledValue(Object value)
- {
- // JBAS-2920. For now, continue using MarshalledValue, as
- // it allows lazy deserialization of the attribute on remote nodes
- // For Branch_4_0 this is what we have to do anyway for backwards
- // compatibility. For HEAD we'll follow suit for now.
- // TODO consider only using MV for complex objects (i.e. not primitives)
- // and Strings longer than X.
-
-// if (useTreeCacheMarshalling_)
-// {
-// return value;
-// }
-// else
-// {
- try
- {
- MarshalledValue mv = new MarshalledValue(value);
- if (log_.isTraceEnabled())
- {
- log_.trace("marshalled object to size " + mv.size() + " bytes");
- }
- return mv;
- }
- catch (IOException e)
- {
- log_.error("IOException occurred marshalling value ", e);
- return null;
- }
-// }
- }
-
- private Object getUnMarshalledValue(Object mv)
- {
- // JBAS-2920. For now, continue using MarshalledValue, as
- // it allows lazy deserialization of the attribute on remote nodes
- // For Branch_4_0 this is what we have to do anyway for backwards
- // compatibility. For HEAD we'll follow suit for now.
-// if (useTreeCacheMarshalling_)
-// {
-// return mv;
-// }
-// else
-// {
- if (mv == null) return null;
- // Swap in/out the tcl for this web app. Needed only for un marshalling.
- ClassLoader prevTCL = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(tcl_);
- try
- {
- return ((MarshalledValue) mv).get();
- }
- catch (IOException e)
- {
- log_.error("IOException occurred unmarshalling value ", e);
- return null;
- }
- catch (ClassNotFoundException e)
- {
- log_.error("ClassNotFoundException occurred unmarshalling value ", e);
- return null;
- }
- finally
- {
- Thread.currentThread().setContextClassLoader(prevTCL);
- }
-// }
- }
-
- private byte[] externalizeSession(ClusteredSession session)
- {
- try
- {
- // Write the contents of session to a byte array and store that
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- // Use MarshalledValueOutputStream instead of superclass ObjectOutputStream
- // or else there are problems finding classes with scoped loaders
- MarshalledValueOutputStream oos = new MarshalledValueOutputStream(baos);
- session.writeExternal(oos);
- oos.close(); // flushes bytes to baos
-
- byte[] bytes = baos.toByteArray();
-
- if (log_.isTraceEnabled())
- {
- log_.trace("marshalled object to size " + bytes.length + " bytes");
- }
-
- return bytes;
- }
- catch (Exception e)
- {
- log_.error("externalizeSession(): exception occurred externalizing session " + session, e);
- return null;
- }
-
- }
-
- private Set parseComplexFields(Class clazz)
- {
- Set result = new HashSet();
-
- while (clazz != null)
- {
- Field[] fields = clazz.getDeclaredFields();
- for (int i = 0; i < fields.length; i++)
- {
- if (!immediates.contains(fields[i].getType())
- && isReplicatable(fields[i]))
- {
- result.add(fields[i].getName());
- }
- }
-
- clazz = clazz.getSuperclass();
- }
- return result;
- }
-
- /**
- * Returns false if the given field is static, transient or final.
- *
- * @param f the field
- * @return
- */
- private static boolean isReplicatable(Field f) {
- int mods = f.getModifiers();
- /**
- * The following modifiers are ignored in the cache, i.e., they will not be stored in the cache.
- * Whenever, user trying to access these fields, it will be accessed from the in-memory version.
- */
- if (Modifier.isStatic(mods)
- || Modifier.isTransient(mods)
- || Modifier.isFinal(mods)) {
- return false;
- }
- return true;
- }
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheWrapper.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheWrapper.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossCacheWrapper.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,350 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import org.jboss.cache.Fqn;
-import org.jboss.cache.aop.PojoCacheMBean;
-import org.jboss.cache.config.Option;
-import org.jboss.cache.lock.TimeoutException;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-public class JBossCacheWrapper
-{
- static final Option GRAVITATE_OPTION = new Option();
-
- static
- {
- GRAVITATE_OPTION.setForceDataGravitation(true);
- }
-
- private static final int RETRY = 3;
- private PojoCacheMBean proxy_;
-
- JBossCacheWrapper(PojoCacheMBean cache)
- {
- proxy_ = cache;
- }
-
- /**
- * Wrapper to embed retyr logic.
- *
- * @param fqn
- * @param id
- * @return
- */
- Object get(Fqn fqn, String id)
- {
- return get(fqn, id, false);
- }
-
- /**
- * Wrapper to embed retyr logic.
- *
- * @param fqn
- * @param id
- * @return
- */
- Object get(Fqn fqn, String id, boolean gravitate)
- {
- Exception ex = null;
- for (int i = 0; i < RETRY; i++)
- {
- try
- {
- Object value = null;
- if (gravitate)
- value = proxy_.get(fqn, id, GRAVITATE_OPTION);
- else
- value = proxy_.get(fqn, id);
- return value;
- }
- catch (TimeoutException e)
- {
- ex = e;
- }
- catch (Exception e)
- {
- if (e instanceof RuntimeException)
- throw (RuntimeException) e;
- throw new RuntimeException("JBossCacheService: exception occurred in cache get ... ", e);
- }
- }
- throw new RuntimeException("JBossCacheService: exception occurred in cache get after retry ... ", ex);
- }
-
- /**
- * Wrapper to embed retry logic.
- *
- * @param fqn
- * @param id
- * @param value
- * @return
- */
- void put(Fqn fqn, String id, Object value)
- {
- Exception ex = null;
- for (int i = 0; i < RETRY; i++)
- {
- try
- {
- proxy_.put(fqn, id, value);
- return;
- }
- catch (TimeoutException e)
- {
- ex = e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("JBossCacheService: exception occurred in cache put ... ", e);
- }
- }
- throw new RuntimeException("JBossCacheService: exception occurred in cache put after retry ... ", ex);
- }
-
-
- /**
- * Wrapper to embed retry logic.
- *
- * @param fqn
- * @param map
- */
- void put(Fqn fqn, Map map)
- {
- Exception ex = null;
- for (int i = 0; i < RETRY; i++)
- {
- try
- {
- proxy_.put(fqn, map);
- return;
- }
- catch (TimeoutException e)
- {
- ex = e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("JBossCacheService: exception occurred in cache put ... ", e);
- }
- }
- throw new RuntimeException("JBossCacheService: exception occurred in cache put after retry ... ", ex);
- }
-
- /**
- * Wrapper to embed retyr logic.
- *
- * @param fqn
- * @param id
- * @return
- */
- Object remove(Fqn fqn, String id)
- {
- Exception ex = null;
- for (int i = 0; i < RETRY; i++)
- {
- try
- {
- return proxy_.remove(fqn, id);
- }
- catch (TimeoutException e)
- {
- ex = e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("JBossCacheService: exception occurred in cache remove ... ", e);
- }
- }
- throw new RuntimeException("JBossCacheService: exception occurred in cache remove after retry ... ", ex);
- }
-
- /**
- * Wrapper to embed retry logic.
- *
- * @param fqn
- */
- void remove(Fqn fqn)
- {
- Exception ex = null;
- for (int i = 0; i < RETRY; i++)
- {
- try
- {
- proxy_.remove(fqn);
- return;
- }
- catch (TimeoutException e)
- {
- ex = e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("JBossCacheService: exception occurred in cache remove ... ", e);
- }
- }
- throw new RuntimeException("JBossCacheService: exception occurred in cache remove after retry ... ", ex);
- }
-
- /**
- * Wrapper to embed retry logic.
- *
- * @param fqn
- */
- void removeLocal(Fqn fqn)
- {
- Exception ex = null;
- for (int i = 0; i < RETRY; i++)
- {
- try
- {
- Option localOverride = new Option();
- localOverride.setCacheModeLocal(true);
- proxy_.remove(fqn, localOverride);
- return;
- }
- catch (TimeoutException e)
- {
- ex = e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("JBossCacheService: exception occurred in cache removeLocal ... ", e);
- }
- }
- throw new RuntimeException("JBossCacheService: exception occurred in cache removeLocal after retry ... ", ex);
- }
-
- /**
- * Wrapper to embed retry logic.
- *
- * @param fqn
- */
- void evict(Fqn fqn)
- {
- Exception ex = null;
- for (int i = 0; i < RETRY; i++)
- {
- try
- {
- proxy_.evict(fqn);
- return;
- }
- catch (TimeoutException e)
- {
- ex = e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("JBossCacheService: exception occurred in cache evict ... ", e);
- }
- }
- throw new RuntimeException("JBossCacheService: exception occurred in cache evict after retry ... ", ex);
- }
-
- void evictSubtree(Fqn fqn)
- {
- Exception ex = null;
- for (int i = 0; i < RETRY; i++)
- {
- try
- {
- // Evict the node itself first, since if it stores a Pojo
- // that will do everything
- proxy_.evict(fqn);
-
- // next do a depth first removal; this ensure all nodes
- // are removed, not just their data map
- Set children = proxy_.getChildrenNames(fqn);
- if (children != null)
- {
- for (Iterator it = children.iterator(); it.hasNext(); )
- {
- Fqn child = new Fqn(fqn, it.next());
- proxy_.evict(child);
- }
-
- proxy_.evict(fqn);
- }
- return;
-
- }
- catch (TimeoutException e)
- {
- ex = e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("JBossCacheService: exception occurred in cache evict ... ", e);
- }
- }
- throw new RuntimeException("JBossCacheService: exception occurred in cache evictSubtree after retry ... ", ex);
- }
-
- void removeLocalSubtree(Fqn fqn)
- {
- // First remove the node itself. If it is the root of an AOP
- // object tree, this will do everything
- removeLocal(fqn);
-
- // Next, clear any children
- Exception ex = null;
- for (int i = 0; i < RETRY; i++)
- {
- try
- {
- // Evict the node itself first, since if it stores a Pojo
- // that will do everything
- removeLocal(fqn);
-
- // next do a depth first removal; this ensure all nodes
- // are removed, not just their data map
- Set children = proxy_.getChildrenNames(fqn);
- if (children != null)
- {
- for (Iterator it = children.iterator(); it.hasNext(); )
- {
- Fqn child = new Fqn(fqn, it.next());
- removeLocal(child);
- }
-
- removeLocal(fqn);
- }
- return;
-
- }
- catch (TimeoutException e)
- {
- ex = e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("JBossCacheService: exception occurred in cache removeLocal ... ", e);
- }
- }
- throw new RuntimeException("JBossCacheService: exception occurred in cache removeLocalSubtree after retry ... ", ex);
- }
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManager.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManager.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,940 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import org.apache.catalina.*;
-import org.jboss.mx.util.MBeanServerLocator;
-
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.beans.PropertyChangeEvent;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.Cookie;
-
-import org.jboss.logging.Logger;
-import org.jboss.metadata.WebMetaData;
-import org.jboss.web.tomcat.statistics.ReplicationStatistics;
-import org.apache.catalina.Container;
-import org.apache.catalina.Context;
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.Session;
-import org.apache.catalina.connector.Connector;
-import org.apache.catalina.connector.Response;
-import org.apache.catalina.util.LifecycleSupport;
-
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-
-/**
- * Base abstract implementation of Tomcat manager without the concept of
- * session operations, e.g., add, remove, etc.
- *
- * @author Ben Wang
- * @author Hany Mesha
- * @version $Revision$
- */
-public abstract class JBossManager
- implements AbstractJBossManager, Lifecycle,
- JBossManagerMBean, PropertyChangeListener
-{
-
- // -- Constants ----------------------------------------
- /**
- * Informational name for this Catalina component
- */
- private static final String info_ = "JBossManager/1.0";
-
- // -- Class attributes ---------------------------------
- protected ReplicationStatistics stats_ = new ReplicationStatistics();
-
- /**
- * Policy to determine if a session is dirty
- */
- protected int invalidateSessionPolicy_ = WebMetaData.SESSION_INVALIDATE_SET_AND_NON_PRIMITIVE_GET;
- /**
- * Replication granulairty.
- */
- protected int replicationGranularity_ = WebMetaData.REPLICATION_GRANULARITY_SESSION;
-
- /**
- * Session passivation flag set in jboss-web.xml by the user.
- * If true, then the session passivation is enabled for this web application,
- * otherwise, it's disabled
- */
- protected boolean passivationMode_ = false;
-
- /**
- * Min time (seconds) the session must be idle since lastAccesstime before it's eligable for passivation
- * This overrides maxActive_, to prevent thrashing if the there are lots of active sessions.
- * Setting to -1 means it's ignored
- */
- protected int passivationMinIdleTime_ = -1;
-
- /**
- * Max time (seconds) the session must be idle since lastAccesstime before it's eligable for passivation
- * This overrides maxActive_, to prevent thrashing if the there are lots of active sessions.
- * Setting to -1 means session should not be forced out.
- */
- protected int passivationMaxIdleTime_ = -1;
-
- /**
- * The lifecycle_ event support for this component.
- */
- protected LifecycleSupport lifecycle_ = new LifecycleSupport(this);
- /**
- * Has this component been started_ yet?
- */
- protected boolean started_ = false;
- /**
- * The objectname this Manager is associated with
- */
- protected ObjectName objectName_;
- /**
- * The Log-object for this class
- */
- protected Logger log_ = Logger.getLogger(this.getClass().getName());
- /**
- * The Container with which this Manager is associated.
- */
- protected Container container_;
- /**
- /**
- * The distributable flag for Sessions created by this Manager. If this
- * flag is set to <code>true</code>, any user attributes added to a
- * session controlled by this Manager must be Serializable.
- */
- protected boolean distributable_ = true;
- /**
- * The default maximum inactive interval for Sessions created by
- * this Manager.
- */
- protected int maxInactiveInterval_ = 60;
- /**
- * The session id length of Sessions created by this Manager.
- */
- protected int sessionIdLength_ = 16;
-
- // Maximum of ative sessions allowed. -1 is unlimited.
- protected int maxActive_ = -1;
-
- // Number of sessions created by this manager
- protected int createdCounter_ = 0;
-
- // number of rejected sessions because the number active sessions exceeds maxActive
- protected int rejectedCounter_ = 0;
-
- // Number of active sessions
- protected int activeCounter_ = 0;
-
- // Maximum number of active sessions seen so far
- protected int maxActiveCounter_ = 0;
-
- // number of expired session ids. Not sure what exactly does it mean in our clustered case.
- protected int expiredCounter_ = 0;
-
- protected long timeSinceLastReset_ = 0;
-
- // Cumulative time spent in backgroundProcess
- protected long processingTime_ = 0;
-
- /**
- * Map<String,ClusteredSession>. Store the local sessions.
- */
- protected final Map sessions_ = new ConcurrentHashMap();
-
- /**
- * If set to true, it will not replicate the access time stamp unless attributes are dirty.
- */
- protected boolean useLocalCache_ = false;
-
- /**
- * The property change support for this component.
- */
- protected PropertyChangeSupport support_ = new PropertyChangeSupport(this);
-
- protected SessionIDGenerator sessionIDGenerator_;
-
- protected String jvmRoute_;
-
- // TODO Need a string manager to handle exception localization
-
- public JBossManager()
- {
- sessionIDGenerator_ = SessionIDGenerator.getInstance();
-
- }
-
- public void init(String name, WebMetaData webMetaData, boolean useJK, boolean useLocalCache)
- throws ClusteringNotSupportedException
- {
- replicationGranularity_ = webMetaData.getReplicationGranularity();
- invalidateSessionPolicy_ = webMetaData.getInvalidateSessionPolicy();
- maxActive_ = webMetaData.getMaxActiveSessionsAllowed();
- passivationMode_ = webMetaData.getSessionPassivationMode();
- if (passivationMode_)
- {
- passivationMinIdleTime_ = webMetaData.getSessionPassivationMinIdleTime();
- passivationMaxIdleTime_ = webMetaData.getSessionPassivationMaxIdleTime();
- }
- useLocalCache_ = useLocalCache;
- log_.info("init(): replicationGranularity_ is " + replicationGranularity_ +
- " and invaldateSessionPolicy is " + invalidateSessionPolicy_ +
- " and maxActiveSessions allowed is " + maxActive_ +
- " and passivationMode is " + passivationMode_);
-
- try
- {
- // Give this manager a name
- objectName_ = new ObjectName("jboss.web:service=ClusterManager,WebModule=" + name);
- }
- catch (Throwable e)
- {
- log_.error("Could not create ObjectName", e);
- throw new ClusteringNotSupportedException(e.toString());
- }
- }
-
- public int getInvalidateSessionPolicy()
- {
- return this.invalidateSessionPolicy_;
- }
-
- /**
- * Retrieve the enclosing Engine for this Manager.
- *
- * @return an Engine object (or null).
- */
- public Engine getEngine()
- {
- Engine e = null;
- for (Container c = getContainer(); e == null && c != null; c = c.getParent())
- {
- if (c != null && c instanceof Engine)
- {
- e = (Engine) c;
- }
- }
- return e;
- }
-
- /**
- * Retrieve the JvmRoute for the enclosing Engine.
- *
- * @return the JvmRoute or null.
- */
- public String getJvmRoute()
- {
- if (jvmRoute_ == null)
- {
- Engine e = getEngine();
- jvmRoute_= (e == null ? null : e.getJvmRoute());
- }
- return jvmRoute_;
- }
-
- /**
- * Get a new session-id from the distributed store
- *
- * @return new session-id
- */
- protected String getNextId()
- {
- return sessionIDGenerator_.getSessionId();
- }
-
- /**
- * Gets the JMX <code>ObjectName</code> under
- * which our <code>TreeCache</code> is registered.
- */
- public ObjectName getObjectName()
- {
- return objectName_;
- }
-
- public boolean isUseLocalCache()
- {
- return useLocalCache_;
- }
-
- /**
- * Sets a new cookie for the given session id and response
- *
- * @param sessionId The session id
- */
- public void setSessionCookie(String sessionId)
- {
- HttpServletResponse response = (HttpServletResponse) ClusteredSessionValve.responseThreadLocal.get();
- setNewSessionCookie(sessionId, response);
- }
-
- public void setNewSessionCookie(String sessionId, HttpServletResponse response)
- {
- if (response != null)
- {
- Context context = (Context) container_;
- Connector connector = ((Response)response).getConnector();
- if (context.getCookies())
- {
- // set a new session cookie
- Cookie newCookie = new Cookie(Globals.SESSION_COOKIE_NAME, sessionId);
- if (log_.isDebugEnabled())
- {
- log_.debug("Setting cookie with session id:" + sessionId + " & name:" + Globals.SESSION_COOKIE_NAME);
- }
-
- String contextPath = null;
- if (!connector.getEmptySessionPath() && (context != null)) {
- contextPath = context.getEncodedPath();
- }
-
- if ((contextPath != null) && (contextPath.length() > 0)) {
- newCookie.setPath(contextPath);
- } else {
- newCookie.setPath("/");
- }
-
- if (connector.getSecure()) {
- newCookie.setSecure(true);
- }
-
- response.addCookie(newCookie);
- }
- }
- }
-
- // JBossManagerMBean-methods -------------------------------------
-
- // A better property name for the MBean API
- public int getMaxActiveAllowed()
- {
- return getMaxActive();
- }
-
- // A better property name for the MBean API
- public void setMaxActiveAllowed(int maxActive)
- {
- setMaxActive(maxActive);
- }
-
- public long getMaxActiveSessionCount()
- {
- return this.maxActiveCounter_;
- }
-
- public ReplicationStatistics getReplicationStatistics()
- {
- return stats_;
- }
-
- public void resetStats()
- {
- stats_.resetStats();
- activeCounter_ = 0;
- maxActiveCounter_ = 0;
- rejectedCounter_ = 0;
- createdCounter_ = 0;
- expiredCounter_ = 0;
- processingTime_ = 0;
- timeSinceLastReset_ = System.currentTimeMillis();
- }
-
- public long timeInSecondsSinceLastReset()
- {
- return (System.currentTimeMillis() - timeSinceLastReset_) / (1000L);
- }
-
- public long getActiveSessionCount()
- {
- return getActiveSessions();
- }
-
- public long getCreatedSessionCount()
- {
- return createdCounter_;
- }
-
- public long getExpiredSessionCount()
- {
- return expiredCounter_;
- }
-
- public long getRejectedSessionCount()
- {
- return rejectedCounter_;
- }
-
- public int getSessionMaxAliveTime()
- {
- return 0;
- }
-
- public void setSessionMaxAliveTime(int sessionMaxAliveTime)
- {
- }
-
- public int getSessionAverageAliveTime()
- {
- return 0;
- }
-
- public void setSessionAverageAliveTime(int sessionAverageAliveTime)
- {
- }
-
- public String reportReplicationStatistics()
- {
- StringBuffer tmp = new StringBuffer();
- HashMap copy = new HashMap(stats_.getStats());
- Iterator iter = copy.entrySet().iterator();
- tmp.append("<table><tr>");
- tmp.append("<th>sessionID</th>");
- tmp.append("<th>replicationCount</th>");
- tmp.append("<th>minPassivationTime</th>");
- tmp.append("<th>maxPassivationTime</th>");
- tmp.append("<th>totalPassivationTime</th>");
- tmp.append("<th>minReplicationTime</th>");
- tmp.append("<th>maxReplicationTime</th>");
- tmp.append("<th>totalReplicationlTime</th>");
- tmp.append("<th>loadCount</th>");
- tmp.append("<th>minLoadTime</th>");
- tmp.append("<th>maxLoadTime</th>");
- tmp.append("<th>totalLoadTime</th>");
- while (iter.hasNext())
- {
- Map.Entry entry = (Map.Entry) iter.next();
- ReplicationStatistics.TimeStatistic stat = (ReplicationStatistics.TimeStatistic) entry.getValue();
- if (stat != null)
- {
- tmp.append("<tr><td>");
- tmp.append(entry.getKey());
- tmp.append("</td><td>");
- tmp.append(stat.replicationCount);
- tmp.append("</td><td>");
- tmp.append(stat.minPassivationTime);
- tmp.append("</td><td>");
- tmp.append(stat.maxPassivationTime);
- tmp.append("</td><td>");
- tmp.append(stat.totalPassivationTime);
- tmp.append("</td><td>");
- tmp.append(stat.minReplicationTime);
- tmp.append("</td><td>");
- tmp.append(stat.maxReplicationTime);
- tmp.append("</td><td>");
- tmp.append(stat.totalReplicationlTime);
- tmp.append("</td><td>");
- tmp.append(stat.loadCount);
- tmp.append("</td><td>");
- tmp.append(stat.minLoadTime);
- tmp.append("</td><td>");
- tmp.append(stat.maxLoadTime);
- tmp.append("</td><td>");
- tmp.append(stat.totalLoadlTime);
- tmp.append("</td></tr>");
- }
- }
- tmp.append("</table>");
- copy.clear();
- return tmp.toString();
-
- }
-
- public String reportReplicationStatisticsCSV()
- {
- StringBuffer tmp = createCSVHeader();
- HashMap copy = new HashMap(stats_.getStats());
- Iterator iter = copy.entrySet().iterator();
- while (iter.hasNext())
- {
- Map.Entry entry = (Map.Entry) iter.next();
- ReplicationStatistics.TimeStatistic stat = (ReplicationStatistics.TimeStatistic) entry.getValue();
- if (stat != null)
- {
- tmp.append("\n");
- tmp.append(entry.getKey());
- tmp.append(",");
- tmp.append(stat.replicationCount);
- tmp.append(",");
- tmp.append(stat.minPassivationTime);
- tmp.append(",");
- tmp.append(stat.maxPassivationTime);
- tmp.append(",");
- tmp.append(stat.totalPassivationTime);
- tmp.append(",");
- tmp.append(stat.minReplicationTime);
- tmp.append(",");
- tmp.append(stat.maxReplicationTime);
- tmp.append(",");
- tmp.append(stat.totalReplicationlTime);
- tmp.append(",");
- tmp.append(stat.loadCount);
- tmp.append(",");
- tmp.append(stat.minLoadTime);
- tmp.append(",");
- tmp.append(stat.maxLoadTime);
- tmp.append(",");
- tmp.append(stat.totalLoadlTime);
- }
- }
- copy.clear();
- return tmp.toString();
-
- }
-
- public String reportReplicationStatisticsCSV(String sessionId)
- {
- StringBuffer tmp = createCSVHeader();
- Map stats = stats_.getStats();
- ReplicationStatistics.TimeStatistic stat =
- (ReplicationStatistics.TimeStatistic) stats.get(sessionId);
- if (stat != null)
- {
- tmp.append("\n");
- tmp.append(sessionId);
- tmp.append(",");
- tmp.append(stat.replicationCount);
- tmp.append(",");
- tmp.append(stat.minPassivationTime);
- tmp.append(",");
- tmp.append(stat.maxPassivationTime);
- tmp.append(",");
- tmp.append(stat.totalPassivationTime);
- tmp.append(",");
- tmp.append(stat.minReplicationTime);
- tmp.append(",");
- tmp.append(stat.maxReplicationTime);
- tmp.append(",");
- tmp.append(stat.totalReplicationlTime);
- tmp.append(",");
- tmp.append(stat.loadCount);
- tmp.append(",");
- tmp.append(stat.minLoadTime);
- tmp.append(",");
- tmp.append(stat.maxLoadTime);
- tmp.append(",");
- tmp.append(stat.totalLoadlTime);
- }
- return tmp.toString();
- }
-
- private StringBuffer createCSVHeader()
- {
- StringBuffer tmp = new StringBuffer();
- tmp.append("sessionID,");
- tmp.append("replicationCount,");
- tmp.append("minPassivationTime,");
- tmp.append("maxPassivationTime,");
- tmp.append("totalPassivationTime,");
- tmp.append("minReplicationTime,");
- tmp.append("maxReplicationTime,");
- tmp.append("totalReplicationlTime,");
- tmp.append("loadCount,");
- tmp.append("minLoadTime,");
- tmp.append("maxLoadTime,");
- tmp.append("totalLoadTime");
-
- return tmp;
- }
-
- // Lifecycle-methods -------------------------------------
-
- public void addLifecycleListener(LifecycleListener listener)
- {
- lifecycle_.addLifecycleListener(listener);
- }
-
- public LifecycleListener[] findLifecycleListeners()
- {
- return lifecycle_.findLifecycleListeners();
- }
-
- public void removeLifecycleListener(LifecycleListener listener)
- {
- lifecycle_.removeLifecycleListener(listener);
- }
-
- /**
- * Start this Manager
- *
- * @throws org.apache.catalina.LifecycleException
- *
- */
- public void start() throws LifecycleException
- {
- startManager();
- }
-
- /**
- * Stop this Manager
- *
- * @throws org.apache.catalina.LifecycleException
- *
- */
- public void stop() throws LifecycleException
- {
- resetStats();
- stopManager();
- }
-
- /**
- * Prepare for the beginning of active use of the public methods of this
- * component. This method should be called after <code>configure()</code>,
- * and before any of the public methods of the component are utilized.
- *
- * @throws IllegalStateException if this component has already been
- * started_
- * @throws org.apache.catalina.LifecycleException
- * if this component detects a fatal error
- * that prevents this component from being used
- */
- protected void startManager() throws LifecycleException
- {
- log_.info("Starting JBossManager");
-
- // Validate and update our current component state
- if (started_)
- throw new LifecycleException
- ("JBossManager alreadyStarted");
- lifecycle_.fireLifecycleEvent(START_EVENT, null);
- started_ = true;
-
- // register ClusterManagerMBean to the MBeanServer
- try
- {
- MBeanServer server = MBeanServerLocator.locateJBoss();
- server.registerMBean(this, objectName_);
- }
- catch (Exception e)
- {
- log_.error("Could not register ClusterManagerMBean to MBeanServer", e);
- }
- }
-
- /**
- * Gracefully terminate the active use of the public methods of this
- * component. This method should be the last one called on a given
- * instance of this component.
- *
- * @throws IllegalStateException if this component has not been started_
- * @throws org.apache.catalina.LifecycleException
- * if this component detects a fatal error
- * that needs to be reported
- */
- protected void stopManager() throws LifecycleException
- {
- log_.info("Stopping JBossManager");
-
- // Validate and update our current component state
- if (!started_)
- throw new LifecycleException
- ("JBossManager notStarted");
- lifecycle_.fireLifecycleEvent(STOP_EVENT, null);
- started_ = false;
-
- // unregister ClusterManagerMBean from the MBeanServer
- try
- {
- MBeanServer server = MBeanServerLocator.locateJBoss();
- server.unregisterMBean(objectName_);
- }
- catch (Exception e)
- {
- log_.error("Could not unregister ClusterManagerMBean from MBeanServer", e);
- }
- }
-
- // Manager-methods -------------------------------------
- public Container getContainer()
- {
- return container_;
- }
-
- public void setContainer(Container container)
- {
-
- // De-register from the old Container (if any)
- if ((this.container_ != null) && (this.container_ instanceof Context))
- this.container_.removePropertyChangeListener(this);
-
- // Default processing provided by our superclass
- this.container_ = container;
-
- // Register with the new Container (if any)
- if ((this.container_ != null) && (this.container_ instanceof Context))
- {
- setMaxInactiveInterval
- (((Context) this.container_).getSessionTimeout() * 60);
- this.container_.addPropertyChangeListener(this);
- }
- }
-
- public boolean getDistributable()
- {
- return distributable_;
- }
-
- public void setDistributable(boolean distributable)
- {
- this.distributable_ = distributable;
- }
-
- public String getInfo()
- {
- return info_;
- }
-
- public int getMaxInactiveInterval()
- {
- return maxInactiveInterval_;
- }
-
- public void setMaxInactiveInterval(int interval)
- {
- this.maxInactiveInterval_ = interval;
- }
-
- public int getSessionIdLength()
- {
- return sessionIdLength_;
- }
-
- public void setSessionIdLength(int idLength)
- {
- this.sessionIdLength_ = idLength;
- }
-
- public int getSessionCounter()
- {
- return createdCounter_;
- }
-
- public void setSessionCounter(int sessionCounter)
- {
- this.createdCounter_ = sessionCounter;
- }
-
- public int getMaxActive()
- {
- return maxActive_;
- }
-
- public void setMaxActive(int maxActive)
- {
- this.maxActive_ = maxActive;
- }
-
- public int getExpiredSessions()
- {
- return expiredCounter_;
- }
-
- public void setExpiredSessions(int expiredSessions)
- {
- this.expiredCounter_ = expiredSessions;
- }
-
- public int getRejectedSessions()
- {
- return rejectedCounter_;
- }
-
- public void setRejectedSessions(int rejectedSessions)
- {
- this.rejectedCounter_ = rejectedSessions;
- }
-
- public long getProcessingTime()
- {
- return this.processingTime_;
- }
-
- public void addPropertyChangeListener(PropertyChangeListener listener)
- {
- support_.addPropertyChangeListener(listener);
- }
-
- /**
- * Remove the active session locally from the manager without replicating to the cluster. This can be
- * useful when the session is exipred, for example, where there is not need to propagate the expiration.
- *
- * @param session
- */
- public abstract void removeLocal(Session session);
-
- /**
- * Store the modified session.
- *
- * @param session
- */
- public abstract boolean storeSession(Session session);
-
- public int getActiveSessions()
- {
- return activeCounter_;
- }
-
-/*
- public void add(Session session)
- {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public Session createEmptySession()
- {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public Session createSession()
- {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public Session findSession(String id) throws IOException
- {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public Session[] findSessions()
- {
- return new Session[0]; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- public void remove(Session session)
- {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-*/
-
- public void load() throws ClassNotFoundException, IOException
- {
- // TODO. Implement persistence layer.
- throw new RuntimeException("JBossManager.load(): Method not implemented.");
- }
-
- public void removePropertyChangeListener(PropertyChangeListener listener)
- {
- support_.removePropertyChangeListener(listener);
- }
-
- public void unload() throws IOException
- {
- // TODO. Implement persistence layer.
- throw new RuntimeException("JBossManager.load(): Method not implemented.");
- }
-
-
- public void backgroundProcess()
- {
- // Called from Catalina StandardEngine for every 60 seconds.
-
- long start = System.currentTimeMillis();
-
- processExpires();
-
- long elapsed = System.currentTimeMillis() - start;
-
- processingTime_ += elapsed;
- }
-
- /**
- * Go through all sessions and look if they have expired
- */
- protected void processExpires()
- {
- // What's the time?
-// long timeNow = System.currentTimeMillis();
-
- // Get all sessions
- Session sessions[] = findSessions();
- if (log_.isDebugEnabled())
- {
- log_.debug("Looking for sessions that have expired ...");
- }
-
- for (int i = 0; i < sessions.length; ++i)
- {
- ClusteredSession session = (ClusteredSession) sessions[i];
-
- // We only look at valid sessions. This will remove session if not valid already.
- if (!session.isValid())
- {
- continue;
- }
-
- /* I don't think it is right to check idle time based on lastAccessedTime since it may
- // remove some request that is currently in progress!!!
- // How long are they allowed to be idle?
- int maxInactiveInterval = session.getMaxInactiveInterval();
-
- // Negative values = never expire
- if( maxInactiveInterval < 0 )
- {
- continue;
- }
-
- // How long has this session been idle?
- int timeIdle =
- (int) ((timeNow - session.getLastAccessedTime()) / 1000L);
-
- // Too long?
- if( timeIdle >= maxInactiveInterval )
- {
- try
- {
- log_.debug("Session with id = " + session.getId() + " has expired on local node");
- remove(session);
- }
- catch(Throwable t)
- {
- log_.error("Problems while expiring session with id = " + session.getId(), t);
- }
- }
- */
- }
- }
-
- public void propertyChange(PropertyChangeEvent evt)
- {
- // TODO Need to handle it here.
- }
-
- /**
- * Find in-memory sessions, if any.
- * @return local session found. Sessions of size 0, if not found.
- */
- abstract public ClusteredSession[] findLocalSessions();
-
- /**
- * Find in-memory sessions, if any.
- * @param realId the Session id without JvmRoute tag.
- * @return local session found. Null if not found.
- */
- abstract public ClusteredSession findLocalSession(String realId);
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManagerMBean.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManagerMBean.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JBossManagerMBean.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,159 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import org.jboss.web.tomcat.statistics.ReplicationStatistics;
-
-/**
- * The MBean-interface for the JBossManager
- *
- * @author Thomas Peuss <jboss at peuss.de>
- * @author Brian Stansberry
- *
- * @version $Revision$
- */
-public interface JBossManagerMBean
-{
- /**
- * Gets the replication statistics for the sessions managed
- * by this manager.
- *
- * @return the statistics
- */
- ReplicationStatistics getReplicationStatistics();
-
- /**
- * Resets all statistics.
- */
- void resetStats();
-
- /**
- * Gets the elapsed time since this manager was instantiated or the
- * last call to resetStats()
- */
- long timeInSecondsSinceLastReset();
-
- /**
- * Gets the number of sessions active on this node. Does not include
- * replicated sessions that have not been accessed on this node.
- */
- long getActiveSessionCount();
-
- /**
- * Gets the number of times session creation has failed because the
- * number of active sessions exceeds
- * {@link #getMaxActiveAllowed() maxActiveAllowed}
- */
- long getRejectedSessionCount();
-
- /**
- * Gets the number of sessions created on this node. Does not include
- * sessions initially created on other nodes, even if those sessions
- * were accessed on this node.
- */
- long getCreatedSessionCount();
-
- /**
- * Gets the number of sessions that have been expired on this node.
- */
- long getExpiredSessionCount();
-
- /**
- * Gets the highest number of sessions concurrently active on this node.
- * Does not include replicated sessions that have not been accessed on
- * this node.
- */
- long getMaxActiveSessionCount();
-
- /**
- * Gets the maximum number of active sessions that will concurrently be
- * allowed on this node. Does not include replicated sessions that have
- * not been accessed on this node.
- */
- int getMaxActiveAllowed();
-
- /**
- * Sets the maximum number of active sessions that will concurrently be
- * allowed on this node. Does not include replicated sessions that have
- * not been accessed on this node.
- *
- * <p>
- * Note that if sessions fail over to this node from other nodes, the max
- * number of active sessions may exceed this value.
- * </p>
- *
- * @param max the max number of sessions, or <code>-1</code> if there is
- * no limit.
- */
- void setMaxActiveAllowed(int max);
-
- /**
- * Gets the maximum time interval, in seconds, between client requests
- * after which sessions created by this manager should be expired. A
- * negative time indicates that the session should never time out.
- */
- int getMaxInactiveInterval();
-
- /**
- * Sets the maximum time interval, in seconds, between client requests
- * after which sessions created by this manager should be expired. A
- * negative time indicates that the session should never time out.
- *
- * @param interval The new maximum interval
- */
- void setMaxInactiveInterval(int minutes);
-
- /**
- * Gets whether this manager's sessions are distributable.
- */
- boolean getDistributable();
-
- /**
- * Gets the cumulative number of milliseconds spent in the
- * <code>Manager.backgroundProcess()</code> method.
- */
- long getProcessingTime();
-
- /**
- * Outputs the replication statistics as an HTML table, with one row
- * per session.
- */
- String reportReplicationStatistics();
-
- /**
- * Outputs the replication statistics as a comma-separated-values, with one
- * row per session. First row is a header listing field names.
- */
- String reportReplicationStatisticsCSV();
-
- /**
- * Outputs the replication statistics for the given session as a set of
- * comma-separated-values. First row is a header listing field names.
- */
- String reportReplicationStatisticsCSV(String sessionId);
-
- /**
- * Gets the number of characters used in creating a session id. Excludes
- * any jvmRoute.
- */
- int getSessionIdLength();
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JvmRouteValve.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JvmRouteValve.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/JvmRouteValve.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,215 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.io.IOException;
-import javax.servlet.http.HttpSession;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.ServletException;
-
-import org.apache.catalina.*;
-import org.apache.catalina.connector.Request;
-import org.apache.catalina.connector.Response;
-import org.apache.catalina.util.LifecycleSupport;
-import org.apache.catalina.valves.ValveBase;
-import org.jboss.logging.Logger;
-
-/**
- * Web request valve to specifically handle Tomcat jvmRoute using mod_jk(2)
- * module. We assume that the session is set by cookie only for now, i.e., no
- * support of that from URL. Furthermore, the session id has a format of
- * id.jvmRoute where jvmRoute is used by JK module to determine sticky session
- * during load balancing.
- *
- * @author Ben Wang
- * @version $Revision$
- */
-public class JvmRouteValve extends ValveBase implements Lifecycle
-{
- // The info string for this Valve
- private static final String info = "JvmRouteValve/1.0";
-
- protected static Logger log_ = Logger.getLogger(JvmRouteValve.class);
-
- // Valve-lifecycle_ helper object
- protected LifecycleSupport support = new LifecycleSupport(this);
-
- protected AbstractJBossManager manager_;
-
- /**
- * Create a new Valve.
- *
- */
- public JvmRouteValve(AbstractJBossManager manager)
- {
- super();
- manager_ = manager;
- }
-
- /**
- * Get information about this Valve.
- */
- public String getInfo()
- {
- return info;
- }
-
- public void invoke(Request request, Response response) throws IOException, ServletException
- {
-
- // Need to check it before let it through. This is ok because this
- // valve is inserted only when mod_jk option is configured.
- checkJvmRoute(request, response);
-
- // let the servlet invokation go through
- getNext().invoke(request, response);
- }
-
- public void checkJvmRoute(Request req, Response res)
- throws IOException, ServletException
- {
- HttpSession session = req.getSession(false);
- if (session != null)
- {
- String sessionId = session.getId();
-
- // Obtain JvmRoute
- String jvmRoute = manager_.getJvmRoute();
- if (log_.isDebugEnabled())
- {
- log_.debug("checkJvmRoute(): check if need to re-route based on JvmRoute. Session id: " +
- sessionId + " jvmRoute: " + jvmRoute);
- }
-
- if (jvmRoute == null)
- {
- throw new RuntimeException("JvmRouteValve.checkJvmRoute(): Tomcat JvmRoute is null. " +
- "Need to assign a value in Tomcat server.xml for load balancing.");
- }
-
- // Check if incoming session id has JvmRoute appended. If not, append it.
- boolean setCookie = !req.isRequestedSessionIdFromURL();
- handleJvmRoute(sessionId, jvmRoute, res, setCookie);
- }
- }
-
- protected void handleJvmRoute(String sessionId,
- String jvmRoute,
- HttpServletResponse response,
- boolean setCookie)
- {
- // Get requested jvmRoute.
- // TODO. The current format is assumed to be id.jvmRoute. Can be generalized later.
- String requestedJvmRoute = null;
- int index = sessionId.lastIndexOf(".");
- if (index > 0)
- {
- requestedJvmRoute = sessionId.substring(index + 1, sessionId.length());
- }
-
- String newId = sessionId;
- if (!jvmRoute.equals(requestedJvmRoute))
- {
- if (requestedJvmRoute == null)
- {
- // If this valve is turned on, we assume we have an appendix of jvmRoute.
- // So this request is new.
- newId = sessionId + "." + jvmRoute;
- }
- else
- {
- // We just had a failover since jvmRoute does not match.
- // We will replace the old one with the new one.
- if (log_.isDebugEnabled())
- {
- log_.debug("handleJvmRoute(): We have detected a failover with different jvmRoute." +
- " old one: " + requestedJvmRoute + " new one: " + jvmRoute + ". Will reset the session id.");
- }
-
- String base = sessionId.substring(0, index);
- newId = base + "." + jvmRoute;
- }
-
- resetSessionId(sessionId, newId);
-
- if (setCookie)
- manager_.setNewSessionCookie(newId, response);
- }
- }
-
- private void resetSessionId(String oldId, String newId)
- {
- try
- {
- ClusteredSession session = (ClusteredSession)manager_.findSession(oldId);
- // change session id with the new one using local jvmRoute.
- if( session != null )
- {
- // Note this will trigger a session remove from the super Tomcat class.
- session.resetIdWithRouteInfo(newId);
- if (log_.isDebugEnabled())
- {
- log_.debug("resetSessionId(): changed catalina session to= [" + newId + "] old one= [" + oldId + "]");
- }
- }
- else if (log_.isDebugEnabled())
- {
- log_.debug("resetSessionId(): no session with id " + newId + " found");
- }
- }
- catch (IOException e)
- {
- if (log_.isDebugEnabled())
- {
- log_.debug("resetSessionId(): manager_.findSession() unable to find session= [" + oldId + "]", e);
- }
- throw new RuntimeException("JvmRouteValve.resetSessionId(): cannot find session [" + oldId + "]", e);
- }
- }
-
- // Lifecycle Interface
- public void addLifecycleListener(LifecycleListener listener)
- {
- support.addLifecycleListener(listener);
- }
-
- public void removeLifecycleListener(LifecycleListener listener)
- {
- support.removeLifecycleListener(listener);
- }
-
- public LifecycleListener[] findLifecycleListeners()
- {
- return support.findLifecycleListeners();
- }
-
- public void start() throws LifecycleException
- {
- support.fireLifecycleEvent(START_EVENT, this);
- }
-
- public void stop() throws LifecycleException
- {
- support.fireLifecycleEvent(STOP_EVENT, this);
- }
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalSessionActivity.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalSessionActivity.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalSessionActivity.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,87 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-/**
- * Binds the session id of a session that is currently being manipulated
- * locally to a ThreadLocal so CacheListener can ignore events generated by the
- * activity.
- *
- * @author Brian Stansberry
- * @version $Id$
- */
-class LocalSessionActivity
-{
- private static ThreadLocal activeSessions = new ThreadLocal();
-
- private String sessionId;
- private int level = 0;
-
- /**
- * Marks the current thread as actively processing the given session.
- * If the thread has already been so marked, increases a counter
- * so a subsequent call to finishLocalActivity does not remove
- * the association (allowing nested calls).
- *
- * @param sessionId. Can be <code>null</code>.
- */
- public static void startLocalActivity(String sessionId)
- {
- LocalSessionActivity current = (LocalSessionActivity) activeSessions.get();
- if (current == null || !(current.sessionId.equals(sessionId)))
- {
- current = new LocalSessionActivity(sessionId);
- activeSessions.set(current);
- }
- current.level++;
- }
-
- /**
- * Marks the completion of activity on a given session. Should be called
- * once for each invocation of {@link #startLocalActivity(String)}.
- *
- */
- public static void finishLocalActivity()
- {
- LocalSessionActivity current = (LocalSessionActivity) activeSessions.get();
- if (current != null)
- {
- if (--current.level == 0)
- activeSessions.set(null);
- }
- }
-
- public static boolean isLocallyActive(String sessionId)
- {
- boolean result = false;
- LocalSessionActivity active = (LocalSessionActivity) activeSessions.get();
- if (active != null)
- result = active.sessionId.equals(sessionId);
-
- return result;
- }
-
- private LocalSessionActivity(String sessionId)
- {
- this.sessionId = sessionId;
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalStrings.properties
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalStrings.properties 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalStrings.properties 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,15 +0,0 @@
-clusteredSession.attributeEvent=Session attribute event listener threw exception
-clusteredSession.invalidate.ise=invalidate: Session already invalidated
-clusteredSession.isNew.ise=isNew: Session already invalidated
-clusteredSession.getAttribute.ise=getAttribute: Session already invalidated
-clusteredSession.getAttributeNames.ise=getAttributeNames: Session already invalidated
-clusteredSession.getCreationTime.ise=getCreationTime: Session already invalidated
-clusteredSession.getMaxInactiveInterval.ise=getMaxInactiveInterval: Session already invalidated
-clusteredSession.getValueNames.ise=getAttributeNames: Session already invalidated
-clusteredSession.notSerializable=Cannot serialize session attribute {0} for session {1}
-clusteredSession.removeAttribute.ise=removeAttribute: Session already invalidated
-clusteredSession.sessionEvent=Session event listener threw exception
-clusteredSession.setAttribute.iae=setAttribute: Non-serializable attribute
-clusteredSession.setAttribute.ise=setAttribute: Session already invalidated
-clusteredSession.setAttribute.namenull=setAttribute: name parameter cannot be null
-clusteredSession.sessionCreated=Created Session id = {0}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalStrings_ja.properties
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalStrings_ja.properties 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/LocalStrings_ja.properties 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,15 +0,0 @@
-clusteredSession.attributeEvent=\u30bb\u30c3\u30b7\u30e7\u30f3\u5c5e\u6027\u30a4\u30d9\u30f3\u30c8\u30ea\u30b9\u30ca\u304c\u4f8b\u5916\u3092\u6295\u3052\u307e\u3057\u305f
-clusteredSession.invalidate.ise=invalidate: \u30bb\u30c3\u30b7\u30e7\u30f3\u306f\u3059\u3067\u306b\u7121\u52b9\u5316\u3055\u308c\u3066\u3044\u307e\u3059
-clusteredSession.isNew.ise=isNew: \u30bb\u30c3\u30b7\u30e7\u30f3\u306f\u3059\u3067\u306b\u7121\u52b9\u5316\u3055\u308c\u3066\u3044\u307e\u3059
-clusteredSession.getAttribute.ise=getAttribute: \u30bb\u30c3\u30b7\u30e7\u30f3\u306f\u3059\u3067\u306b\u7121\u52b9\u5316\u3055\u308c\u3066\u3044\u307e\u3059
-clusteredSession.getAttributeNames.ise=getAttributeNames: \u30bb\u30c3\u30b7\u30e7\u30f3\u306f\u3059\u3067\u306b\u7121\u52b9\u5316\u3055\u308c\u3066\u3044\u307e\u3059
-clusteredSession.getCreationTime.ise=getCreationTime: \u30bb\u30c3\u30b7\u30e7\u30f3\u306f\u3059\u3067\u306b\u7121\u52b9\u5316\u3055\u308c\u3066\u3044\u307e\u3059
-clusteredSession.getMaxInactiveInterval.ise=getMaxInactiveInterval: \u30bb\u30c3\u30b7\u30e7\u30f3\u306f\u3059\u3067\u306b\u7121\u52b9\u5316\u3055\u308c\u3066\u3044\u307e\u3059
-clusteredSession.getValueNames.ise=getAttributeNames: \u30bb\u30c3\u30b7\u30e7\u30f3\u306f\u3059\u3067\u306b\u7121\u52b9\u5316\u3055\u308c\u3066\u3044\u307e\u3059
-clusteredSession.notSerializable=\u30bb\u30c3\u30b7\u30e7\u30f3 {1} \u306e\u305f\u3081\u306b\u30bb\u30c3\u30b7\u30e7\u30f3\u5c5e\u6027 {0} \u3092\u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u3067\u304d\u307e\u305b\u3093
-clusteredSession.removeAttribute.ise=removeAttribute: \u30bb\u30c3\u30b7\u30e7\u30f3\u306f\u3059\u3067\u306b\u7121\u52b9\u5316\u3055\u308c\u3066\u3044\u307e\u3059
-clusteredSession.sessionEvent=\u30bb\u30c3\u30b7\u30e7\u30f3\u30a4\u30d9\u30f3\u30c8\u30ea\u30b9\u30ca\u304c\u4f8b\u5916\u3092\u6295\u3052\u307e\u3057\u305f
-clusteredSession.setAttribute.iae=setAttribute: \u30b7\u30ea\u30a2\u30e9\u30a4\u30ba\u3067\u304d\u306a\u3044\u5c5e\u6027\u3067\u3059
-clusteredSession.setAttribute.ise=setAttribute: \u30bb\u30c3\u30b7\u30e7\u30f3\u306f\u3059\u3067\u306b\u7121\u52b9\u5316\u3055\u308c\u3066\u3044\u307e\u3059
-clusteredSession.setAttribute.namenull=setAttribute: name\u30d1\u30e9\u30e1\u30bf\u306fnull\u3067\u3042\u3063\u3066\u306f\u3044\u3051\u307e\u305b\u3093
-clusteredSession.sessionCreated=\u30bb\u30c3\u30b7\u30e7\u30f3ID = {0} \u3092\u751f\u6210\u3057\u307e\u3057\u305f
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionBasedClusteredSession.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionBasedClusteredSession.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionBasedClusteredSession.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,198 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.Map;
-
-
-/**
- * Implementation of a clustered session for the JBossCacheManager. The replication granularity
- * level is session based; that is, we replicate per whole session object.
- * We use JBossCache for our internal replicated data store.
- * The internal structure in JBossCache is as follows:
- * <pre>
- * /JSESSION
- * /hostname
- * /web_app_path (path + session id is unique)
- * /id Map(id, session)
- * (VERSION_KEY, version) // Used for version tracking. version is an Integer.
- * </pre>
- * <p/>
- * Note that the isolation level of the cache dictates the
- * concurrency behavior.</p>
- *
- * @author Ben Wang
- * @author Brian Stansberry
- *
- * @version $Revision$
- */
-class SessionBasedClusteredSession
- extends JBossCacheClusteredSession
-{
- static final long serialVersionUID = 3200976125245487256L;
-
- /**
- * Descriptive information describing this Session implementation.
- */
- protected static final String info = "SessionBasedClusteredSession/1.0";
-
- public SessionBasedClusteredSession(JBossCacheManager manager)
- {
- super(manager);
- }
-
- // ---------------------------------------------- Overridden Public Methods
-
- /**
- * Return a string representation of this object.
- */
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
- sb.append("SessionBasedClusteredSession[");
- sb.append(super.toString());
- sb.append("]");
- return (sb.toString());
-
- }
-
- public void removeMyself()
- {
- proxy_.removeSession(realId);
- }
-
- public void removeMyselfLocal()
- {
- proxy_.removeSessionLocal(realId);
- }
-
- // ----------------------------------------------HttpSession Public Methods
-
- /**
- * Does nothing -- all attributes are populated already
- */
- protected void populateAttributes()
- {
- // no-op
- }
-
- protected Object getJBossInternalAttribute(String name)
- {
- Object result = attributes.get(name);
-
- // Do dirty check even if result is null, as w/ SET_AND_GET null
- // still makes us dirty (ensures timely replication w/o using ACCESS)
- if (isGetDirty(result))
- {
- sessionAttributesDirty();
- }
-
- return result;
-
- }
-
- protected Object removeJBossInternalAttribute(String name,
- boolean localCall,
- boolean localOnly)
- {
- if (localCall)
- sessionAttributesDirty();
- return attributes.remove(name);
- }
-
- protected Map getJBossInternalAttributes()
- {
- return attributes;
- }
-
- protected Object setJBossInternalAttribute(String name, Object value)
- {
- sessionAttributesDirty();
- return attributes.put(name, value);
- }
-
- /**
- * Overrides the superclass version by additionally reading the
- * attributes map.
- *
- * <p>
- * This method is deliberately public so it can be used to reset
- * the internal state of a session object using serialized
- * contents replicated from another JVM via JBossCache.
- * </p>
- *
- * @see org.jboss.web.tomcat.tc5.session.ClusteredSession#readExternal(java.io.ObjectInput)
- */
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
- {
- synchronized (this)
- {
- // Let superclass read in everything but the attribute map
- super.readExternal(in);
-
- attributes = (Map) in.readObject();
- }
- }
-
- /**
- * Overrides the superclass version by appending the attributes map. Does
- * not write any attributes whose names are found in
- * {@link ClusteredSession#excludedAttributes}.
- *
- * @see org.jboss.web.tomcat.tc5.session.ClusteredSession#writeExternal(java.io.ObjectOutput)
- */
- public void writeExternal(ObjectOutput out) throws IOException
- {
- synchronized (this)
- {
- // Let superclass write out everything but the attribute map
- super.writeExternal(out);
-
- synchronized (attributes)
- {
- // Don't replicate any excluded attributes
- Map excluded = removeExcludedAttributes(attributes);
-
- out.writeObject(attributes);
-
- // Restore any excluded attributes
- if (excluded != null)
- attributes.putAll(excluded);
- }
- }
-
- }
-
-
- /**
- * Overrides the superclass version to return <code>true</code> if either
- * the metadata or the attributes are dirty.
- */
- public boolean getReplicateSessionBody()
- {
- return isSessionDirty() || getExceedsMaxUnreplicatedInterval();
- }
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionIDGenerator.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionIDGenerator.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SessionIDGenerator.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,239 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Random;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-
-import org.jboss.logging.Logger;
-
-/**
- * Unique session id generator
- *
- * @author Ben Wang
- */
-public class SessionIDGenerator
-{
- protected final static int SESSION_ID_BYTES = 16; // We want 16 Bytes for the session-id
- protected final static String SESSION_ID_HASH_ALGORITHM = "MD5";
- protected final static String SESSION_ID_RANDOM_ALGORITHM = "SHA1PRNG";
- protected final static String SESSION_ID_RANDOM_ALGORITHM_ALT = "IBMSecureRandom";
- protected Logger log = Logger.getLogger(SessionIDGenerator.class);
-
- protected MessageDigest digest = null;
- protected Random random = null;
- protected static SessionIDGenerator s_;
-
- protected String sessionIdAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-*";
-
- public static SessionIDGenerator getInstance()
- {
- if (s_ == null) s_ = new SessionIDGenerator();
- return s_;
- }
-
- /**
- * The SessionIdAlphabet is the set of characters used to create a session Id
- */
- public void setSessionIdAlphabet(String sessionIdAlphabet)
- {
- if (sessionIdAlphabet.length() != 65) {
- throw new IllegalArgumentException("SessionIdAlphabet must be exactly 65 characters long");
- }
-
- checkDuplicateChars(sessionIdAlphabet);
-
- this.sessionIdAlphabet = sessionIdAlphabet;
- }
-
- protected void checkDuplicateChars(String sessionIdAlphabet) {
- char[] alphabet = sessionIdAlphabet.toCharArray();
- for (int i=0; i < alphabet.length; i++) {
- if (!uniqueChar(alphabet[i], sessionIdAlphabet)) {
- throw new IllegalArgumentException("All chars in SessionIdAlphabet must be unique");
- }
- }
- }
-
- // does a character appear in the String once and only once?
- protected boolean uniqueChar(char c, String s) {
- int firstIndex = s.indexOf(c);
- if (firstIndex == -1) return false;
- return s.indexOf(c, firstIndex + 1) == -1;
- }
-
- /**
- * The SessionIdAlphabet is the set of characters used to create a session Id
- */
- public String getSessionIdAlphabet() {
- return this.sessionIdAlphabet;
- }
-
- public synchronized String getSessionId()
- {
- String id = generateSessionId();
- if (log.isDebugEnabled())
- log.debug("getSessionId called: " + id);
- return id;
- }
-
-
- /**
- * Generate a session-id that is not guessable
- *
- * @return generated session-id
- */
- protected synchronized String generateSessionId()
- {
- if (this.digest == null)
- {
- this.digest = getDigest();
- }
-
- if (this.random == null)
- {
- this.random = getRandom();
- }
-
- byte[] bytes = new byte[SESSION_ID_BYTES];
-
- // get random bytes
- this.random.nextBytes(bytes);
-
- // Hash the random bytes
- bytes = this.digest.digest(bytes);
-
- // Render the result as a String of hexadecimal digits
- return encode(bytes);
- }
-
- /**
- * Encode the bytes into a String with a slightly modified Base64-algorithm
- * This code was written by Kevin Kelley <kelley at ruralnet.net>
- * and adapted by Thomas Peuss <jboss at peuss.de>
- *
- * @param data The bytes you want to encode
- * @return the encoded String
- */
- protected String encode(byte[] data)
- {
- char[] out = new char[((data.length + 2) / 3) * 4];
- char[] alphabet = this.sessionIdAlphabet.toCharArray();
-
- //
- // 3 bytes encode to 4 chars. Output is always an even
- // multiple of 4 characters.
- //
- for (int i = 0, index = 0; i < data.length; i += 3, index += 4)
- {
- boolean quad = false;
- boolean trip = false;
-
- int val = (0xFF & (int) data[i]);
- val <<= 8;
- if ((i + 1) < data.length)
- {
- val |= (0xFF & (int) data[i + 1]);
- trip = true;
- }
- val <<= 8;
- if ((i + 2) < data.length)
- {
- val |= (0xFF & (int) data[i + 2]);
- quad = true;
- }
- out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
- val >>= 6;
- out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
- val >>= 6;
- out[index + 1] = alphabet[val & 0x3F];
- val >>= 6;
- out[index + 0] = alphabet[val & 0x3F];
- }
- return new String(out);
- }
-
- /**
- * get a random-number generator
- *
- * @return a random-number generator
- */
- protected synchronized Random getRandom()
- {
- long seed;
- Random random = null;
-
- // Mix up the seed a bit
- seed = System.currentTimeMillis();
- seed ^= Runtime.getRuntime().freeMemory();
-
- try
- {
- random = SecureRandom.getInstance(SESSION_ID_RANDOM_ALGORITHM);
- }
- catch (NoSuchAlgorithmException e)
- {
- try
- {
- random = SecureRandom.getInstance(SESSION_ID_RANDOM_ALGORITHM_ALT);
- }
- catch (NoSuchAlgorithmException e_alt)
- {
- log.error("Could not generate SecureRandom for session-id randomness", e);
- log.error("Could not generate SecureRandom for session-id randomness", e_alt);
- return null;
- }
- }
-
- // set the generated seed for this PRNG
- random.setSeed(seed);
-
- return random;
- }
-
- /**
- * get a MessageDigest hash-generator
- *
- * @return a hash generator
- */
- protected synchronized MessageDigest getDigest()
- {
- MessageDigest digest = null;
-
- try
- {
- digest = MessageDigest.getInstance(SESSION_ID_HASH_ALGORITHM);
- }
- catch (NoSuchAlgorithmException e)
- {
- log.error("Could not generate MessageDigest for session-id hashing", e);
- return null;
- }
-
- return digest;
- }
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SnapshotManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SnapshotManager.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/SnapshotManager.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,61 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import org.apache.catalina.Context;
-
-/**
- * Abstract base class for a session snapshot manager.
- *
- * @author Thomas Peuss <jboss at peuss.de>
- * @version $Revision$
- */
-public abstract class SnapshotManager
-{
- // The manager the snapshot manager should use
- protected AbstractJBossManager manager;
-
- // The context-path
- protected String contextPath;
-
- public SnapshotManager(AbstractJBossManager manager, String path)
- {
- this.manager = manager;
- contextPath = path;
- }
-
- /**
- * Tell the snapshot manager which session was modified and
- * must be replicated
- */
- public abstract void snapshot(String id);
-
- /**
- * Start the snapshot manager
- */
- public abstract void start();
-
- /**
- * Stop the snapshot manager
- */
- public abstract void stop();
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/Util.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/Util.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/session/Util.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,84 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.session;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Map;
-
-import org.jboss.aop.Advised;
-import org.jboss.cache.aop.CachedType;
-
-/**
- * Utility methods related to JBoss distributed sessions.
- *
- * @author Brian Stansberry
- * @version $Revision$
- */
-public abstract class Util
-{
-
- /**
- * Returns a session id with any trailing jvmRoute removed.
- *
- * @param sessionId the raw session id
- *
- * @return <code>sessionId</code> with the final '.' and any
- * characters thereafter removed.
- */
- public static String getRealId(String sessionId)
- {
- int index = sessionId.lastIndexOf(".");
- if (index > 0)
- {
- return sessionId.substring(0, index);
- }
- else
- {
- return sessionId;
- }
- }
-
- /**
- * Checks whether the given object is usable for FIELD granularity
- * replication.
- *
- * @param pojo the pojo
- * @return <code>true</code> if the attribute type is acceptable,
- * <code>false</code> otherwise
- */
- public static boolean checkPojoType(Object pojo)
- {
- return ( (pojo instanceof Serializable)
- || (pojo instanceof Collection)
- || (pojo instanceof Map)
- || (pojo instanceof Advised)
- || (CachedType.isImmediate(pojo.getClass())));
- }
-
- /**
- * Prevent instantiation.
- */
- private Util() {}
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/ClusteredSingleSignOn.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/ClusteredSingleSignOn.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/ClusteredSingleSignOn.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,1039 +0,0 @@
-/*
- * Copyright 1999-2001,2004 The Apache Software Foundation.
- *
- * Licensed 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.jboss.web.tomcat.tc5.sso;
-
-
-import org.jboss.web.tomcat.tc5.Tomcat5;
-import org.jboss.web.tomcat.tc5.session.JBossManager;
-
-import java.io.IOException;
-import java.security.Principal;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.management.ObjectName;
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleEvent;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.Manager;
-import org.apache.catalina.Session;
-import org.apache.catalina.Realm;
-import org.apache.catalina.SessionEvent;
-import org.apache.catalina.authenticator.Constants;
-import org.apache.catalina.connector.Request;
-import org.apache.catalina.connector.Response;
-import org.apache.catalina.session.ManagerBase;
-
-
-/**
- * A <strong>Valve</strong> that supports a "single sign on" user experience,
- * where the security identity of a user who successfully authenticates to one
- * web application is propogated to other web applications in the same
- * security domain. For successful use, the following requirements must
- * be met:
- * <ul>
- * <li>This Valve must be configured on the Container that represents a
- * virtual host (typically an implementation of <code>Host</code>).</li>
- * <li>The <code>Realm</code> that contains the shared user and role
- * information must be configured on the same Container (or a higher
- * one), and not overridden at the web application level.</li>
- * <li>The web applications themselves must use one of the standard
- * Authenticators found in the
- * <code>org.apache.catalina.authenticator</code> package.</li>
- * </ul>
- *
- * @author Brian E. Stansberry based on the work of Craig R. McClanahan
- * @version $Revision$ $Date$
- */
-public class ClusteredSingleSignOn
- extends org.apache.catalina.authenticator.SingleSignOn
- implements LifecycleListener
-{
-
- // Override the superclass value
- static
- {
- info = ClusteredSingleSignOn.class.getName();
- }
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * Fully qualified name of a class implementing
- * {@link SSOClusterManager SSOClusterManager} that will be used
- * to manage SSOs across a cluster.
- */
- private String clusterManagerClass =
- TreeCacheSSOClusterManager.class.getName();
-
- /**
- * Object used to provide cross-cluster support for single sign on.
- */
- private SSOClusterManager ssoClusterManager = null;
-
- /**
- * Object name of the tree cache used by SSOClusterManager.
- * Only relevant if the SSOClusterManager implementation is
- * TreeCacheSSOClusterManager.
- */
- private String treeCacheName = Tomcat5.DEFAULT_CACHE_NAME;
-
- private Set activeManagers = Collections.synchronizedSet(new HashSet());
-
- // ------------------------------------------------------------- Properties
-
- /**
- * Gets the object that provides SSO support across a cluster.
- *
- * @return the object provided cluster support, or <code>null</code> if
- * no such object has been configured.
- */
- public SSOClusterManager getClusterManager()
- {
- return this.ssoClusterManager;
- }
-
-
- /**
- * Sets the object that provides SSO support across a cluster.
- *
- * @param clusterManager the object that provides SSO support.
- * @throws IllegalStateException if this method is invoked after this valve
- * has been started.
- */
- public void setClusterManager(SSOClusterManager clusterManager)
- {
- if (started && (clusterManager != ssoClusterManager))
- {
- throw new IllegalStateException("already started -- cannot set a " +
- "new SSOClusterManager");
- }
-
- this.ssoClusterManager = clusterManager;
-
- if (clusterManager != null)
- {
- clusterManagerClass = clusterManager.getClass().getName();
- }
- }
-
-
- /**
- * Gets the name of the class that will be used to provide SSO support
- * across a cluster.
- *
- * @return Fully qualified name of a class implementing
- * {@link SSOClusterManager SSOClusterManager}
- * that is being used to manage SSOs across a cluster.
- * May return <code>null</code> (the default) if clustered
- * SSO support is not configured.
- */
- public String getClusterManagerClass()
- {
- return clusterManagerClass;
- }
-
-
- /**
- * Sets the name of the class that will be used to provide SSO support
- * across a cluster.
- * <p><b>NOTE: </b>
- * If this Valve has already started, and no SSOClusterManager has been
- * configured for it, calling this method will
- *
- * @param managerClass Fully qualified name of a class implementing
- * {@link SSOClusterManager SSOClusterManager}
- * that will be used to manage SSOs across a cluster.
- * Class must declare a public no-arguments
- * constructor. <code>null</code> is allowed.
- */
- public void setClusterManagerClass(String managerClass)
- {
- if (!started)
- {
- clusterManagerClass = managerClass;
- }
- else if (ssoClusterManager == null)
- {
- try
- {
- createClusterManager(managerClass);
- }
- catch (LifecycleException e)
- {
- getContainer().getLogger().error("Exception creating SSOClusterManager " +
- managerClass, e);
- }
- }
- else
- {
- getContainer().getLogger().error("Cannot set clusterManagerClass to " + managerClass +
- "; already started using " + clusterManagerClass);
- }
- }
-
- /**
- * Object name of the tree cache used by SSOClusterManager.
- * Only relevant if the SSOClusterManager implementation is
- * TreeCacheSSOClusterManager.
- */
- public String getTreeCacheName()
- {
- return treeCacheName;
- }
-
- /**
- * Sets the object name of the tree cache used by SSOClusterManager.
- * Only relevant if the SSOClusterManager implementation is
- * TreeCacheSSOClusterManager.
- */
- public void setTreeCacheName(String cacheName)
- throws Exception
- {
- this.treeCacheName = cacheName;
- if (ssoClusterManager != null
- && ssoClusterManager instanceof TreeCacheSSOClusterManager)
- {
- ((TreeCacheSSOClusterManager) ssoClusterManager).setCacheName(cacheName);
- }
- }
-
-
- // ------------------------------------------------------ Lifecycle Methods
-
-
- /**
- * Prepare for the beginning of active use of the public methods of this
- * component. This method should be called after <code>configure()</code>,
- * and before any of the public methods of the component are utilized.
- *
- * @throws LifecycleException if this component detects a fatal error
- * that prevents this component from being used
- */
- public void start() throws LifecycleException
- {
- // Validate and update our current component state
- if (started)
- {
- throw new LifecycleException
- (sm.getString("authenticator.alreadyStarted"));
- }
-
- // Attempt to create an SSOClusterManager
- createClusterManager(getClusterManagerClass());
-
- lifecycle.fireLifecycleEvent(START_EVENT, null);
- started = true;
-
- if (ssoClusterManager != null)
- {
- ssoClusterManager.start();
- }
-
- }
-
-
- /**
- * Gracefully terminate the active use of the public methods of this
- * component. This method should be the last one called on a given
- * instance of this component.
- *
- * @throws LifecycleException if this component detects a fatal error
- * that needs to be reported
- */
- public void stop() throws LifecycleException
- {
- // Validate and update our current component state
- if (!started)
- {
- throw new LifecycleException
- (sm.getString("authenticator.notStarted"));
- }
-
- if (ssoClusterManager != null)
- {
- ssoClusterManager.stop();
- }
-
- lifecycle.fireLifecycleEvent(STOP_EVENT, null);
- started = false;
-
- }
-
-
- // ------------------------------------------------ SessionListener Methods
-
-
- /**
- * Updates the state of a single sign on session to reflect the destruction
- * of a standard HTTP session.
- * <p/>
- * If the given event is a {@link Session#SESSION_DESTROYED_EVENT
- * Session destroyed event}, checks whether the session was destroyed due
- * to timeout or user action (i.e. logout). If due to timeout, disassociates
- * the Session from the single sign on session. If due to logout, invokes
- * the {@link #logout} method.
- *
- * @param event SessionEvent that has occurred
- */
- public void sessionEvent(SessionEvent event)
- {
- // 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 (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug("Process session destroyed on " + session);
-
- String ssoId = null;
- synchronized (reverse)
- {
- ssoId = (String) reverse.get(session);
- }
- if (ssoId == null)
- return;
-
- // Was the session destroyed as the result of a timeout or
- // the undeployment of the containing webapp?
- // If so, we'll just remove the expired session from the
- // SSO. If the session was logged out, we'll log out
- // of all sessions associated with the SSO.
- if (isSessionTimedOut(session) || isManagerStopped(session))
- {
- removeSession(ssoId, session);
- }
- else
- {
- // The session was logged out.
- logout(ssoId);
- }
-
- }
-
- private boolean isSessionTimedOut(Session session)
- {
- return (session.getMaxInactiveInterval() > 0)
- && (System.currentTimeMillis() - session.getLastAccessedTime() >=
- session.getMaxInactiveInterval() * 1000);
- }
-
- private boolean isManagerStopped(Session session)
- {
- boolean stopped = false;
-
- Manager manager = session.getManager();
-
- if (manager instanceof ManagerBase)
- {
- ObjectName mgrName = ((ManagerBase)manager).getObjectName();
- stopped = (!activeManagers.contains(mgrName));
- }
- else if (manager instanceof JBossManager)
- {
- ObjectName mgrName = ((JBossManager)manager).getObjectName();
- stopped = (!activeManagers.contains(mgrName));
- }
- else if (manager instanceof Lifecycle)
- {
- stopped = (!activeManagers.contains(manager));
- }
- // else we have no way to tell, so assume not
-
- return stopped;
- }
-
- // ---------------------------------------------- LifecycleListener Methods
-
-
- public void lifecycleEvent(LifecycleEvent event)
- {
- String type = event.getType();
- if (Lifecycle.BEFORE_STOP_EVENT.equals(type)
- || Lifecycle.STOP_EVENT.equals(type)
- || Lifecycle.AFTER_STOP_EVENT.equals(type))
- {
- Lifecycle source = event.getLifecycle();
- boolean removed;
- if (source instanceof ManagerBase)
- {
- removed = activeManagers.remove(((ManagerBase)source).getObjectName());
- }
- else if (source instanceof JBossManager)
- {
- removed = activeManagers.remove(((JBossManager)source).getObjectName());
- }
- else
- {
- removed = activeManagers.remove(source);
- }
-
- if (removed)
- {
- source.removeLifecycleListener(this);
-
- if (getContainer().getLogger().isDebugEnabled())
- {
- getContainer().getLogger().debug("ClusteredSSO: removed " +
- "stopped manager " + source.toString());
- }
- }
-
- // TODO consider getting the sessions and removing any from our sso's
- // Idea is to cleanup after managers that don't destroy sessions
-
- }
- }
-
-
- // ---------------------------------------------------------- Valve Methods
-
-
- /**
- * Perform single-sign-on support processing for this request.
- * <p/>
- * Overrides the superclass version by handling the fact that a
- * single sign on may have been originated on another cluster node and
- * thus may not have a <code>Principal</code> object associated with it
- * on this node.
- *
- * @param request The servlet request we are processing
- * @param response The servlet response we are creating
- * @param context The valve context used to invoke the next valve
- * in the current processing pipeline
- * @throws IOException if an input/output error occurs
- * @throws ServletException if a servlet error occurs
- */
- public void invoke(Request request, Response response)
- throws IOException, ServletException
- {
- request.removeNote(Constants.REQ_SSOID_NOTE);
-
- // Has a valid user already been authenticated?
- if (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug("Process request for '" + request.getRequestURI() + "'");
- if (request.getUserPrincipal() != null)
- {
- if (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug(" Principal '" + request.getUserPrincipal().getName() +
- "' has already been authenticated");
- getNext().invoke(request, response);
- return;
- }
-
- // Check for the single sign on cookie
- Cookie cookie = null;
- Cookie cookies[] = request.getCookies();
- if (cookies == null)
- cookies = new Cookie[0];
- for (int i = 0; i < cookies.length; i++)
- {
- if (Constants.SINGLE_SIGN_ON_COOKIE.equals(cookies[i].getName()))
- {
- cookie = cookies[i];
- break;
- }
- }
- if (cookie == null)
- {
- if (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug(" SSO cookie is not present");
- getNext().invoke(request, response);
- return;
- }
-
- // Look up the cached Principal associated with this cookie value
- if (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug(" Checking for cached principal for " + cookie.getValue());
- SingleSignOnEntry entry = getSingleSignOnEntry(cookie.getValue());
- if (entry != null)
- {
- Principal ssoPrinc = entry.getPrincipal();
- // have to deal with the fact that the entry may not have an
- // associated Principal. SSO entries retrieved via a lookup from a
- // cluster will not have a Principal, as Principal is not Serializable
- if (getContainer().getLogger().isDebugEnabled())
- {
- getContainer().getLogger().debug(" Found cached principal '" +
- (ssoPrinc == null ? "NULL" : ssoPrinc.getName()) +
- "' with auth type '" + entry.getAuthType() + "'");
- }
- request.setNote(Constants.REQ_SSOID_NOTE, cookie.getValue());
- // Only set security elements if per-request reauthentication is
- // not required AND the SSO entry had a Principal.
- if (!getRequireReauthentication() && ssoPrinc != null)
- {
- request.setAuthType(entry.getAuthType());
- request.setUserPrincipal(ssoPrinc);
- }
- }
- else
- {
- if (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug(" No cached principal found, erasing SSO cookie");
- cookie.setMaxAge(0);
- response.addCookie(cookie);
- }
-
- // Invoke the next Valve in our pipeline
- getNext().invoke(request, response);
- }
-
-
- // ------------------------------------------------------ Protected Methods
-
-
- /**
- * Associate the specified single sign on identifier with the
- * specified Session.
- * <p/>
- * Differs from the superclass version in that it notifies the cluster
- * of any new association of SSO and Session.
- *
- * @param ssoId Single sign on identifier
- * @param session Session to be associated
- */
- protected void associate(String ssoId, Session session)
- {
- if (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug("Associate sso id " + ssoId + " with session " + session);
-
- SingleSignOnEntry sso = getSingleSignOnEntry(ssoId);
- boolean added = false;
- if (sso != null)
- added = sso.addSession(this, session);
-
- synchronized (reverse)
- {
- reverse.put(session, ssoId);
- }
-
- // If we made a change, track the manager and notify any cluster
- if (added)
- {
- Manager manager = session.getManager();
-
- // Prefer to cache an ObjectName to avoid risk of leaking a manager,
- // so if the manager exposes one, use it
- Object mgrKey = null;
- if (manager instanceof ManagerBase)
- {
- mgrKey = ((ManagerBase)manager).getObjectName();
- }
- else if (manager instanceof JBossManager)
- {
- mgrKey = ((JBossManager)manager).getObjectName();
- }
- else if (manager instanceof Lifecycle)
- {
- mgrKey = manager;
- }
- else {
- getContainer().getLogger().warn("Manager for session " +
- session.getIdInternal() +
- " does not implement Lifecycle; web app shutdown may " +
- " lead to incorrect SSO invalidations");
- }
-
- if (mgrKey != null)
- {
- synchronized (activeManagers)
- {
- if (!activeManagers.contains(mgrKey))
- {
- activeManagers.add(mgrKey);
- ((Lifecycle) manager).addLifecycleListener(this);
- }
- }
- }
-
- if (ssoClusterManager != null)
- ssoClusterManager.addSession(ssoId, session);
- }
- }
-
-
- /**
- * Deregister the specified session. If it is the last session,
- * then also get rid of the single sign on identifier.
- * <p/>
- * Differs from the superclass version in that it notifies the cluster
- * of any disassociation of SSO and Session.
- *
- * @param ssoId Single sign on identifier
- * @param session Session to be deregistered
- */
- protected void deregister(String ssoId, Session session)
- {
- synchronized (reverse)
- {
- reverse.remove(session);
- }
-
- SingleSignOnEntry sso = getSingleSignOnEntry(ssoId);
- if (sso == null)
- return;
-
- boolean removed = sso.removeSession(session);
- // If we changed anything, notify any cluster
- if (removed && ssoClusterManager != null)
- {
- ssoClusterManager.removeSession(ssoId, session);
- }
-
- // see if this was the last session on this node,
- // if remove sso entry from our local cache
- if (sso.getSessionCount() == 0)
- {
- synchronized (cache)
- {
- sso = (SingleSignOnEntry) cache.remove(ssoId);
- }
- }
- }
-
-
- /**
- * Deregister the specified single sign on identifier, and invalidate
- * any associated sessions.
- *
- * @param ssoId Single sign on identifier to deregister
- */
- protected void deregister(String ssoId)
- {
- if (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug("Deregistering sso id '" + ssoId + "'");
-
- // Look up and remove the corresponding SingleSignOnEntry
- SingleSignOnEntry sso = null;
- synchronized (cache)
- {
- sso = (SingleSignOnEntry) cache.remove(ssoId);
- }
-
- if (sso == null)
- return;
-
- // Expire any associated sessions
- Session sessions[] = sso.findSessions();
- for (int i = 0; i < sessions.length; i++)
- {
- if (getContainer().getLogger().isTraceEnabled())
- getContainer().getLogger().trace(" Invalidating session " + sessions[i]);
- // Remove from reverse cache first to avoid recursion
- synchronized (reverse)
- {
- reverse.remove(sessions[i]);
- }
- // Invalidate this session
- sessions[i].expire();
- }
-
- // NOTE: Clients may still possess the old single sign on cookie,
- // but it will be removed on the next request since it is no longer
- // in the cache
- }
-
-
- /**
- * Deregister the given SSO, invalidating any associated sessions, then
- * notify any cluster of the logout.
- *
- * @param ssoId the id of the SSO session
- */
- protected void logout(String ssoId)
- {
- deregister(ssoId);
- // broadcast logout to any cluster
- if (ssoClusterManager != null)
- ssoClusterManager.logout(ssoId);
- }
-
-
- /**
- * Look up and return the cached SingleSignOn entry associated with this
- * sso id value, if there is one; otherwise return <code>null</code>.
- *
- * @param ssoId Single sign on identifier to look up
- */
- protected SingleSignOnEntry getSingleSignOnEntry(String ssoId)
- {
- SingleSignOnEntry sso = localLookup(ssoId);
- // If we don't have one locally and there is a cluster,
- // query the cluster for the SSO
- if (sso == null && ssoClusterManager != null)
- {
- sso = ssoClusterManager.lookup(ssoId);
- if (sso != null)
- {
- // Store it locally
- synchronized (cache)
- {
- cache.put(ssoId, sso);
- }
- }
- }
-
- return sso;
- }
-
-
- /**
- * Attempts reauthentication to the given <code>Realm</code> using
- * the credentials associated with the single sign-on session
- * identified by argument <code>ssoId</code>.
- * <p/>
- * If reauthentication is successful, the <code>Principal</code> and
- * authorization type associated with the SSO session will be bound
- * to the given <code>HttpRequest</code> object via calls to
- * {@link HttpRequest#setAuthType HttpRequest.setAuthType()} and
- * {@link HttpRequest#setUserPrincipal HttpRequest.setUserPrincipal()}
- * </p>
- *
- * @param ssoId identifier of SingleSignOn session with which the
- * caller is associated
- * @param realm Realm implementation against which the caller is to
- * be authenticated
- * @param request the request that needs to be authenticated
- * @return <code>true</code> if reauthentication was successful,
- * <code>false</code> otherwise.
- */
- protected boolean reauthenticate(String ssoId, Realm realm,
- Request request)
- {
- if (ssoId == null || realm == null)
- return false;
-
- boolean reauthenticated = false;
-
- SingleSignOnEntry entry = getSingleSignOnEntry(ssoId);
- if (entry != null && entry.getCanReauthenticate())
- {
-
- String username = entry.getUsername();
- if (username != null)
- {
- Principal reauthPrincipal =
- realm.authenticate(username, entry.getPassword());
- if (reauthPrincipal != null)
- {
- reauthenticated = true;
- // Bind the authorization credentials to the request
- request.setAuthType(entry.getAuthType());
- request.setUserPrincipal(reauthPrincipal);
- // JBAS-2314 -- bind principal to the entry as well
- entry.setPrincipal(reauthPrincipal);
- }
- }
- }
-
- return reauthenticated;
- }
-
-
- /**
- * Register the specified Principal as being associated with the specified
- * value for the single sign on identifier.
- * <p/>
- * Differs from the superclass version in that it notifies the cluster
- * of the registration.
- *
- * @param ssoId Single sign on identifier to register
- * @param principal Associated user principal that is identified
- * @param authType Authentication type used to authenticate this
- * user principal
- * @param username Username used to authenticate this user
- * @param password Password used to authenticate this user
- */
- protected void register(String ssoId, Principal principal, String authType,
- String username, String password)
- {
- registerLocal(ssoId, principal, authType, username, password);
-
- // broadcast change to any cluster
- if (ssoClusterManager != null)
- ssoClusterManager.register(ssoId, authType, username, password);
- }
-
-
- /**
- * Remove a single Session from a SingleSignOn. Called when
- * a session is timed out and no longer active.
- * <p/>
- * Differs from the superclass version in that it notifies the cluster
- * of any disassociation of SSO and Session.
- *
- * @param ssoId Single sign on identifier from which to remove the session.
- * @param session the session to be removed.
- */
- protected void removeSession(String ssoId, Session session)
- {
- if (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug("Removing session " + session.toString() +
- " from sso id " + ssoId);
-
- // Get a reference to the SingleSignOn
- SingleSignOnEntry entry = getSingleSignOnEntry(ssoId);
- if (entry == null)
- return;
-
- // Remove the inactive session from SingleSignOnEntry
- boolean removed = entry.removeSession(session);
- // If we changed anything, notify any cluster
- if (removed && ssoClusterManager != null)
- {
- ssoClusterManager.removeSession(ssoId, session);
- }
-
- // Remove the inactive session from the 'reverse' Map.
- synchronized (reverse)
- {
- reverse.remove(session);
- }
-
- // If there are no sessions left in the SingleSignOnEntry,
- // deregister the entry.
- if (entry.getSessionCount() == 0)
- {
- deregister(ssoId);
- }
- }
-
-
- /**
- * Updates any <code>SingleSignOnEntry</code> found under key
- * <code>ssoId</code> with the given authentication data.
- * <p/>
- * The purpose of this method is to allow an SSO entry that was
- * established without a username/password combination (i.e. established
- * following DIGEST or CLIENT-CERT authentication) to be updated with
- * a username and password if one becomes available through a subsequent
- * BASIC or FORM authentication. The SSO entry will then be usable for
- * reauthentication.
- * <p/>
- * <b>NOTE:</b> Only updates the SSO entry if a call to
- * <code>SingleSignOnEntry.getCanReauthenticate()</code> returns
- * <code>false</code>; otherwise, it is assumed that the SSO entry already
- * has sufficient information to allow reauthentication and that no update
- * is needed.
- * <p/>
- * Differs from the superclass version in that it notifies the cluster
- * of any update.
- *
- * @param ssoId identifier of Single sign to be updated
- * @param principal the <code>Principal</code> returned by the latest
- * call to <code>Realm.authenticate</code>.
- * @param authType the type of authenticator used (BASIC, CLIENT-CERT,
- * DIGEST or FORM)
- * @param username the username (if any) used for the authentication
- * @param password the password (if any) used for the authentication
- */
- protected void update(String ssoId, Principal principal, String authType,
- String username, String password)
- {
- boolean needToBroadcast = updateLocal(ssoId, principal, authType,
- username, password);
-
- // if there was a change, broadcast it to any cluster
- if (needToBroadcast && ssoClusterManager != null)
- {
- ssoClusterManager.updateCredentials(ssoId, authType,
- username, password);
- }
- }
-
- //---------------------------------------------- Package-Protected Methods
-
- /**
- * Search in our local cache for an SSO entry.
- *
- * @param ssoId the id of the SSO session
- * @return any SingleSignOnEntry associated with the given id, or
- * <code>null</code> if there is none.
- */
- SingleSignOnEntry localLookup(String ssoId)
- {
- synchronized (cache)
- {
- return ((SingleSignOnEntry) cache.get(ssoId));
- }
-
- }
-
- /**
- * Create a SingleSignOnEntry using the passed configuration parameters and
- * register it in the local cache, bound to the given id.
- *
- * @param ssoId the id of the SSO session
- * @param principal the <code>Principal</code> returned by the latest
- * call to <code>Realm.authenticate</code>.
- * @param authType the type of authenticator used (BASIC, CLIENT-CERT,
- * DIGEST or FORM)
- * @param username the username (if any) used for the authentication
- * @param password the password (if any) used for the authentication
- */
- void registerLocal(String ssoId, Principal principal, String authType,
- String username, String password)
- {
- if (getContainer().getLogger().isDebugEnabled())
- {
- getContainer().getLogger().debug("Registering sso id '" + ssoId + "' for user '" +
- principal.getName() + "' with auth type '" + authType + "'");
- }
-
- synchronized (cache)
- {
- cache.put(ssoId, new SingleSignOnEntry(principal, authType,
- username, password));
- }
- }
-
- /**
- * Updates any <code>SingleSignOnEntry</code> found under key
- * <code>ssoId</code> with the given authentication data.
- *
- * @param ssoId identifier of Single sign to be updated
- * @param principal the <code>Principal</code> returned by the latest
- * call to <code>Realm.authenticate</code>.
- * @param authType the type of authenticator used (BASIC, CLIENT-CERT,
- * DIGEST or FORM)
- * @param username the username (if any) used for the authentication
- * @param password the password (if any) used for the authentication
- * @return <code>true</code> if the update resulted in an actual change
- * to the entry's authType, username or principal properties
- */
- boolean updateLocal(String ssoId, Principal principal, String authType,
- String username, String password)
- {
- boolean shouldBroadcast = false;
-
- SingleSignOnEntry sso = getSingleSignOnEntry(ssoId);
- // Only update if the entry is missing information
- if (sso != null)
- {
- if (sso.getCanReauthenticate() == false)
- {
- if (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug("Update sso id " + ssoId + " to auth type " + authType);
-
- synchronized (sso)
- {
- shouldBroadcast = sso.updateCredentials(principal, authType,
- username, password);
- }
- }
- else if (sso.getPrincipal() == null && principal != null)
- {
- if (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug("Update sso id " + ssoId + " with principal " +
- principal.getName());
-
- synchronized (sso)
- {
- sso.setPrincipal(principal);
- // No need to notify cluster; Principals don't replicate
- }
- }
-
- }
-
- return shouldBroadcast;
-
- }
-
- void remoteUpdate(String ssoId, String authType,
- String username, String password)
- {
- SingleSignOnEntry sso = getSingleSignOnEntry(ssoId);
- // Only update if the entry is missing information
- if (sso != null && sso.getCanReauthenticate() == false)
- {
- if (getContainer().getLogger().isDebugEnabled())
- getContainer().getLogger().debug("Update sso id " + ssoId + " to auth type " + authType);
-
- synchronized (sso)
- {
- // Use the existing principal
- Principal p = sso.getPrincipal();
- sso.updateCredentials(p, authType, username, password);
- }
- }
-
- }
-
-
- // ------------------------------------------------------- Private Methods
-
-
- /**
- * Instantiates an instance of the given class, making it this valve's
- * SSOClusterManager.
- * <p/>
- * If this valve has been started and the given class implements
- * <code>Lifecycle</code>, starts the new SSOClusterManager.
- *
- * @param className fully qualified class name of an implementation
- * of {@link SSOClusterManager SSOClusterManager}.
- * @throws LifecycleException if there is any problem instantiating or
- * starting the object, or if the created
- * object does not implement
- * <code>SSOClusterManger</code>
- */
- private void createClusterManager(String className)
- throws LifecycleException
- {
- if (ssoClusterManager != null)
- return;
-
- if (className != null)
- {
- SSOClusterManager mgr = null;
- try
- {
- ClassLoader tcl =
- Thread.currentThread().getContextClassLoader();
- Class clazz = tcl.loadClass(className);
- mgr = (SSOClusterManager) clazz.newInstance();
- mgr.setSingleSignOnValve(this);
- if (mgr instanceof TreeCacheSSOClusterManager)
- {
- ((TreeCacheSSOClusterManager) mgr).setCacheName(getTreeCacheName());
- }
- ssoClusterManager = mgr;
- clusterManagerClass = className;
- }
- catch (Throwable t)
- {
- throw new LifecycleException("Cannot create " +
- "SSOClusterManager using " +
- className, t);
- }
-
- if (started)
- {
- ssoClusterManager.start();
- }
- }
- }
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/SSOClusterManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/SSOClusterManager.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/SSOClusterManager.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,121 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.sso;
-
-import org.apache.catalina.Session;
-import org.apache.catalina.Lifecycle;
-
-/**
- * Provides communications support between a SingleSignOn valve and other
- * such valves configured for the same hostname within a server cluster.
- * <p/>
- * Implementations of this interface must declare a public no-arguments
- * constructor.
- *
- * @author Brian E. Stansberry
- * @version $Revision$ $Date$
- * @see ClusteredSingleSignOn
- */
-public interface SSOClusterManager
- extends Lifecycle
-{
-
- /**
- * Notify the cluster of the addition of a Session to an SSO session.
- *
- * @param ssoId the id of the SSO session
- * @param session the Session that has been added
- */
- void addSession(String ssoId, Session session);
-
- /**
- * Gets the SingleSignOn valve for which this object is handling
- * cluster communications.
- *
- * @return the <code>SingleSignOn</code> valve.
- */
- ClusteredSingleSignOn getSingleSignOnValve();
-
- /**
- * Sets the SingleSignOn valve for which this object is handling
- * cluster communications.
- * <p><b>NOTE:</b> This method must be called before calls can be
- * made to the other methods of this interface.
- *
- * @param valve a <code>SingleSignOn</code> valve.
- */
- void setSingleSignOnValve(ClusteredSingleSignOn valve);
-
- /**
- * Notifies the cluster that a single sign on session has been terminated
- * due to a user logout.
- *
- * @param ssoId the id of the SSO session
- */
- void logout(String ssoId);
-
- /**
- * Queries the cluster for the existence of a SSO session with the given
- * id, returning a <code>SingleSignOnEntry</code> if one is found.
- *
- * @param ssoId the id of the SSO session
- * @return a <code>SingleSignOnEntry</code> created using information
- * found on another cluster node, or <code>null</code> if no
- * entry could be found.
- */
- SingleSignOnEntry lookup(String ssoId);
-
- /**
- * Notifies the cluster of the creation of a new SSO entry.
- *
- * @param ssoId the id of the SSO session
- * @param authType the type of authenticator (BASIC, CLIENT-CERT, DIGEST
- * or FORM) used to authenticate the SSO.
- * @param username the username (if any) used for the authentication
- * @param password the password (if any) used for the authentication
- */
- void register(String ssoId, String authType, String username,
- String password);
-
- /**
- * Notify the cluster of the removal of a Session from an SSO session.
- *
- * @param ssoId the id of the SSO session
- * @param session the Session that has been removed
- */
- void removeSession(String ssoId, Session session);
-
- /**
- * Notifies the cluster of an update of the security credentials
- * associated with an SSO session.
- *
- * @param ssoId the id of the SSO session
- * @param authType the type of authenticator (BASIC, CLIENT-CERT, DIGEST
- * or FORM) used to authenticate the SSO.
- * @param username the username (if any) used for the authentication
- * @param password the password (if any) used for the authentication
- */
- void updateCredentials(String ssoId, String authType, String username,
- String password);
-
-
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/SingleSignOnEntry.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/SingleSignOnEntry.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/SingleSignOnEntry.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,264 +0,0 @@
-/*
- * Copyright 1999-2001,2004 The Apache Software Foundation.
- *
- * Licensed 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.jboss.web.tomcat.tc5.sso;
-
-import java.security.Principal;
-
-import org.apache.catalina.Session;
-import org.apache.catalina.authenticator.Constants;
-import org.apache.catalina.authenticator.SingleSignOn;
-
-/**
- * A class that represents entries in the cache of authenticated users.
- *
- * @author Brian E. Stansberry, based on work by Craig R. McClanahan
- * @version $Revision$ $Date$
- * @see SingleSignOn
- */
-class SingleSignOnEntry
-{
- // ------------------------------------------------------ Instance Fields
-
- private String authType = null;
-
- private String password = null;
-
- private Principal principal = null;
-
- private Session sessions[] = new Session[0];
-
- private String username = null;
-
- private boolean canReauthenticate = false;
-
- // --------------------------------------------------------- Constructors
-
- /**
- * Creates a new SingleSignOnEntry
- *
- * @param principal the <code>Principal</code> returned by the latest
- * call to <code>Realm.authenticate</code>.
- * @param authType the type of authenticator used (BASIC, CLIENT-CERT,
- * DIGEST or FORM)
- * @param username the username (if any) used for the authentication
- * @param password the password (if any) used for the authentication
- */
- SingleSignOnEntry(Principal principal, String authType,
- String username, String password)
- {
- updateCredentials(principal, authType, username, password);
- }
-
- // ------------------------------------------------------- Package Methods
-
- /**
- * Adds a <code>Session</code> to the list of those associated with
- * this SSO.
- *
- * @param sso The <code>SingleSignOn</code> valve that is managing
- * the SSO session.
- * @param session The <code>Session</code> being associated with the SSO.
- * @return <code>true</code> if the given Session was a new addition (i.e.
- * was not previously associated with this entry);
- * <code>false</code> otherwise.
- */
- synchronized boolean addSession(SingleSignOn sso, Session session)
- {
- for (int i = 0; i < sessions.length; i++)
- {
- if (session == sessions[i])
- return false;
- }
- Session results[] = new Session[sessions.length + 1];
- System.arraycopy(sessions, 0, results, 0, sessions.length);
- results[sessions.length] = session;
- sessions = results;
- session.addSessionListener(sso);
- return true;
- }
-
- /**
- * Removes the given <code>Session</code> from the list of those
- * associated with this SSO.
- *
- * @param session the <code>Session</code> to remove.
- * @return <code>true</code> if the given Session needed to be removed
- * (i.e. was in fact previously associated with this entry);
- * <code>false</code> otherwise.
- */
- synchronized boolean removeSession(Session session)
- {
- if (sessions.length == 0)
- return false;
-
- boolean removed = false;
- Session[] nsessions = new Session[sessions.length - 1];
- for (int i = 0, j = 0; i < sessions.length; i++)
- {
- if (session == sessions[i])
- {
- removed = true;
- continue;
- }
- else if (!removed && i == nsessions.length)
- {
- // We have tested all our sessions, and have not had to
- // remove any; break loop now so we don't cause an
- // ArrayIndexOutOfBounds on nsessions
- break;
- }
- nsessions[j++] = sessions[i];
- }
- sessions = nsessions;
- // Only if we removed a session, do we replace our session list
- if (removed)
- sessions = nsessions;
- return removed;
- }
-
- /**
- * Returns the <code>Session</code>s associated with this SSO.
- */
- synchronized Session[] findSessions()
- {
- return (this.sessions);
- }
-
- /**
- * Gets the name of the authentication type originally used to authenticate
- * the user associated with the SSO.
- *
- * @return "BASIC", "CLIENT-CERT", "DIGEST", "FORM" or "NONE"
- */
- String getAuthType()
- {
- return (this.authType);
- }
-
- /**
- * Gets whether the authentication type associated with the original
- * authentication supports reauthentication.
- *
- * @return <code>true</code> if <code>getAuthType</code> returns
- * "BASIC" or "FORM", <code>false</code> otherwise.
- */
- boolean getCanReauthenticate()
- {
- return (this.canReauthenticate);
- }
-
- /**
- * Gets the password credential (if any) associated with the SSO.
- *
- * @return the password credential associated with the SSO, or
- * <code>null</code> if the original authentication type
- * does not involve a password.
- */
- String getPassword()
- {
- return (this.password);
- }
-
- /**
- * Gets the <code>Principal</code> that has been authenticated by
- * the SSO.
- * <p/>
- * <b>NOTE: </b> May return <code>null</code> if this object was
- * retrieved via a lookup from another node in a cluster. Interface
- * <code>Principal</code> does not extend <code>Serializable</code>,
- * so a <code>SingleSignOnEntry</code>'s principal member cannot be
- * serialized as part of SSO management in a cluster. A
- * <code>Principal</code> cannot be bound to a
- * <code>SingleSignOnEntry</code> until the SSO has been authenticated
- * by the local node.
- *
- * @return The <code>Principal</code> that has been authenticated by
- * the local SSO, or <code>null</code> if no authentication
- * has been performed yet in this cluster node.
- */
- Principal getPrincipal()
- {
- return (this.principal);
- }
-
- /**
- * Sets the <code>Principal</code> that has been authenticated by
- * the SSO.
- */
- void setPrincipal(Principal principal)
- {
- this.principal = principal;
- }
-
- /**
- * Returns the number of sessions associated with this SSO, either
- * locally or remotely.
- */
- int getSessionCount()
- {
- return (sessions.length);
- }
-
- /**
- * Gets the username provided by the user as part of the authentication
- * process.
- */
- String getUsername()
- {
- return (this.username);
- }
-
-
- /**
- * Updates the SingleSignOnEntry to reflect the latest security
- * information associated with the caller.
- *
- * @param principal the <code>Principal</code> returned by the latest
- * call to <code>Realm.authenticate</code>.
- * @param authType the type of authenticator used (BASIC, CLIENT-CERT,
- * DIGEST or FORM)
- * @param username the username (if any) used for the authentication
- * @param password the password (if any) used for the authentication
- */
- synchronized boolean updateCredentials(Principal principal, String authType,
- String username, String password)
- {
-
- boolean changed =
- (safeEquals(this.principal, principal)
- || safeEquals(this.authType, authType)
- || safeEquals(this.username, username)
- || safeEquals(this.password, password));
-
- this.principal = principal;
- this.authType = authType;
- this.username = username;
- this.password = password;
- this.canReauthenticate =
- (Constants.BASIC_METHOD.equals(authType)
- || Constants.FORM_METHOD.equals(authType));
- return changed;
- }
-
- // ------------------------------------------------------- Private Methods
-
- private boolean safeEquals(Object a, Object b)
- {
- return ((a == b)
- || (a != null && a.equals(b))
- || (b != null && b.equals(a)));
- }
-}
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/TreeCacheSSOClusterManager.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/TreeCacheSSOClusterManager.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/TreeCacheSSOClusterManager.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,1339 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt 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.web.tomcat.tc5.sso;
-
-import java.io.Serializable;
-import java.security.Principal;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.management.AttributeNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.transaction.Status;
-import javax.transaction.TransactionManager;
-
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.Session;
-import org.apache.catalina.util.LifecycleSupport;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.TreeCache;
-import org.jboss.cache.TreeCacheListener;
-import org.jboss.logging.Logger;
-import org.jboss.mx.util.MBeanServerLocator;
-import org.jboss.util.NestedRuntimeException;
-import org.jboss.web.tomcat.tc5.Tomcat5;
-import org.jgroups.View;
-
-/**
- * An implementation of SSOClusterManager that uses a TreeCache
- * to share SSO information between cluster nodes.
- *
- * @author Brian E. Stansberry
- * @version $Revision$ $Date$
- */
-public final class TreeCacheSSOClusterManager
- implements SSOClusterManager, TreeCacheListener
-{
- // ------------------------------------------------------------- Constants
-
- /**
- * Final segment of any FQN that names a TreeCache node storing
- * SSO credential information.
- */
- private static final String CREDENTIALS = "credentials";
-
- /**
- * First segment of any FQN that names a TreeCache node associated
- * with an SSO
- */
- private static final String SSO = "SSO";
-
- /**
- * Final segment of any FQN that names a TreeCache node storing
- * the set of Sessions associated with an SSO.
- */
- private static final String SESSIONS = "sessions";
-
- /**
- * Key under which data is stored to the TreeCache.
- */
- private static final String KEY = "key";
-
- /**
- * Default global value for the cacheName property
- */
- public static final String DEFAULT_GLOBAL_CACHE_NAME =
- Tomcat5.DEFAULT_CACHE_NAME;
-
- /**
- * Parameter signature used for TreeCache.get calls over JMX
- */
- private static final String[] GET_SIGNATURE =
- {Fqn.class.getName(), Object.class.getName()};
-
- /**
- * Parameter signature used for TreeCache.put calls over JMX
- */
- private static final String[] PUT_SIGNATURE =
- {Fqn.class.getName(), Object.class.getName(), Object.class.getName()};
-
- /**
- * Parameter signature used for TreeCache.remove calls over JMX
- */
- private static final String[] REMOVE_SIGNATURE = {Fqn.class.getName()};
-
- // ------------------------------------------------------- Instance Fields
-
- /**
- * SSO id which the thread is currently storing to the cache
- */
- private ThreadLocal beingLocallyAdded = new ThreadLocal();
-
- /**
- * SSO id which a thread is currently removing from the cache
- */
- private ThreadLocal beingLocallyRemoved = new ThreadLocal();
-
- /**
- * SSO id which the thread is deregistering due to removal on another node
- */
- private ThreadLocal beingRemotelyRemoved = new ThreadLocal();
-
- /**
- * ObjectName of the TreeCache
- */
- private ObjectName cacheObjectName = null;
-
- /**
- * String version of the object name to use to access the TreeCache
- */
- private String cacheName = null;
-
- /**
- * Transaction Manager
- */
- private TransactionManager tm = null;
-
- /**
- * The lifecycle event support for this component.
- */
- private LifecycleSupport lifecycle = new LifecycleSupport(this);
-
- /**
- * The Log-object for this class
- */
- private Logger log = Logger.getLogger(getClass().getName());;
-
- /**
- * Whether we are registered as a TreeCacheListener anywhere
- */
- private boolean registeredAsListener = false;
-
- /**
- * The MBean server we use to access our TreeCache
- */
- private MBeanServer server = null;
-
- /**
- * The SingleSignOn for which we are providing cluster support
- */
- private ClusteredSingleSignOn ssoValve = null;
-
- /**
- * Whether we have been started
- */
- private boolean started = false;
-
- /**
- * Whether a valid TreeCache is available for use
- */
- private boolean treeCacheAvailable = false;
-
- /**
- * 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;
-
- // ---------------------------------------------------------- Constructors
-
-
- /**
- * Creates a new TreeCacheSSOClusterManager
- */
- public TreeCacheSSOClusterManager()
- {
- // Find our MBeanServer
- server = MBeanServerLocator.locateJBoss();
- if (server == null)
- server = MBeanServerLocator.locate();
- }
-
-
- /**
- * Creates a new TreeCacheSSOClusterManager that works with the given
- * MBeanServer. This constructor is only intended for use in unit testing.
- */
- public TreeCacheSSOClusterManager(MBeanServer server)
- {
- this.server = server;
- }
-
-
- // ------------------------------------------------------------ Properties
-
- public String getCacheName()
- {
- return cacheName;
- }
-
- public void setCacheName(String objectName)
- throws Exception
- {
- if (objectName == null)
- {
- setCacheObjectName(null);
- }
- else if (objectName.equals(cacheName) == false)
- {
- setCacheObjectName(new ObjectName(objectName));
- }
- }
-
- public ObjectName getCacheObjectName()
- {
- return cacheObjectName;
- }
-
- public void setCacheObjectName(ObjectName objectName)
- throws Exception
- {
- // If no change, do nothing
- if ((objectName != null && objectName.equals(cacheObjectName))
- || (cacheObjectName != null && cacheObjectName.equals(objectName))
- || (objectName == null && cacheObjectName == null))
- {
- return;
- }
-
- removeAsTreeCacheListener();
- this.tm = null;
-
- this.cacheObjectName = objectName;
- this.cacheName = (objectName == null
- ? null
- : objectName.getCanonicalName());
-
- if (false == isTreeCacheAvailable(true))
- {
- if (started)
- {
- logMissingCacheError();
- }
- else
- {
- // Just put an advice in the log
- log.info("Cannot find TreeCache using " + cacheName + " -- tree" +
- "CacheName must be set to point to a running TreeCache " +
- "before ClusteredSingleSignOn can handle requests");
- }
- }
- }
-
- // ----------------------------------------------------- SSOClusterManager
-
- /**
- * Notify the cluster of the addition of a Session to an SSO session.
- *
- * @param ssoId the id of the SSO session
- * @param session the Session that has been added
- */
- public void addSession(String ssoId, Session session)
- {
- if (ssoId == null || session == null)
- {
- return;
- }
-
- if (!checkTreeCacheAvailable())
- {
- return;
- }
-
- if (log.isTraceEnabled())
- {
- log.trace("addSession(): adding Session " + session.getId() +
- " to cached session set for SSO " + ssoId);
- }
-
- Fqn fqn = getSessionsFqn(ssoId);
- boolean doTx = false;
- try
- {
- // Confirm we have a transaction manager; if not get it from TreeCache
- // failure to find will throw an IllegalStateException
- if (tm == null)
- configureFromCache();
-
- // 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);
- sessions.add(new SessionAddress(session.getId(), localAddress));
- putInTreeCache(fqn, sessions);
- }
- catch (Exception e)
- {
- try
- {
- if(doTx)
- tm.setRollbackOnly();
- }
- catch (Exception ignored)
- {
- }
- String sessId = (session == null ? "NULL" : session.getId());
- log.error("caught exception adding session " + sessId +
- " to SSO id " + ssoId, e);
- }
- finally
- {
- if (doTx)
- endTransaction();
- }
- }
-
-
- /**
- * Gets the SingleSignOn valve for which this object is handling
- * cluster communications.
- *
- * @return the <code>SingleSignOn</code> valve.
- */
- public ClusteredSingleSignOn getSingleSignOnValve()
- {
- return ssoValve;
- }
-
-
- /**
- * Sets the SingleSignOn valve for which this object is handling
- * cluster communications.
- * <p><b>NOTE:</b> This method must be called before calls can be
- * made to the other methods of this interface.
- *
- * @param valve a <code>SingleSignOn</code> valve.
- */
- public void setSingleSignOnValve(ClusteredSingleSignOn valve)
- {
- ssoValve = valve;
- }
-
-
- /**
- * Notifies the cluster that a single sign on session has been terminated
- * due to a user logout.
- *
- * @param ssoId
- */
- public void logout(String ssoId)
- {
- if (!checkTreeCacheAvailable())
- {
- return;
- }
-
- // 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);
-
- if (log.isTraceEnabled())
- {
- log.trace("Registering logout of SSO " + ssoId +
- " in clustered cache");
- }
-
- Fqn fqn = getSingleSignOnFqn(ssoId);
-
- try
- {
- removeFromTreeCache(fqn);
- }
- catch (Exception e)
- {
- log.error("Exception attempting to remove node " +
- fqn.toString() + " from TreeCache", e);
- }
- finally
- {
- beingLocallyRemoved.set(null);
- }
- }
-
-
- /**
- * Queries the cluster for the existence of an SSO session with the given
- * id, returning a <code>SingleSignOnEntry</code> if one is found.
- *
- * @param ssoId the id of the SSO session
- * @return a <code>SingleSignOnEntry</code> created using information
- * found on another cluster node, or <code>null</code> if no
- * entry could be found.
- */
- public SingleSignOnEntry lookup(String ssoId)
- {
- if (!checkTreeCacheAvailable())
- {
- return null;
- }
-
- SingleSignOnEntry entry = null;
- // Find the latest credential info from the cluster
- Fqn fqn = getCredentialsFqn(ssoId);
- try
- {
- SSOCredentials data = (SSOCredentials) getFromTreeCache(fqn);
- if (data != null)
- {
- entry = new SingleSignOnEntry(null,
- data.getAuthType(),
- data.getUsername(),
- data.getPassword());
- }
- }
- catch (Exception e)
- {
- log.error("caught exception looking up SSOCredentials for SSO id " +
- ssoId, e);
- }
- return entry;
- }
-
-
- /**
- * Notifies the cluster of the creation of a new SSO entry.
- *
- * @param ssoId the id of the SSO session
- * @param authType the type of authenticator (BASIC, CLIENT-CERT, DIGEST
- * or FORM) used to authenticate the SSO.
- * @param username the username (if any) used for the authentication
- * @param password the password (if any) used for the authentication
- */
- public void register(String ssoId, String authType,
- String username, String password)
- {
- if (!checkTreeCacheAvailable())
- {
- return;
- }
-
- if (log.isTraceEnabled())
- {
- log.trace("Registering SSO " + ssoId + " in clustered cache");
- }
-
- storeSSOData(ssoId, authType, username, password);
- }
-
-
- /**
- * Notify the cluster of the removal of a Session from an SSO session.
- *
- * @param ssoId the id of the SSO session
- * @param session the Session that has been removed
- */
- public void removeSession(String ssoId, Session session)
- {
- if (ssoId == null || session == null)
- {
- 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;
- }
-
- if (log.isTraceEnabled())
- {
- log.trace("removeSession(): removing Session " + session.getId() +
- " from cached session set for SSO " + ssoId);
- }
-
- Fqn fqn = getSessionsFqn(ssoId);
- boolean doTx = false;
- boolean removing = false;
- try
- {
- // Confirm we have a transaction manager; if not get it from TreeCache
- // failure to find will throw an IllegalStateException
- if (tm == null)
- configureFromCache();
-
- // 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);
- if (sessions != null)
- {
- sessions.remove(new SessionAddress(session.getId(), localAddress));
- if (sessions.size() == 0)
- {
- // No sessions left; remove node
-
- // Add this SSO to our list of in-process local removals so
- // this.nodeRemoved() will ignore the removal
- removing = true;
- beingLocallyRemoved.set(ssoId);
- removeFromTreeCache(getSingleSignOnFqn(ssoId));
- }
- else
- {
- putInTreeCache(fqn, sessions);
- }
- }
- }
- catch (Exception e)
- {
- try
- {
- if(doTx)
- tm.setRollbackOnly();
- }
- catch (Exception x)
- {
- }
-
- String sessId = (session == null ? "NULL" : session.getId());
- log.error("caught exception removing session " + sessId +
- " from SSO id " + ssoId, e);
- }
- finally
- {
- try
- {
- if (removing)
- {
- beingLocallyRemoved.set(null);
- }
- }
- finally
- {
- if (doTx)
- endTransaction();
- }
- }
- }
-
-
- /**
- * Notifies the cluster of an update of the security credentials
- * associated with an SSO session.
- *
- * @param ssoId the id of the SSO session
- * @param authType the type of authenticator (BASIC, CLIENT-CERT, DIGEST
- * or FORM) used to authenticate the SSO.
- * @param username the username (if any) used for the authentication
- * @param password the password (if any) used for the authentication
- */
- public void updateCredentials(String ssoId, String authType,
- String username, String password)
- {
- if (!checkTreeCacheAvailable())
- {
- return;
- }
-
- if (log.isTraceEnabled())
- {
- log.trace("Updating credentials for SSO " + ssoId +
- " in clustered cache");
- }
-
- storeSSOData(ssoId, authType, username, password);
- }
-
-
- // ------------------------------------------------------ TreeCacheListener
-
- /**
- * Does nothing
- */
- public void nodeCreated(Fqn fqn)
- {
- ; // do nothing
- }
-
- /**
- * Does nothing
- */
- public void nodeLoaded(Fqn fqn)
- {
- ; // do nothing
- }
-
-
- /**
- * Does nothing
- */
- public void nodeVisited(Fqn fqn)
- {
- ; // do nothing
- }
-
-
- /**
- * Does nothing
- */
- public void cacheStarted(TreeCache cache)
- {
- ; // do nothing
- }
-
-
- /**
- * Does nothing
- */
- public void cacheStopped(TreeCache cache)
- {
- ; // do nothing
- }
-
-
- /**
- * Extracts an SSO session id from the Fqn and uses it in an invocation of
- * {@link ClusteredSingleSignOn#deregister(String) ClusteredSingleSignOn.deregister(String)}.
- * <p/>
- * Ignores invocations resulting from TreeCache changes originated by
- * this object.
- *
- * @param fqn the fully-qualified name of the node that was removed
- */
- public void nodeRemoved(Fqn fqn)
- {
- String ssoId = getIdFromFqn(fqn);
-
- if (ssoId == null)
- return;
-
- // Ignore messages generated by our own activity
- if (ssoId.equals(beingLocallyRemoved.get()))
- {
- return;
- }
-
- beingRemotelyRemoved.set(ssoId);
-
- try
- {
- if (log.isTraceEnabled())
- {
- log.trace("received a node removed message for SSO " + ssoId);
- }
-
- ssoValve.deregister(ssoId);
- }
- finally
- {
- beingRemotelyRemoved.set(null);
- }
-
- }
-
-
- /**
- * Extracts an SSO session id from the Fqn and uses it in an invocation of
- * {@link ClusteredSingleSignOn#update ClusteredSingleSignOn.update()}.
- * <p/>
- * Only responds to modifications of nodes whose FQN's final segment is
- * "credentials".
- * <p/>
- * Ignores invocations resulting from TreeCache changes originated by
- * this object.
- * <p/>
- * Ignores invocations for SSO session id's that are not registered
- * with the local SingleSignOn valve.
- *
- * @param fqn the fully-qualified name of the node that was modified
- */
- public void nodeModified(Fqn fqn)
- {
- // We are only interested in changes to the CREDENTIALS node
- if (CREDENTIALS.equals(getTypeFromFqn(fqn)) == false)
- {
- return;
- }
-
- String ssoId = getIdFromFqn(fqn); // won't be null or above check fails
-
- // Ignore invocations that come as a result of our additions
- if (ssoId.equals(beingLocallyAdded.get()))
- {
- return;
- }
-
- SingleSignOnEntry sso = ssoValve.localLookup(ssoId);
- if (sso == null || sso.getCanReauthenticate())
- {
- // No reason to update
- return;
- }
-
- if (log.isTraceEnabled())
- {
- log.trace("received a credentials modified message for SSO " + ssoId);
- }
-
- // Put this SSO in the queue of those to be updated
-// credentialUpdater.enqueue(sso, ssoId);
- try
- {
- SSOCredentials data = (SSOCredentials) getFromTreeCache(fqn);
- if (data != null)
- {
- // We want to release our read lock quickly, so get the needed
- // data from the cache, commit the tx, and then use the data
- String authType = data.getAuthType();
- String username = data.getUsername();
- String password = data.getPassword();
-
- if (log.isTraceEnabled())
- {
- log.trace("CredentialUpdater: Updating credentials for SSO " + sso);
- }
-
- synchronized (sso)
- {
- // Use the existing principal
- Principal p = sso.getPrincipal();
- sso.updateCredentials(p, authType, username, password);
- }
- }
- }
- catch (Exception e)
- {
- log.error("failed to update credentials for SSO " + ssoId, e);
- }
- }
-
-
- /**
- * Does nothing
- */
- public void viewChange(View new_view)
- {
- ; // do nothing
- }
-
-
- /**
- * Does nothing. Called when a node is evicted (not the same as remove()).
- *
- * @param fqn
- */
- public void nodeEvicted(Fqn fqn)
- {
- // TODO do we need to handle this?
- ; // do nothing
- }
-
-
- // ------------------------------------------------------------- Lifecycle
-
-
- /**
- * Add a lifecycle event listener to this component.
- *
- * @param listener The listener to add
- */
- public void addLifecycleListener(LifecycleListener listener)
- {
- lifecycle.addLifecycleListener(listener);
- }
-
-
- /**
- * Get the lifecycle listeners associated with this lifecycle. If this
- * Lifecycle has no listeners registered, a zero-length array is returned.
- */
- public LifecycleListener[] findLifecycleListeners()
- {
- return lifecycle.findLifecycleListeners();
- }
-
-
- /**
- * Remove a lifecycle event listener from this component.
- *
- * @param listener The listener to remove
- */
- public void removeLifecycleListener(LifecycleListener listener)
- {
- lifecycle.removeLifecycleListener(listener);
- }
-
- /**
- * Prepare for the beginning of active use of the public methods of this
- * component. This method should be called before any of the public
- * methods of this component are utilized. It should also send a
- * LifecycleEvent of type START_EVENT to any registered listeners.
- *
- * @throws LifecycleException if this component detects a fatal error
- * that prevents this component from being used
- */
- public void start() throws LifecycleException
- {
- // Validate and update our current component state
- if (started)
- {
- throw new LifecycleException
- ("TreeCacheSSOClusterManager already Started");
- }
-
- try
- {
- if (isTreeCacheAvailable(true))
- {
- integrateWithCache();
- }
- }
- catch (Exception e)
- {
- throw new LifecycleException("Caught exception looking up " +
- "TransactionManager from TreeCache", e);
- }
-
- started = true;
-
- // Notify our interested LifecycleListeners
- lifecycle.fireLifecycleEvent(START_EVENT, null);
- }
-
-
- /**
- * Gracefully terminate the active use of the public methods of this
- * component. This method should be the last one called on a given
- * instance of this component. It should also send a LifecycleEvent
- * of type STOP_EVENT to any registered listeners.
- *
- * @throws LifecycleException if this component detects a fatal error
- * that needs to be reported
- */
- public void stop() throws LifecycleException
- {
- // Validate and update our current component state
- if (!started)
- {
- throw new LifecycleException
- ("TreeCacheSSOClusterManager not Started");
- }
-
- started = false;
-
- // Notify our interested LifecycleListeners
- lifecycle.fireLifecycleEvent(STOP_EVENT, null);
- }
-
-
- // ------------------------------------------------------- Private Methods
-
- private Object getFromTreeCache(Fqn fqn) throws Exception
- {
- Object[] args = new Object[]{fqn, KEY};
- return server.invoke(getCacheObjectName(), "get", args, GET_SIGNATURE);
- }
-
- private Fqn getCredentialsFqn(String ssoid)
- {
- Object[] objs = new Object[]{SSO, ssoid, CREDENTIALS};
- return new Fqn(objs);
- }
-
- private Fqn getSessionsFqn(String ssoid)
- {
- Object[] objs = new Object[]{SSO, ssoid, SESSIONS};
- return new Fqn(objs);
- }
-
- private Fqn getSingleSignOnFqn(String ssoid)
- {
- Object[] objs = new Object[]{SSO, ssoid};
- return new Fqn(objs);
- }
-
- /**
- * Extracts an SSO session id from a fully qualified name object.
- *
- * @param fqn the Fully Qualified Name used by TreeCache
- * @return the second element in the Fqn -- the SSO session id
- */
- private String getIdFromFqn(Fqn fqn)
- {
- String id = null;
- if (fqn.size() > 1 && SSO.equals(fqn.get(0)))
- {
- id = (String) fqn.get(1);
- }
- return id;
- }
-
- private Set getSessionSet(Fqn fqn, boolean create)
- throws Exception
- {
- Set sessions = (Set) getFromTreeCache(fqn);
- if (create && sessions == null)
- {
- sessions = new HashSet();
- }
- return sessions;
- }
-
- /**
- * Extracts the SSO tree cache node type from a fully qualified name
- * object.
- *
- * @param fqn the Fully Qualified Name used by TreeCache
- * @return the 3rd in the Fqn -- either
- * {@link #CREDENTIALS CREDENTIALS} or {@link #SESSIONS SESSIONS},
- * or <code>null</code> if <code>fqn</code> is not for an SSO.
- */
- private String getTypeFromFqn(Fqn fqn)
- {
- String type = null;
- if (fqn.size() > 2 && SSO.equals(fqn.get(0)))
- 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(),
- "TransactionManager");
-
- 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
- // "Object" so we have to be sure its Serializable
- if (address instanceof Serializable)
- localAddress = (Serializable) address;
- else
- localAddress = address.toString();
- }
-
-
- private void endTransaction()
- {
- try
- {
- if(tm.getTransaction().getStatus() != Status.STATUS_MARKED_ROLLBACK)
- {
- tm.commit();
- }
- else
- {
- tm.rollback();
- }
- }
- catch (Exception e)
- {
- log.error(e);
- throw new NestedRuntimeException("TreeCacheSSOClusterManager.endTransaction(): ", e);
- }
- }
-
- /**
- * Checks whether an MBean is registered under the value of property
- * "cacheObjectName".
- *
- * @param forceCheck check for availability whether or not it has already
- * been positively established
- * @return <code>true</code> if property <code>cacheName</code> has been
- * set and points to a registered MBean.
- */
- private synchronized boolean isTreeCacheAvailable(boolean forceCheck)
- {
- if (forceCheck || treeCacheAvailable == false)
- {
- boolean available = (cacheObjectName != null);
- if (available)
- {
- Set s = server.queryMBeans(cacheObjectName, null);
- available = s.size() > 0;
- if (available)
- {
- try
- {
- // If Tomcat5 overrides the default cache name, it will do so
- // after we are started. So we need to configure ourself here
- // and throw an exception if there is a problem. Having this
- // here also allows us to recover if our cache is started
- // after we are
- if (started)
- integrateWithCache();
- setMissingCacheErrorLogged(false);
- }
- catch (Exception e)
- {
- log.error("Caught exception configuring from cache " +
- cacheObjectName, e);
- available = false;
- }
- }
- }
- treeCacheAvailable = available;
- }
- return treeCacheAvailable;
- }
-
- private boolean checkTreeCacheAvailable()
- {
- boolean avail = isTreeCacheAvailable(false);
- if (!avail)
- logMissingCacheError();
- return avail;
- }
-
- private void putInTreeCache(Fqn fqn, Object data) throws Exception
- {
- Object[] args = new Object[]{fqn, KEY, data};
- server.invoke(getCacheObjectName(), "put", args, PUT_SIGNATURE);
- }
-
- private void integrateWithCache() throws Exception
- {
- // 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);
- }
-
-
- /**
- * 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
- {
- // NOTE: to be compatible with 1.2.3, no direct use of the 1.2.4
- // region activation API can be used here even if the rest of this
- // class is converted to using MBean proxies
- try
- {
- Boolean inactive = (Boolean) server.getAttribute(cacheObjectName, "InactiveOnStartup");
- if (inactive.booleanValue())
- {
- Boolean useMarshalling = (Boolean) server.getAttribute(cacheObjectName, "UseMarshalling");
- if (useMarshalling.booleanValue())
- {
- // TODO replace this try/catch with a call to an isRegionActive API
- try
- {
- server.invoke(cacheObjectName, "activateRegion",
- new Object[]{ "/" + SSO },
- new String[]{ "java.lang.String"});
- }
- catch (MBeanException e)
- {
- Exception cause = e.getTargetException();
- if (cause != null
- && "org.jboss.cache.RegionNotEmptyException".equals(cause.getClass().getName()))
- {
- log.debug(SSO + " region already active", cause);
- }
- else
- throw e;
- }
- }
- }
- }
- catch (AttributeNotFoundException ignore)
- {
- log.debug("Attribute InactiveOnStartup not available; " +
- "must be using JBossCache 1.2.3 or earlier");
- }
- }
-
- /**
- * Invokes an operation on the JMX server to register ourself as a
- * listener on the TreeCache service.
- *
- * @throws Exception
- */
- private void registerAsTreeCacheListener() throws Exception
- {
- server.invoke(cacheObjectName, "addTreeCacheListener",
- new Object[]{this},
- new String[]{TreeCacheListener.class.getName()});
- registeredAsListener = true;
- }
-
-
- /**
- * Invokes an operation on the JMX server to register ourself as a
- * listener on the TreeCache service.
- *
- * @throws Exception
- */
- private void removeAsTreeCacheListener() throws Exception
- {
- if (registeredAsListener && cacheObjectName != null)
- {
- server.invoke(cacheObjectName, "removeTreeCacheListener",
- new Object[]{this},
- new String[]{TreeCacheListener.class.getName()});
- }
- }
-
- private void removeFromTreeCache(Fqn fqn) throws Exception
- {
- server.invoke(getCacheObjectName(), "remove",
- new Object[]{fqn},
- REMOVE_SIGNATURE);
- }
-
- /**
- * Stores the given data to the clustered cache in a tree branch whose FQN
- * is the given SSO id. Stores the given credential data in a child node
- * named "credentials". If parameter <code>storeSessions</code> is
- * <code>true</code>, also stores an empty HashSet in a sibling node
- * named "sessions". This HashSet will later be used to hold session ids
- * associated with the SSO.
- * <p/>
- * Any items stored are stored under the key "key".
- *
- * @param ssoId the id of the SSO session
- * @param authType the type of authenticator (BASIC, CLIENT-CERT, DIGEST
- * or FORM) used to authenticate the SSO.
- * @param username the username (if any) used for the authentication
- * @param password the password (if any) used for the authentication
- */
- private void storeSSOData(String ssoId, String authType, String username,
- 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);
- }
- catch (Exception e)
- {
- log.error("Exception attempting to add TreeCache nodes for SSO " +
- ssoId, e);
- }
- finally
- {
- beingLocallyAdded.set(null);
- }
- }
-
- private boolean isMissingCacheErrorLogged()
- {
- return missingCacheErrorLogged;
- }
-
- private void setMissingCacheErrorLogged(boolean missingCacheErrorLogged)
- {
- this.missingCacheErrorLogged = missingCacheErrorLogged;
- }
-
- private void logMissingCacheError()
- {
- StringBuffer msg = new StringBuffer("Cannot find TreeCache using ");
- msg.append(getCacheName());
- msg.append(" -- TreeCache must be started before ClusteredSingleSignOn ");
- msg.append("can handle requests");
-
- if (isMissingCacheErrorLogged())
- {
- // Just log it as a warning
- log.warn(msg);
- }
- else
- {
- log.error(msg);
- // Set a flag so we don't relog this error over and over
- setMissingCacheErrorLogged(true);
- }
- }
-
- // --------------------------------------------------------- Outer Classes
-
- /**
- * Private class used to store authentication credentials in the TreeCache.
- * <p/>
- * For security, password accessor is private.
- */
- public static class SSOCredentials
- implements Serializable
- {
- /** The serialVersionUID */
- private static final long serialVersionUID = 5704877226920571663L;
-
- private String authType = null;
- private String password = null;
- private String username = null;
-
- /**
- * Creates a new SSOCredentials.
- *
- * @param authType The authorization method used to authorize the
- * SSO (BASIC, CLIENT-CERT, DIGEST, FORM or NONE).
- * @param username The username of the user associated with the SSO
- * @param password The password of the user associated with the SSO
- */
- private SSOCredentials(String authType, String username, String password)
- {
- this.authType = authType;
- this.username = username;
- this.password = password;
- }
-
- /**
- * Gets the username of the user associated with the SSO.
- *
- * @return the username
- */
- public String getUsername()
- {
- return username;
- }
-
- /**
- * Gets the authorization method used to authorize the SSO.
- *
- * @return "BASIC", "CLIENT-CERT", "DIGEST" or "FORM"
- */
- public String getAuthType()
- {
- return authType;
- }
-
- /**
- * Gets the password of the user associated with the SSO.
- *
- * @return the password, or <code>null</code> if the authorization
- * type was DIGEST or CLIENT-CERT.
- */
- private String getPassword()
- {
- return password;
- }
-
- } // 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;
- this.address = address;
- }
-
- public boolean equals(Object obj)
- {
- if (this == obj)
- return true;
-
- if (!(obj instanceof SessionAddress))
- return false;
-
- SessionAddress other = (SessionAddress) obj;
-
- return (sessionId.equals(other.sessionId)
- && address.equals(other.address));
- }
-
- public int hashCode()
- {
- int total = (19 * 43) + sessionId.hashCode();
- return ((total * 43) + address.hashCode());
- }
-
-
- }
-
-} // end TreeCacheSSOClusterManager
-
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/mbeans-descriptors.xml
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/mbeans-descriptors.xml 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc5/sso/mbeans-descriptors.xml 2006-09-06 13:57:20 UTC (rev 56603)
@@ -1,38 +0,0 @@
-<?xml version="1.0"?>
-<mbeans-descriptors>
-
- <mbean name="ClusteredSingleSignOn"
- description="A Valve that supports a 'single signon' user experience"
- domain="Catalina"
- group="Valve"
- type="org.jboss.web.tomcat.tc5.sso.ClusteredSingleSignOn">
-
- <attribute name="className"
- description="Fully qualified class name of the managed object"
- type="java.lang.String"
- writeable="false"/>
-
- <attribute name="cookieDomain"
- description="Domain to which sso cookies should be scoped"
- type="java.lang.String"/>
-
- <attribute name="requireReauthentication"
- description="Should we attempt to reauthenticate each request against the security Realm?"
- type="boolean"/>
-
- <attribute name="clusterManager"
- description="SSOClusterManager to use for cluster support"
- type="org.jboss.web.tomcat.tc5.sso.SSOClusterManager"/>
-
- <attribute name="clusterManagerClass"
- description="Fully qualified class name of the SSOClusterManager to use for cluster support"
- type="java.lang.String"/>
-
- <attribute name="treeCacheName"
- description="The ObjectName of the TreeCache that this Valve should use for cluster communications.
- Only relevant if clusterManagerClass is org.jboss.web.tomcat.tc5.sso.TreeCacheSSOClusterManager"
- type="java.lang.String"/>
-
- </mbean>
-
-</mbeans-descriptors>
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/StandardService.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/StandardService.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/StandardService.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -40,7 +40,7 @@
import org.apache.catalina.core.ContainerBase;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;
-import org.apache.commons.modeler.Registry;
+import org.apache.tomcat.util.modeler.Registry;
import org.jboss.logging.Logger;
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/StatusServlet.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/StatusServlet.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/StatusServlet.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -35,7 +35,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.commons.modeler.Registry;
+import org.apache.tomcat.util.modeler.Registry;
import org.apache.catalina.util.ServerInfo;
import org.apache.catalina.util.StringManager;
Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/Tomcat6.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/Tomcat6.java 2006-09-06 13:54:37 UTC (rev 56602)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/Tomcat6.java 2006-09-06 13:57:20 UTC (rev 56603)
@@ -38,7 +38,7 @@
import org.apache.catalina.Lifecycle;
import org.apache.catalina.connector.Connector;
-import org.apache.commons.modeler.Registry;
+import org.apache.tomcat.util.modeler.Registry;
import org.jboss.deployment.DeploymentInfo;
import org.jboss.deployment.SubDeployerExt;
import org.jboss.mx.util.MBeanProxyExt;
Deleted: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/sso/TreeCacheSSOClusterManager.java~
===================================================================
(Binary files differ)
More information about the jboss-cvs-commits
mailing list