This is an automated email from the ASF dual-hosted git repository.
rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwebbeans.git
The following commit(s) were added to refs/heads/master by this push:
new e933276 [OWB-1384][OWB-1385] ensure OwbRequestContextController is
thread safe and BaseSeContextsService respects supportsConversation flag
e933276 is described below
commit e9332767af5abd81867b21b8a4d10718733fb188
Author: Romain Manni-Bucau <[email protected]>
AuthorDate: Fri May 14 12:04:27 2021 +0200
[OWB-1384][OWB-1385] ensure OwbRequestContextController is thread safe and
BaseSeContextsService respects supportsConversation flag
---
.../control/OwbRequestContextController.java | 59 ++++++++++++++++++++--
.../webbeans/corespi/se/BaseSeContextsService.java | 8 +++
.../webbeans/lifecycle/StandaloneLifeCycle.java | 8 +--
.../control/OwbRequestContextControllerTest.java | 2 +
.../conversation/ConversationScopedTest.java | 53 +++++++------------
5 files changed, 87 insertions(+), 43 deletions(-)
diff --git
a/webbeans-impl/src/main/java/org/apache/webbeans/context/control/OwbRequestContextController.java
b/webbeans-impl/src/main/java/org/apache/webbeans/context/control/OwbRequestContextController.java
index 1c45dd5..a6f66f8 100644
---
a/webbeans-impl/src/main/java/org/apache/webbeans/context/control/OwbRequestContextController.java
+++
b/webbeans-impl/src/main/java/org/apache/webbeans/context/control/OwbRequestContextController.java
@@ -27,15 +27,18 @@ import javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.control.RequestContextController;
import javax.enterprise.context.spi.Context;
+import java.util.ArrayList;
+import java.util.List;
public class OwbRequestContextController implements RequestContextController
{
private final ContextsService contextsService;
- private boolean didActivate = false;
+ private final ThreadLocal<List<Op>> deactivateOperations;
- OwbRequestContextController(WebBeansContext context)
+ OwbRequestContextController(final WebBeansContext context)
{
this.contextsService = context.getContextsService();
+ this.deactivateOperations = findThreadLocal(context);
}
@Override
@@ -45,20 +48,66 @@ public class OwbRequestContextController implements
RequestContextController
if (ctx == null || !ctx.isActive())
{
contextsService.startContext(RequestScoped.class, null);
- didActivate = true;
+ final List<Op> ops = new ArrayList<>();
+ ops.add(Op.DEACTIVATE);
+ deactivateOperations.set(ops);
return true;
}
+ List<Op> deactivateOps = deactivateOperations.get();
+ if (deactivateOps == null)
+ {
+ deactivateOps = new ArrayList<>();
+ deactivateOperations.set(deactivateOps);
+ }
+ deactivateOps.add(Op.NOOP);
return false;
}
@Override
public void deactivate() throws ContextNotActiveException
{
- // spec says we only must deactivate the RequestContest "f it was
activated by this context controller"
- if (didActivate)
+ // spec says we only must deactivate the RequestContest "if it was
activated by this context controller"
+ final List<Op> ops = deactivateOperations.get();
+ if (ops == null)
+ {
+ return;
+ }
+ if (ops.remove(ops.size() - 1) == Op.DEACTIVATE)
{
contextsService.endContext(RequestScoped.class, null);
RequestScopedBeanInterceptorHandler.removeThreadLocals();
}
+ if (ops.isEmpty())
+ {
+ deactivateOperations.remove();
+ }
+ }
+
+ // must be per webbeanscontext
+ private ThreadLocal<List<Op>> findThreadLocal(final WebBeansContext
context)
+ {
+ ThreadLocalService service =
context.getService(ThreadLocalService.class);
+ if (service == null)
+ {
+ synchronized (context)
+ {
+ if (service == null)
+ {
+ service = new ThreadLocalService();
+ context.registerService(ThreadLocalService.class, service);
+ }
+ }
+ }
+ return service.instance;
+ }
+
+ private enum Op
+ {
+ DEACTIVATE, NOOP
+ }
+
+ private static class ThreadLocalService
+ {
+ private final ThreadLocal<List<Op>> instance = new ThreadLocal<>();
}
}
diff --git
a/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/BaseSeContextsService.java
b/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/BaseSeContextsService.java
index 3df8f18..c2bec79 100644
---
a/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/BaseSeContextsService.java
+++
b/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/BaseSeContextsService.java
@@ -307,6 +307,10 @@ public abstract class BaseSeContextsService extends
AbstractContextsService
private void startConversationContext()
{
+ if (!supportsConversation)
+ {
+ return;
+ }
ConversationManager conversationManager =
webBeansContext.getConversationManager();
ConversationContext ctx =
conversationManager.getConversationContext(getCurrentSessionContext());
ctx.setActive(true);
@@ -393,6 +397,10 @@ public abstract class BaseSeContextsService extends
AbstractContextsService
private void stopConversationContext()
{
+ if (!supportsConversation)
+ {
+ return;
+ }
if(conversationContext.get() != null)
{
conversationContext.get().destroy();
diff --git
a/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/StandaloneLifeCycle.java
b/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/StandaloneLifeCycle.java
index cfb6e73..7afa83e 100644
---
a/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/StandaloneLifeCycle.java
+++
b/webbeans-impl/src/main/java/org/apache/webbeans/lifecycle/StandaloneLifeCycle.java
@@ -59,6 +59,10 @@ public class StandaloneLifeCycle extends AbstractLifeCycle
@Override
protected void afterStartApplication(Object startupObject)
{
+ webBeansContext.getContextsService().startContext(RequestScoped.class,
null);
+ webBeansContext.getContextsService().startContext(SessionScoped.class,
null);
+
webBeansContext.getContextsService().startContext(ConversationScoped.class,
null);
+
if
(!BaseSeContextsService.class.isInstance(webBeansContext.getContextsService())
||
BaseSeContextsService.class.cast(webBeansContext.getContextsService()).fireApplicationScopeEvents())
{
@@ -67,10 +71,6 @@ public class StandaloneLifeCycle extends AbstractLifeCycle
webBeansContext.getBeanManagerImpl().fireContextLifecyleEvent(
new Object(),
InitializedLiteral.INSTANCE_APPLICATION_SCOPED);
}
-
- webBeansContext.getContextsService().startContext(RequestScoped.class,
null);
- webBeansContext.getContextsService().startContext(SessionScoped.class,
null);
-
webBeansContext.getContextsService().startContext(ConversationScoped.class,
null);
}
@Override
diff --git
a/webbeans-impl/src/test/java/org/apache/webbeans/context/control/OwbRequestContextControllerTest.java
b/webbeans-impl/src/test/java/org/apache/webbeans/context/control/OwbRequestContextControllerTest.java
index f8521a0..e6edd6e 100644
---
a/webbeans-impl/src/test/java/org/apache/webbeans/context/control/OwbRequestContextControllerTest.java
+++
b/webbeans-impl/src/test/java/org/apache/webbeans/context/control/OwbRequestContextControllerTest.java
@@ -45,6 +45,8 @@ public class OwbRequestContextControllerTest extends
AbstractUnitTest
assertFalse(getInstance(RequestContextController.class).activate());
assertTrue(cs.getCurrentContext(RequestScoped.class).isActive());
controller.deactivate();
+ controller.deactivate();
+ controller.deactivate();
assertNull(cs.getCurrentContext(RequestScoped.class));
}
}
diff --git
a/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedTest.java
b/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedTest.java
index d3b4512..936e175 100644
---
a/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedTest.java
+++
b/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedTest.java
@@ -42,56 +42,41 @@ public class ConversationScopedTest extends AbstractUnitTest
@Test
public void testTransientConversation() throws Exception
{
- try
- {
-
System.setProperty(OpenWebBeansConfiguration.APPLICATION_SUPPORTS_CONVERSATION,
"true");
- startContainer(ConversationScopedBean.class);
+
addConfiguration(OpenWebBeansConfiguration.APPLICATION_SUPPORTS_CONVERSATION,
"true");
+ startContainer(ConversationScopedBean.class);
- ConversationScopedBean instance =
getInstance(ConversationScopedBean.class);
- instance.setValue("a");
- instance.begin();
- ensureSerialisableContext();
+ ConversationScopedBean instance =
getInstance(ConversationScopedBean.class);
+ instance.setValue("a");
+ instance.begin();
+ ensureSerialisableContext();
- restartContext(RequestScoped.class);
+ restartContext(RequestScoped.class);
- instance.end();
- Assert.assertNull(instance.getValue());
-
- }
- finally
- {
-
System.clearProperty(OpenWebBeansConfiguration.APPLICATION_SUPPORTS_CONVERSATION);
- }
+ instance.end();
+ Assert.assertNull(instance.getValue());
}
@Test
public void testConversationEvents() throws Exception
{
- try
- {
- ConversationScopedInitBean.gotStarted = false;
- EndConversationObserver.endConversationCalled = false;
+ ConversationScopedInitBean.gotStarted = false;
+ EndConversationObserver.endConversationCalled = false;
-
System.setProperty(OpenWebBeansConfiguration.APPLICATION_SUPPORTS_CONVERSATION,
"true");
- startContainer(ConversationScopedInitBean.class,
EndConversationObserver.class);
+
addConfiguration(OpenWebBeansConfiguration.APPLICATION_SUPPORTS_CONVERSATION,
"true");
+ startContainer(ConversationScopedInitBean.class,
EndConversationObserver.class);
- ConversationScopedInitBean instance =
getInstance(ConversationScopedInitBean.class);
- instance.ping();
+ ConversationScopedInitBean instance =
getInstance(ConversationScopedInitBean.class);
+ instance.ping();
- Assert.assertTrue(ConversationScopedInitBean.gotStarted);
+ Assert.assertTrue(ConversationScopedInitBean.gotStarted);
- ensureSerialisableContext();
+ ensureSerialisableContext();
- shutDownContainer();
+ shutDownContainer();
- Assert.assertTrue(EndConversationObserver.endConversationCalled);
- }
- finally
- {
-
System.clearProperty(OpenWebBeansConfiguration.APPLICATION_SUPPORTS_CONVERSATION);
- }
+ Assert.assertTrue(EndConversationObserver.endConversationCalled);
}
private void ensureSerialisableContext() throws IOException,
ClassNotFoundException