Search in sources :

Example 1 with SessionExpiredException

use of com.vaadin.flow.server.SessionExpiredException in project flow by vaadin.

the class PushHandler method callWithUi.

/**
 * Find the UI for the atmosphere resource, lock it and invoke the callback.
 *
 * @param resource
 *            the atmosphere resource for the current request
 * @param callback
 *            the push callback to call when a UI is found and locked
 * @param websocket
 *            true if this is a websocket message (as opposed to a HTTP
 *            request)
 */
private void callWithUi(final AtmosphereResource resource, final PushEventCallback callback, boolean websocket) {
    AtmosphereRequest req = resource.getRequest();
    VaadinServletRequest vaadinRequest = new VaadinServletRequest(req, service);
    VaadinSession session = null;
    if (websocket) {
        // For any HTTP request we have already started the request in the
        // servlet
        service.requestStart(vaadinRequest, null);
    }
    try {
        try {
            session = service.findVaadinSession(vaadinRequest);
            assert VaadinSession.getCurrent() == session;
        } catch (SessionExpiredException e) {
            sendNotificationAndDisconnect(resource, VaadinService.createSessionExpiredJSON());
            return;
        }
        UI ui = null;
        session.lock();
        try {
            ui = service.findUI(vaadinRequest);
            assert UI.getCurrent() == ui;
            if (ui == null) {
                sendNotificationAndDisconnect(resource, VaadinService.createUINotFoundJSON());
            } else {
                callback.run(resource, ui);
            }
        } catch (final IOException e) {
            callErrorHandler(session, e);
        } catch (final Exception e) {
            SystemMessages msg = service.getSystemMessages(ServletHelper.findLocale(null, vaadinRequest), vaadinRequest);
            AtmosphereResource errorResource = resource;
            if (ui != null && ui.getInternals().getPushConnection() != null) {
                // We MUST use the opened push connection if there is one.
                // Otherwise we will write the response to the wrong request
                // when using streaming (the client -> server request
                // instead of the opened push channel)
                errorResource = ((AtmospherePushConnection) ui.getInternals().getPushConnection()).getResource();
            }
            sendNotificationAndDisconnect(errorResource, VaadinService.createCriticalNotificationJSON(msg.getInternalErrorCaption(), msg.getInternalErrorMessage(), null, msg.getInternalErrorURL()));
            callErrorHandler(session, e);
        } finally {
            try {
                session.unlock();
            } catch (Exception e) {
                getLogger().warn("Error while unlocking session", e);
            // can't call ErrorHandler, we (hopefully) don't have a lock
            }
        }
    } finally {
        try {
            if (websocket) {
                service.requestEnd(vaadinRequest, null, session);
            }
        } catch (Exception e) {
            getLogger().warn("Error while ending request", e);
        // can't call ErrorHandler, we don't have a lock
        }
    }
}
Also used : AtmosphereRequest(org.atmosphere.cpr.AtmosphereRequest) VaadinSession(com.vaadin.flow.server.VaadinSession) UI(com.vaadin.flow.component.UI) AtmosphereResource(org.atmosphere.cpr.AtmosphereResource) VaadinServletRequest(com.vaadin.flow.server.VaadinServletRequest) SessionExpiredException(com.vaadin.flow.server.SessionExpiredException) SystemMessages(com.vaadin.flow.server.SystemMessages) IOException(java.io.IOException) InvalidUIDLSecurityKeyException(com.vaadin.flow.server.communication.ServerRpcHandler.InvalidUIDLSecurityKeyException) JsonException(elemental.json.JsonException) SessionExpiredException(com.vaadin.flow.server.SessionExpiredException) IOException(java.io.IOException)

Example 2 with SessionExpiredException

use of com.vaadin.flow.server.SessionExpiredException in project flow by vaadin.

the class PushHandler method connectionLost.

void connectionLost(AtmosphereResourceEvent event) {
    if (event == null) {
        getLogger().error("Could not get event. This should never happen.");
        return;
    }
    // We don't want to use callWithUi here, as it assumes there's a client
    // request active and does requestStart and requestEnd among other
    // things.
    AtmosphereResource resource = event.getResource();
    if (resource == null) {
        getLogger().error("Could not get resource. This should never happen.");
        return;
    }
    VaadinServletRequest vaadinRequest = new VaadinServletRequest(resource.getRequest(), service);
    VaadinSession session;
    try {
        session = service.findVaadinSession(vaadinRequest);
    } catch (SessionExpiredException e) {
        // This happens at least if the server is restarted without
        // preserving the session. After restart the client reconnects, gets
        // a session expired notification and then closes the connection and
        // ends up here
        getLogger().debug("Session expired before push disconnect event was received", e);
        return;
    }
    UI ui;
    session.lock();
    try {
        VaadinSession.setCurrent(session);
        // Sets UI.currentInstance
        ui = service.findUI(vaadinRequest);
        if (ui == null) {
            /*
                 * UI not found, could be because FF has asynchronously closed
                 * the websocket connection and Atmosphere has already done
                 * cleanup of the request attributes.
                 *
                 * In that case, we still have a chance of finding the right UI
                 * by iterating through the UIs in the session looking for one
                 * using the same AtmosphereResource.
                 */
            ui = findUiUsingResource(resource, session.getUIs());
            if (ui == null) {
                getLogger().debug("Could not get UI. This should never happen," + " except when reloading in Firefox and Chrome -" + " see http://dev.vaadin.com/ticket/14251.");
                return;
            } else {
                getLogger().info("No UI was found based on data in the request," + " but a slower lookup based on the AtmosphereResource succeeded." + " See http://dev.vaadin.com/ticket/14251 for more details.");
            }
        }
        PushMode pushMode = ui.getPushConfiguration().getPushMode();
        AtmospherePushConnection pushConnection = getConnectionForUI(ui);
        String id = resource.uuid();
        if (pushConnection == null) {
            getLogger().warn("Could not find push connection to close: {} with transport {}", id, resource.transport());
        } else {
            if (!pushMode.isEnabled()) {
                /*
                     * The client is expected to close the connection after push
                     * mode has been set to disabled.
                     */
                getLogger().debug("Connection closed for resource {}", id);
            } else {
                /*
                     * Unexpected cancel, e.g. if the user closes the browser
                     * tab.
                     */
                getLogger().debug("Connection unexpectedly closed for resource {} with transport {}", id, resource.transport());
            }
            pushConnection.connectionLost();
        }
    } catch (final Exception e) {
        callErrorHandler(session, e);
    } finally {
        try {
            session.unlock();
        } catch (Exception e) {
            getLogger().warn("Error while unlocking session", e);
        // can't call ErrorHandler, we (hopefully) don't have a lock
        }
    }
}
Also used : VaadinSession(com.vaadin.flow.server.VaadinSession) UI(com.vaadin.flow.component.UI) AtmosphereResource(org.atmosphere.cpr.AtmosphereResource) VaadinServletRequest(com.vaadin.flow.server.VaadinServletRequest) SessionExpiredException(com.vaadin.flow.server.SessionExpiredException) InvalidUIDLSecurityKeyException(com.vaadin.flow.server.communication.ServerRpcHandler.InvalidUIDLSecurityKeyException) JsonException(elemental.json.JsonException) SessionExpiredException(com.vaadin.flow.server.SessionExpiredException) IOException(java.io.IOException) PushMode(com.vaadin.flow.shared.communication.PushMode)

Aggregations

UI (com.vaadin.flow.component.UI)2 SessionExpiredException (com.vaadin.flow.server.SessionExpiredException)2 VaadinServletRequest (com.vaadin.flow.server.VaadinServletRequest)2 VaadinSession (com.vaadin.flow.server.VaadinSession)2 InvalidUIDLSecurityKeyException (com.vaadin.flow.server.communication.ServerRpcHandler.InvalidUIDLSecurityKeyException)2 JsonException (elemental.json.JsonException)2 IOException (java.io.IOException)2 AtmosphereResource (org.atmosphere.cpr.AtmosphereResource)2 SystemMessages (com.vaadin.flow.server.SystemMessages)1 PushMode (com.vaadin.flow.shared.communication.PushMode)1 AtmosphereRequest (org.atmosphere.cpr.AtmosphereRequest)1