From: Tatu Lund Date: Fri, 24 Sep 2021 12:55:44 +0000 (+0300) Subject: fix: set Vaadin session attribute using lock in reinitializeSession (#12409) X-Git-Tag: 7.7.28~9 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=0f7e06233849aa0abb042d3778ccc110e5f240b6;p=vaadin-framework.git fix: set Vaadin session attribute using lock in reinitializeSession (#12409) * fix: set Vaadin session attribute using lock in reinitializeSession * Add unit test * Revert * Add unit test Backport to Java 6 * Add imports * More Java 6 --- diff --git a/server/src/main/java/com/vaadin/server/VaadinService.java b/server/src/main/java/com/vaadin/server/VaadinService.java index f6e21f6776..c8481b9876 100644 --- a/server/src/main/java/com/vaadin/server/VaadinService.java +++ b/server/src/main/java/com/vaadin/server/VaadinService.java @@ -1078,8 +1078,13 @@ public abstract class VaadinService implements Serializable { if (value instanceof VaadinSession) { // set flag to avoid cleanup VaadinSession serviceSession = (VaadinSession) value; - serviceSession.setAttribute(PRESERVE_UNBOUND_SESSION_ATTRIBUTE, - Boolean.TRUE); + serviceSession.lock(); + try { + serviceSession.setAttribute( + PRESERVE_UNBOUND_SESSION_ATTRIBUTE, Boolean.TRUE); + } finally { + serviceSession.unlock(); + } } attrs.put(name, value); } @@ -1105,8 +1110,13 @@ public abstract class VaadinService implements Serializable { serviceSession.getLockInstance()); service.storeSession(serviceSession, newSession); - serviceSession.setAttribute(PRESERVE_UNBOUND_SESSION_ATTRIBUTE, - null); + serviceSession.lock(); + try { + serviceSession.setAttribute( + PRESERVE_UNBOUND_SESSION_ATTRIBUTE, null); + } finally { + serviceSession.unlock(); + } } } diff --git a/server/src/test/java/com/vaadin/server/VaadinServiceTest.java b/server/src/test/java/com/vaadin/server/VaadinServiceTest.java index 1ec8067ba6..aafdb40d83 100644 --- a/server/src/test/java/com/vaadin/server/VaadinServiceTest.java +++ b/server/src/test/java/com/vaadin/server/VaadinServiceTest.java @@ -7,9 +7,15 @@ import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpSessionBindingEvent; +import java.util.Collections; + import org.easymock.EasyMock; import org.junit.Assert; import org.junit.Test; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + /** * @@ -125,4 +131,47 @@ public class VaadinServiceTest { assertThat(notification, containsString("\"url\":null")); } + @Test + public void reinitializeSession_setVaadinSessionAttriuteWithLock() { + final VaadinRequest request = Mockito.mock(VaadinRequest.class); + + VaadinSession vaadinSession = Mockito.mock(VaadinSession.class); + final VaadinSession newVaadinSession = Mockito.mock(VaadinSession.class); + + WrappedSession session = mockSession(request, vaadinSession, "foo"); + + Mockito.doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) { + mockSession(request, newVaadinSession, "bar"); + return null; + } + }).when(session).invalidate(); + + VaadinService.reinitializeSession(request); + + Mockito.verify(vaadinSession, Mockito.times(2)).lock(); + Mockito.verify(vaadinSession).setAttribute( + VaadinService.PRESERVE_UNBOUND_SESSION_ATTRIBUTE, Boolean.TRUE); + Mockito.verify(vaadinSession).setAttribute( + VaadinService.PRESERVE_UNBOUND_SESSION_ATTRIBUTE, null); + Mockito.verify(vaadinSession, Mockito.times(2)).unlock(); + } + + private WrappedSession mockSession(VaadinRequest request, + VaadinSession vaadinSession, String attributeName) { + WrappedSession session = Mockito.mock(WrappedSession.class); + Mockito.when(request.getWrappedSession()).thenReturn(session); + + Mockito.when(session.getAttributeNames()) + .thenReturn(Collections.singleton(attributeName)); + + Mockito.when(session.getAttribute(attributeName)) + .thenReturn(vaadinSession); + + VaadinService service = Mockito.mock(VaadinService.class); + + Mockito.when(vaadinSession.getService()).thenReturn(service); + return session; + } }