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/04 00:53:40 UTC

svn commit: r1677494 - in /openwebbeans/trunk: webbeans-impl/src/main/java/org/apache/webbeans/context/ webbeans-impl/src/main/java/org/apache/webbeans/conversation/ webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/ webbeans-spi/src/main/java...

Author: struberg
Date: Sun May  3 22:53:40 2015
New Revision: 1677494

URL: http://svn.apache.org/r1677494
Log:
OWB-1050 further Conversation handling cleanup.

* on session destroy (invalidate) only destroy all conversations except the one from the current threads
* destroy the current conversation at the end of a thread

Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/AbstractContextsService.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/DefaultContextsService.java
    openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/ContextsService.java
    openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/test/java/org/apache/openwebbeans/web/it/ConversationScopedIT.java
    openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/test/java/org/apache/openwebbeans/web/it/OwbITBase.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/AbstractContextsService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/AbstractContextsService.java?rev=1677494&r1=1677493&r2=1677494&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/AbstractContextsService.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/AbstractContextsService.java Sun May  3 22:53:40 2015
@@ -19,8 +19,11 @@
 package org.apache.webbeans.context;
 
 import java.lang.annotation.Annotation;
+import java.util.Iterator;
+import java.util.Set;
 
 import javax.enterprise.context.ContextException;
+import javax.enterprise.context.SessionScoped;
 import javax.enterprise.context.spi.Context;
 
 import org.apache.webbeans.config.WebBeansContext;
@@ -62,6 +65,13 @@ public abstract class AbstractContextsSe
     }
 
     @Override
+    public Context getCurrentContext(Class<? extends Annotation> scopeType, boolean createIfNotExists)
+    {
+        // by default behaves the same
+        return getCurrentContext(scopeType);
+    }
+
+    @Override
     public void init(Object initializeObject)
     {
         //Default no-op        
@@ -105,28 +115,6 @@ public abstract class AbstractContextsSe
         }        
     }
 
-    protected void cleanupConversations(ConversationContext conversationCtx)
-    {
-        if (conversationCtx == null)
-        {
-            return;
-        }
-
-        ConversationManager conversationManager = webBeansContext.getConversationManager();
-
-        ConversationImpl conversation = conversationCtx.getConversation();
-        if (!conversation.isTransient())
-        {
-            //Conversation must be used by one thread at a time
-            conversation.updateLastAccessTime();
-            //Other threads can now access propagated conversation.
-            conversation.iDontUseItAnymore();
-        }
-
-        // and now destroy all timed-out and transient conversations
-        conversationManager.destroyUnrequiredConversations();
-    }
-
     @Override
     public void removeThreadLocals()
     {
@@ -138,4 +126,66 @@ public abstract class AbstractContextsSe
     {
         this.supportsConversation = supportConversations;
     }
+
+    protected void destroyAllBut(ConversationContext currentConversationCtx)
+    {
+        Context sessionContext = getCurrentContext(SessionScoped.class, false);
+        ConversationManager conversationManager = webBeansContext.getConversationManager();
+        Set<ConversationContext> sessionConversations = conversationManager.getSessionConversations(sessionContext, false);
+        if (sessionConversations != null)
+        {
+            for (ConversationContext conversationCtx : sessionConversations)
+            {
+                if (conversationCtx != currentConversationCtx)
+                {
+                    conversationManager.destroyConversationContext(conversationCtx);
+                }
+            }
+        }
+
+        if (currentConversationCtx != null && !currentConversationCtx.getConversation().isTransient())
+        {
+            currentConversationCtx.getConversation().end();
+        }
+
+
+    }
+
+
+    /**
+     * Destroy inactive (timed out) and transient conversations.
+     * This also will store the currentConversationContext into the session if it is long-running.
+     */
+    public void cleanupConversations(ConversationContext currentConversationContext)
+    {
+        Context sessionContext = getCurrentContext(SessionScoped.class,
+                currentConversationContext != null && !currentConversationContext.getConversation().isTransient());
+        if (sessionContext != null)
+        {
+            ConversationManager conversationManager = webBeansContext.getConversationManager();
+            Set<ConversationContext> conversationContexts = conversationManager.getSessionConversations(sessionContext, false);
+            if (conversationContexts != null)
+            {
+                Iterator<ConversationContext> convIt = conversationContexts.iterator();
+                while (convIt.hasNext())
+                {
+                    ConversationContext conversationContext = convIt.next();
+
+                    ConversationImpl conv = conversationContext.getConversation();
+                    if (conv.isTransient() || conversationManager.conversationTimedOut(conv))
+                    {
+                        conversationManager.destroyConversationContext(conversationContext);
+                        convIt.remove();
+                    }
+                    else
+                    {
+                        conv.iDontUseItAnymore();
+                    }
+                }
+            }
+        }
+
+    }
+
+
 }

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java?rev=1677494&r1=1677493&r2=1677494&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java Sun May  3 22:53:40 2015
@@ -18,7 +18,6 @@
  */
 package org.apache.webbeans.conversation;
 
-import java.util.Iterator;
 import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -73,11 +72,11 @@ public class ConversationManager
      * It will create a new ConversationContext if there is no long running Conversation already running.
      * @return the ConversationContext which is valid for the whole request.
      */
-    public ConversationContext getConversationContext()
+    public ConversationContext getConversationContext(Context sessionContext)
     {
         ConversationService conversationService = webBeansContext.getConversationService();
 
-        Set<ConversationContext> conversationContexts = getConversations(true);
+        Set<ConversationContext> conversationContexts = getSessionConversations(sessionContext, true);
 
         String conversationId = conversationService.getConversationId();
         if (conversationId != null && conversationId.length() > 0)
@@ -114,8 +113,14 @@ public class ConversationManager
         {
             return false;
         }
+        Context sessionContext = webBeansContext.getContextsService().getCurrentContext(SessionScoped.class, false);
+        if (sessionContext == null)
 
-        Set<ConversationContext> conversationContexts = getConversations(false);
+        {
+            return false;
+        }
+
+        Set<ConversationContext> conversationContexts = getSessionConversations(sessionContext, false);
         if (conversationContexts == null)
         {
             return false;
@@ -135,8 +140,8 @@ public class ConversationManager
     /**
      * Gets conversation instance from conversation bean.
      * @return conversation instance
+     * @deprecated is in
      */
-    @SuppressWarnings("unchecked")
     public Conversation getConversationBeanReference()
     {
         BeanManager beanManager = webBeansContext.getBeanManagerImpl();
@@ -146,32 +151,8 @@ public class ConversationManager
         return conversation;
     }
 
-    /**
-     * Destroy inactive (timed out) and transient conversations.
-     */
-    public void destroyUnrequiredConversations()
-    {
-        Set<ConversationContext> conversationContexts = getConversations(false);
-        if (conversationContexts == null)
-        {
-            return;
-        }
-
-        Iterator<ConversationContext> convIt = conversationContexts.iterator();
-        while (convIt.hasNext())
-        {
-            ConversationContext conversationContext = convIt.next();
-
-            ConversationImpl conv = conversationContext.getConversation();
-            if (conv.isTransient() || conversationTimedOut(conv))
-            {
-                destroyConversationContext(conversationContext);
-                convIt.remove();
-            }
-        }
-    }
 
-    private boolean conversationTimedOut(ConversationImpl conv)
+    public boolean conversationTimedOut(ConversationImpl conv)
     {
         long timeout = conv.getTimeout();
         if (timeout != 0L && (System.currentTimeMillis() - conv.getLastAccessTime()) > timeout)
@@ -222,10 +203,9 @@ public class ConversationManager
      * @param create whether a session and the map in there shall get created or not
      * @return the conversation Map from the current session
      */
-    private Set<ConversationContext> getConversations(boolean create)
+    public Set<ConversationContext> getSessionConversations(Context sessionContext, boolean create)
     {
         Set<ConversationContext> conversationContexts = null;
-        Context sessionContext = webBeansContext.getContextsService().getCurrentContext(SessionScoped.class);
         if (sessionContext != null)
         {
             if (!create)

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/DefaultContextsService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/DefaultContextsService.java?rev=1677494&r1=1677493&r2=1677494&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/DefaultContextsService.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/DefaultContextsService.java Sun May  3 22:53:40 2015
@@ -262,7 +262,7 @@ public class DefaultContextsService exte
         ConversationContext conversationCtx = conversationContext.get();
         if (conversationCtx == null)
         {
-            conversationCtx = webBeansContext.getConversationManager().getConversationContext();
+            conversationCtx = webBeansContext.getConversationManager().getConversationContext(getCurrentSessionContext());
             conversationContext.set(conversationCtx);
 
             // check for busy and non-existing conversations
@@ -336,7 +336,7 @@ public class DefaultContextsService exte
     
     private void startConversationContext(Object object)
     {
-        ConversationContext ctx = webBeansContext.getConversationManager().getConversationContext();
+        ConversationContext ctx = webBeansContext.getConversationManager().getConversationContext(getCurrentSessionContext());
 
         conversationContext.set(ctx);
     }

Modified: openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/ContextsService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/ContextsService.java?rev=1677494&r1=1677493&r2=1677494&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/ContextsService.java (original)
+++ openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/ContextsService.java Sun May  3 22:53:40 2015
@@ -63,6 +63,20 @@ public interface ContextsService
     public Context getCurrentContext(Class<? extends Annotation> scopeType);
     
     /**
+     * Gets current context with given scope type with
+     * respect to the current thread of execution.
+     * <p>
+     * If there is not current context, it will try to create one if {@code createIfNotExists} is set.
+     * This is mostly usefull for the SessionContext. If there is no HttpSession <em>yet</em> and the
+     * {@code createIfNotExists} is set to {@code false} then we do not create the HttpSession.
+     * </p>
+     * @param scopeType context scope type
+     * @param createIfNotExists whether to create a new context if the underlying storage is not yet initialized
+     * @return current context with given scope type
+     */
+    public Context getCurrentContext(Class<? extends Annotation> scopeType, boolean createIfNotExists);
+
+    /**
      * If container supports the given scope type it returns
      * true, otherwise it return false.
      * @param scopeType scope type

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=1677494&r1=1677493&r2=1677494&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 Sun May  3 22:53:40 2015
@@ -19,13 +19,7 @@
 package org.apache.openwebbeans.web.it;
 
 import javax.servlet.http.HttpServletResponse;
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
 
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.junit.Assert;
 import org.junit.Test;

Modified: openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/test/java/org/apache/openwebbeans/web/it/OwbITBase.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/test/java/org/apache/openwebbeans/web/it/OwbITBase.java?rev=1677494&r1=1677493&r2=1677494&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/test/java/org/apache/openwebbeans/web/it/OwbITBase.java (original)
+++ openwebbeans/trunk/webbeans-web/src/it/webcdiapp/src/test/java/org/apache/openwebbeans/web/it/OwbITBase.java Sun May  3 22:53:40 2015
@@ -152,7 +152,6 @@ public class OwbITBase
         Assert.assertNotNull(response);
 
         int statusCode = response.getStatusLine().getStatusCode();
-        Assert.assertEquals(expectedHttpCode, statusCode);
 
         HttpEntity httpEntity = response.getEntity();
         Assert.assertNotNull(httpEntity);
@@ -181,6 +180,7 @@ public class OwbITBase
         String content = sb.toString();
         log.info("  status=" + statusCode + " content: " + content);
 
+        Assert.assertEquals(expectedHttpCode, statusCode);
         getRequest.releaseConnection();
         return content;
     }

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=1677494&r1=1677493&r2=1677494&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 Sun May  3 22:53:40 2015
@@ -477,8 +477,9 @@ public class WebContextsService extends
         {
             if (supportsConversation)
             {
-                //X TODO get all conversations stored in the Session and mark them as transient
-                //X TODO also set the current conversation (if any) to transient
+                // get all conversations stored in the Session and destroy them
+                // also set the current conversation (if any) to transient
+                destroyAllBut(getConversationContext(true));
             }
             context.destroy();
             webBeansContext.getBeanManagerImpl().fireEvent(payload != null ? payload : new Object(), DestroyedLiteral.INSTANCE_SESSION_SCOPED);
@@ -658,7 +659,7 @@ public class WebContextsService extends
         ConversationContext conversationContext = conversationContexts.get();
         if (conversationContext == null && create)
         {
-            conversationContext = conversationManager.getConversationContext();
+            conversationContext = conversationManager.getConversationContext(getSessionContext(true));
             conversationContexts.set(conversationContext);
 
             // check for busy and non-existing conversations
@@ -687,6 +688,7 @@ public class WebContextsService extends
     }
 
     /**
+     * TODO probably not needed anymore
      * Remember for this request that a fresh transient conversation got created.
      * @return {@code false} if this request already got marked previously, {@code true} if we are the first to set the marker
      */