Search in sources :

Example 1 with AtmosphereResource

use of org.atmosphere.cpr.AtmosphereResource 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 AtmosphereResource

use of org.atmosphere.cpr.AtmosphereResource 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 3 with AtmosphereResource

use of org.atmosphere.cpr.AtmosphereResource in project atmosphere by Atmosphere.

the class BlockingIOCometSupport method suspend.

/**
 * Suspend the connection by blocking the current {@link Thread}
 *
 * @param action The {@link Action}
 * @param req    the {@link AtmosphereRequest}
 * @param res    the {@link AtmosphereResponse}
 */
protected void suspend(Action action, AtmosphereRequest req, AtmosphereResponse res) throws IOException, ServletException {
    final CountDownLatch latch = new CountDownLatch(1);
    req.setAttribute(LATCH, latch);
    boolean ok = true;
    AtmosphereResource resource = req.resource();
    if (resource != null) {
        try {
            resource.addEventListener(new OnResume() {

                @Override
                public void onResume(AtmosphereResourceEvent event) {
                    latch.countDown();
                }
            });
            if (action.timeout() != -1) {
                ok = latch.await(action.timeout(), TimeUnit.MILLISECONDS);
            } else {
                latch.await();
            }
        } catch (InterruptedException ex) {
            logger.trace("", ex);
        } finally {
            if (!ok) {
                timedout(req, res);
            } else {
                ((AtmosphereResourceImpl) resource).cancel();
            }
        }
    }
}
Also used : OnResume(org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter.OnResume) AtmosphereResource(org.atmosphere.cpr.AtmosphereResource) AtmosphereResourceEvent(org.atmosphere.cpr.AtmosphereResourceEvent) AtmosphereResourceImpl(org.atmosphere.cpr.AtmosphereResourceImpl) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 4 with AtmosphereResource

use of org.atmosphere.cpr.AtmosphereResource in project atmosphere by Atmosphere.

the class SessionBroadcasterCache method retrieveFromCache.

@Override
public List<Object> retrieveFromCache(String broadcasterId, String uuid) {
    if (uuid == null) {
        throw new IllegalArgumentException("AtmosphereResource can't be null");
    }
    List<Object> result = new ArrayList<>();
    try {
        AtmosphereResource r = config.resourcesFactory().find(uuid);
        if (r == null) {
            logger.trace("Invalid UUID {}", uuid);
            return result;
        }
        HttpSession session = r.session();
        if (session == null) {
            logger.error(ERROR_MESSAGE);
            return result;
        }
        String cacheHeaderTimeStr = (String) session.getAttribute(broadcasterId);
        if (cacheHeaderTimeStr == null)
            return result;
        long cacheHeaderTime = Long.parseLong(cacheHeaderTimeStr);
        return get(cacheHeaderTime);
    } catch (IllegalStateException ex) {
        logger.trace("", ex);
        logger.warn("The Session has been invalidated. Unable to retrieve cached messages");
        return Collections.emptyList();
    }
}
Also used : AtmosphereResource(org.atmosphere.cpr.AtmosphereResource) HttpSession(jakarta.servlet.http.HttpSession) ArrayList(java.util.ArrayList)

Example 5 with AtmosphereResource

use of org.atmosphere.cpr.AtmosphereResource in project atmosphere by Atmosphere.

the class AtmosphereServiceProcessor method handle.

@Override
public void handle(AtmosphereFramework framework, Class<Object> annotatedClass) {
    try {
        AtmosphereService a = annotatedClass.getAnnotation(AtmosphereService.class);
        framework.setBroadcasterCacheClassName(a.broadcasterCache().getName());
        atmosphereConfig(a.atmosphereConfig(), framework);
        framework.setDefaultBroadcasterClassName(a.broadcaster().getName());
        filters(a.broadcastFilters(), framework);
        LinkedList<AtmosphereInterceptor> l = new LinkedList<>();
        AtmosphereInterceptor aa = listeners(a.listeners(), framework);
        if (aa != null) {
            l.add(aa);
        }
        if (!a.servlet().isEmpty()) {
            final ReflectorServletProcessor r = framework.newClassInstance(ReflectorServletProcessor.class, ReflectorServletProcessor.class);
            r.setServletClassName(a.servlet());
            String mapping = a.path();
            AnnotationUtil.interceptorsForHandler(framework, Arrays.asList(a.interceptors()), l);
            if (!a.dispatch()) {
                AtmosphereHandler proxy = new AtmosphereServletProcessor() {

                    private String method = "GET";

                    @Override
                    public void onRequest(AtmosphereResource resource) throws IOException {
                        if (!resource.getRequest().getMethod().equalsIgnoreCase(method)) {
                            r.onRequest(resource);
                        }
                    }

                    @Override
                    public void onStateChange(AtmosphereResourceEvent event) throws IOException {
                        r.onStateChange(event);
                    }

                    @Override
                    public void destroy() {
                        r.destroy();
                    }

                    @Override
                    public void init(AtmosphereConfig config) throws ServletException {
                        String s = config.getInitParameter(ATMOSPHERERESOURCE_INTERCEPTOR_METHOD);
                        if (s != null) {
                            method = s;
                        }
                        r.init(config);
                    }
                };
                framework.addAtmosphereHandler(mapping, proxy, l);
            } else {
                framework.addAtmosphereHandler(mapping, r, l);
            }
        } else {
            interceptors(a.interceptors(), framework);
        }
    } catch (Throwable e) {
        logger.warn("", e);
    }
}
Also used : AtmosphereService(org.atmosphere.config.service.AtmosphereService) AtmosphereInterceptor(org.atmosphere.cpr.AtmosphereInterceptor) AtmosphereConfig(org.atmosphere.cpr.AtmosphereConfig) AtmosphereHandler(org.atmosphere.cpr.AtmosphereHandler) AtmosphereResource(org.atmosphere.cpr.AtmosphereResource) AtmosphereServletProcessor(org.atmosphere.cpr.AtmosphereServletProcessor) AtmosphereResourceEvent(org.atmosphere.cpr.AtmosphereResourceEvent) ReflectorServletProcessor(org.atmosphere.handler.ReflectorServletProcessor) LinkedList(java.util.LinkedList)

Aggregations

AtmosphereResource (org.atmosphere.cpr.AtmosphereResource)37 AtmosphereRequest (org.atmosphere.cpr.AtmosphereRequest)14 IOException (java.io.IOException)10 AtmosphereResourceImpl (org.atmosphere.cpr.AtmosphereResourceImpl)9 Broadcaster (org.atmosphere.cpr.Broadcaster)8 Test (org.junit.Test)7 UI (com.vaadin.flow.component.UI)5 SessionExpiredException (com.vaadin.flow.server.SessionExpiredException)4 VaadinServletRequest (com.vaadin.flow.server.VaadinServletRequest)4 VaadinSession (com.vaadin.flow.server.VaadinSession)4 InvalidUIDLSecurityKeyException (com.vaadin.flow.server.communication.ServerRpcHandler.InvalidUIDLSecurityKeyException)4 JsonException (elemental.json.JsonException)4 AsynchronousProcessor (org.atmosphere.cpr.AsynchronousProcessor)4 AtmosphereResourceEvent (org.atmosphere.cpr.AtmosphereResourceEvent)4 MockVaadinServletService (com.vaadin.flow.server.MockVaadinServletService)3 ServletException (jakarta.servlet.ServletException)3 HashSet (java.util.HashSet)3 Future (java.util.concurrent.Future)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 AtmosphereResourceEventImpl (org.atmosphere.cpr.AtmosphereResourceEventImpl)3