Also test that the HttpSession can be invalidated (#6093) Change-Id: I4e415fe15d7a734db81562e24a5ab6a7fbc5304btags/7.0.0.beta6
@@ -737,4 +737,22 @@ public abstract class VaadinService implements Serializable { | |||
*/ | |||
public abstract String getMainDivId(VaadinServiceSession session, | |||
VaadinRequest request, Class<? extends UI> uiClass); | |||
/** | |||
* Closes the VaadinServiceSession and discards all associated UI state. | |||
* After the session has been discarded, any UIs that have been left open | |||
* will give an Out of sync error ( | |||
* {@link SystemMessages#getOutOfSyncCaption()}) error and a new session | |||
* will be created for serving new UIs. | |||
* <p> | |||
* To avoid causing out of sync errors, you should typically redirect to | |||
* some other page using {@link Page#setLocation(String)} to make the | |||
* browser unload the invalidated UI. | |||
* | |||
* @param session | |||
* the session to close | |||
*/ | |||
public void closeSession(VaadinServiceSession session) { | |||
session.removeFromSession(this); | |||
} | |||
} |
@@ -1036,4 +1036,24 @@ public class VaadinServiceSession implements HttpSessionBindingListener, | |||
return service; | |||
} | |||
/** | |||
* Closes this session and discards all associated UI state. After the | |||
* session has been discarded, any UIs that have been left open will give an | |||
* Out of sync error ({@link SystemMessages#getOutOfSyncCaption()}) error | |||
* and a new session will be created for serving new UIs. | |||
* <p> | |||
* To avoid causing out of sync errors, you should typically redirect to | |||
* some other page using {@link Page#setLocation(String)} to make the | |||
* browser unload the invalidated UI. | |||
* <p> | |||
* This method is just a shorthand to | |||
* {@link VaadinService#closeSession(VaadinServiceSession)} | |||
* | |||
* @see VaadinService#closeSession(VaadinServiceSession) | |||
* | |||
*/ | |||
public void close() { | |||
getService().closeSession(this); | |||
} | |||
} |
@@ -0,0 +1,90 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |||
<head profile="http://selenium-ide.openqa.org/profiles/test-case"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | |||
<link rel="selenium.base" href="" /> | |||
<title>New Test</title> | |||
</head> | |||
<body> | |||
<table cellpadding="1" cellspacing="1" border="1"> | |||
<thead> | |||
<tr><td rowspan="1" colspan="3">New Test</td></tr> | |||
</thead><tbody> | |||
<!--Close, reload and assert there's a new VaadinServiceSession in the old HttpSession--> | |||
<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[2]/VButton[0]/domChild[0]/domChild[0]</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::PID_SLog_row_2</td> | |||
<td>exact:4. Same hash as current? false</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::PID_SLog_row_0</td> | |||
<td>exact:6. Same WrappedSession id? true</td> | |||
</tr> | |||
<!--invalidate reload and assert there's a new VaadinServiceSession in a new HttpSession--> | |||
<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[4]/VButton[0]/domChild[0]/domChild[0]</td> | |||
<td></td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::PID_SLog_row_2</td> | |||
<td>exact:4. Same hash as current? false</td> | |||
</tr> | |||
<tr> | |||
<td>assertText</td> | |||
<td>vaadin=runcomvaadintestsapplicationcontextCloseSession::PID_SLog_row_0</td> | |||
<td>exact:6. Same WrappedSession id? false</td> | |||
</tr> | |||
<!--Test closing session and redirecting to google--> | |||
<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>assertLocation</td> | |||
<td>https://www.google.com/</td> | |||
<td>https://www.google.com/</td> | |||
</tr> | |||
<!--Open again and verify we get a Session Expired error if doing something after closing the session--> | |||
<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[3]/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[3]/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> | |||
</tbody></table> | |||
</body> | |||
</html> |
@@ -0,0 +1,105 @@ | |||
/* | |||
* Copyright 2012 Vaadin Ltd. | |||
* | |||
* Licensed 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 com.vaadin.tests.applicationcontext; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.server.VaadinService; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.tests.util.Log; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Button.ClickEvent; | |||
public class CloseSession extends AbstractTestUI { | |||
private static final String OLD_HASH_PARAM = "oldHash"; | |||
private static final String OLD_SESSION_ID_PARAM = "oldSessionId"; | |||
private final Log log = new Log(6); | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
final int sessionHash = getSession().hashCode(); | |||
final String sessionId = request.getWrappedSession().getId(); | |||
log.log("Current session hashcode: " + sessionHash); | |||
log.log("Current WrappedSession id: " + sessionId); | |||
// Log previous values to make it easier to see what has changed | |||
String oldHashValue = request.getParameter(OLD_HASH_PARAM); | |||
if (oldHashValue != null) { | |||
log.log("Old session hashcode: " + oldHashValue); | |||
log.log("Same hash as current? " | |||
+ oldHashValue.equals(Integer.toString(sessionHash))); | |||
} | |||
String oldSessionId = request.getParameter(OLD_SESSION_ID_PARAM); | |||
if (oldSessionId != null) { | |||
log.log("Old WrappedSession id: " + oldSessionId); | |||
log.log("Same WrappedSession id? " + oldSessionId.equals(sessionId)); | |||
} | |||
// Add parameters to help see what has changed | |||
final String reopenUrl = getPage().getLocation().getPath() + "?" | |||
+ OLD_HASH_PARAM + "=" + sessionHash + "&" | |||
+ OLD_SESSION_ID_PARAM + "=" + sessionId; | |||
addComponent(log); | |||
addComponent(new Button( | |||
"Close VaadinServiceSession and redirect to Google", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
getPage().setLocation("https://www.google.com"); | |||
getSession().close(); | |||
} | |||
})); | |||
addComponent(new Button("Close VaadinServiceSession and reopen page", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
getPage().setLocation(reopenUrl); | |||
getSession().close(); | |||
} | |||
})); | |||
addComponent(new Button("Just close session", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
getSession().close(); | |||
} | |||
})); | |||
addComponent(new Button("Invalidate HttpSession and reopen page", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
getPage().setLocation(reopenUrl); | |||
VaadinService.getCurrentRequest().getWrappedSession() | |||
.invalidate(); | |||
} | |||
})); | |||
} | |||
@Override | |||
protected String getTestDescription() { | |||
return "Test for closing the session and redirecting the user"; | |||
} | |||
@Override | |||
protected Integer getTicketNumber() { | |||
return Integer.valueOf(9859); | |||
} | |||
} |