Browse Source

fix: set Vaadin session attribute using lock in reinitializeSession (#12401)

* Cherry picked unit test from Flow

See https://github.com/vaadin/flow/pull/11538

* Fix missing import

* Cherry pick fix from Flow
tags/8.15.0
Tatu Lund 2 years ago
parent
commit
ba5e586b24
No account linked to committer's email address

+ 14
- 4
server/src/main/java/com/vaadin/server/VaadinService.java View File

@@ -1156,8 +1156,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);
}
@@ -1183,8 +1188,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();
}
}
}


+ 44
- 0
server/src/test/java/com/vaadin/server/VaadinServiceTest.java View File

@@ -8,8 +8,11 @@ import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSessionBindingEvent;

import java.util.Collections;

import org.easymock.EasyMock;
import org.junit.Test;
import org.mockito.Mockito;

import com.vaadin.shared.Registration;
import com.vaadin.util.CurrentInstance;
@@ -179,4 +182,45 @@ public class VaadinServiceTest {
assertEquals(1, listener.callCount);
assertEquals(1, listener2.callCount);
}

@Test
public void reinitializeSession_setVaadinSessionAttriuteWithLock() {
VaadinRequest request = Mockito.mock(VaadinRequest.class);

VaadinSession vaadinSession = Mockito.mock(VaadinSession.class);
VaadinSession newVaadinSession = Mockito.mock(VaadinSession.class);

WrappedSession session = mockSession(request, vaadinSession, "foo");

Mockito.doAnswer(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;
}
}

Loading…
Cancel
Save