Adopted from https://github.com/vaadin/flow/pull/8567tags/8.12.0.alpha1
import com.vaadin.shared.JsonConstants; | import com.vaadin.shared.JsonConstants; | ||||
import com.vaadin.shared.communication.PushMode; | import com.vaadin.shared.communication.PushMode; | ||||
import com.vaadin.ui.UI; | import com.vaadin.ui.UI; | ||||
import com.vaadin.util.CurrentInstance; | |||||
import elemental.json.JsonException; | import elemental.json.JsonException; | ||||
} | } | ||||
void connectionLost(AtmosphereResourceEvent event) { | void connectionLost(AtmosphereResourceEvent event) { | ||||
VaadinSession session = null; | |||||
try { | |||||
session = handleConnectionLost(event); | |||||
} finally { | |||||
if (session != null) { | |||||
session.access(new Runnable() { | |||||
@Override | |||||
public void run() { | |||||
CurrentInstance.clearAll(); | |||||
} | |||||
}); | |||||
} | |||||
} | |||||
} | |||||
private VaadinSession handleConnectionLost(AtmosphereResourceEvent event) { | |||||
// We don't want to use callWithUi here, as it assumes there's a client | // We don't want to use callWithUi here, as it assumes there's a client | ||||
// request active and does requestStart and requestEnd among other | // request active and does requestStart and requestEnd among other | ||||
// things. | // things. | ||||
if (event == null) { | if (event == null) { | ||||
getLogger().log(Level.SEVERE, | getLogger().log(Level.SEVERE, | ||||
"Could not get event. This should never happen."); | "Could not get event. This should never happen."); | ||||
return; | |||||
return null; | |||||
} | } | ||||
AtmosphereResource resource = event.getResource(); | AtmosphereResource resource = event.getResource(); | ||||
if (resource == null) { | if (resource == null) { | ||||
getLogger().log(Level.SEVERE, | getLogger().log(Level.SEVERE, | ||||
"Could not get resource. This should never happen."); | "Could not get resource. This should never happen."); | ||||
return; | |||||
return null; | |||||
} | } | ||||
VaadinServletRequest vaadinRequest = new VaadinServletRequest( | VaadinServletRequest vaadinRequest = new VaadinServletRequest( | ||||
} catch (ServiceException e) { | } catch (ServiceException e) { | ||||
getLogger().log(Level.SEVERE, | getLogger().log(Level.SEVERE, | ||||
"Could not get session. This should never happen", e); | "Could not get session. This should never happen", e); | ||||
return; | |||||
return null; | |||||
} catch (SessionExpiredException e) { | } catch (SessionExpiredException e) { | ||||
// This happens at least if the server is restarted without | // This happens at least if the server is restarted without | ||||
// preserving the session. After restart the client reconnects, gets | // preserving the session. After restart the client reconnects, gets | ||||
getLogger().log(Level.FINER, | getLogger().log(Level.FINER, | ||||
"Session expired before push disconnect event was received", | "Session expired before push disconnect event was received", | ||||
e); | e); | ||||
return; | |||||
return session; | |||||
} | } | ||||
UI ui = null; | UI ui = null; | ||||
getLogger().log(Level.FINE, | getLogger().log(Level.FINE, | ||||
"Could not get UI. This should never happen," | "Could not get UI. This should never happen," | ||||
+ " except when reloading in Firefox and Chrome -" | + " except when reloading in Firefox and Chrome -" | ||||
+ " see http://dev.vaadin.com/ticket/14251."); | |||||
return; | |||||
+ " see https://github.com/vaadin/framework/issues/5449."); | |||||
return session; | |||||
} else { | } else { | ||||
getLogger().log(Level.INFO, | getLogger().log(Level.INFO, | ||||
"No UI was found based on data in the request," | "No UI was found based on data in the request," | ||||
+ " but a slower lookup based on the AtmosphereResource succeeded." | + " but a slower lookup based on the AtmosphereResource succeeded." | ||||
+ " See http://dev.vaadin.com/ticket/14251 for more details."); | |||||
+ " See https://github.com/vaadin/framework/issues/5449 for more details."); | |||||
} | } | ||||
} | } | ||||
// can't call ErrorHandler, we (hopefully) don't have a lock | // can't call ErrorHandler, we (hopefully) don't have a lock | ||||
} | } | ||||
} | } | ||||
return session; | |||||
} | } | ||||
private static UI findUiUsingResource(AtmosphereResource resource, | private static UI findUiUsingResource(AtmosphereResource resource, |
/* | |||||
* Copyright 2000-2020 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.server; | |||||
import java.util.Collections; | |||||
import java.util.List; | |||||
import javax.servlet.ServletException; | |||||
import com.vaadin.tests.util.MockDeploymentConfiguration; | |||||
/** | |||||
* | |||||
* @author Vaadin Ltd | |||||
*/ | |||||
public class MockVaadinServletService extends VaadinServletService { | |||||
public MockVaadinServletService() throws ServiceException { | |||||
this(new MockDeploymentConfiguration()); | |||||
} | |||||
public MockVaadinServletService( | |||||
DeploymentConfiguration deploymentConfiguration) throws ServiceException { | |||||
this(new VaadinServlet(), deploymentConfiguration); | |||||
} | |||||
public MockVaadinServletService(VaadinServlet servlet, | |||||
DeploymentConfiguration deploymentConfiguration) throws ServiceException { | |||||
super(servlet, deploymentConfiguration); | |||||
try { | |||||
servlet.init(new MockServletConfig()); | |||||
} catch (ServletException e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
@Override | |||||
protected List<RequestHandler> createRequestHandlers() | |||||
throws ServiceException { | |||||
return Collections.emptyList(); | |||||
} | |||||
@Override | |||||
public void init() { | |||||
try { | |||||
super.init(); | |||||
} catch (ServiceException e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
} |
super(service); | super(service); | ||||
} | } | ||||
public MockVaadinSession() throws ServiceException { | |||||
super(new MockVaadinServletService()); | |||||
} | |||||
@Override | @Override | ||||
public void close() { | public void close() { | ||||
super.close(); | super.close(); |
/* | |||||
* Copyright 2000-2020 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.server.communication; | |||||
import java.util.concurrent.Future; | |||||
import org.atmosphere.cpr.AtmosphereRequest; | |||||
import org.atmosphere.cpr.AtmosphereResource; | |||||
import org.atmosphere.cpr.AtmosphereResourceEvent; | |||||
import org.junit.Assert; | |||||
import org.junit.Test; | |||||
import org.mockito.Mockito; | |||||
import com.vaadin.server.MockVaadinServletService; | |||||
import com.vaadin.server.MockVaadinSession; | |||||
import com.vaadin.server.ServiceException; | |||||
import com.vaadin.server.SessionExpiredException; | |||||
import com.vaadin.server.VaadinRequest; | |||||
import com.vaadin.server.VaadinSession; | |||||
import com.vaadin.ui.UI; | |||||
public class PushHandlerTest { | |||||
MockVaadinSession session = null; | |||||
@Test | |||||
public void connectionLost_currentInstancesAreCleared() | |||||
throws SessionExpiredException, ServiceException { | |||||
session = new MockVaadinSession() { | |||||
@Override | |||||
public Future<Void> access(Runnable runnable) { | |||||
runnable.run(); | |||||
return Mockito.mock(Future.class); | |||||
} | |||||
}; | |||||
VaadinSession.setCurrent(session); | |||||
Assert.assertNotNull(VaadinSession.getCurrent()); | |||||
MockVaadinServletService service = null; | |||||
service = new MockVaadinServletService() { | |||||
@Override | |||||
public com.vaadin.server.VaadinSession findVaadinSession( | |||||
VaadinRequest request) throws SessionExpiredException { | |||||
return session; | |||||
} | |||||
@Override | |||||
public UI findUI(VaadinRequest request) { | |||||
return null; | |||||
} | |||||
}; | |||||
service.init(); | |||||
PushHandler handler = new PushHandler(service); | |||||
AtmosphereResource resource = Mockito.mock(AtmosphereResource.class); | |||||
AtmosphereRequest request = Mockito.mock(AtmosphereRequest.class); | |||||
Mockito.when(resource.getRequest()).thenReturn(request); | |||||
AtmosphereResourceEvent event = Mockito | |||||
.mock(AtmosphereResourceEvent.class); | |||||
Mockito.when(event.getResource()).thenReturn(resource); | |||||
handler.connectionLost(event); | |||||
Assert.assertNull(VaadinSession.getCurrent()); | |||||
} | |||||
} |
"com\\.vaadin\\.server\\.VaadinPortlet", // | "com\\.vaadin\\.server\\.VaadinPortlet", // | ||||
"com\\.vaadin\\.server\\.MockServletConfig", // | "com\\.vaadin\\.server\\.MockServletConfig", // | ||||
"com\\.vaadin\\.server\\.MockServletContext", // | "com\\.vaadin\\.server\\.MockServletContext", // | ||||
"com\\.vaadin\\.server\\.MockVaadinServletService", // | |||||
"com\\.vaadin\\.server\\.Constants", // | "com\\.vaadin\\.server\\.Constants", // | ||||
"com\\.vaadin\\.server\\.VaadinServiceClassLoaderUtil", // | "com\\.vaadin\\.server\\.VaadinServiceClassLoaderUtil", // | ||||
"com\\.vaadin\\.server\\.VaadinServiceClassLoaderUtil\\$GetClassLoaderPrivilegedAction", // | "com\\.vaadin\\.server\\.VaadinServiceClassLoaderUtil\\$GetClassLoaderPrivilegedAction", // |