@GET public void longGet(@Suspended final AsyncResponse ar) { TASK_EXECUTOR.submit(new Runnable() { @Override public void run() { try { Thread.sleep(SLEEP_TIME_IN_MILLIS); } catch (InterruptedException ex) { LOGGER.log(Level.SEVERE, "Response processing interrupted", ex); } ar.resume(NOTIFICATION_RESPONSE); } }); } }
@GET @Path("async") public void suspendViaContextExample(@Suspended final AsyncResponse ar, @QueryParam("query") final String query) { TASK_EXECUTOR.submit(new Runnable() { @Override public void run() { try { Thread.sleep(SLEEP_TIME_IN_MILLIS); } catch (InterruptedException ex) { LOGGER.log(Level.SEVERE, "Response processing interrupted", ex); } ar.resume("Complex result for " + query); } }); } }
@GET @Path("{queryId}/{token}") @Produces(MediaType.APPLICATION_JSON) public void getQueryResults( @PathParam("queryId") QueryId queryId, @PathParam("token") long token, @QueryParam("maxWait") Duration maxWait, @QueryParam("targetResultSize") DataSize targetResultSize, @HeaderParam(X_FORWARDED_PROTO) String proto, @Context UriInfo uriInfo, @Suspended AsyncResponse asyncResponse) { Query query = queries.get(queryId); if (query == null) { asyncResponse.resume(Response.status(Status.NOT_FOUND).build()); return; } if (isNullOrEmpty(proto)) { proto = uriInfo.getRequestUri().getScheme(); } asyncQueryResults(query, OptionalLong.of(token), maxWait, targetResultSize, uriInfo, proto, asyncResponse); }
@POST @ManagedAsync @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.MULTIPART_FORM_DATA) @Path("/segments") @ApiOperation(value = "Upload a segment", notes = "Upload a segment as binary") // For the multipart endpoint, we will always move segment to final location regardless of the segment endpoint. public void uploadSegmentAsMultiPart(FormDataMultiPart multiPart, @ApiParam(value = "Whether to enable parallel push protection") @DefaultValue("false") @QueryParam(FileUploadDownloadClient.QueryParameters.ENABLE_PARALLEL_PUSH_PROTECTION) boolean enableParallelPushProtection, @Context HttpHeaders headers, @Context Request request, @Suspended final AsyncResponse asyncResponse) { try { asyncResponse.resume(uploadSegment(multiPart, enableParallelPushProtection, headers, request, true)); } catch (Throwable t) { asyncResponse.resume(t); } }
@DELETE @Path("/v1/proxy") @Produces(APPLICATION_JSON) public void cancelQuery( @QueryParam("uri") String uri, @QueryParam("hmac") String hash, @Context HttpServletRequest servletRequest, @Suspended AsyncResponse asyncResponse) { if (!hmac.hashString(uri, UTF_8).equals(HashCode.fromString(hash))) { throw badRequest(FORBIDDEN, "Failed to validate HMAC of URI"); } Request.Builder request = prepareDelete().setUri(URI.create(uri)); performRequest(servletRequest, asyncResponse, request, response -> responseWithHeaders(noContent(), response)); }
@GET @ManagedAsync public void longGet(@Suspended final AsyncResponse ar, @QueryParam("id") int requestId) { try { Thread.sleep(SLEEP_TIME_IN_MILLIS); } catch (InterruptedException ex) { LOGGER.log(Level.SEVERE, "Response processing interrupted", ex); } ar.resume(requestId + " - " + NOTIFICATION_RESPONSE); } }
@GET @Path("/{name}/value") @Produces(MediaType.APPLICATION_JSON) public void get(@PathParam("name") String name, @Suspended AsyncResponse response) { getPrimitive(name).thenCompose(value -> value.get()).whenComplete((result, error) -> { if (error == null) { response.resume(Response.ok(result).build()); } else { LOGGER.warn("{}", error); response.resume(Response.serverError().build()); } }); }
@GET @Path("parameterized-async") @ResponseBodyFromCdiBean public void interceptedParameterizedAsync(@QueryParam("q") final String q, @Suspended final AsyncResponse response) { bean.setRequestId(q); executor.execute(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException ex) { Logger.getLogger(RequestScopedResource.class.getName()).log(Level.SEVERE, null, ex); } response.resume("this will never make it to the client"); } }); }
@POST @ManagedAsync @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.MULTIPART_FORM_DATA) @Path("/v2/segments") @ApiOperation(value = "Upload a segment", notes = "Upload a segment as binary") // This behavior does not differ from v1 of the same endpoint. public void uploadSegmentAsMultiPartV2(FormDataMultiPart multiPart, @ApiParam(value = "Whether to enable parallel push protection") @DefaultValue("false") @QueryParam(FileUploadDownloadClient.QueryParameters.ENABLE_PARALLEL_PUSH_PROTECTION) boolean enableParallelPushProtection, @Context HttpHeaders headers, @Context Request request, @Suspended final AsyncResponse asyncResponse) { try { asyncResponse.resume(uploadSegment(multiPart, enableParallelPushProtection, headers, request, true)); } catch (Throwable t) { asyncResponse.resume(t); } }
@POST @Path("/v1/statement") @Produces(APPLICATION_JSON) public void postStatement( String statement, @Context HttpServletRequest servletRequest, @Context UriInfo uriInfo, @Suspended AsyncResponse asyncResponse) { Request.Builder request = preparePost() .setUri(uriBuilderFrom(remoteUri).replacePath("/v1/statement").build()) .setBodyGenerator(createStaticBodyGenerator(statement, UTF_8)); performRequest(servletRequest, asyncResponse, request, response -> buildResponse(uriInfo, response)); }
@GET @Produces("application/json") public void mainfest(@Suspended AsyncResponse asyncResponse, @Context ServletContext context) { ReactiveSeq.of("/META-INF/MANIFEST.MF") .map(url->context.getResourceAsStream(url)) .map(this::getManifest) .foldFuture(WorkerThreads.ioExecutor.get(), s->s.forEach(Long.MAX_VALUE,result->asyncResponse.resume(result))); }
@DELETE @Path("/{name}/lock") public void unlock(@PathParam("name") String name, @Suspended AsyncResponse response) { getPrimitive(name).thenCompose(lock -> lock.unlock()).whenComplete((result, error) -> { if (error == null) { response.resume(Response.ok().build()); } else { LOGGER.warn("{}", error); response.resume(Response.serverError().build()); } }); } }
@GET @Path("/v1/proxy") @Produces(APPLICATION_JSON) public void getNext( @QueryParam("uri") String uri, @QueryParam("hmac") String hash, @Context HttpServletRequest servletRequest, @Context UriInfo uriInfo, @Suspended AsyncResponse asyncResponse) { if (!hmac.hashString(uri, UTF_8).equals(HashCode.fromString(hash))) { throw badRequest(FORBIDDEN, "Failed to validate HMAC of URI"); } Request.Builder request = prepareGet().setUri(URI.create(uri)); performRequest(servletRequest, asyncResponse, request, response -> buildResponse(uriInfo, response)); }
@GET public void pickUpMessage(@Suspended final AsyncResponse ar, @QueryParam("id") final String messageId) throws InterruptedException { LOGGER.log(DEBUG, "Received GET <{0}> with context {1} on thread {2}.", new Object[] {messageId, ar.toString(), Thread.currentThread().getName()}); QUEUE_EXECUTOR.submit(new Runnable() { @Override public void run() { try { suspended.put(ar); LOGGER.log(DEBUG, "GET <{0}> context {1} scheduled for resume.", new Object[] {messageId, ar.toString()}); } catch (InterruptedException ex) { LOGGER.log(Level.SEVERE, "Waiting for a message pick-up interrupted. Cancelling context" + ar.toString(), ex); ar.cancel(); // close the open connection } } }); }
@DELETE @Path("/{name}/lock") public void unlock(@PathParam("name") String name, @Suspended AsyncResponse response) { getPrimitive(name).thenCompose(lock -> lock.unlock()).whenComplete((result, error) -> { if (error == null) { response.resume(Response.ok().build()); } else { LOGGER.warn("{}", error); response.resume(Response.serverError().build()); } }); } }
@GET @Path("/v1/info") @Produces(APPLICATION_JSON) public void getInfo( @Context HttpServletRequest servletRequest, @Suspended AsyncResponse asyncResponse) { Request.Builder request = prepareGet() .setUri(uriBuilderFrom(remoteUri).replacePath("/v1/info").build()); performRequest(servletRequest, asyncResponse, request, response -> responseWithHeaders(Response.ok(response.getBody()), response)); }
@GET public void pickUpMessage(@Suspended final AsyncResponse ar, @QueryParam("id") final String messageId) { LOGGER.log(DEBUG, "Received GET <{0}> with context {1} on thread {2}.", new Object[]{messageId, ar.toString(), Thread.currentThread().getName()}); QUEUE_EXECUTOR.submit(new Runnable() { @Override public void run() { try { final String message = messages.take(); LOGGER.log(DEBUG, "Resuming GET <{0}> context {1} with a message {2} on thread {3}.", new Object[]{messageId, ar.toString(), message, Thread.currentThread().getName()}); ar.resume(message); } catch (InterruptedException ex) { LOGGER.log(Level.SEVERE, "Waiting for a message pick-up interrupted. Cancelling context" + ar.toString(), ex); ar.cancel(); // close the open connection } } }); }
@POST @Path("/{name}/lock") @Produces(MediaType.APPLICATION_JSON) public void lock(@PathParam("name") String name, @Suspended AsyncResponse response) { getPrimitive(name).thenCompose(lock -> lock.lock()).whenComplete((result, error) -> { if (error == null) { response.resume(Response.ok().build()); } else { LOGGER.warn("{}", error); response.resume(Response.serverError().build()); } }); }