433244 Session manager lifecycle cleanup
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
index f76df68..1f966c5 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionManager.java
@@ -26,7 +26,6 @@
import java.util.EventListener;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -49,7 +48,7 @@
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.ManagedOperation;
-import org.eclipse.jetty.util.component.AbstractLifeCycle;
+import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.statistic.CounterStatistic;
import org.eclipse.jetty.util.statistic.SampleStatistic;
@@ -66,7 +65,7 @@
*/
@SuppressWarnings("deprecation")
@ManagedObject("Abstract Session Manager")
-public abstract class AbstractSessionManager extends AbstractLifeCycle implements SessionManager
+public abstract class AbstractSessionManager extends ContainerLifeCycle implements SessionManager
{
final static Logger __log = SessionHandler.LOG;
@@ -82,11 +81,13 @@
static final HttpSessionContext __nullSessionContext=new HttpSessionContext()
{
+ @Override
public HttpSession getSession(String sessionId)
{
return null;
}
+ @Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Enumeration getIds()
{
@@ -162,6 +163,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public HttpCookie access(HttpSession session,boolean secure)
{
long now=System.currentTimeMillis();
@@ -187,6 +189,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public void addEventListener(EventListener listener)
{
if (listener instanceof HttpSessionAttributeListener)
@@ -195,17 +198,22 @@
_sessionListeners.add((HttpSessionListener)listener);
if (listener instanceof HttpSessionIdListener)
_sessionIdListeners.add((HttpSessionIdListener)listener);
+ addBean(listener,false);
}
/* ------------------------------------------------------------ */
+ @Override
public void clearEventListeners()
{
+ for (EventListener e :getBeans(EventListener.class))
+ removeBean(e);
_sessionAttributeListeners.clear();
_sessionListeners.clear();
_sessionIdListeners.clear();
}
/* ------------------------------------------------------------ */
+ @Override
public void complete(HttpSession session)
{
AbstractSession s = ((SessionIf)session).getSession();
@@ -237,17 +245,20 @@
Thread.currentThread().setContextClassLoader(serverLoader);
_sessionIdManager=new HashSessionIdManager();
server.setSessionIdManager(_sessionIdManager);
+ server.manage(_sessionIdManager);
+ _sessionIdManager.start();
}
finally
{
Thread.currentThread().setContextClassLoader(_loader);
}
}
+
+ // server session id is never managed by this manager
+ addBean(_sessionIdManager,false);
}
}
- if (!_sessionIdManager.isStarted())
- _sessionIdManager.start();
// Look for a session cookie name
if (_context!=null)
@@ -299,6 +310,7 @@
/**
* @return Returns the httpOnly.
*/
+ @Override
@ManagedAttribute("true if cookies use the http only flag")
public boolean getHttpOnly()
{
@@ -306,6 +318,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public HttpSession getHttpSession(String nodeId)
{
String cluster_id = getSessionIdManager().getClusterId(nodeId);
@@ -318,18 +331,9 @@
/* ------------------------------------------------------------ */
/**
- * @return Returns the metaManager used for cross context session management
- * @deprecated Use {@link #getSessionIdManager()}
- */
- public SessionIdManager getIdManager()
- {
- return getSessionIdManager();
- }
-
- /* ------------------------------------------------------------ */
- /**
* @return Returns the SessionIdManager used for cross context session management
*/
+ @Override
@ManagedAttribute("Session ID Manager")
public SessionIdManager getSessionIdManager()
{
@@ -350,16 +354,6 @@
/* ------------------------------------------------------------ */
/**
- * @see #getSessionsMax()
- */
- @Deprecated
- public int getMaxSessions()
- {
- return getSessionsMax();
- }
-
- /* ------------------------------------------------------------ */
- /**
* @return maximum number of sessions
*/
@ManagedAttribute("maximum number of simultaneous sessions")
@@ -379,33 +373,12 @@
}
/* ------------------------------------------------------------ */
- /**
- * @deprecated use {@link #getSessionIdManager()}
- */
- @Deprecated
- public SessionIdManager getMetaManager()
- {
- return getSessionIdManager();
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @deprecated always returns 0. no replacement available.
- */
- @Deprecated
- public int getMinSessions()
- {
- return 0;
- }
-
- /* ------------------------------------------------------------ */
@ManagedAttribute("time before a session cookie is re-set (in s)")
public int getRefreshCookieAge()
{
return _refreshCookieAge;
}
-
/* ------------------------------------------------------------ */
/**
* @return same as SessionCookieConfig.getSecure(). If true, session
@@ -438,8 +411,6 @@
_secureRequestOnly = secureRequestOnly;
}
-
-
/* ------------------------------------------------------------ */
@ManagedAttribute("the set session cookie")
public String getSessionCookie()
@@ -473,6 +444,7 @@
*
* @see org.eclipse.jetty.server.SessionManager#getSessionCookie(javax.servlet.http.HttpSession, java.lang.String, boolean)
*/
+ @Override
public HttpCookie getSessionCookie(HttpSession session, String contextPath, boolean requestIsSecure)
{
if (isUsingCookies())
@@ -527,18 +499,6 @@
}
/* ------------------------------------------------------------ */
- /**
- * @deprecated Need to review if it is needed.
- */
- @SuppressWarnings("rawtypes")
- public Map getSessionMap()
- {
- throw new UnsupportedOperationException();
- }
-
-
-
- /* ------------------------------------------------------------ */
@ManagedAttribute("number of currently active sessions")
public int getSessions()
{
@@ -546,6 +506,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
@ManagedAttribute("name of use for URL session tracking")
public String getSessionIdPathParameterName()
{
@@ -553,6 +514,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public String getSessionIdPathParameterNamePrefix()
{
return _sessionIdPathParameterNamePrefix;
@@ -562,12 +524,14 @@
/**
* @return Returns the usingCookies.
*/
+ @Override
public boolean isUsingCookies()
{
return _usingCookies;
}
/* ------------------------------------------------------------ */
+ @Override
public boolean isValid(HttpSession session)
{
AbstractSession s = ((SessionIf)session).getSession();
@@ -575,6 +539,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public String getClusterId(HttpSession session)
{
AbstractSession s = ((SessionIf)session).getSession();
@@ -582,6 +547,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public String getNodeId(HttpSession session)
{
AbstractSession s = ((SessionIf)session).getSession();
@@ -592,6 +558,7 @@
/**
* Create a new HttpSession for a request
*/
+ @Override
public HttpSession newHttpSession(HttpServletRequest request)
{
AbstractSession session=newSession(request);
@@ -601,6 +568,7 @@
}
/* ------------------------------------------------------------ */
+ @Override
public void removeEventListener(EventListener listener)
{
if (listener instanceof HttpSessionAttributeListener)
@@ -608,17 +576,7 @@
if (listener instanceof HttpSessionListener)
_sessionListeners.remove(listener);
}
-
- /* ------------------------------------------------------------ */
- /**
- * @see #statsReset()
- */
- @Deprecated
- public void resetStats()
- {
- statsReset();
- }
-
+
/* ------------------------------------------------------------ */
/**
* Reset statistics values
@@ -643,54 +601,42 @@
/* ------------------------------------------------------------ */
/**
* @param metaManager The metaManager used for cross context session management.
- * @deprecated use {@link #setSessionIdManager(SessionIdManager)}
*/
- public void setIdManager(SessionIdManager metaManager)
- {
- setSessionIdManager(metaManager);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @param metaManager The metaManager used for cross context session management.
- */
+ @Override
public void setSessionIdManager(SessionIdManager metaManager)
{
+ updateBean(_sessionIdManager, metaManager);
_sessionIdManager=metaManager;
}
-
-
/* ------------------------------------------------------------ */
/**
* @param seconds
*/
+ @Override
public void setMaxInactiveInterval(int seconds)
{
_dftMaxIdleSecs=seconds;
}
-
/* ------------------------------------------------------------ */
public void setRefreshCookieAge(int ageInSeconds)
{
_refreshCookieAge=ageInSeconds;
}
-
-
+ /* ------------------------------------------------------------ */
public void setSessionCookie(String cookieName)
{
_sessionCookie=cookieName;
}
-
-
/* ------------------------------------------------------------ */
/**
* @param sessionHandler
* The sessionHandler to set.
*/
+ @Override
public void setSessionHandler(SessionHandler sessionHandler)
{
_sessionHandler=sessionHandler;
@@ -698,6 +644,7 @@
/* ------------------------------------------------------------ */
+ @Override
public void setSessionIdPathParameterName(String param)
{
_sessionIdPathParameterName =(param==null||"none".equals(param))?null:param;
@@ -844,12 +791,14 @@
}
/* ------------------------------------------------------------ */
+ @Override
public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
{
return __defaultSessionTrackingModes;
}
/* ------------------------------------------------------------ */
+ @Override
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
{
return Collections.unmodifiableSet(_sessionTrackingModes);
@@ -871,8 +820,8 @@
return _usingURLs;
}
-
/* ------------------------------------------------------------ */
+ @Override
public SessionCookieConfig getSessionCookieConfig()
{
return _cookieConfig;
@@ -917,6 +866,7 @@
/**
* @see org.eclipse.jetty.server.SessionManager#isCheckingRemoteSessionIdEncoding()
*/
+ @Override
@ManagedAttribute("check remote session id encoding")
public boolean isCheckingRemoteSessionIdEncoding()
{
@@ -927,6 +877,7 @@
/**
* @see org.eclipse.jetty.server.SessionManager#setCheckingRemoteSessionIdEncoding(boolean)
*/
+ @Override
public void setCheckingRemoteSessionIdEncoding(boolean remote)
{
_checkingRemoteSessionIdEncoding=remote;
@@ -1091,4 +1042,11 @@
}
}
}
+
+ @Override
+ @Deprecated
+ public SessionIdManager getMetaManager()
+ {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
index beda6ce..1effd32 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionManager.java
@@ -34,6 +34,7 @@
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
+import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.IO;
@@ -60,9 +61,7 @@
final static Logger LOG = SessionHandler.LOG;
protected final ConcurrentMap<String,HashedSession> _sessions=new ConcurrentHashMap<String,HashedSession>();
- private static int __id;
private Scheduler _timer;
- private boolean _timerStop=false;
private Scheduler.Task _task;
long _scavengePeriodMs=30000;
long _savePeriodMs=0; //don't do period saves by default
@@ -134,14 +133,11 @@
@Override
public void doStart() throws Exception
{
- super.doStart();
-
- _timerStop=false;
//try shared scheduler from Server first
_timer = getSessionHandler().getServer().getBean(Scheduler.class);
if (_timer == null)
{
- //try one passwed into the context
+ //try one passed into the context
ServletContext context = ContextHandler.getCurrentContext();
if (context!=null)
_timer = (Scheduler)context.getAttribute("org.eclipse.jetty.server.session.timer");
@@ -149,12 +145,14 @@
if (_timer == null)
{
- //make a scheduler if none useable
- _timerStop=true;
- _timer=new ScheduledExecutorScheduler();
- _timer.start();
+ //make a scheduler if none useable
+ _timer=new ScheduledExecutorScheduler(toString()+"Timer",true);
+ addBean(_timer,true);
}
-
+ else
+ addBean(_timer,false);
+
+ super.doStart();
setScavengePeriod(getScavengePeriod());
@@ -186,8 +184,6 @@
if (_task!=null)
_task.cancel();
_task=null;
- if (_timer!=null && _timerStop)
- _timer.stop();
_timer=null;
}
@@ -427,7 +423,7 @@
/* ------------------------------------------------------------ */
@Override
protected void shutdownSessions() throws Exception
- {
+ {
// Invalidate all sessions to cause unbind events
ArrayList<HashedSession> sessions=new ArrayList<HashedSession>(_sessions.values());
int loop=100;
@@ -672,7 +668,6 @@
if (size>0)
{
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is);
-
for (int i=0; i<size;i++)
{
String key = ois.readUTF();
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java
index 451cb00..1cd77af 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/session/HashSessionManagerTest.java
@@ -23,6 +23,7 @@
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
+import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.StdErrLog;
import org.junit.After;
@@ -41,7 +42,7 @@
@Before
public void quietStacks()
{
- enableStacks(false);
+ enableStacks(true);
}
protected void enableStacks(boolean enabled)
@@ -94,6 +95,7 @@
public void testHashSession() throws Exception
{
File testDir = MavenTestingUtils.getTargetTestingDir("saved");
+ IO.delete(testDir);
testDir.mkdirs();
Server server = new Server();
@@ -109,10 +111,12 @@
AbstractSessionIdManager idManager = new HashSessionIdManager();
idManager.setWorkerName("foo");
manager.setSessionIdManager(idManager);
+ server.setSessionIdManager(idManager);
- idManager.start();
+ server.start();
manager.start();
+
HashedSession session = (HashedSession)manager.newHttpSession(new Request(null, null));
String sessionId = session.getId();
@@ -120,14 +124,12 @@
session.setAttribute("two", new Integer(2));
//stop will persist sessions
- idManager.stop();
manager.setMaxInactiveInterval(30); //change max inactive interval for *new* sessions
manager.stop();
Assert.assertTrue("File should exist!", new File(testDir, session.getId()).exists());
//start will restore sessions
- idManager.start();
manager.start();
HashedSession restoredSession = (HashedSession)manager.getSession(sessionId);
@@ -138,5 +140,7 @@
Assert.assertEquals(1, ((Integer)o).intValue());
Assert.assertEquals(5, restoredSession.getMaxInactiveInterval());
+
+ server.stop();
}
}
diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java
index e629638..9a8d616 100644
--- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java
+++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java
@@ -21,11 +21,30 @@
import java.io.File;
import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.util.IO;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
public class SessionRenewTest extends AbstractSessionRenewTest
{
-
+ File tmpDir;
+
+ @Before
+ public void before() throws Exception
+ {
+ tmpDir = File.createTempFile("hash-session-renew-test", null);
+ tmpDir.delete();
+ tmpDir.mkdirs();
+ tmpDir.deleteOnExit();
+ }
+
+ @After
+ public void after()
+ {
+ IO.delete(tmpDir);
+ }
+
@Override
public AbstractTestServer createServer(int port, int max, int scavenge)
{
@@ -37,9 +56,7 @@
{
HashSessionManager sessionManager = (HashSessionManager)super.newSessionManager();
sessionManager.setSavePeriod(2);
- File tmpDir = new File(System.getProperty("java.io.tmpdir"), "hash-session-renew-test");
- tmpDir.deleteOnExit();
- tmpDir.mkdirs();
+
try
{
sessionManager.setStoreDirectory(tmpDir);