Search in sources :

Example 6 with Action

use of org.atmosphere.cpr.Action in project cxf by apache.

the class DefaultProtocolInterceptor method inspect.

@Override
public Action inspect(final AtmosphereResource r) {
    LOG.log(Level.FINE, "inspect");
    if (AtmosphereResource.TRANSPORT.WEBSOCKET != r.transport() && AtmosphereResource.TRANSPORT.SSE != r.transport() && AtmosphereResource.TRANSPORT.POLLING != r.transport()) {
        LOG.fine("Skipping ignorable request");
        return Action.CONTINUE;
    }
    if (AtmosphereResource.TRANSPORT.POLLING == r.transport()) {
        final String saruuid = (String) r.getRequest().getAttribute(ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
        final AtmosphereResponse suspendedResponse = suspendedResponses.get(saruuid);
        LOG.fine("Attaching a proxy writer to suspended response");
        r.getResponse().asyncIOWriter(new AtmosphereInterceptorWriter() {

            @Override
            public AsyncIOWriter write(AtmosphereResponse r, String data) throws IOException {
                suspendedResponse.write(data);
                suspendedResponse.flushBuffer();
                return this;
            }

            @Override
            public AsyncIOWriter write(AtmosphereResponse r, byte[] data) throws IOException {
                suspendedResponse.write(data);
                suspendedResponse.flushBuffer();
                return this;
            }

            @Override
            public AsyncIOWriter write(AtmosphereResponse r, byte[] data, int offset, int length) throws IOException {
                suspendedResponse.write(data, offset, length);
                suspendedResponse.flushBuffer();
                return this;
            }

            @Override
            public void close(AtmosphereResponse response) throws IOException {
            }
        });
        // REVISIT we need to keep this response's asyncwriter alive so that data can be written to the
        // suspended response, but investigate if there is a better alternative.
        r.getResponse().destroyable(false);
        return Action.CONTINUE;
    }
    r.addEventListener(new AtmosphereResourceEventListenerAdapter() {

        @Override
        public void onSuspend(AtmosphereResourceEvent event) {
            final String srid = (String) event.getResource().getRequest().getAttribute(ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
            LOG.log(Level.FINE, "Registrering suspended resource: {}", srid);
            suspendedResponses.put(srid, event.getResource().getResponse());
            AsyncIOWriter writer = event.getResource().getResponse().getAsyncIOWriter();
            if (writer instanceof AtmosphereInterceptorWriter) {
                ((AtmosphereInterceptorWriter) writer).interceptor(interceptor);
            }
        }

        @Override
        public void onDisconnect(AtmosphereResourceEvent event) {
            super.onDisconnect(event);
            final String srid = (String) event.getResource().getRequest().getAttribute(ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
            LOG.log(Level.FINE, "Unregistrering suspended resource: {}", srid);
            suspendedResponses.remove(srid);
        }
    });
    AtmosphereRequest request = r.getRequest();
    if (request.getAttribute(REQUEST_DISPATCHED) == null) {
        AtmosphereResponse response = null;
        AtmosphereFramework framework = r.getAtmosphereConfig().framework();
        try {
            byte[] data = WebSocketUtils.readBody(request.getInputStream());
            if (data.length == 0) {
                if (AtmosphereResource.TRANSPORT.WEBSOCKET == r.transport() || AtmosphereResource.TRANSPORT.SSE == r.transport()) {
                    r.suspend();
                    return Action.SUSPEND;
                }
                return Action.CANCELLED;
            }
            if (LOG.isLoggable(Level.FINE)) {
                LOG.log(Level.FINE, "inspecting data {0}", new String(data));
            }
            try {
                AtmosphereRequest ar = createAtmosphereRequest(request, data);
                response = new WrappedAtmosphereResponse(r.getResponse(), ar);
                ar.localAttributes().put(REQUEST_DISPATCHED, "true");
                String refid = ar.getHeader(WebSocketConstants.DEFAULT_REQUEST_ID_KEY);
                if (refid != null) {
                    ar.localAttributes().put(WebSocketConstants.DEFAULT_REQUEST_ID_KEY, refid);
                }
                // This is a new request, we must clean the Websocket AtmosphereResource.
                request.removeAttribute(FrameworkConfig.INJECTED_ATMOSPHERE_RESOURCE);
                response.request(ar);
                attachWriter(r);
                Action action = framework.doCometSupport(ar, response);
                if (action.type() == Action.TYPE.SUSPEND) {
                    ar.destroyable(false);
                    response.destroyable(false);
                }
            } catch (Exception e) {
                LOG.log(Level.WARNING, "Error during request dispatching", e);
                if (response == null) {
                    response = new WrappedAtmosphereResponse(r.getResponse(), request);
                }
                if (e instanceof InvalidPathException) {
                    response.setIntHeader(WebSocketUtils.SC_KEY, 400);
                } else {
                    response.setIntHeader(WebSocketUtils.SC_KEY, 500);
                }
                OutputStream out = response.getOutputStream();
                out.write(createResponse(response, null, true));
                out.close();
            }
            return Action.CANCELLED;
        } catch (IOException e) {
            LOG.log(Level.WARNING, "Error during protocol processing", e);
        }
    } else {
        request.destroyable(false);
    }
    return Action.CONTINUE;
}
Also used : AtmosphereResponse(org.atmosphere.cpr.AtmosphereResponse) Action(org.atmosphere.cpr.Action) ServletOutputStream(javax.servlet.ServletOutputStream) OutputStream(java.io.OutputStream) CachedOutputStream(org.apache.cxf.io.CachedOutputStream) AsyncIOWriter(org.atmosphere.cpr.AsyncIOWriter) IOException(java.io.IOException) InvalidPathException(org.apache.cxf.transport.websocket.InvalidPathException) IOException(java.io.IOException) InvalidPathException(org.apache.cxf.transport.websocket.InvalidPathException) AtmosphereResourceEventListenerAdapter(org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter) AtmosphereRequest(org.atmosphere.cpr.AtmosphereRequest) AtmosphereFramework(org.atmosphere.cpr.AtmosphereFramework) AtmosphereResourceEvent(org.atmosphere.cpr.AtmosphereResourceEvent) AtmosphereInterceptorWriter(org.atmosphere.cpr.AtmosphereInterceptorWriter)

Example 7 with Action

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

the class DefaultWebSocketProcessor method configure.

public WebSocketProcessor configure(AtmosphereConfig config) {
    this.framework = config.framework();
    this.webSocketProtocol = framework.getWebSocketProtocol();
    destroyable = Boolean.parseBoolean(framework.getAtmosphereConfig().getInitParameter(RECYCLE_ATMOSPHERE_REQUEST_RESPONSE));
    executeAsync = Boolean.parseBoolean(framework.getAtmosphereConfig().getInitParameter(WEBSOCKET_PROTOCOL_EXECUTION));
    allow1005StatusCode = Boolean.parseBoolean(framework.getAtmosphereConfig().getInitParameter(ALLOW_WEBSOCKET_STATUS_CODE_1005_AS_DISCONNECT));
    String s = framework.getAtmosphereConfig().getInitParameter(IN_MEMORY_STREAMING_BUFFER_SIZE);
    if (s != null) {
        byteBufferMaxSize = Integer.parseInt(s);
        charBufferMaxSize = byteBufferMaxSize;
    }
    if (executeAsync) {
        asyncExecutor = ExecutorsFactory.getAsyncOperationExecutor(config, "WebSocket");
    } else {
        asyncExecutor = VoidExecutorService.VOID;
    }
    scheduler = ExecutorsFactory.getScheduler(config);
    optimizeMapping();
    closingTime = Long.valueOf(config.getInitParameter(ApplicationConfig.CLOSED_ATMOSPHERE_THINK_TIME, "0"));
    invokeInterceptors = Boolean.valueOf(config.getInitParameter(INVOKE_ATMOSPHERE_INTERCEPTOR_ON_WEBSOCKET_MESSAGE, "true"));
    config.startupHook(framework -> {
        if (AsynchronousProcessor.class.isAssignableFrom(framework.getAsyncSupport().getClass())) {
            asynchronousProcessor = AsynchronousProcessor.class.cast(framework.getAsyncSupport());
        } else {
            asynchronousProcessor = new AsynchronousProcessor(framework.getAtmosphereConfig()) {

                @Override
                public Action service(AtmosphereRequest req, AtmosphereResponse res) throws IOException, ServletException {
                    return framework.getAsyncSupport().service(req, res);
                }
            };
        }
    });
    return this;
}
Also used : ServletException(jakarta.servlet.ServletException) AtmosphereResponse(org.atmosphere.cpr.AtmosphereResponse) Action(org.atmosphere.cpr.Action) AtmosphereRequest(org.atmosphere.cpr.AtmosphereRequest) AsynchronousProcessor(org.atmosphere.cpr.AsynchronousProcessor) IOException(java.io.IOException)

Example 8 with Action

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

the class DefaultWebSocketProcessor method invokeInterceptors.

private void invokeInterceptors(WebSocketHandlerProxy webSocketHandler, WebSocket webSocket, Object webSocketMessageAsBody, int offset, int length) throws IOException {
    AtmosphereResourceImpl resource = AtmosphereResourceImpl.class.cast(webSocket.resource());
    if (resource == null) {
        return;
    }
    AtmosphereRequest request = resource.getRequest(false);
    if (String.class.isAssignableFrom(webSocketMessageAsBody.getClass())) {
        request.body(String.class.cast(webSocketMessageAsBody));
    } else if (Reader.class.isAssignableFrom(webSocketMessageAsBody.getClass())) {
        request.body(Reader.class.cast(webSocketMessageAsBody));
    } else if (InputStream.class.isAssignableFrom(webSocketMessageAsBody.getClass())) {
        request.body(InputStream.class.cast(webSocketMessageAsBody));
    } else {
        request.body(new ByteArrayInputStream((byte[]) webSocketMessageAsBody, offset, length));
    }
    String path = webSocketHandler.proxied.getClass().isAnnotationPresent(WebSocketHandlerService.class) ? webSocketHandler.proxied.getClass().getAnnotation(WebSocketHandlerService.class).path() : "/";
    AtmosphereFramework.AtmosphereHandlerWrapper w = framework.getAtmosphereHandlers().get(framework.normalizePath(path));
    List<AtmosphereInterceptor> l;
    if (w == null) {
        l = framework.interceptors();
    } else {
        l = w.interceptors;
    }
    // Globally defined
    int tracing = 0;
    Action a = asynchronousProcessor.invokeInterceptors(l, resource, tracing);
    if (a.type() != Action.TYPE.CONTINUE && a.type() != Action.TYPE.SKIP_ATMOSPHEREHANDLER) {
        return;
    }
    try {
        // Unit test mock the request and will throw NPE.
        boolean skipAtmosphereHandler = request.getAttribute(SKIP_ATMOSPHEREHANDLER.name()) != null ? (Boolean) request.getAttribute(SKIP_ATMOSPHEREHANDLER.name()) : Boolean.FALSE;
        if (!skipAtmosphereHandler) {
            try {
                if (String.class.isAssignableFrom(webSocketMessageAsBody.getClass())) {
                    webSocketHandler.onTextMessage(webSocket, String.class.cast(webSocketMessageAsBody));
                } else if (Reader.class.isAssignableFrom(webSocketMessageAsBody.getClass())) {
                    WebSocketStreamingHandler.class.cast(webSocketHandler.proxied).onTextStream(webSocket, Reader.class.cast(webSocketMessageAsBody));
                } else if (InputStream.class.isAssignableFrom(webSocketMessageAsBody.getClass())) {
                    WebSocketStreamingHandler.class.cast(webSocketHandler.proxied()).onBinaryStream(webSocket, InputStream.class.cast(webSocketMessageAsBody));
                } else {
                    webSocketHandler.onByteMessage(webSocket, (byte[]) webSocketMessageAsBody, offset, length);
                }
            } catch (IOException t) {
                resource.onThrowable(t);
                throw t;
            }
        }
        request.setAttribute(SKIP_ATMOSPHEREHANDLER.name(), Boolean.FALSE);
    } finally {
        asynchronousProcessor.postInterceptors(l, resource);
    }
}
Also used : AtmosphereInterceptor(org.atmosphere.cpr.AtmosphereInterceptor) Action(org.atmosphere.cpr.Action) WebSocketHandlerService(org.atmosphere.config.service.WebSocketHandlerService) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Reader(java.io.Reader) StringReader(java.io.StringReader) IOException(java.io.IOException) AtmosphereRequest(org.atmosphere.cpr.AtmosphereRequest) ByteArrayInputStream(java.io.ByteArrayInputStream) AtmosphereFramework(org.atmosphere.cpr.AtmosphereFramework) AtmosphereResourceImpl(org.atmosphere.cpr.AtmosphereResourceImpl)

Example 9 with Action

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

the class SimpleRestInterceptor method inspect.

@Override
public Action inspect(final AtmosphereResource r) {
    if (AtmosphereResource.TRANSPORT.WEBSOCKET != r.transport() && AtmosphereResource.TRANSPORT.SSE != r.transport() && AtmosphereResource.TRANSPORT.POLLING != r.transport()) {
        LOG.debug("Skipping for non websocket request");
        return Action.CONTINUE;
    }
    if (AtmosphereResource.TRANSPORT.POLLING == r.transport()) {
        final String saruuid = (String) r.getRequest().getAttribute(ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
        final AtmosphereResponse suspendedResponse = suspendedResponses.get(saruuid);
        LOG.debug("Attaching a proxy writer to suspended response");
        r.getResponse().asyncIOWriter(new AtmosphereInterceptorWriter() {

            @Override
            public AsyncIOWriter write(AtmosphereResponse r, String data) throws IOException {
                suspendedResponse.write(data);
                suspendedResponse.flushBuffer();
                return this;
            }

            @Override
            public AsyncIOWriter write(AtmosphereResponse r, byte[] data) throws IOException {
                suspendedResponse.write(data);
                suspendedResponse.flushBuffer();
                return this;
            }

            @Override
            public AsyncIOWriter write(AtmosphereResponse r, byte[] data, int offset, int length) throws IOException {
                suspendedResponse.write(data, offset, length);
                suspendedResponse.flushBuffer();
                return this;
            }

            @Override
            public void close(AtmosphereResponse response) throws IOException {
            }
        });
        // REVISIT we need to keep this response's asyncwriter alive so that data can be written to the
        // suspended response, but investigate if there is a better alternative.
        r.getResponse().destroyable(false);
        return Action.CONTINUE;
    }
    r.addEventListener(new AtmosphereResourceEventListenerAdapter() {

        @Override
        public void onSuspend(AtmosphereResourceEvent event) {
            final String srid = (String) event.getResource().getRequest().getAttribute(ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
            LOG.debug("Registrering suspended resource: {}", srid);
            suspendedResponses.put(srid, event.getResource().getResponse());
            AsyncIOWriter writer = event.getResource().getResponse().getAsyncIOWriter();
            if (writer == null) {
                writer = new AtmosphereInterceptorWriter();
                r.getResponse().asyncIOWriter(writer);
            }
            if (writer instanceof AtmosphereInterceptorWriter) {
                ((AtmosphereInterceptorWriter) writer).interceptor(interceptor);
            }
        }

        @Override
        public void onDisconnect(AtmosphereResourceEvent event) {
            super.onDisconnect(event);
            final String srid = (String) event.getResource().getRequest().getAttribute(ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
            LOG.debug("Unregistrering suspended resource: {}", srid);
            suspendedResponses.remove(srid);
        }
    });
    AtmosphereRequest request = r.getRequest();
    if (request.getAttribute(REQUEST_DISPATCHED) == null) {
        try {
            // REVISIT use a more efficient approach for the detached mode (i.e.,avoid reading the message into a string)
            // read the message entity and dispatch a service call
            String body = IOUtils.readEntirelyAsString(r).toString();
            LOG.debug("Request message: '{}'", body);
            if (body.length() == 0) {
                // TODO we might want to move this heartbeat scheduling after the handshake phase (if that is added)
                if ((AtmosphereResource.TRANSPORT.WEBSOCKET == r.transport() || AtmosphereResource.TRANSPORT.SSE == r.transport()) && request.getAttribute(HEARTBEAT_SCHEDULED) == null) {
                    r.suspend();
                    scheduleHeartbeat(r);
                    request.setAttribute(HEARTBEAT_SCHEDULED, "true");
                    return Action.SUSPEND;
                }
                return Action.CANCELLED;
            }
            AtmosphereRequest ar = createAtmosphereRequest(request, body);
            if (ar == null) {
                return Action.CANCELLED;
            }
            AtmosphereResponse response = r.getResponse();
            ar.localAttributes().put(REQUEST_DISPATCHED, "true");
            request.removeAttribute(FrameworkConfig.INJECTED_ATMOSPHERE_RESOURCE);
            response.request(ar);
            attachWriter(r);
            Action action = r.getAtmosphereConfig().framework().doCometSupport(ar, response);
            if (action.type() == Action.TYPE.SUSPEND) {
                ar.destroyable(false);
                response.destroyable(false);
            }
            return Action.CANCELLED;
        } catch (IOException | ServletException e) {
            LOG.error("Failed to process", e);
        }
    }
    return Action.CONTINUE;
}
Also used : AtmosphereResponse(org.atmosphere.cpr.AtmosphereResponse) Action(org.atmosphere.cpr.Action) AsyncIOWriter(org.atmosphere.cpr.AsyncIOWriter) IOException(java.io.IOException) ServletException(jakarta.servlet.ServletException) AtmosphereResourceEventListenerAdapter(org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter) AtmosphereRequest(org.atmosphere.cpr.AtmosphereRequest) AtmosphereResourceEvent(org.atmosphere.cpr.AtmosphereResourceEvent) AtmosphereInterceptorWriter(org.atmosphere.cpr.AtmosphereInterceptorWriter)

Aggregations

Action (org.atmosphere.cpr.Action)9 IOException (java.io.IOException)6 AtmosphereRequest (org.atmosphere.cpr.AtmosphereRequest)5 ServletException (jakarta.servlet.ServletException)4 AtmosphereResourceImpl (org.atmosphere.cpr.AtmosphereResourceImpl)4 AtmosphereResponse (org.atmosphere.cpr.AtmosphereResponse)4 AsynchronousProcessor (org.atmosphere.cpr.AsynchronousProcessor)3 AtmosphereFramework (org.atmosphere.cpr.AtmosphereFramework)3 Future (java.util.concurrent.Future)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 AsyncIOWriter (org.atmosphere.cpr.AsyncIOWriter)2 AtmosphereInterceptorWriter (org.atmosphere.cpr.AtmosphereInterceptorWriter)2 AtmosphereResource (org.atmosphere.cpr.AtmosphereResource)2 AtmosphereResourceEvent (org.atmosphere.cpr.AtmosphereResourceEvent)2 AtmosphereResourceEventListenerAdapter (org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 Reader (java.io.Reader)1 StringReader (java.io.StringReader)1