You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by st...@apache.org on 2015/05/06 09:56:32 UTC
svn commit: r1677942 - in /openwebbeans/trunk:
webbeans-impl/src/main/java/org/apache/webbeans/context/
webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/
webbeans-web/src/it/webcdiapp/src/test/java/org/apache/open...
Author: struberg
Date: Wed May 6 07:56:32 2015
New Revision: 1677942
URL: http://svn.apache.org/r1677942
Log:
OWB-1048 SessionContext must only get destroyed at the end of the context where it got called in.
Added:
openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/SessionUser.java
- copied, changed from r1677886, openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/ConversationalShoppingCart.java
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/RequestContext.java
openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/ConversationITServlet.java
openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/test/java/org/apache/openwebbeans/web/it/ConversationScopedIT.java
openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/WebContextsService.java
Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/RequestContext.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/RequestContext.java?rev=1677942&r1=1677941&r2=1677942&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/RequestContext.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/RequestContext.java Wed May 6 07:56:32 2015
@@ -27,14 +27,18 @@ import org.apache.webbeans.context.creat
/**
* Request context implementation.
- *
- * @author <a href="mailto:gurkanerdogdu@yahoo.com">Gurkan Erdogdu</a>
- * @since 1.0
+ *
*/
public class RequestContext extends AbstractContext
{
private static final long serialVersionUID = -1030240915163272268L;
+ /**
+ * If a Session gets destroyed in a HttpRequest then we store the session away
+ * and only destroy it at the end of the request.
+ */
+ private SessionContext propagatedSessionContext;
+
/*
* Constructor
*/
@@ -65,4 +69,17 @@ public class RequestContext extends Abst
return null;
}
+ public void setPropagatedSessionContext(SessionContext propagatedSessionContext)
+ {
+ this.propagatedSessionContext = propagatedSessionContext;
+ }
+
+ /**
+ * @return the SessionContext to get destroyed at the end of the request or {@code null} otherwise
+ */
+ public SessionContext getPropagatedSessionContext()
+ {
+ return propagatedSessionContext;
+ }
+
}
Modified: openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/ConversationITServlet.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/ConversationITServlet.java?rev=1677942&r1=1677941&r2=1677942&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/ConversationITServlet.java (original)
+++ openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/ConversationITServlet.java Wed May 6 07:56:32 2015
@@ -36,14 +36,17 @@ public class ConversationITServlet exten
private static final Logger log = Logger.getLogger(ConversationITServlet.class.getName());
private ConversationalShoppingCart shoppingCart;
+ private SessionUser sessionUser;
@Override
public void init() throws ServletException
{
shoppingCart = CDI.current().select(ConversationalShoppingCart.class).get();
+ sessionUser = CDI.current().select(SessionUser.class).get();
}
+
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
@@ -79,14 +82,20 @@ public class ConversationITServlet exten
{
shoppingCart.getConversation().end();
}
+ // user actions
+ else if ("setUser".equals(action))
+ {
+ String name = request.getParameter("name");
+ sessionUser.setName(name);
+ }
else
{
response.getWriter().append("error - unknown command");
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
- String msg = shoppingCart.toString();
- log.info("action = " + action + " shoppingCart=" + shoppingCart);
+ String msg = shoppingCart.toString() + "/" + sessionUser.toString();
+ log.info("action = " + action + " shoppingCart=" + shoppingCart + " user=" + sessionUser);
response.getWriter().append(msg);
response.setStatus(HttpServletResponse.SC_OK);
}
Copied: openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/SessionUser.java (from r1677886, openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/ConversationalShoppingCart.java)
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/SessionUser.java?p2=openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/SessionUser.java&p1=openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/ConversationalShoppingCart.java&r1=1677886&r2=1677942&rev=1677942&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/ConversationalShoppingCart.java (original)
+++ openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/main/java/org/apache/openwebbeans/web/it/conversation/SessionUser.java Wed May 6 07:56:32 2015
@@ -18,40 +18,27 @@
*/
package org.apache.openwebbeans.web.it.conversation;
-import javax.enterprise.context.Conversation;
-import javax.enterprise.context.ConversationScoped;
-import javax.inject.Inject;
+import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
/**
- *
+ * the logged in user
*/
-@ConversationScoped
-public class ConversationalShoppingCart implements Serializable
+@SessionScoped
+public class SessionUser implements Serializable
{
- private @Inject Conversation conversation;
- private String content = "empty";
+ private String name = null;
- public Conversation getConversation()
+ public void setName(String name)
{
- return conversation;
- }
-
- public String getContent()
- {
- return content;
- }
-
- public void setContent(String content)
- {
- this.content = content;
+ this.name = name;
}
@Override
public String toString()
{
- return conversation.getId() + "/" + conversation.isTransient() + "/" + content + "/" + System.identityHashCode(this);
+ return name + "/" + System.identityHashCode(this);
}
}
Modified: openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/test/java/org/apache/openwebbeans/web/it/ConversationScopedIT.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/test/java/org/apache/openwebbeans/web/it/ConversationScopedIT.java?rev=1677942&r1=1677941&r2=1677942&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/test/java/org/apache/openwebbeans/web/it/ConversationScopedIT.java (original)
+++ openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/test/java/org/apache/openwebbeans/web/it/ConversationScopedIT.java Wed May 6 07:56:32 2015
@@ -29,6 +29,42 @@ public class ConversationScopedIT extend
{
@Test
+ public void testSessionScope() throws Exception
+ {
+ DefaultHttpClient client = new DefaultHttpClient();
+
+ ConversationInfo previousInfo;
+ {
+ String content = httpGet(client, "conversation/setUser?name=Mark", HttpServletResponse.SC_OK);
+ ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null, "Mark", null);
+ previousInfo = info;
+ }
+
+ {
+ // should still get the same sessionscoped userName+instance
+ String content = httpGet(client, "conversation/info", HttpServletResponse.SC_OK);
+ ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null, "Mark", previousInfo.userHash);
+ previousInfo = info;
+ }
+
+ {
+ // and now we invalidate the session
+ // For the first request we should STILL get the old values as per spec
+ String content = httpGet(client, "conversation/invalidateSession", HttpServletResponse.SC_OK);
+ ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null, "Mark", previousInfo.userHash);
+ previousInfo = info;
+ }
+
+ {
+ // now we finally should get a new userName+instance
+ String content = httpGet(client, "conversation/info", HttpServletResponse.SC_OK);
+ ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null, "null", null);
+ Assert.assertTrue(!previousInfo.userHash.equals(info.userHash));
+ previousInfo = info;
+ }
+ }
+
+ @Test
public void testStandardConversation() throws Exception
{
DefaultHttpClient client = new DefaultHttpClient();
@@ -38,22 +74,22 @@ public class ConversationScopedIT extend
ConversationInfo previousInfo;
{
String content = httpGet(client, "conversation/info", HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null);
+ ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null, null, null);
previousInfo = info;
}
{
// once again, we like to make sure we really get different instances
String content = httpGet(client, "conversation/info", HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null);
- Assert.assertTrue(!info.instanceHash.equals(previousInfo.instanceHash));
+ ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null, null, null);
+ Assert.assertTrue(!info.conversationHash.equals(previousInfo.conversationHash));
}
{
// now we begin the transaction
String content = httpGet(client, "conversation/begin", HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, null, false, "empty", null);
- Assert.assertTrue(!info.instanceHash.equals(previousInfo.instanceHash));
+ ConversationInfo info = assertConversationInfo(content, null, false, "empty", null, null, null);
+ Assert.assertTrue(!info.conversationHash.equals(previousInfo.conversationHash));
Assert.assertTrue(!"null".equals(info.cid));
previousInfo = info;
}
@@ -61,21 +97,21 @@ public class ConversationScopedIT extend
{
// let's look what we got.
String content = httpGet(client, "conversation/info?cid=" + previousInfo.cid, HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, previousInfo.cid, false, "empty", previousInfo.instanceHash);
+ ConversationInfo info = assertConversationInfo(content, previousInfo.cid, false, "empty", previousInfo.conversationHash, null, null);
previousInfo = info;
}
{
// now let's set a value
String content = httpGet(client, "conversation/set?cid=" + previousInfo.cid + "&content=full", HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, previousInfo.cid, false, "full", previousInfo.instanceHash);
+ ConversationInfo info = assertConversationInfo(content, previousInfo.cid, false, "full", previousInfo.conversationHash, null, null);
previousInfo = info;
}
{
// and look again
String content = httpGet(client, "conversation/info?cid=" + previousInfo.cid, HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, previousInfo.cid, false, "full", previousInfo.instanceHash);
+ ConversationInfo info = assertConversationInfo(content, previousInfo.cid, false, "full", previousInfo.conversationHash, null, null);
previousInfo = info;
}
@@ -85,15 +121,15 @@ public class ConversationScopedIT extend
// we STILL should see 'full' and the old instance
// as the ConversationContext only needs to destroyed at the END of the request!
- ConversationInfo info = assertConversationInfo(content, "null", true, "full", previousInfo.instanceHash);
+ ConversationInfo info = assertConversationInfo(content, "null", true, "full", previousInfo.conversationHash, null, null);
previousInfo = info;
}
{
// the last request should result in a new ConversationScoped instance
String content = httpGet(client, "conversation/info", HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null);
- Assert.assertTrue(!info.instanceHash.equals(previousInfo.instanceHash));
+ ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null, null, null);
+ Assert.assertTrue(!info.conversationHash.equals(previousInfo.conversationHash));
}
}
@@ -110,22 +146,22 @@ public class ConversationScopedIT extend
ConversationInfo previousInfo;
{
String content = httpGet(client, "conversation/info", HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null);
+ ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null, null, null);
previousInfo = info;
}
{
// once again, we like to make sure we really get different instances
String content = httpGet(client, "conversation/info", HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null);
- Assert.assertTrue(!info.instanceHash.equals(previousInfo.instanceHash));
+ ConversationInfo info = assertConversationInfo(content, "null", true, "empty", null, null, null);
+ Assert.assertTrue(!info.conversationHash.equals(previousInfo.conversationHash));
}
{
// now we begin the transaction
String content = httpGet(client, "conversation/begin", HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, null, false, "empty", null);
- Assert.assertTrue(!info.instanceHash.equals(previousInfo.instanceHash));
+ ConversationInfo info = assertConversationInfo(content, null, false, "empty", null, null, null);
+ Assert.assertTrue(!info.conversationHash.equals(previousInfo.conversationHash));
Assert.assertTrue(!"null".equals(info.cid));
previousInfo = info;
}
@@ -133,14 +169,14 @@ public class ConversationScopedIT extend
{
// let's look what we got.
String content = httpGet(client, "conversation/info?cid=" + previousInfo.cid, HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, previousInfo.cid, false, "empty", previousInfo.instanceHash);
+ ConversationInfo info = assertConversationInfo(content, previousInfo.cid, false, "empty", previousInfo.conversationHash, null, null);
previousInfo = info;
}
{
// and set a value
String content = httpGet(client, "conversation/set?cid=" + previousInfo.cid + "&content=full", HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, previousInfo.cid, false, "full", previousInfo.instanceHash);
+ ConversationInfo info = assertConversationInfo(content, previousInfo.cid, false, "full", previousInfo.conversationHash, null, null);
previousInfo = info;
}
String oldCid = previousInfo.cid;
@@ -151,7 +187,7 @@ public class ConversationScopedIT extend
// the Conversation only gets destroyed at the end of the Request
// But the Conversation got ended (now is transient) and the cid is null
String content = httpGet(client, "conversation/invalidateSession?cid=" + previousInfo.cid, HttpServletResponse.SC_OK);
- ConversationInfo info = assertConversationInfo(content, "null", true, "full", previousInfo.instanceHash);
+ ConversationInfo info = assertConversationInfo(content, oldCid, false, "full", previousInfo.conversationHash, null, null);
previousInfo = info;
}
@@ -165,7 +201,8 @@ public class ConversationScopedIT extend
}
- private ConversationInfo assertConversationInfo(String content, String expectedCid, boolean expectedIsTransient, String expectedValue, Object expectedInstanceHash)
+ private ConversationInfo assertConversationInfo(String content, String expectedCid, boolean expectedIsTransient, String expectedValue, Object expectedInstanceHash,
+ String expectedUserName, String expectedUserHash)
{
Assert.assertNotNull(content);
ConversationInfo info = new ConversationInfo(content.split("/"));
@@ -184,8 +221,18 @@ public class ConversationScopedIT extend
if (expectedInstanceHash != null)
{
- Assert.assertEquals(expectedInstanceHash, info.instanceHash);
+ Assert.assertEquals(expectedInstanceHash, info.conversationHash);
+ }
+
+ if (expectedUserName != null)
+ {
+ Assert.assertEquals(expectedUserName, info.userName);
+ }
+ if (expectedUserHash != null)
+ {
+ Assert.assertEquals(expectedUserHash, info.userHash);
}
+
return info;
}
@@ -195,15 +242,19 @@ public class ConversationScopedIT extend
public String cid;
public boolean isTransient;
public String content;
- public String instanceHash;
+ public String conversationHash;
+ public String userName;
+ public String userHash;
public ConversationInfo(String[] info)
{
- Assert.assertEquals(4, info.length);
+ Assert.assertEquals(6, info.length);
cid = info[0];
isTransient = Boolean.parseBoolean(info[1]);
content = info[2];
- instanceHash = info[3];
+ conversationHash = info[3];
+ userName = info[4];
+ userHash = info[5];
}
}
Modified: openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/WebContextsService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/WebContextsService.java?rev=1677942&r1=1677941&r2=1677942&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/WebContextsService.java (original)
+++ openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/WebContextsService.java Wed May 6 07:56:32 2015
@@ -61,6 +61,11 @@ public class WebContextsService extends
private static final String OWB_SESSION_CONTEXT_ATTRIBUTE_NAME = "openWebBeansSessionContext";
+ /**
+ * TODO implement later: optional immediate destroy
+ */
+ private final boolean destroySessionImmediately = false;
+
/**Current request context*/
protected static ThreadLocal<ServletRequestContext> requestContexts = null;
@@ -353,7 +358,7 @@ public class WebContextsService extends
protected void destroyRequestContext(Object endObject)
{
//Get context
- RequestContext context = getRequestContext(true);
+ ServletRequestContext context = getRequestContext(true);
if (context == null)
{
@@ -366,6 +371,20 @@ public class WebContextsService extends
destroyOutdatedConversations(conversationContexts.get());
}
+ if (context.getPropagatedSessionContext() != null)
+ {
+ context.destroy();
+
+ Object payload = null;
+ if (context.getServletRequest() != null)
+ {
+ payload = context.getServletRequest().getSession();
+ }
+
+ webBeansContext.getBeanManagerImpl().fireEvent(payload != null ? payload : new Object(), DestroyedLiteral.INSTANCE_SESSION_SCOPED);
+
+ }
+
context.destroy();
// clean up the EL caches after each request
@@ -460,43 +479,39 @@ public class WebContextsService extends
{
// Get current session context from ThreadLocal
SessionContext context = sessionContexts.get();
-
- Object payload = null;
-
+ HttpSession session = null;
if (endObject != null && endObject instanceof HttpSession)
{
- HttpSession session = (HttpSession) endObject;
+ session = (HttpSession) endObject;
if (context == null)
{
// init in this case only attaches the existing session to the ThreadLocal
initSessionContext(session);
context = sessionContexts.get();
}
- payload = session;
}
// Destroy context
if (context != null && context.isActive())
{
- if (supportsConversation)
+
+ if (destroySessionImmediately)
{
- // get all conversations stored in the Session and destroy them
- // also set the current conversation (if any) to transient
- ConversationContext currentConversationContext = getConversationContext(true, true);
- if (currentConversationContext != null && !currentConversationContext.getConversation().isTransient())
- {
- // an active conversation will now be set to transient
- // note that ConversationImpl#end() also removes the conversation from the Session
- currentConversationContext.getConversation().end();
- }
+ context.destroy();
+ webBeansContext.getBeanManagerImpl().fireEvent(session != null ? session : new Object(), DestroyedLiteral.INSTANCE_SESSION_SCOPED);
+
+ // Clear thread locals
+ sessionContexts.set(null);
+ sessionContexts.remove();
+ }
+ else
+ {
+ // we need to mark the conversation to get destroyed at the end of the request
+ ServletRequestContext requestContext = getRequestContext(true);
+ requestContext.setPropagatedSessionContext(context);
}
- context.destroy();
- webBeansContext.getBeanManagerImpl().fireEvent(payload != null ? payload : new Object(), DestroyedLiteral.INSTANCE_SESSION_SCOPED);
}
- // Clear thread locals
- sessionContexts.set(null);
- sessionContexts.remove();
}
/**