destroying session in a SessionManager in embedded mode and not in cdi context
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/de0c9893 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/de0c9893 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/de0c9893 Branch: refs/heads/fb_tomee2_owb16 Commit: de0c9893cc03c5e3fec1647dc87150e96d3bd9b8 Parents: cfe9fdf Author: Romain Manni-Bucau <rmannibu...@apache.org> Authored: Sun May 3 23:59:34 2015 +0200 Committer: Romain Manni-Bucau <rmannibu...@apache.org> Committed: Sun May 3 23:59:34 2015 +0200 ---------------------------------------------------------------------- .../openejb/cdi/CdiAppContextsService.java | 32 ------------ .../server/httpd/BeginWebBeansListener.java | 15 +++--- .../openejb/server/httpd/HttpRequestImpl.java | 3 +- .../openejb/server/httpd/HttpSessionImpl.java | 1 - .../openejb/server/httpd/OpenEJBHttpServer.java | 17 ++++--- .../server/httpd/session/SessionManager.java | 52 ++++++++++++++------ tck/cdi-embedded/src/test/resources/failing.xml | 2 +- 7 files changed, 55 insertions(+), 67 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/de0c9893/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java b/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java index b8b49bc..d6a202e 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java @@ -199,26 +199,6 @@ public class CdiAppContextsService extends AbstractContextsService implements Co webBeansContext.getBeanManagerImpl().fireEvent(id, DestroyedLiteral.INSTANCE_CONVERSATION_SCOPED); } } - for (final SessionContext sc : sessionCtxManager.getContextById().values()) { - final Object event = HttpSessionContextSessionAware.class.isInstance(sc) ? HttpSessionContextSessionAware.class.cast(sc).getSession() : sc; - if (HttpSession.class.isInstance(event)) { - final HttpSession httpSession = HttpSession.class.cast(event); - if (httpSession.getId() == null) { - continue; - } - initSessionContext(httpSession); - try { - httpSession.invalidate(); - } catch (final IllegalStateException ise) { - // no-op - } finally { - destroySessionContext(httpSession); - } - } else { - sc.destroy(); - } - webBeansContext.getBeanManagerImpl().fireEvent(event, DestroyedLiteral.INSTANCE_SESSION_SCOPED); - } sessionCtxManager.getContextById().clear(); } @@ -729,11 +709,6 @@ public class CdiAppContextsService extends AbstractContextsService implements Co } private Context lazyStartSessionContext() { - - if (logger.isDebugEnabled()) { - logger.debug(">lazyStartSessionContext"); - } - final Context webContext = null; final Context context = getCurrentContext(RequestScoped.class); if (context instanceof ServletRequestContext) { @@ -743,10 +718,6 @@ public class CdiAppContextsService extends AbstractContextsService implements Co try { final HttpSession currentSession = servletRequest.getSession(); initSessionContext(currentSession); - - if (logger.isDebugEnabled()) { - logger.debug("Lazy SESSION context initialization SUCCESS"); - } } catch (final Exception e) { logger.error(OWBLogConst.ERROR_0013, e); } @@ -758,9 +729,6 @@ public class CdiAppContextsService extends AbstractContextsService implements Co logger.warning("Could NOT lazily initialize session context because of " + context + " RequestContext"); } - if (logger.isDebugEnabled()) { - logger.debug("<lazyStartSessionContext " + webContext); - } return webContext; } http://git-wip-us.apache.org/repos/asf/tomee/blob/de0c9893/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/BeginWebBeansListener.java ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/BeginWebBeansListener.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/BeginWebBeansListener.java index 36e83aa..d379927 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/BeginWebBeansListener.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/BeginWebBeansListener.java @@ -117,7 +117,7 @@ public class BeginWebBeansListener implements ServletContextListener, ServletReq elStore.destroyELContextStore(); } - webBeansContext.getContextsService().endContext(RequestScoped.class, event); + contextsService.endContext(RequestScoped.class, event); if (webBeansContext instanceof WebappWebBeansContext) { // end after child ((WebappWebBeansContext) webBeansContext).getParent().getContextsService().endContext(RequestScoped.class, event); } @@ -145,7 +145,7 @@ public class BeginWebBeansListener implements ServletContextListener, ServletReq if (webBeansContext instanceof WebappWebBeansContext) { // start before child ((WebappWebBeansContext) webBeansContext).getParent().getContextsService().startContext(RequestScoped.class, event); } - this.webBeansContext.getContextsService().startContext(RequestScoped.class, event); + contextsService.startContext(RequestScoped.class, event); // we don't initialise the Session here but do it lazily if it gets requested // the first time. See OWB-457 @@ -168,7 +168,7 @@ public class BeginWebBeansListener implements ServletContextListener, ServletReq if (webBeansContext instanceof WebappWebBeansContext) { // start before child ((WebappWebBeansContext) webBeansContext).getParent().getContextsService().startContext(SessionScoped.class, event.getSession()); } - this.webBeansContext.getContextsService().startContext(SessionScoped.class, event.getSession()); + contextsService.startContext(SessionScoped.class, event.getSession()); } catch (final Exception e) { logger.error(OWBLogConst.ERROR_0020, event.getSession()); WebBeansUtil.throwRuntimeExceptions(e); @@ -189,16 +189,15 @@ public class BeginWebBeansListener implements ServletContextListener, ServletReq } // ensure session ThreadLocal is set - webBeansContext.getContextsService().startContext(SessionScoped.class, event.getSession()); + contextsService.startContext(SessionScoped.class, event.getSession()); if (WebappWebBeansContext.class.isInstance(webBeansContext)) { // end after child WebappWebBeansContext.class.cast(webBeansContext).getParent().getContextsService().endContext(SessionScoped.class, event.getSession()); } - final CdiAppContextsService appContextsService = CdiAppContextsService.class.cast(webBeansContext.getContextsService()); - if (appContextsService.getRequestContext(false) != null) { + if (contextsService.getRequestContext(false) != null) { final String id = event.getSession().getId(); // capture it eagerly! - appContextsService.pushRequestReleasable(new Runnable() { + contextsService.pushRequestReleasable(new Runnable() { @Override public void run() { doDestroyConversations(id); @@ -208,7 +207,7 @@ public class BeginWebBeansListener implements ServletContextListener, ServletReq doDestroyConversations(event.getSession().getId()); } - webBeansContext.getContextsService().endContext(SessionScoped.class, event.getSession()); + contextsService.endContext(SessionScoped.class, event.getSession()); WebBeansListenerHelper.destroyFakedRequest(this); } http://git-wip-us.apache.org/repos/asf/tomee/blob/de0c9893/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java index 384e254..eaf420f 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java @@ -896,7 +896,7 @@ public class HttpRequestImpl implements HttpRequest { impl.callListeners(); // can call req.getSession() so do it after affectation + do it after cdi init final SessionManager sessionManager = SystemInstance.get().getComponent(SessionManager.class); - final SessionManager.SessionWrapper previous = sessionManager.newSession(begin, session, application); + final SessionManager.SessionWrapper previous = sessionManager.newSession(begin, end, session, application); if (previous != null) { session = previous.session; } @@ -1222,7 +1222,6 @@ public class HttpRequestImpl implements HttpRequest { @Override public void invalidate() { - SystemInstance.get().getComponent(SessionManager.class).removeSession(session.getId()); try { super.invalidate(); } finally { http://git-wip-us.apache.org/repos/asf/tomee/blob/de0c9893/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpSessionImpl.java ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpSessionImpl.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpSessionImpl.java index 657a394..f82b7bf 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpSessionImpl.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpSessionImpl.java @@ -102,7 +102,6 @@ public class HttpSessionImpl implements HttpSession { } } - attributes.clear(); final SessionManager sessionManager = SystemInstance.get().getComponent(SessionManager.class); if (sessionManager != null) { sessionManager.removeSession(sessionId); http://git-wip-us.apache.org/repos/asf/tomee/blob/de0c9893/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java index 65e8c66..16277fb 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java @@ -29,12 +29,6 @@ import org.apache.openejb.util.LogCategory; import org.apache.openejb.util.Logger; import org.apache.openejb.util.OptionsLog; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -46,6 +40,12 @@ import java.net.URI; import java.util.Map; import java.util.Properties; import java.util.Set; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; /** * This is the main class for the web administration. It takes care of the @@ -62,7 +62,7 @@ public class OpenEJBHttpServer implements HttpServer { private boolean indent; public OpenEJBHttpServer() { - this(getHttpListenerRegistry()); + this(null); } public static HttpListenerRegistry getHttpListenerRegistry() { @@ -76,10 +76,11 @@ public class OpenEJBHttpServer implements HttpServer { } public OpenEJBHttpServer(final HttpListener listener) { - this.listener = new OpenEJBHttpRegistry.ClassLoaderHttpListener(listener, ParentClassLoaderFinder.Helper.get()); if (SystemInstance.get().getComponent(SessionManager.class) == null) { SystemInstance.get().setComponent(SessionManager.class, new SessionManager()); } + this.listener = new OpenEJBHttpRegistry.ClassLoaderHttpListener( + listener == null ? getHttpListenerRegistry() : listener, ParentClassLoaderFinder.Helper.get()); } public static boolean isTextXml(final Map<String, String> headers) { http://git-wip-us.apache.org/repos/asf/tomee/blob/de0c9893/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/session/SessionManager.java ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/session/SessionManager.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/session/SessionManager.java index ad455b1..2284421 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/session/SessionManager.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/session/SessionManager.java @@ -19,10 +19,11 @@ package org.apache.openejb.server.httpd.session; import org.apache.openejb.core.WebContext; import org.apache.openejb.loader.SystemInstance; import org.apache.openejb.server.httpd.BeginWebBeansListener; -import org.apache.openejb.server.httpd.HttpRequestImpl; +import org.apache.openejb.server.httpd.EndWebBeansListener; import org.apache.openejb.server.httpd.HttpSession; import org.apache.openejb.util.DaemonThreadFactory; import org.apache.openejb.util.Duration; +import org.apache.webbeans.config.WebBeansContext; import java.util.ArrayList; import java.util.Collection; @@ -43,16 +44,37 @@ public class SessionManager { private static volatile ScheduledExecutorService es; public void destroy(final WebContext app) { + if (app == null) { + return; + } + + final WebBeansContext wbc = app.getWebBeansContext(); final Iterator<SessionWrapper> iterator = sessions.values().iterator(); while (iterator.hasNext()) { final SessionWrapper next = iterator.next(); if (next.app == app) { - next.session.invalidate(); + doDestroy(next); iterator.remove(); } } } + private void doDestroy(final SessionWrapper next) { + HttpSessionEvent event = null; + if (next.end != null) { + event = new HttpSessionEvent(next.session); + next.end.sessionDestroyed(event); + next.begin.sessionCreated(event); // just set session thread local + } + try { + next.session.invalidate(); + } finally { + if (next.begin != null) { + next.begin.sessionDestroyed(event); + } + } + } + public void destroy() { if (es == null) { return; @@ -69,7 +91,7 @@ public class SessionManager { return; } final Duration duration = new Duration(SystemInstance.get().getProperty("openejb.http.eviction.duration", "1 minute")); - es = Executors.newScheduledThreadPool(1, new DaemonThreadFactory(HttpRequestImpl.class)); + es = Executors.newScheduledThreadPool(1, new DaemonThreadFactory(SessionManager.class)); es.scheduleWithFixedDelay(new Runnable() { @Override public void run() { @@ -77,12 +99,8 @@ public class SessionManager { final HttpSession session = data.session; if (session.getMaxInactiveInterval() > 0 && session.getLastAccessedTime() + TimeUnit.SECONDS.toMillis(session.getMaxInactiveInterval()) < System.currentTimeMillis()) { - sessions.remove(session.getId()); - session.invalidate(); - - if (data.listener != null) { - data.listener.sessionDestroyed(new HttpSessionEvent(session)); - } + doDestroy(data); + sessions.remove(data.session.getId()); } } } @@ -105,8 +123,10 @@ public class SessionManager { return sessions.size(); } - public SessionWrapper newSession(final BeginWebBeansListener listener, final HttpSession session, final WebContext app) { - final SessionWrapper existing = sessions.putIfAbsent(session.getId(), new SessionWrapper(listener, session, app)); + public SessionWrapper newSession(final BeginWebBeansListener begin, final EndWebBeansListener end, + final HttpSession session, final WebContext app) { + final SessionWrapper wrapper = new SessionWrapper(begin, end, session, app); + final SessionWrapper existing = sessions.putIfAbsent(session.getId(), wrapper); if (existing == null && es == null) { synchronized (this) { if (es == null) { @@ -114,17 +134,19 @@ public class SessionManager { } } } - return existing; + return existing == null ? wrapper : existing; } public static class SessionWrapper extends HttpSessionEvent { - public final BeginWebBeansListener listener; + public final BeginWebBeansListener begin; + public final EndWebBeansListener end; public final HttpSession session; public final WebContext app; - public SessionWrapper(final BeginWebBeansListener listener, final HttpSession session, final WebContext app) { + public SessionWrapper(final BeginWebBeansListener begin, final EndWebBeansListener end, final HttpSession session, final WebContext app) { super(session); - this.listener = listener; + this.begin = begin; + this.end = end; this.session = session; this.app = app; } http://git-wip-us.apache.org/repos/asf/tomee/blob/de0c9893/tck/cdi-embedded/src/test/resources/failing.xml ---------------------------------------------------------------------- diff --git a/tck/cdi-embedded/src/test/resources/failing.xml b/tck/cdi-embedded/src/test/resources/failing.xml index bf0d833..3a10892 100644 --- a/tck/cdi-embedded/src/test/resources/failing.xml +++ b/tck/cdi-embedded/src/test/resources/failing.xml @@ -32,7 +32,7 @@ -Dopenejb.cdi.conversation.http.use-get-parameter=true --> <classes> - <class name="org.jboss.cdi.tck.tests.lookup.injection.non.contextual.InjectionIntoNonContextualComponentTest" /> + <class name="org.jboss.cdi.tck.tests.context.session.listener.shutdown.SessionContextListenerShutdownTest" /> </classes> </test> </suite>