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
commit 239b0b705dcf1c22c7b9308c6c4f3fa6e304605a Author: Romain Manni-Bucau <rmannibu...@apache.org> AuthorDate: Wed Feb 26 18:53:06 2020 +0100 OWB-1314 ensure conversation last accessed time is updated when conversation is touched if conversation service handles propagation of id properly --- .../webbeans/conversation/ConversationImpl.java | 7 +- .../webbeans/conversation/ConversationManager.java | 4 ++ .../webbeans/corespi/se/BaseSeContextsService.java | 8 ++- .../conversation/ConversationManagerTest.java | 79 ++++++++++++++++++++++ 4 files changed, 96 insertions(+), 2 deletions(-) diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java b/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java index bbc8c68..1670db4 100644 --- a/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java +++ b/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java @@ -178,7 +178,12 @@ public class ConversationImpl implements Conversation, Serializable synchronized (this) { threadsUsingIt.add(thread); - return threadsUsingIt.size(); + final int size = threadsUsingIt.size(); + if (size == 1) + { + updateLastAccessTime(); + } + return size; } } diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java b/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java index cb10836..8332357 100644 --- a/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java +++ b/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java @@ -107,6 +107,10 @@ public class ConversationManager " is used by other request. It creates a new transient conversation"); conversationContext.getConversation().setProblemDuringCreation(problem); } + else + { + conversationContext.getConversation().updateLastAccessTime(); + } conversationContext.setActive(true); return conversationContext; 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 69c8cf4..11ea0db 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 @@ -41,6 +41,7 @@ import org.apache.webbeans.context.ConversationContext; import org.apache.webbeans.context.DependentContext; import org.apache.webbeans.context.RequestContext; import org.apache.webbeans.context.SessionContext; +import org.apache.webbeans.conversation.ConversationImpl; import org.apache.webbeans.conversation.ConversationManager; import org.apache.webbeans.intercept.RequestScopedBeanInterceptorHandler; import org.apache.webbeans.intercept.SessionScopedBeanInterceptorHandler; @@ -311,11 +312,16 @@ public abstract class BaseSeContextsService extends AbstractContextsService ctx.setActive(true); conversationContext.set(ctx); - if (ctx.getConversation().isTransient()) + final ConversationImpl conversation = ctx.getConversation(); + if (conversation.isTransient()) { webBeansContext.getBeanManagerImpl().fireContextLifecyleEvent( conversationManager.getLifecycleEventPayload(ctx), InitializedLiteral.INSTANCE_CONVERSATION_SCOPED); } + else + { + conversation.updateLastAccessTime(); + } } diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/conversation/ConversationManagerTest.java b/webbeans-impl/src/test/java/org/apache/webbeans/conversation/ConversationManagerTest.java new file mode 100644 index 0000000..077a8f8 --- /dev/null +++ b/webbeans-impl/src/test/java/org/apache/webbeans/conversation/ConversationManagerTest.java @@ -0,0 +1,79 @@ +/* + * 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.webbeans.conversation; + +import static java.lang.Thread.sleep; +import static org.apache.webbeans.util.Asserts.assertNotNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import java.util.concurrent.atomic.AtomicReference; + +import javax.enterprise.context.ConversationScoped; + +import org.apache.webbeans.context.ConversationContext; +import org.apache.webbeans.spi.ContextsService; +import org.apache.webbeans.spi.ConversationService; +import org.apache.webbeans.test.AbstractUnitTest; +import org.junit.Test; + +public class ConversationManagerTest extends AbstractUnitTest +{ + @Test + public void ensureLastUpdateIsCorrect() + { + final AtomicReference<String> conversationId = new AtomicReference<>(); + addService(ConversationService.class, new DefaultConversationService() { + @Override + public String getConversationId() { + return conversationId.get(); + } + }); + addConfiguration("org.apache.webbeans.application.supportsConversation", "true"); + startContainer(); + final ContextsService contextsService = getWebBeansContext().getContextsService(); + contextsService.startContext(ConversationScoped.class, null); + final ConversationContext conversationContext1 = ConversationContext.class.cast( + contextsService.getCurrentContext(ConversationScoped.class)); + final ConversationImpl conversation1 = conversationContext1.getConversation(); + assertNotNull(conversation1); + assertEquals(0, conversation1.getLastAccessTime()); + conversation1.begin("foo"); + conversationId.set(conversation1.getId()); + final long beginTime = conversation1.getLastAccessTime(); + assertNotEquals(0, beginTime); + try { + sleep(100); // avoid cached value (win) + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); + } + + // another request, will trigger the update + contextsService.endContext(ConversationScoped.class, null); + + contextsService.startContext(ConversationScoped.class, null); + final ConversationContext conversationContext2 = ConversationContext.class.cast( + contextsService.getCurrentContext(ConversationScoped.class)); + final ConversationImpl conversation2 = conversationContext2.getConversation(); + assertEquals(conversation1, conversation2); + + contextsService.getCurrentContext(ConversationScoped.class); // trigger update + assertNotEquals(beginTime, conversation2.getLastAccessTime()); + } +}