Search in sources :

Example 6 with VaadinSession

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

the class EventUtilTest method setUp.

@Before
public void setUp() {
    VaadinSession session = Mockito.mock(VaadinSession.class);
    UI ui = new UI() {

        @Override
        public VaadinSession getSession() {
            return session;
        }
    };
    VaadinService service = Mockito.mock(VaadinService.class);
    when(session.getService()).thenReturn(service);
    DefaultInstantiator instantiator = new DefaultInstantiator(service);
    when(service.getInstantiator()).thenReturn(instantiator);
    UI.setCurrent(ui);
}
Also used : DefaultInstantiator(com.vaadin.flow.di.DefaultInstantiator) VaadinSession(com.vaadin.flow.server.VaadinSession) UI(com.vaadin.flow.component.UI) VaadinService(com.vaadin.flow.server.VaadinService) Before(org.junit.Before)

Example 7 with VaadinSession

use of com.vaadin.flow.server.VaadinSession 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 8 with VaadinSession

use of com.vaadin.flow.server.VaadinSession 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)

Example 9 with VaadinSession

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

the class PushConfigurationImpl method setPushMode.

@Override
public void setPushMode(PushMode pushMode) {
    if (pushMode == null) {
        throw new IllegalArgumentException("Push mode cannot be null");
    }
    VaadinSession session = ui.getSession();
    if (session == null) {
        throw new UIDetachedException("Cannot set the push mode for a detached UI");
    }
    assert session.hasLock();
    if (pushMode.isEnabled() && !session.getService().ensurePushAvailable()) {
        throw new IllegalStateException("Push is not available. See previous log messages for more information.");
    }
    PushMode oldMode = getPushConfigurationMap().getPushMode();
    if (oldMode != pushMode) {
        getPushConfigurationMap().setPushMode(pushMode);
        if (!oldMode.isEnabled() && pushMode.isEnabled()) {
            // The push connection is initially in a disconnected state;
            // the client will establish the connection
            ui.getInternals().setPushConnection(new AtmospherePushConnection(ui));
        }
    // Nothing to do here if disabling push;
    // the client will close the connection
    }
}
Also used : AtmospherePushConnection(com.vaadin.flow.server.communication.AtmospherePushConnection) VaadinSession(com.vaadin.flow.server.VaadinSession) PushMode(com.vaadin.flow.shared.communication.PushMode)

Example 10 with VaadinSession

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

the class UI method accessSynchronously.

/**
 * Locks the session of this UI and runs the provided command right away.
 * <p>
 * It is generally recommended to use {@link #access(Command)} instead of
 * this method for accessing a session from a different thread as
 * {@link #access(Command)} can be used while holding the lock of another
 * session. To avoid causing deadlocks, this methods throws an exception if
 * it is detected than another session is also locked by the current thread.
 * <p>
 * This method behaves differently than {@link #access(Command)} in some
 * situations:
 * <ul>
 * <li>If the current thread is currently holding the lock of the session,
 * {@link #accessSynchronously(Command)} runs the task right away whereas
 * {@link #access(Command)} defers the task to a later point in time.</li>
 * <li>If some other thread is currently holding the lock for the session,
 * {@link #accessSynchronously(Command)} blocks while waiting for the lock
 * to be available whereas {@link #access(Command)} defers the task to a
 * later point in time.</li>
 * </ul>
 *
 * @since 7.1
 *
 * @param command
 *            the command which accesses the UI
 * @throws UIDetachedException
 *             if the UI is not attached to a session (and locking can
 *             therefore not be done)
 * @throws IllegalStateException
 *             if the current thread holds the lock for another session
 *
 * @see #access(Command)
 * @see VaadinSession#accessSynchronously(Command)
 */
public void accessSynchronously(Command command) throws UIDetachedException {
    Map<Class<?>, CurrentInstance> old = null;
    VaadinSession session = getSession();
    if (session == null) {
        throw new UIDetachedException();
    }
    VaadinService.verifyNoOtherSessionLocked(session);
    session.lock();
    try {
        if (getSession() == null) {
            // acquired the lock.
            throw new UIDetachedException();
        }
        old = CurrentInstance.setCurrent(this);
        command.execute();
    } finally {
        session.unlock();
        if (old != null) {
            CurrentInstance.restoreInstances(old);
        }
    }
}
Also used : CurrentInstance(com.vaadin.flow.internal.CurrentInstance) VaadinSession(com.vaadin.flow.server.VaadinSession)

Aggregations

VaadinSession (com.vaadin.flow.server.VaadinSession)26 UI (com.vaadin.flow.component.UI)9 VaadinService (com.vaadin.flow.server.VaadinService)9 Before (org.junit.Before)6 DefaultInstantiator (com.vaadin.flow.di.DefaultInstantiator)4 VaadinServletRequest (com.vaadin.flow.server.VaadinServletRequest)4 SpringVaadinSession (com.vaadin.flow.spring.SpringVaadinSession)4 Test (org.junit.Test)4 CurrentInstance (com.vaadin.flow.internal.CurrentInstance)3 DeploymentConfiguration (com.vaadin.flow.function.DeploymentConfiguration)2 SessionExpiredException (com.vaadin.flow.server.SessionExpiredException)2 SystemMessages (com.vaadin.flow.server.SystemMessages)2 VaadinServlet (com.vaadin.flow.server.VaadinServlet)2 VaadinServletService (com.vaadin.flow.server.VaadinServletService)2 InvalidUIDLSecurityKeyException (com.vaadin.flow.server.communication.ServerRpcHandler.InvalidUIDLSecurityKeyException)2 PushMode (com.vaadin.flow.shared.communication.PushMode)2 JsonException (elemental.json.JsonException)2 IOException (java.io.IOException)2 Serializable (java.io.Serializable)2 Field (java.lang.reflect.Field)2