use of org.jboss.resteasy.spi.ResteasyAsynchronousResponse in project resteasy by resteasy.
the class AsynchronousResponseInjector method inject.
@Override
public Object inject(HttpRequest request, HttpResponse response, boolean unwrapAsync) {
ResteasyAsynchronousResponse asynchronousResponse = null;
if (timeout == -1) {
asynchronousResponse = request.getAsyncContext().suspend();
} else {
asynchronousResponse = request.getAsyncContext().suspend(timeout, unit);
}
ResourceMethodInvoker invoker = (ResourceMethodInvoker) request.getAttribute(ResourceMethodInvoker.class.getName());
invoker.initializeAsync(asynchronousResponse);
return asynchronousResponse;
}
use of org.jboss.resteasy.spi.ResteasyAsynchronousResponse in project resteasy by resteasy.
the class SseEventOutputImpl method close.
private void close(final boolean flushBeforeClose, final Throwable error) {
// avoid even attempting to get a lock if someone else has closed it or is closing it
if (state.getAndSet(CLOSED) != CLOSED) {
if (error != null) {
drainQueue(error);
} else {
synchronized (lock) {
events.clear();
}
}
if (flushBeforeClose && responseFlushed) {
try (CloseableContext c = ResteasyContext.addCloseableContextDataLevel(contextDataMap)) {
// make sure we flush to await for any queued data being sent
AsyncOutputStream aos = response.getAsyncOutputStream();
aos.asyncFlush().toCompletableFuture().get();
} catch (IOException | InterruptedException | ExecutionException x) {
// ignore it and let's just close
}
}
if (asyncContext.isSuspended()) {
ResteasyAsynchronousResponse asyncResponse = asyncContext.getAsyncResponse();
if (asyncResponse != null) {
try {
asyncResponse.complete();
} catch (RuntimeException x) {
Throwable cause = x;
while (cause.getCause() != null && cause.getCause() != cause) cause = cause.getCause();
if (cause instanceof IOException) {
// ignore it, we're closed now
} else {
LOG.debug(cause.getMessage());
return;
}
}
}
}
clearContextData();
}
}
use of org.jboss.resteasy.spi.ResteasyAsynchronousResponse in project resteasy by resteasy.
the class ContainerResponseContextImpl method writeException.
private void writeException(Throwable t) {
/*
* Here we cannot call AsyncResponse.resume(t) because that would invoke the response filters
* and we should not invoke them because we're already in them.
*/
HttpResponse httpResponse = (HttpResponse) contextDataMap.get(HttpResponse.class);
SynchronousDispatcher dispatcher = (SynchronousDispatcher) contextDataMap.get(Dispatcher.class);
ResteasyAsynchronousResponse asyncResponse = request.getAsyncContext().getAsyncResponse();
RESTEasyTracingLogger tracingLogger = RESTEasyTracingLogger.getInstance(request);
tracingLogger.flush(httpResponse.getOutputHeaders());
dispatcher.unhandledAsynchronousException(httpResponse, t);
onComplete.accept(t);
asyncResponse.complete();
asyncResponse.completionCallbacks(t);
}
use of org.jboss.resteasy.spi.ResteasyAsynchronousResponse in project resteasy by resteasy.
the class AsyncResponseFilter method filter.
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
// copy request filter callback values
for (Entry<String, List<String>> entry : requestContext.getHeaders().entrySet()) {
if (entry.getKey().startsWith("RequestFilterCallback"))
addValuesToContext(responseContext, entry);
}
responseContext.getHeaders().add("ResponseFilterCallback" + name, String.valueOf(callbackException));
callbackException = null;
SuspendableContainerResponseContext ctx = (SuspendableContainerResponseContext) responseContext;
String action = requestContext.getHeaderString(name);
LOG.error("Filter response for " + name + " with action: " + action);
if ("sync-pass".equals(action)) {
// do nothing
} else if ("sync-fail".equals(action)) {
ctx.setEntity(name);
} else if ("async-pass".equals(action)) {
ctx.suspend();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> ctx.resume());
} else if ("async-pass-instant".equals(action)) {
ctx.suspend();
ctx.resume();
} else if ("async-fail".equals(action)) {
ctx.suspend();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
ctx.setEntity(name);
ctx.resume();
});
} else if ("async-fail-late".equals(action)) {
ctx.suspend();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LOG.error("Error:", e);
}
ctx.setEntity(name);
ctx.resume();
});
} else if ("async-fail-instant".equals(action)) {
ctx.suspend();
ctx.setEntity(name);
ctx.resume();
} else if ("sync-throw".equals(action)) {
throw new AsyncFilterException("ouch");
} else if ("async-throw-late".equals(action)) {
ctx.suspend();
HttpRequest req = ResteasyContext.getContextData(HttpRequest.class);
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LOG.error("Error:", e);
}
ctx.setEntity(name);
ResteasyAsynchronousResponse resp = req.getAsyncContext().getAsyncResponse();
resp.register((CompletionCallback) (t) -> {
if (callbackException != null)
throw new RuntimeException("Callback called twice");
callbackException = Objects.toString(t);
});
if ("true".equals(req.getHttpHeaders().getHeaderString("UseExceptionMapper")))
ctx.resume(new AsyncFilterException("ouch"));
else
ctx.resume(new Throwable("ouch"));
});
}
LOG.error("Filter response for " + name + " with action: " + action + " done");
}
use of org.jboss.resteasy.spi.ResteasyAsynchronousResponse in project resteasy by resteasy.
the class AsyncResponseFilter method filter.
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
// copy request filter callback values
for (Entry<String, List<String>> entry : requestContext.getHeaders().entrySet()) {
if (entry.getKey().startsWith("RequestFilterCallback"))
addValuesToContext(responseContext, entry);
}
responseContext.getHeaders().add("ResponseFilterCallback" + name, String.valueOf(callbackException));
callbackException = null;
SuspendableContainerResponseContext ctx = (SuspendableContainerResponseContext) responseContext;
String action = requestContext.getHeaderString(name);
LOG.error("Filter response for " + name + " with action: " + action);
if ("sync-pass".equals(action)) {
// do nothing
} else if ("sync-fail".equals(action)) {
ctx.setEntity(name);
} else if ("async-pass".equals(action)) {
ctx.suspend();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> ctx.resume());
} else if ("async-pass-instant".equals(action)) {
ctx.suspend();
ctx.resume();
} else if ("async-fail".equals(action)) {
ctx.suspend();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
ctx.setEntity(name);
ctx.resume();
});
} else if ("async-fail-late".equals(action)) {
ctx.suspend();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LOG.error("Error:", e);
}
ctx.setEntity(name);
ctx.resume();
});
} else if ("async-fail-instant".equals(action)) {
ctx.suspend();
ctx.setEntity(name);
ctx.resume();
} else if ("sync-throw".equals(action)) {
throw new AsyncFilterException("ouch");
} else if ("async-throw-late".equals(action)) {
ctx.suspend();
HttpRequest req = ResteasyContext.getContextData(HttpRequest.class);
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
LOG.error("Error:", e);
}
ctx.setEntity(name);
ResteasyAsynchronousResponse resp = req.getAsyncContext().getAsyncResponse();
resp.register((CompletionCallback) (t) -> {
if (callbackException != null)
throw new RuntimeException("Callback called twice");
callbackException = Objects.toString(t);
});
if ("true".equals(req.getHttpHeaders().getHeaderString("UseExceptionMapper")))
ctx.resume(new AsyncFilterException("ouch"));
else
ctx.resume(new Throwable("ouch"));
});
}
LOG.error("Filter response for " + name + " with action: " + action + " done");
}
Aggregations