You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2015/05/04 00:00:18 UTC
[1/4] tomee git commit: TOMEE-1571 destroying http session of
openejb-http layer when undeploying applications with openejb embedded
arquillian adapter
Repository: tomee
Updated Branches:
refs/heads/master 075c46542 -> de0c9893c
TOMEE-1571 destroying http session of openejb-http layer when undeploying applications with openejb embedded arquillian adapter
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/5af485d0
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/5af485d0
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/5af485d0
Branch: refs/heads/master
Commit: 5af485d0d271fd8c30b279290d173e88fbf37fd5
Parents: 075c465
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Sun May 3 22:20:13 2015 +0200
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Sun May 3 22:20:13 2015 +0200
----------------------------------------------------------------------
.../openejb/OpenEJBDeployableContainer.java | 30 ++++-
.../http/WebArchiveResourceProvider.java | 16 +++
.../arquillian/openejb/SessionDestroyTest.java | 113 ++++++++++++++++
.../openejb/server/httpd/HttpRequestImpl.java | 124 +++++------------
.../openejb/server/httpd/HttpResponseImpl.java | 3 +-
.../openejb/server/httpd/HttpSessionImpl.java | 26 ++--
.../server/httpd/OpenEJBHttpRegistry.java | 2 +
.../openejb/server/httpd/OpenEJBHttpServer.java | 9 +-
.../server/httpd/session/SessionManager.java | 132 +++++++++++++++++++
.../httpd/HttpResponseImplSessionTest.java | 16 +--
10 files changed, 347 insertions(+), 124 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/5af485d0/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java b/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
index 90d86b1..44915b8 100644
--- a/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
+++ b/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
@@ -37,8 +37,10 @@ import org.apache.openejb.config.DeploymentFilterable;
import org.apache.openejb.config.WebModule;
import org.apache.openejb.core.LocalInitialContext;
import org.apache.openejb.core.LocalInitialContextFactory;
+import org.apache.openejb.core.WebContext;
import org.apache.openejb.loader.IO;
import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.httpd.session.SessionManager;
import org.apache.openejb.web.LightweightWebAppBuilder;
import org.apache.webbeans.web.lifecycle.test.MockHttpSession;
import org.apache.webbeans.web.lifecycle.test.MockServletContext;
@@ -58,11 +60,6 @@ import org.jboss.arquillian.test.spi.annotation.SuiteScoped;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.descriptor.api.Descriptor;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpSession;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.IOException;
@@ -75,6 +72,11 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
import static org.apache.openejb.cdi.ScopeHelper.startContexts;
import static org.apache.openejb.cdi.ScopeHelper.stopContexts;
@@ -295,7 +297,8 @@ public class OpenEJBDeployableContainer implements DeployableContainer<OpenEJBCo
final AppInfo appInfo = configurationFactory.configureApplication(module);
final WebAppBuilder webAppBuilder = SystemInstance.get().getComponent(WebAppBuilder.class);
- if (webAppBuilder != null && LightweightWebAppBuilder.class.isInstance(webAppBuilder)) {
+ final boolean isEmbeddedWebAppBuilder = webAppBuilder != null && LightweightWebAppBuilder.class.isInstance(webAppBuilder);
+ if (isEmbeddedWebAppBuilder) {
// for now we keep the same classloader, open to discussion if we should recreate it, not sure it does worth it
final LightweightWebAppBuilder lightweightWebAppBuilder = LightweightWebAppBuilder.class.cast(webAppBuilder);
for (final WebModule w : module.getWebModules()) {
@@ -310,6 +313,21 @@ public class OpenEJBDeployableContainer implements DeployableContainer<OpenEJBCo
}
}
final AppContext appCtx = assembler.createApplication(appInfo, module.getClassLoader());
+ if (isEmbeddedWebAppBuilder && PROPERTIES.containsKey(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE) && !appCtx.getWebContexts().isEmpty()) {
+ cls.add(new Closeable() {
+ @Override
+ public void close() throws IOException {
+ try {
+ final SessionManager sessionManager = SystemInstance.get().getComponent(SessionManager.class);
+ for (final WebContext web : appCtx.getWebContexts()) {
+ sessionManager.destroy(web);
+ }
+ } catch (final Throwable e) {
+ // no-op
+ }
+ }
+ });
+ }
final ServletContext appServletContext = new MockServletContext();
final HttpSession appSession = new MockHttpSession();
http://git-wip-us.apache.org/repos/asf/tomee/blob/5af485d0/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/http/WebArchiveResourceProvider.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/http/WebArchiveResourceProvider.java b/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/http/WebArchiveResourceProvider.java
index 2f1f731..5fd0b04 100644
--- a/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/http/WebArchiveResourceProvider.java
+++ b/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/http/WebArchiveResourceProvider.java
@@ -1,3 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.apache.openejb.arquillian.openejb.http;
import org.apache.openejb.arquillian.openejb.SWClassLoader;
http://git-wip-us.apache.org/repos/asf/tomee/blob/5af485d0/arquillian/arquillian-openejb-embedded-5/src/test/java/org/apache/openejb/arquillian/openejb/SessionDestroyTest.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-openejb-embedded-5/src/test/java/org/apache/openejb/arquillian/openejb/SessionDestroyTest.java b/arquillian/arquillian-openejb-embedded-5/src/test/java/org/apache/openejb/arquillian/openejb/SessionDestroyTest.java
new file mode 100644
index 0000000..fbae01e
--- /dev/null
+++ b/arquillian/arquillian-openejb-embedded-5/src/test/java/org/apache/openejb/arquillian/openejb/SessionDestroyTest.java
@@ -0,0 +1,113 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.arquillian.openejb;
+
+import org.apache.openejb.loader.IO;
+import org.jboss.arquillian.container.test.api.Deployer;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.OperateOnDeployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.junit.InSequence;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.net.URL;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebListener;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(Arquillian.class)
+public class SessionDestroyTest {
+ @Deployment(name = "app", managed = false, testable = false)
+ public static Archive<?> app() {
+ return ShrinkWrap.create(WebArchive.class).addClasses(SessionTestManager.class, SessionListener.class);
+ }
+
+ @ArquillianResource
+ private Deployer deployer;
+
+ private static String id;
+
+ @Test
+ @InSequence(1)
+ public void deploy() {
+ reset();
+ deployer.deploy("app");
+ }
+
+ @Test
+ @InSequence(2)
+ @OperateOnDeployment("app")
+ public void doTest(@ArquillianResource final URL url) throws IOException {
+ id = IO.slurp(new URL(url.toExternalForm() + "create"));
+ assertNotNull(SessionListener.created);
+ assertEquals(id, SessionListener.created);
+ }
+
+ @Test
+ @InSequence(3)
+ public void undeployAndAsserts() {
+ deployer.undeploy("app");
+ assertNotNull(SessionListener.destroyed);
+ assertEquals(id, SessionListener.destroyed);
+ reset();
+ }
+
+ private void reset() {
+ SessionListener.destroyed = null;
+ SessionListener.created = null;
+ id = null;
+ }
+
+ @WebServlet("/create")
+ public static class SessionTestManager extends HttpServlet {
+ @Override
+ protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ req.getSession().setAttribute("test", "ok");
+ resp.getWriter().write(req.getSession().getId());
+ }
+ }
+
+ @WebListener
+ public static class SessionListener implements HttpSessionListener {
+ private static String created;
+ private static String destroyed;
+
+ @Override
+ public void sessionCreated(final HttpSessionEvent httpSessionEvent) {
+ created = httpSessionEvent.getSession().getId();
+ }
+
+ @Override
+ public void sessionDestroyed(final HttpSessionEvent httpSessionEvent) {
+ destroyed = httpSessionEvent.getSession().getId();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tomee/blob/5af485d0/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 3751ef0..384e254 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
@@ -19,30 +19,13 @@ package org.apache.openejb.server.httpd;
import org.apache.openejb.assembler.classic.AppInfo;
import org.apache.openejb.assembler.classic.Assembler;
import org.apache.openejb.assembler.classic.WebAppInfo;
+import org.apache.openejb.core.WebContext;
import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.httpd.session.SessionManager;
import org.apache.openejb.spi.SecurityService;
import org.apache.openejb.util.ArrayEnumeration;
-import org.apache.openejb.util.DaemonThreadFactory;
-import org.apache.openejb.util.Duration;
import org.apache.openejb.util.Logger;
-import javax.security.auth.login.LoginException;
-import javax.servlet.AsyncContext;
-import javax.servlet.DispatcherType;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletInputStream;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletRequestEvent;
-import javax.servlet.ServletRequestListener;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSessionEvent;
-import javax.servlet.http.HttpUpgradeHandler;
-import javax.servlet.http.Part;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
@@ -67,11 +50,23 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
+import javax.security.auth.login.LoginException;
+import javax.servlet.AsyncContext;
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpUpgradeHandler;
+import javax.servlet.http.Part;
import static java.util.Collections.singletonList;
@@ -83,11 +78,6 @@ public class HttpRequestImpl implements HttpRequest {
private static final String FORM_URL_ENCODED = "application/x-www-form-urlencoded";
private static final String TRANSFER_ENCODING = "Transfer-Encoding";
private static final String CHUNKED = "chunked";
- protected static final String EJBSESSIONID = "EJBSESSIONID";
- protected static final String JSESSIONID = "JSESSIONID";
-
- // note: no eviction so invalidate has to be called properly
- private static final ConcurrentMap<String, RequestSession> SESSIONS = new ConcurrentHashMap<>();
public static final Class<?>[] SERVLET_CONTEXT_INTERFACES = new Class<?>[]{ServletContext.class};
public static final InvocationHandler SERVLET_CONTEXT_HANDLER = new InvocationHandler() {
@@ -97,43 +87,9 @@ public class HttpRequestImpl implements HttpRequest {
}
};
- private static volatile ScheduledExecutorService es;
-
- public static void destroyEviction() {
- if (es == null) {
- return;
- }
- es.shutdownNow();
- SESSIONS.clear();
- }
-
- public static void initEviction() {
- if (!"true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.http.eviction", "true"))) {
- return;
- }
- final Duration duration = new Duration(SystemInstance.get().getProperty("openejb.http.eviction.duration", "1 minute"));
- es = Executors.newScheduledThreadPool(1, new DaemonThreadFactory(HttpRequestImpl.class));
- es.scheduleWithFixedDelay(new Runnable() {
- @Override
- public void run() {
- for (final RequestSession data : new ArrayList<>(SESSIONS.values())) {
- 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.request != null && data.request.begin != null) {
- data.request.begin.sessionDestroyed(new HttpSessionEvent(session));
- }
- }
- }
- }
- }, duration.getTime(), duration.getTime(), duration.getUnit());
- }
-
private EndWebBeansListener end;
private BeginWebBeansListener begin;
+ private WebContext application;
/**
* 5.1.1 Method
@@ -438,11 +394,13 @@ public class HttpRequestImpl implements HttpRequest {
for (String c : cookies) {
final String current = c.trim();
if (current.startsWith("EJBSESSIONID=")) {
- final RequestSession requestSession = SESSIONS.get(current.substring("EJBSESSIONID=".length()));
- session = requestSession == null ? null : requestSession.session;
+ final SessionManager.SessionWrapper sessionWrapper =
+ SystemInstance.get().getComponent(SessionManager.class).findSession(current.substring("EJBSESSIONID=".length()));
+ session = sessionWrapper == null ? null : sessionWrapper.session;
} else if (current.startsWith("JSESSIONID=")) {
- final RequestSession requestSession = SESSIONS.get(current.substring("JSESSIONID=".length()));
- session = requestSession == null ? null : requestSession.session;
+ final SessionManager.SessionWrapper sessionWrapper =
+ SystemInstance.get().getComponent(SessionManager.class).findSession(current.substring("JSESSIONID=".length()));
+ session = sessionWrapper == null ? null : sessionWrapper.session;
}
}
}
@@ -929,7 +887,7 @@ public class HttpRequestImpl implements HttpRequest {
}
}
- final HttpSessionImpl impl = new HttpSessionImpl(SESSIONS, contextPath, timeout);
+ final HttpSessionImpl impl = new HttpSessionImpl(contextPath, timeout);
session = impl;
if (begin != null) {
begin.sessionCreated(new HttpSessionEvent(session));
@@ -937,17 +895,10 @@ public class HttpRequestImpl implements HttpRequest {
}
impl.callListeners(); // can call req.getSession() so do it after affectation + do it after cdi init
- final RequestSession previous = SESSIONS.putIfAbsent(session.getId(), new RequestSession(this, session));
+ final SessionManager sessionManager = SystemInstance.get().getComponent(SessionManager.class);
+ final SessionManager.SessionWrapper previous = sessionManager.newSession(begin, session, application);
if (previous != null) {
session = previous.session;
- } else {
- if (es == null) {
- synchronized (HttpRequestImpl.class) {
- if (es == null) {
- initEviction();
- }
- }
- }
}
}
return session;
@@ -1219,6 +1170,10 @@ public class HttpRequestImpl implements HttpRequest {
}
}
+ public void setApplication(final WebContext app) {
+ this.application = app;
+ }
+
public void setBeginListener(final BeginWebBeansListener begin) {
if (this.begin == null) {
this.begin = begin;
@@ -1267,7 +1222,7 @@ public class HttpRequestImpl implements HttpRequest {
@Override
public void invalidate() {
- SESSIONS.remove(session.getId());
+ SystemInstance.get().getComponent(SessionManager.class).removeSession(session.getId());
try {
super.invalidate();
} finally {
@@ -1314,15 +1269,4 @@ public class HttpRequestImpl implements HttpRequest {
// not yet supported: TODO: fake response write in ByteArrayOutputStream and then call HttpListenerRegistry and write it back
}
}
-
- private static class RequestSession extends HttpSessionEvent {
- private final HttpRequestImpl request;
- private final HttpSession session;
-
- public RequestSession(final HttpRequestImpl request, final HttpSession session) {
- super(session);
- this.request = request;
- this.session = session;
- }
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tomee/blob/5af485d0/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java
----------------------------------------------------------------------
diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java
index 9692e28..180e3e2 100644
--- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java
+++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java
@@ -17,6 +17,7 @@
package org.apache.openejb.server.httpd;
import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.httpd.session.SessionManager;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
import org.apache.openejb.util.OpenEjbVersion;
@@ -483,7 +484,7 @@ public class HttpResponseImpl implements HttpResponse {
return;
}
- headers.put(HttpRequest.HEADER_SET_COOKIE, HttpRequestImpl.EJBSESSIONID + '=' + session.getId() + "; Path=/");
+ headers.put(HttpRequest.HEADER_SET_COOKIE, SessionManager.EJBSESSIONID + '=' + session.getId() + "; Path=/");
}
/**
http://git-wip-us.apache.org/repos/asf/tomee/blob/5af485d0/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 cd0a394..657a394 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
@@ -18,11 +18,8 @@ package org.apache.openejb.server.httpd;
import org.apache.openejb.client.ArrayEnumeration;
import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.httpd.session.SessionManager;
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpSessionContext;
-import javax.servlet.http.HttpSessionEvent;
-import javax.servlet.http.HttpSessionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -31,19 +28,20 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
-import java.util.concurrent.ConcurrentMap;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSessionContext;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
public class HttpSessionImpl implements HttpSession {
private Collection<HttpSessionListener> listeners;
private String sessionId = UUID.randomUUID().toString();
private Map<String, Object> attributes = new HashMap<String, Object>();
- private final ConcurrentMap<String, ? extends HttpSessionEvent> mapToClean;
private final long created = System.currentTimeMillis();
private volatile long timeout;
private volatile long lastAccessed = created;
- public HttpSessionImpl(final ConcurrentMap<String, ? extends HttpSessionEvent> sessions, final String contextPath, final long timeout) {
- this.mapToClean = sessions;
+ public HttpSessionImpl(final String contextPath, final long timeout) {
this.timeout = timeout;
if (contextPath == null) {
return;
@@ -62,7 +60,7 @@ public class HttpSessionImpl implements HttpSession {
}
public HttpSessionImpl() {
- this(null, null, 30000);
+ this(null, 30000);
}
public void newSessionId() {
@@ -105,8 +103,9 @@ public class HttpSessionImpl implements HttpSession {
}
attributes.clear();
- if (mapToClean != null) {
- mapToClean.remove(sessionId);
+ final SessionManager sessionManager = SystemInstance.get().getComponent(SessionManager.class);
+ if (sessionManager != null) {
+ sessionManager.removeSession(sessionId);
}
}
@@ -186,16 +185,17 @@ public class HttpSessionImpl implements HttpSession {
@Override
public HttpSessionContext getSessionContext() {
touch();
+ final SessionManager component = SystemInstance.get().getComponent(SessionManager.class);
return new HttpSessionContext() {
@Override
public javax.servlet.http.HttpSession getSession(final String sessionId) {
- final HttpSessionEvent event = mapToClean.get(sessionId);
+ final HttpSessionEvent event = component.findSession(sessionId);
return event == null ? null : event.getSession();
}
@Override
public Enumeration<String> getIds() {
- return Collections.enumeration(mapToClean.keySet());
+ return Collections.enumeration(component.findSessionIds());
}
};
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/5af485d0/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
----------------------------------------------------------------------
diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
index 3a61442..6dd8d9e 100644
--- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
+++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
@@ -113,6 +113,8 @@ public class OpenEJBHttpRegistry {
final HttpRequestImpl httpRequest = HttpRequestImpl.class.cast(request);
final WebContext web = findWebContext(request.getURI() == null ? request.getContextPath() : request.getURI().getPath());
if (web != null) {
+ httpRequest.setApplication(web);
+
if (web.getClassLoader() != null) {
thread.setContextClassLoader(web.getClassLoader());
} else if (web.getAppContext().getClassLoader() != null) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/5af485d0/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 33f358c..65e8c66 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
@@ -22,6 +22,7 @@ import org.apache.openejb.loader.Options;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.server.ServiceException;
import org.apache.openejb.server.context.RequestInfos;
+import org.apache.openejb.server.httpd.session.SessionManager;
import org.apache.openejb.server.stream.CountingInputStream;
import org.apache.openejb.server.stream.CountingOutputStream;
import org.apache.openejb.util.LogCategory;
@@ -76,6 +77,9 @@ 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());
+ }
}
public static boolean isTextXml(final Map<String, String> headers) {
@@ -170,7 +174,10 @@ public class OpenEJBHttpServer implements HttpServer {
@Override
public void stop() throws ServiceException {
OpenEJBAsyncContext.destroy();
- HttpRequestImpl.destroyEviction();
+ final SessionManager component = SystemInstance.get().getComponent(SessionManager.class);
+ if (component != null) {
+ component.destroy();
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/tomee/blob/5af485d0/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
new file mode 100644
index 0000000..ad455b1
--- /dev/null
+++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/session/SessionManager.java
@@ -0,0 +1,132 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.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.HttpSession;
+import org.apache.openejb.util.DaemonThreadFactory;
+import org.apache.openejb.util.Duration;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import javax.servlet.http.HttpSessionEvent;
+
+public class SessionManager {
+ public static final String EJBSESSIONID = "EJBSESSIONID";
+ public static final String JSESSIONID = "JSESSIONID";
+
+ private final ConcurrentMap<String, SessionWrapper> sessions = new ConcurrentHashMap<>();
+
+ private static volatile ScheduledExecutorService es;
+
+ public void destroy(final WebContext app) {
+ final Iterator<SessionWrapper> iterator = sessions.values().iterator();
+ while (iterator.hasNext()) {
+ final SessionWrapper next = iterator.next();
+ if (next.app == app) {
+ next.session.invalidate();
+ iterator.remove();
+ }
+ }
+ }
+
+ public void destroy() {
+ if (es == null) {
+ return;
+ }
+ es.shutdownNow();
+ for (final SessionWrapper rs : sessions.values()) {
+ rs.session.invalidate();
+ }
+ sessions.clear();
+ }
+
+ public void initEviction() {
+ if (!"true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.http.eviction", "true"))) {
+ return;
+ }
+ final Duration duration = new Duration(SystemInstance.get().getProperty("openejb.http.eviction.duration", "1 minute"));
+ es = Executors.newScheduledThreadPool(1, new DaemonThreadFactory(HttpRequestImpl.class));
+ es.scheduleWithFixedDelay(new Runnable() {
+ @Override
+ public void run() {
+ for (final SessionWrapper data : new ArrayList<>(sessions.values())) {
+ 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));
+ }
+ }
+ }
+ }
+ }, duration.getTime(), duration.getTime(), duration.getUnit());
+ }
+
+ public SessionWrapper findSession(final String id) {
+ return sessions.get(id);
+ }
+
+ public void removeSession(final String sessionId) {
+ sessions.remove(sessionId);
+ }
+
+ public Collection<String> findSessionIds() {
+ return sessions.keySet();
+ }
+
+ public int size() {
+ 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));
+ if (existing == null && es == null) {
+ synchronized (this) {
+ if (es == null) {
+ initEviction();
+ }
+ }
+ }
+ return existing;
+ }
+
+ public static class SessionWrapper extends HttpSessionEvent {
+ public final BeginWebBeansListener listener;
+ public final HttpSession session;
+ public final WebContext app;
+
+ public SessionWrapper(final BeginWebBeansListener listener, final HttpSession session, final WebContext app) {
+ super(session);
+ this.listener = listener;
+ this.session = session;
+ this.app = app;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tomee/blob/5af485d0/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/HttpResponseImplSessionTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/HttpResponseImplSessionTest.java b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/HttpResponseImplSessionTest.java
index 595c9be..b43d130 100644
--- a/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/HttpResponseImplSessionTest.java
+++ b/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/HttpResponseImplSessionTest.java
@@ -21,41 +21,31 @@ import org.apache.openejb.core.CoreContainerSystem;
import org.apache.openejb.core.ivm.naming.IvmJndiFactory;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.server.ServiceException;
+import org.apache.openejb.server.httpd.session.SessionManager;
import org.apache.openejb.spi.ContainerSystem;
import org.junit.After;
import org.junit.Before;
-import org.junit.BeforeClass;
import org.junit.Test;
-import javax.servlet.http.HttpSession;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.lang.reflect.Field;
import java.net.Socket;
-import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;
+import javax.servlet.http.HttpSession;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class HttpResponseImplSessionTest {
- private static Field sessions;
-
private OpenEJBHttpEjbServer server;
- @BeforeClass
- public static void findSessionsField() throws NoSuchFieldException {
- sessions = HttpRequestImpl.class.getDeclaredField("SESSIONS");
- sessions.setAccessible(true);
- }
-
private static int numberOfSessions() throws IllegalAccessException {
- return Map.class.cast(sessions.get(null)).size();
+ return SystemInstance.get().getComponent(SessionManager.class).size();
}
@Before
[2/4] tomee git commit: destroying sessions in application composer
as well
Posted by rm...@apache.org.
destroying sessions in application composer as well
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/fd7e9b21
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/fd7e9b21
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/fd7e9b21
Branch: refs/heads/master
Commit: fd7e9b2103e44e7610e91ee2d34c39aea3a17b2d
Parents: 5af485d
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Sun May 3 22:23:57 2015 +0200
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Sun May 3 22:23:57 2015 +0200
----------------------------------------------------------------------
.../openejb/OpenEJBDeployableContainer.java | 6 ++++--
.../openejb/testing/ApplicationComposers.java | 22 ++++++++++++++++++++
2 files changed, 26 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/fd7e9b21/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java b/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
index 44915b8..f999c20 100644
--- a/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
+++ b/arquillian/arquillian-openejb-embedded-5/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
@@ -319,8 +319,10 @@ public class OpenEJBDeployableContainer implements DeployableContainer<OpenEJBCo
public void close() throws IOException {
try {
final SessionManager sessionManager = SystemInstance.get().getComponent(SessionManager.class);
- for (final WebContext web : appCtx.getWebContexts()) {
- sessionManager.destroy(web);
+ if (sessionManager != null) {
+ for (final WebContext web : appCtx.getWebContexts()) {
+ sessionManager.destroy(web);
+ }
}
} catch (final Throwable e) {
// no-op
http://git-wip-us.apache.org/repos/asf/tomee/blob/fd7e9b21/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java b/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java
index 9616622..08c2c5e 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java
@@ -46,6 +46,7 @@ import org.apache.openejb.config.sys.JaxbOpenejb;
import org.apache.openejb.config.sys.Openejb;
import org.apache.openejb.core.LocalInitialContextFactory;
import org.apache.openejb.core.Operation;
+import org.apache.openejb.core.ParentClassLoaderFinder;
import org.apache.openejb.core.ThreadContext;
import org.apache.openejb.core.WebContext;
import org.apache.openejb.core.ivm.naming.InitContextFactory;
@@ -75,6 +76,7 @@ import org.apache.openejb.util.NetworkUtil;
import org.apache.openejb.util.PropertyPlaceHolderHelper;
import org.apache.openejb.util.ServiceManagerProxy;
import org.apache.openejb.util.URLs;
+import org.apache.openejb.util.reflection.Reflections;
import org.apache.openejb.web.LightweightWebAppBuilder;
import org.apache.webbeans.inject.OWBInjector;
import org.apache.webbeans.spi.ContextsService;
@@ -1447,6 +1449,26 @@ public class ApplicationComposers {
}
}
});
+ if (!composer.appContext.getWebContexts().isEmpty()) {
+ composer.beforeDestroyAfterRunnables.add(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ final Object sessionManager = SystemInstance.get().getComponent(
+ ParentClassLoaderFinder.Helper.get().loadClass("org.apache.openejb.server.httpd.session.SessionManager")
+ );
+ if (sessionManager != null) {
+ final Class<?>[] paramTypes = {WebContext.class};
+ for (final WebContext web : composer.appContext.getWebContexts()) {
+ Reflections.invokeByReflection(sessionManager, "destroy", paramTypes, new Object[] { web });
+ }
+ }
+ } catch (final Throwable e) {
+ // no-op
+ }
+ }
+ });
+ }
composer.afterRunnables.add(new Runnable() {
@Override
public void run() {
[3/4] tomee git commit: OWB-1049 removing failoverservice references
Posted by rm...@apache.org.
OWB-1049 removing failoverservice references
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/cfe9fdf2
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/cfe9fdf2
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/cfe9fdf2
Branch: refs/heads/master
Commit: cfe9fdf29149db57097541faf90969e9f3a201b9
Parents: fd7e9b2
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Sun May 3 22:26:11 2015 +0200
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Sun May 3 22:26:11 2015 +0200
----------------------------------------------------------------------
.../apache/openejb/cdi/CdiAppContextsService.java | 7 -------
.../openejb/cdi/ThreadSingletonServiceImpl.java | 16 ++--------------
2 files changed, 2 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/cfe9fdf2/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 655af39..b8b49bc 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
@@ -744,13 +744,6 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
final HttpSession currentSession = servletRequest.getSession();
initSessionContext(currentSession);
- /*
- final FailOverService failoverService = webBeansContext.getService(FailOverService.class);
- if (failoverService != null && failoverService.isSupportFailOver()) {
- failoverService.sessionIsInUse(currentSession);
- }
- */
-
if (logger.isDebugEnabled()) {
logger.debug("Lazy SESSION context initialization SUCCESS");
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/cfe9fdf2/container/openejb-core/src/main/java/org/apache/openejb/cdi/ThreadSingletonServiceImpl.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cdi/ThreadSingletonServiceImpl.java b/container/openejb-core/src/main/java/org/apache/openejb/cdi/ThreadSingletonServiceImpl.java
index ed48b9e..2f688f7 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/cdi/ThreadSingletonServiceImpl.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/cdi/ThreadSingletonServiceImpl.java
@@ -47,8 +47,6 @@ import org.apache.webbeans.spi.TransactionService;
import org.apache.webbeans.spi.adaptor.ELAdaptor;
import org.apache.webbeans.web.intercept.RequestScopedBeanInterceptorHandler;
-import javax.enterprise.inject.spi.DeploymentException;
-import javax.transaction.Transactional;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -56,6 +54,8 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
+import javax.enterprise.inject.spi.DeploymentException;
+import javax.transaction.Transactional;
/**
* @version $Rev:$ $Date:$
@@ -71,7 +71,6 @@ public class ThreadSingletonServiceImpl implements ThreadSingletonService {
//this needs to be static because OWB won't tell us what the existing SingletonService is and you can't set it twice.
private static final ThreadLocal<WebBeansContext> contexts = new ThreadLocal<WebBeansContext>();
private static final Map<ClassLoader, WebBeansContext> contextByClassLoader = new ConcurrentHashMap<ClassLoader, WebBeansContext>();
- private static final String WEBBEANS_FAILOVER_ISSUPPORTFAILOVER = "org.apache.webbeans.web.failover.issupportfailover";
@Override
public void initialize(final StartupObject startupObject) {
@@ -102,13 +101,6 @@ public class ThreadSingletonServiceImpl implements ThreadSingletonService {
properties.setProperty(OpenWebBeansConfiguration.APPLICATION_SUPPORTS_CONVERSATION, "true");
properties.setProperty(OpenWebBeansConfiguration.IGNORED_INTERFACES, "org.apache.aries.proxy.weaving.WovenProxy");
- final String failoverService = startupObject.getAppInfo().properties.getProperty("org.apache.webbeans.spi.FailOverService",
- SystemInstance.get().getProperty("org.apache.webbeans.spi.FailOverService",
- null));
- if (failoverService != null) {
- properties.setProperty(OpenWebBeansConfiguration.IGNORED_INTERFACES, failoverService);
- }
-
final boolean tomee = SystemInstance.get().getProperty("openejb.loader", "foo").startsWith("tomcat");
final String defaultNormalScopeHandlerClass = NormalScopedBeanInterceptorHandler.class.getName();
@@ -125,10 +117,6 @@ public class ThreadSingletonServiceImpl implements ThreadSingletonService {
properties.setProperty("org.apache.webbeans.proxy.mapping.javax.enterprise.context.SessionScoped", "org.apache.tomee.catalina.cdi.SessionNormalScopeBeanHandler");
}
- if (SystemInstance.get().getOptions().get(WEBBEANS_FAILOVER_ISSUPPORTFAILOVER, false)) {
- properties.setProperty(WEBBEANS_FAILOVER_ISSUPPORTFAILOVER, "true");
- }
-
properties.put(OpenWebBeansConfiguration.PRODUCER_INTERCEPTION_SUPPORT, SystemInstance.get().getProperty("openejb.cdi.producer.interception", "true"));
properties.putAll(appContext.getProperties());
[4/4] tomee git commit: destroying session in a SessionManager in
embedded mode and not in cdi context
Posted by rm...@apache.org.
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/master
Commit: de0c9893cc03c5e3fec1647dc87150e96d3bd9b8
Parents: cfe9fdf
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Sun May 3 23:59:34 2015 +0200
Committer: Romain Manni-Bucau <rm...@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>