Example usage for javax.servlet AsyncContext dispatch

List of usage examples for javax.servlet AsyncContext dispatch

Introduction

In this page you can find the example usage for javax.servlet AsyncContext dispatch.

Prototype

public void dispatch();

Source Link

Document

Dispatches the request and response objects of this AsyncContext to the servlet container.

Usage

From source file:com.boylesoftware.web.AsynchronousExecutor.java

@Override
public void onTimeout(final AsyncEvent event) {

    final boolean debug = this.log.isDebugEnabled();
    if (debug)/*  ww  w.  j  a v  a  2s .c  o  m*/
        this.log.debug("async event: timeout");

    this.timedOut = true;

    this.cleanup();

    if (debug)
        this.log.debug("recycling router request " + this.routerReq);
    RouterRequestLifecycle.recycle(this.routerReq);

    this.routerReq = null;
    this.asyncContext = null;
    this.webapp = null;

    if (this.executorThread != null)
        this.executorThread.interrupt();

    final AsyncContext asyncCtx = event.getAsyncContext();
    Router.setAsyncException(asyncCtx.getRequest(), new ServiceUnavailableException());
    if (debug)
        this.log.debug("dispatching service unavailable exception back to" + " the router");
    asyncCtx.dispatch();
}

From source file:org.apache.vysper.xmpp.extension.xep0124.BoshBackedSessionContext.java

/**
 * Writes a server-to-client XMPP stanza as a BOSH response (wrapped in a <body/> element) if there are 
 * available HTTP requests to respond to, otherwise the response is queued to be sent later 
 * (when a HTTP request becomes available).
 * <p>/*from   www .j  a  va2s  .  c o m*/
 * (package access)
 * 
 * @param responseStanza The BOSH response to write
 */
/*package*/ void writeBoshResponse(Stanza responseStanza) {
    if (responseStanza == null)
        throw new IllegalArgumentException();
    final boolean isEmtpyResponse = responseStanza == BoshStanzaUtils.EMPTY_BOSH_RESPONSE;

    final ArrayList<BoshRequest> boshRequestsForRID = new ArrayList<BoshRequest>(1);
    BoshResponse boshResponse;
    final Long rid;
    synchronized (requestsWindow) {
        BoshRequest req = requestsWindow.pollNext();
        if (req == null) {
            if (isEmtpyResponse)
                return; // do not delay empty responses, everything's good.
            // delay sending until request comes available
            final boolean accepted = delayedResponseQueue.offer(responseStanza);
            if (!accepted) {
                LOGGER.debug(
                        "SID = " + getSessionId()
                                + " - stanza not queued. BOSH delayedResponseQueue is full: {}",
                        delayedResponseQueue.size());
                // TODO do not silently drop this stanza
            }
            return;
        }

        rid = req.getRid();
        // in rare cases, we have same RID in two separate requests
        boshRequestsForRID.add(req);

        // collect more requests for this RID
        while (rid.equals(requestsWindow.firstRid())) {
            final BoshRequest sameRidRequest = requestsWindow.pollNext();
            boshRequestsForRID.add(sameRidRequest);
            LOGGER.warn("SID = " + getSessionId() + " - rid = {} - multi requests ({}) per RID.", rid,
                    boshRequestsForRID.size());
        }

        long highestContinuousRid = requestsWindow.getHighestContinuousRid();
        final Long ack = rid.equals(highestContinuousRid) ? null : highestContinuousRid;
        boshResponse = getBoshResponse(responseStanza, ack);
        if (LOGGER.isDebugEnabled()) {
            String emptyHint = isEmtpyResponse ? "empty " : StringUtils.EMPTY;
            LOGGER.debug("SID = " + getSessionId() + " - rid = " + rid + " - BOSH writing {}response: {}",
                    emptyHint, new String(boshResponse.getContent()));
        }
    }

    synchronized (sentResponses) {
        if (isResponseSavable(boshRequestsForRID.get(0), responseStanza)) {
            sentResponses.put(rid, boshResponse);
            // The number of responses to non-pause requests kept in the buffer SHOULD be either the same as the maximum
            // number of simultaneous requests allowed or, if Acknowledgements are being used, the number of responses
            // that have not yet been acknowledged (this part is handled in insertRequest(BoshRequest)), or 
            // the hard limit maximumSentResponses (not in the specification) that prevents excessive memory consumption.
            if (sentResponses.size() > maximumSentResponses
                    || (!isClientAcknowledgements() && sentResponses.size() > parallelRequestsCount)) {
                final Long key = sentResponses.firstKey();
                sentResponsesBacklog.add(key, sentResponses.remove(key));
            }
        }
    }

    if (sentResponses.size() > maximumSentResponses + 10) {
        synchronized (sentResponses) {
            LOGGER.warn("stored sent responses ({}) exeeds maximum ({}). purging.", sentResponses.size(),
                    maximumSentResponses);
            while (sentResponses.size() > maximumSentResponses) {
                final Long key = sentResponses.firstKey();
                sentResponsesBacklog.add(key, sentResponses.remove(key));
            }
        }
    }

    for (BoshRequest boshRequest : boshRequestsForRID) {
        try {
            final AsyncContext asyncContext = saveResponse(boshRequest, boshResponse);
            asyncContext.dispatch();
        } catch (Exception e) {
            LOGGER.warn("SID = " + getSessionId() + " - exception in async processing rid = {}",
                    boshRequest.getRid(), e);
        }
    }
    setLatestWriteTimestamp();
    updateInactivityChecker();
}

From source file:org.apache.vysper.xmpp.extension.xep0124.BoshBackedSessionContext.java

/**
 * Writes an error to the client and closes the connection
 * @param condition the error condition/*from ww w .j  av a2s  .c  o  m*/
 */
protected void sendError(BoshRequest req, String condition) {
    req = req == null ? requestsWindow.pollNext() : req;
    if (req == null) {
        LOGGER.warn("SID = " + getSessionId() + " - no request for sending BOSH error " + condition);
        endSession(SessionTerminationCause.CONNECTION_ABORT);
        return;
    }
    final Long rid = req.getRid();
    Stanza body = BoshStanzaUtils.createTerminateResponse(condition).build();
    BoshResponse boshResponse = getBoshResponse(body, null);
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("SID = " + getSessionId() + " - rid = {} - BOSH writing response: {}", rid,
                new String(boshResponse.getContent()));
    }

    try {
        final AsyncContext asyncContext = saveResponse(req, boshResponse);
        asyncContext.dispatch();
    } catch (Exception e) {
        LOGGER.warn("SID = " + getSessionId() + " - exception in async processing", e);
    }
    close();
}

From source file:org.apache.vysper.xmpp.extension.xep0124.BoshBackedSessionContext.java

public void close() {
    // respond to all the queued HTTP requests with termination responses
    synchronized (requestsWindow) {
        BoshRequest next;/*from  w ww .  ja  va2s .co  m*/
        while ((next = requestsWindow.pollNext()) != null) {
            Stanza body = BoshStanzaUtils.TERMINATE_BOSH_RESPONSE;
            BoshResponse boshResponse = getBoshResponse(body, null);
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("SID = " + getSessionId() + " - rid = {} - BOSH writing response: {}",
                        next.getRid(), new String(boshResponse.getContent()));
            }

            try {
                final AsyncContext asyncContext = saveResponse(next, boshResponse);
                asyncContext.dispatch();
            } catch (Exception e) {
                LOGGER.warn("SID = " + getSessionId() + " - exception in async processing", e);
            }
        }

        inactivityChecker.updateExpireTime(this, lastInactivityExpireTime, null);
        lastInactivityExpireTime = null;
    }

    LOGGER.info("SID = " + getSessionId() + " - session closed");
}

From source file:org.apache.vysper.xmpp.extension.xep0124.BoshBackedSessionContext.java

protected void resendResponse(BoshRequest br, Long rid, BoshResponse boshResponse) {
    if (boshResponse == null) {
        LOGGER.debug("SID = " + getSessionId()
                + " - rid = {} - BOSH response could not (no longer) be retrieved for resending.", rid);
        return;//from   w  w  w .j av a  2  s.  c o  m
    }
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("SID = " + getSessionId() + " - rid = {} - BOSH writing response (resending): {}", rid,
                new String(boshResponse.getContent()));
    }

    try {
        final AsyncContext asyncContext = saveResponse(br, boshResponse);
        asyncContext.dispatch();
    } catch (Exception e) {
        LOGGER.warn("SID = " + getSessionId() + " - exception in async processing", e);
    }
    setLatestWriteTimestamp();
    updateInactivityChecker();
}

From source file:org.apache.vysper.xmpp.extension.xep0124.BoshBackedSessionContextTest.java

@Test
public void testWrite0() {
    HttpServletRequest httpServletRequest = mocksControl.createMock(HttpServletRequest.class);
    AsyncContext asyncContext = mocksControl.createMock(AsyncContext.class);
    expect(httpServletRequest.startAsync()).andReturn(asyncContext);
    expectLastCall().atLeastOnce();//w  w w . j  av a 2 s.  c om
    expect(httpServletRequest.getAsyncContext()).andReturn(asyncContext);
    expectLastCall().atLeastOnce();
    asyncContext.setTimeout(anyLong());
    asyncContext.dispatch();
    expectLastCall().atLeastOnce();
    httpServletRequest.setAttribute(eq(BOSH_REQUEST_ATTRIBUTE), EasyMock.<BoshRequest>notNull());
    asyncContext.addListener(EasyMock.<AsyncListener>anyObject());
    Capture<BoshResponse> captured = new Capture<BoshResponse>();
    httpServletRequest.setAttribute(eq(BOSH_RESPONSE_ATTRIBUTE), EasyMock.<BoshResponse>capture(captured));
    mocksControl.replay();

    BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(serverRuntimeContext, null,
            inactivityChecker);
    Stanza body = BoshStanzaUtils.EMPTY_BOSH_RESPONSE;
    boshBackedSessionContext.insertRequest(new BoshRequest(httpServletRequest, body, 1L));
    boshBackedSessionContext.writeBoshResponse(body);
    mocksControl.verify();

    BoshResponse boshResponse = captured.getValue();
    assertEquals(BoshServlet.XML_CONTENT_TYPE, boshResponse.getContentType());
    assertEquals(new Renderer(body).getComplete(), new String(boshResponse.getContent()));
}

From source file:org.apache.vysper.xmpp.extension.xep0124.BoshBackedSessionContextTest.java

@Test
public void testRequestExpired() throws IOException {
    Stanza emtpyStanza = BoshStanzaUtils.EMPTY_BOSH_RESPONSE;

    // addRequest
    HttpServletRequest httpServletRequest = mocksControl.createMock(HttpServletRequest.class);
    AsyncContext asyncContext = mocksControl.createMock(AsyncContext.class);
    expect(httpServletRequest.startAsync()).andReturn(asyncContext).atLeastOnce();
    expect(httpServletRequest.getAsyncContext()).andReturn(asyncContext).atLeastOnce();
    asyncContext.setTimeout(anyLong());//from   w  w  w . j  a  va 2s .  c  o m
    httpServletRequest.setAttribute(eq(BOSH_REQUEST_ATTRIBUTE), EasyMock.<BoshRequest>notNull());

    expect(asyncContext.getRequest()).andReturn(httpServletRequest).atLeastOnce();
    asyncContext.dispatch();
    expectLastCall().atLeastOnce();

    Capture<AsyncListener> listenerCaptured = new Capture<AsyncListener>();
    asyncContext.addListener(EasyMock.<AsyncListener>capture(listenerCaptured));

    AsyncEvent asyncEvent = mocksControl.createMock(AsyncEvent.class);

    BoshRequest br = new BoshRequest(httpServletRequest, emtpyStanza, 1L);

    // requestExpired
    expect(httpServletRequest.getAttribute(BOSH_REQUEST_ATTRIBUTE)).andReturn(br);
    Capture<BoshResponse> responseCaptured = new Capture<BoshResponse>();
    httpServletRequest.setAttribute(eq(BOSH_RESPONSE_ATTRIBUTE),
            EasyMock.<BoshResponse>capture(responseCaptured));

    // write0
    mocksControl.replay();
    BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(serverRuntimeContext, null,
            inactivityChecker);

    boshBackedSessionContext.insertRequest(br);
    listenerCaptured.getValue().onTimeout(asyncEvent);
    mocksControl.verify();

    assertEquals(new Renderer(emtpyStanza).getComplete(), new String(responseCaptured.getValue().getContent()));
    assertEquals(BoshServlet.XML_CONTENT_TYPE, responseCaptured.getValue().getContentType());
}

From source file:org.apache.vysper.xmpp.extension.xep0124.BoshBackedSessionContextTest.java

@Test
public void testAddRequest() {
    // addRequest
    HttpServletRequest httpServletRequest1 = mocksControl.createMock(HttpServletRequest.class);
    HttpServletRequest httpServletRequest2 = mocksControl.createMock(HttpServletRequest.class);
    AsyncContext asyncContext1 = mocksControl.createMock(AsyncContext.class);
    AsyncContext asyncContext2 = mocksControl.createMock(AsyncContext.class);
    BoshStanzaUtils boshStanzaUtils = mocksControl.createMock(BoshStanzaUtils.class);

    expect(httpServletRequest1.startAsync()).andReturn(asyncContext1).atLeastOnce();
    expect(httpServletRequest1.getAsyncContext()).andReturn(asyncContext1).atLeastOnce();

    expect(httpServletRequest2.startAsync()).andReturn(asyncContext2).atLeastOnce();
    expect(httpServletRequest2.getAsyncContext()).andReturn(asyncContext2).anyTimes();

    asyncContext1.setTimeout(anyLong());
    Capture<BoshRequest> br1 = new Capture<BoshRequest>();
    httpServletRequest1.setAttribute(eq(BOSH_REQUEST_ATTRIBUTE), EasyMock.<BoshRequest>capture(br1));

    asyncContext2.setTimeout(anyLong());
    Capture<BoshRequest> br2 = new Capture<BoshRequest>();
    httpServletRequest2.setAttribute(eq(BOSH_REQUEST_ATTRIBUTE), EasyMock.<BoshRequest>capture(br2));

    asyncContext1.addListener(EasyMock.<AsyncListener>anyObject());
    asyncContext2.addListener(EasyMock.<AsyncListener>anyObject());

    asyncContext1.dispatch();
    expectLastCall().atLeastOnce();/*from w  w w.  j  av  a  2s  .com*/

    Stanza body = BoshStanzaUtils.EMPTY_BOSH_RESPONSE;

    // write0
    Capture<BoshResponse> captured = new Capture<BoshResponse>();
    httpServletRequest1.setAttribute(eq(BOSH_RESPONSE_ATTRIBUTE), EasyMock.<BoshResponse>capture(captured));

    mocksControl.replay();
    BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(serverRuntimeContext, null,
            inactivityChecker);

    boshBackedSessionContext.setHold(2);
    // consecutive writes with RID 1 and 2
    long maxRID = 2L;
    boshBackedSessionContext.insertRequest(new BoshRequest(httpServletRequest1, body, 1L));
    boshBackedSessionContext.insertRequest(new BoshRequest(httpServletRequest2, body, maxRID));
    boshBackedSessionContext.writeBoshResponse(body);
    mocksControl.verify();

    assertEquals(httpServletRequest1, br1.getValue().getHttpServletRequest());
    assertEquals(httpServletRequest2, br2.getValue().getHttpServletRequest());

    // expect ack for newest/largest RID
    final Stanza ackedResponse = BoshStanzaUtils.addAttribute(body, "ack", Long.toString(maxRID));
    assertEquals(new Renderer(ackedResponse).getComplete(), new String(captured.getValue().getContent()));
    assertEquals(BoshServlet.XML_CONTENT_TYPE, captured.getValue().getContentType());
}

From source file:org.apache.vysper.xmpp.extension.xep0124.BoshBackedSessionContextTest.java

@Test
public void testAddRequestWithDelayedResponses() {
    HttpServletRequest httpServletRequest = mocksControl.createMock(HttpServletRequest.class);
    AsyncContext asyncContext = mocksControl.createMock(AsyncContext.class);
    expect(httpServletRequest.startAsync()).andReturn(asyncContext).atLeastOnce();
    expect(httpServletRequest.getAsyncContext()).andReturn(asyncContext).atLeastOnce();
    asyncContext.setTimeout(anyLong());/*from  w  w w .  java  2  s  . co  m*/
    httpServletRequest.setAttribute(eq(BOSH_REQUEST_ATTRIBUTE), EasyMock.<BoshRequest>notNull());

    asyncContext.addListener(EasyMock.<AsyncListener>anyObject());

    asyncContext.dispatch();
    expectLastCall().atLeastOnce();

    Stanza body = BoshStanzaUtils.createBoshStanzaBuilder().startInnerElement("presence").endInnerElement()
            .build();

    Capture<BoshResponse> captured = new Capture<BoshResponse>();
    httpServletRequest.setAttribute(eq(BOSH_RESPONSE_ATTRIBUTE), EasyMock.<BoshResponse>capture(captured));

    mocksControl.replay();

    BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(serverRuntimeContext, null,
            inactivityChecker);
    boshBackedSessionContext.writeBoshResponse(body); // queued for merging
    boshBackedSessionContext.writeBoshResponse(body); // queued for merging
    boshBackedSessionContext.writeBoshResponse(body); // queued for merging
    boshBackedSessionContext.insertRequest(new BoshRequest(httpServletRequest, body, 1L));

    mocksControl.verify();

    final String mergedAllBodiesStanza = new String(captured.getValue().getContent());
    assertEquals(3, StringUtils.countMatches(mergedAllBodiesStanza, "<presence"));
}