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();
     }
 
     /**