]> source.dussan.org Git - vaadin-framework.git/commitdiff
fix: set Vaadin session attribute using lock in reinitializeSession (#12409)
authorTatu Lund <tatu@vaadin.com>
Fri, 24 Sep 2021 12:55:44 +0000 (15:55 +0300)
committerGitHub <noreply@github.com>
Fri, 24 Sep 2021 12:55:44 +0000 (15:55 +0300)
* 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

server/src/main/java/com/vaadin/server/VaadinService.java
server/src/test/java/com/vaadin/server/VaadinServiceTest.java

index f6e21f677669384d9ae1c950d11ea3915f95caed..c8481b9876f5bd3d3db07691a924c4e207fac6fc 100644 (file)
@@ -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();
+                }
             }
         }
 
index 1ec8067ba6969551c54cb309a11035be38be1f86..aafdb40d839125b4ba7653389c87b334d8d3aa20 100644 (file)
@@ -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;
+    }
 }