Change-Id: I121d6999eababb7eaa53ba16fb8ed029cc154a12tags/7.0.0.beta11
@@ -789,12 +789,27 @@ public abstract class VaadinService implements Serializable { | |||
removeClosedUIs(session); | |||
} else { | |||
if (!session.isClosing()) { | |||
getLogger().fine( | |||
"Closing inactive session " | |||
+ session.getSession().getId()); | |||
closeSession(session); | |||
if (session.getSession() != null) { | |||
getLogger().fine( | |||
"Closing inactive session " | |||
+ session.getSession().getId()); | |||
} | |||
} | |||
if (session.getSession() != null) { | |||
/* | |||
* If the VaadinSession has no WrappedSession then it has | |||
* already been removed from the HttpSession and we do not have | |||
* to do it again | |||
*/ | |||
session.removeFromSession(this); | |||
} | |||
session.removeFromSession(this); | |||
/* | |||
* The session was destroyed during this request and therefore no | |||
* destroy event has yet been sent | |||
*/ | |||
fireSessionDestroy(session); | |||
} | |||
} | |||
@@ -914,7 +929,7 @@ public abstract class VaadinService implements Serializable { | |||
* @return true if the session is active, false if it could be closed. | |||
*/ | |||
private boolean isSessionActive(VaadinSession session) { | |||
if (session.isClosing()) { | |||
if (session.isClosing() || session.getSession() == null) { | |||
return false; | |||
} else { | |||
long now = System.currentTimeMillis(); |
@@ -160,7 +160,18 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { | |||
"A VaadinSession instance not associated to any service is getting unbound. " | |||
+ "Session destroy events will not be fired and UIs in the session will not get detached. " | |||
+ "This might happen if a session is deserialized but never used before it expires."); | |||
} else if (VaadinService.getCurrentRequest() != null | |||
&& getCurrent() == this) { | |||
// There is still a request in progress for this session. The | |||
// session will be destroyed after the response has been written. | |||
if (!isClosing()) { | |||
close(); | |||
} | |||
} else { | |||
/* | |||
* We are not in a request related to this session so we can | |||
* immediately destroy it | |||
*/ | |||
service.fireSessionDestroy(this); | |||
} | |||
session = null; |
@@ -40,7 +40,7 @@ | |||
</tr> | |||
<tr> | |||
<td>clickAndWait</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[4]/VButton[0]/domChild[0]/domChild[0]</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[5]/VButton[0]/domChild[0]/domChild[0]</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
@@ -53,7 +53,7 @@ | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::PID_SLog_row_0</td> | |||
<td>exact:6. Same WrappedSession id? false</td> | |||
</tr> | |||
<!--Test closing session and redirecting to google--> | |||
<!--Test closing session and redirecting to another page--> | |||
<tr> | |||
<td>clickAndWait</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VButton[0]/domChild[0]/domChild[0]</td> | |||
@@ -64,7 +64,7 @@ | |||
<td>//h1</td> | |||
<td>This is a static file</td> | |||
</tr> | |||
<!--Open again and verify we get a Session Expired error if doing something after closing the session--> | |||
<!--Open again and verify we get a Session Expired error if doing something after closing the VaadinSession--> | |||
<tr> | |||
<td>open</td> | |||
<td>/run/com.vaadin.tests.applicationcontext.CloseSession?restartApplication</td> | |||
@@ -85,6 +85,69 @@ | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::Root/VNotification[0]/HTML[0]/domChild[0]</td> | |||
<td>Session Expired</td> | |||
</tr> | |||
<!--Open again and verify we get a Session Expired error if doing something after closing the HttpSession--> | |||
<tr> | |||
<td>open</td> | |||
<td>/run/com.vaadin.tests.applicationcontext.CloseSession?restartApplication</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>click</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[4]/VButton[0]/domChild[0]/domChild[0]</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>click</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[4]/VButton[0]/domChild[0]/domChild[0]</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::Root/VNotification[0]/HTML[0]/domChild[0]</td> | |||
<td>Session Expired</td> | |||
</tr> | |||
<!--Open again and verify we get a Session Expired error if closing HttpSession in a background thread--> | |||
<tr> | |||
<td>open</td> | |||
<td>/run/com.vaadin.tests.applicationcontext.CloseSession?restartApplication</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>click</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[7]/VButton[0]/domChild[0]/domChild[0]</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>pause</td> | |||
<td>2000</td> | |||
<td>2000</td> | |||
</tr> | |||
<tr> | |||
<td>click</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[7]/VButton[0]/domChild[0]/domChild[0]</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::Root/VNotification[0]/HTML[0]/domChild[0]</td> | |||
<td>Session Expired</td> | |||
</tr> | |||
<!--Open again and test closing session and redirecting to another page--> | |||
<tr> | |||
<td>open</td> | |||
<td>/run/com.vaadin.tests.applicationcontext.CloseSession?restartApplication</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>clickAndWait</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VButton[0]/domChild[0]/domChild[0]</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>//h1</td> | |||
<td>This is a static file</td> | |||
</tr> | |||
</tbody></table> | |||
</body> | |||
</html> |
@@ -16,8 +16,11 @@ | |||
package com.vaadin.tests.applicationcontext; | |||
import javax.servlet.http.HttpSession; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.server.VaadinService; | |||
import com.vaadin.server.WrappedHttpSession; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.tests.util.Log; | |||
import com.vaadin.ui.Button; | |||
@@ -31,6 +34,8 @@ public class CloseSession extends AbstractTestUI { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
System.out.println("UI " + getUIId() + " inited"); | |||
final int sessionHash = getSession().hashCode(); | |||
final String sessionId = request.getWrappedSession().getId(); | |||
@@ -75,20 +80,67 @@ public class CloseSession extends AbstractTestUI { | |||
getSession().close(); | |||
} | |||
})); | |||
addComponent(new Button("Just close session", | |||
addComponent(new Button("Just close VaadinSession", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
getSession().close(); | |||
} | |||
})); | |||
addComponent(new Button("Just close HttpSession", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
getSession().getSession().invalidate(); | |||
} | |||
})); | |||
addComponent(new Button("Invalidate HttpSession and reopen page", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
VaadinService.getCurrentRequest().getWrappedSession() | |||
.invalidate(); | |||
getPage().setLocation(reopenUrl); | |||
} | |||
})); | |||
addComponent(new Button( | |||
"Invalidate HttpSession and redirect elsewhere", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
VaadinService.getCurrentRequest().getWrappedSession() | |||
.invalidate(); | |||
getPage().setLocation("/statictestfiles/static.html"); | |||
} | |||
})); | |||
addComponent(new Button( | |||
"Invalidate HttpSession in a background thread", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
final HttpSession session = ((WrappedHttpSession) VaadinService | |||
.getCurrentRequest().getWrappedSession()) | |||
.getHttpSession(); | |||
Thread t = new Thread(new Runnable() { | |||
@Override | |||
public void run() { | |||
try { | |||
Thread.sleep(1000); | |||
} catch (InterruptedException e) { | |||
e.printStackTrace(); | |||
} | |||
System.out | |||
.println("Invalidating session from thread " | |||
+ session.getId()); | |||
session.invalidate(); | |||
System.out | |||
.println("Invalidated session from thread " | |||
+ session.getId()); | |||
} | |||
}); | |||
t.start(); | |||
} | |||
})); | |||
} | |||
@@ -103,4 +155,9 @@ public class CloseSession extends AbstractTestUI { | |||
return Integer.valueOf(9859); | |||
} | |||
@Override | |||
public void detach() { | |||
super.detach(); | |||
System.out.println("UI " + getUIId() + " detached"); | |||
} | |||
} |