use of javax.ws.rs.container.AsyncResponse in project openremote by openremote.
the class AssetDatapointResourceImpl method getDatapointExport.
@Override
public void getDatapointExport(AsyncResponse asyncResponse, String attributeRefsString, long fromTimestamp, long toTimestamp) {
try {
AttributeRef[] attributeRefs = JSON.readValue(attributeRefsString, AttributeRef[].class);
for (AttributeRef attributeRef : attributeRefs) {
if (isRestrictedUser() && !assetStorageService.isUserAsset(getUserId(), attributeRef.getId())) {
throw new WebApplicationException(Response.Status.FORBIDDEN);
}
Asset<?> asset = assetStorageService.find(attributeRef.getId(), true);
if (asset == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
if (!isTenantActiveAndAccessible(asset.getRealm())) {
DATA_EXPORT_LOG.info("Forbidden access for user '" + getUsername() + "': " + asset);
throw new WebApplicationException(Response.Status.FORBIDDEN);
}
asset.getAttribute(attributeRef.getName()).orElseThrow(() -> new WebApplicationException(Response.Status.NOT_FOUND));
}
DATA_EXPORT_LOG.info("User '" + getUsername() + "' started data export for " + attributeRefsString + " from " + fromTimestamp + " to " + toTimestamp);
ScheduledFuture<File> exportFuture = assetDatapointService.exportDatapoints(attributeRefs, fromTimestamp, toTimestamp);
asyncResponse.register((ConnectionCallback) disconnected -> {
exportFuture.cancel(true);
});
File exportFile = null;
try {
exportFile = exportFuture.get();
ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream());
FileInputStream fin = new FileInputStream(exportFile);
ZipEntry zipEntry = new ZipEntry(exportFile.getName());
zipOut.putNextEntry(zipEntry);
IOUtils.copy(fin, zipOut);
zipOut.closeEntry();
zipOut.close();
fin.close();
response.setContentType("application/zip");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"dataexport.zip\"");
asyncResponse.resume(response);
} catch (Exception ex) {
exportFuture.cancel(true);
asyncResponse.resume(new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR));
DATA_EXPORT_LOG.log(Level.SEVERE, "Exception in ScheduledFuture: ", ex);
} finally {
if (exportFile != null && exportFile.exists()) {
try {
exportFile.delete();
} catch (Exception e) {
DATA_EXPORT_LOG.log(Level.SEVERE, "Failed to delete temporary export file: " + exportFile.getPath(), e);
}
}
}
} catch (JsonProcessingException ex) {
asyncResponse.resume(new BadRequestException(ex));
}
}
use of javax.ws.rs.container.AsyncResponse in project jersey by jersey.
the class Jersey2812ITCase method asyncSuspendedResourceDoesNotGetStuck.
/**
* Tests whether the server-side thread that is processing a http request to the servlet-filter-based Jersey setup ends up
* stuck or returned back to the pool of available threads.
* <p/>
* This test prevents a regression reported in JERSEY-2812.
* <p/>
* When the {@link javax.ws.rs.container.AsyncResponse} was left intact in the RESTful resource (as implemented in {@link
* TestWaitResource#waitForEvent(AsyncResponse, HttpServletRequest, String)}), the server-side Jersey thread ended up in
* {@link org.glassfish.jersey.servlet.internal.ResponseWriter#getResponseContext()} blocked because of the resolution of http
* response status from {@link org.glassfish.jersey.servlet.ServletContainer#doFilter(HttpServletRequest, HttpServletResponse,
* FilterChain, String, String, String)}
* <p/>
* This test uses a separate thread to call {@code /async/wait/{uuid}} resource which blocks until the {@code
* /async/release/{uuid}} is called. In the meantime the JUnit thread calls {@code /async/await/{uuid}} to discover whether
* the server-side thread processing the request to {@code /async/await/{uuid}/started} did start processing of the request.
* Consecutively, the JUnit thread calls {@code /async/await/{uuid}/finished} with a timeout {@code #WAIT_TIMEOUT} to discover
* whether the server-side thread got stuck (which is what JERSEY-2812 reported) or not.
*
* @throws Exception
*/
@Test
public void asyncSuspendedResourceDoesNotGetStuck() throws Exception {
// [1] wait for the /async/wait request to be processed
final Response startResponse = target("/asyncTest/async/await").path(uuid).path("started").queryParam("millis", WAIT_TIMEOUT).request().get();
assertTrue("The server-side thread handling the request to /async/wait didn't start in timely fashion. " + "This error indicates this test is not executed / designed properly rather than a regression in " + "JERSEY-2812 fix.", startResponse.readEntity(Boolean.class));
// [2] wait for the /async/wait request to finish
final Response finishResponse = target("/asyncTest/async/await").path(uuid).path("finished").queryParam("millis", WAIT_TIMEOUT).request().get();
assertTrue("The thread processing the /async/wait request did not respond in timely fashion. " + "Memory leak / thread got stuck detected!", finishResponse.readEntity(Boolean.class));
// [3] release the blocked http call to /async/wait
final String releaseResponse = target("/asyncTest/async/release").path(uuid).request().post(null, String.class);
assertEquals("RELEASED", releaseResponse);
// [4] test whether everything ended as expected
executorService.shutdown();
assertTrue("The test thread did not finish in timely fashion!", executorService.awaitTermination(WAIT_TIMEOUT, TimeUnit.MILLISECONDS));
assertEquals("async-OK-" + uuid, asyncResult.get());
}
use of javax.ws.rs.container.AsyncResponse in project jersey by jersey.
the class FlowableAgentResource method flowable.
@GET
public void flowable(@Suspended final AsyncResponse async) {
final long time = System.nanoTime();
final Queue<String> errors = new ConcurrentLinkedQueue<>();
Flowable.just(new AgentResponse()).zipWith(visited(errors), (agentResponse, visited) -> {
agentResponse.setVisited(visited);
return agentResponse;
}).zipWith(recommended(errors), (agentResponse, recommendations) -> {
agentResponse.setRecommended(recommendations);
return agentResponse;
}).observeOn(Schedulers.io()).subscribe(agentResponse -> {
agentResponse.setProcessingTime((System.nanoTime() - time) / 1000000);
async.resume(agentResponse);
}, async::resume);
}
use of javax.ws.rs.container.AsyncResponse in project jersey by jersey.
the class AsyncCancelTimeoutResource method setTimeout.
@POST
@Path("timeout")
public void setTimeout(final String stage) throws Exception {
final AsyncResponse async = stages[Integer.parseInt(stage)].take();
async.setTimeoutHandler(new TimeoutHandler() {
@Override
public void handleTimeout(final AsyncResponse response) {
response.cancel();
}
});
async.setTimeout(200L, TimeUnit.MILLISECONDS);
stages[Integer.parseInt(stage) + 1].add(async);
}
use of javax.ws.rs.container.AsyncResponse in project jersey by jersey.
the class AsyncResumeTimeoutResource method setTimeOut.
@POST
@Path("timeout")
public void setTimeOut(final Integer millis) throws InterruptedException {
final AsyncResponse asyncResponse = queue.take();
final boolean timeout1 = asyncResponse.setTimeout(millis, TimeUnit.MILLISECONDS);
asyncResponse.setTimeoutHandler(new TimeoutHandler() {
@Override
public void handleTimeout(final AsyncResponse asyncResponse) {
final boolean timeout2 = asyncResponse.setTimeout(millis, TimeUnit.MILLISECONDS);
asyncResponse.setTimeoutHandler(new TimeoutHandler() {
@Override
public void handleTimeout(final AsyncResponse asyncResponse) {
asyncResponse.resume("timeout1=" + timeout1 + "_timeout2=" + timeout2 + "_handled");
}
});
}
});
}
Aggregations