Search in sources :

Example 11 with StreamingOutput

use of javax.ws.rs.core.StreamingOutput in project druid by druid-io.

the class QueryResource method doPost.

@POST
@Produces({ MediaType.APPLICATION_JSON, SmileMediaTypes.APPLICATION_JACKSON_SMILE })
@Consumes({ MediaType.APPLICATION_JSON, SmileMediaTypes.APPLICATION_JACKSON_SMILE, APPLICATION_SMILE })
public Response doPost(InputStream in, @QueryParam("pretty") String pretty, // used to get request content-type, remote address and AuthorizationInfo
@Context final HttpServletRequest req) throws IOException {
    final long start = System.currentTimeMillis();
    Query query = null;
    QueryToolChest toolChest = null;
    String queryId = null;
    final ResponseContext context = createContext(req.getContentType(), pretty != null);
    final String currThreadName = Thread.currentThread().getName();
    try {
        query = context.getObjectMapper().readValue(in, Query.class);
        queryId = query.getId();
        if (queryId == null) {
            queryId = UUID.randomUUID().toString();
            query = query.withId(queryId);
        }
        if (query.getContextValue(QueryContextKeys.TIMEOUT) == null) {
            query = query.withOverriddenContext(ImmutableMap.of(QueryContextKeys.TIMEOUT, config.getMaxIdleTime().toStandardDuration().getMillis()));
        }
        toolChest = warehouse.getToolChest(query);
        Thread.currentThread().setName(String.format("%s[%s_%s_%s]", currThreadName, query.getType(), query.getDataSource().getNames(), queryId));
        if (log.isDebugEnabled()) {
            log.debug("Got query [%s]", query);
        }
        if (authConfig.isEnabled()) {
            // This is an experimental feature, see - https://github.com/druid-io/druid/pull/2424
            AuthorizationInfo authorizationInfo = (AuthorizationInfo) req.getAttribute(AuthConfig.DRUID_AUTH_TOKEN);
            if (authorizationInfo != null) {
                for (String dataSource : query.getDataSource().getNames()) {
                    Access authResult = authorizationInfo.isAuthorized(new Resource(dataSource, ResourceType.DATASOURCE), Action.READ);
                    if (!authResult.isAllowed()) {
                        return Response.status(Response.Status.FORBIDDEN).header("Access-Check-Result", authResult).build();
                    }
                }
            } else {
                throw new ISE("WTF?! Security is enabled but no authorization info found in the request");
            }
        }
        String prevEtag = req.getHeader(HDR_IF_NONE_MATCH);
        if (prevEtag != null) {
            query = query.withOverriddenContext(ImmutableMap.of(HDR_IF_NONE_MATCH, prevEtag));
        }
        final Map<String, Object> responseContext = new MapMaker().makeMap();
        final Sequence res = query.run(texasRanger, responseContext);
        if (prevEtag != null && prevEtag.equals(responseContext.get(HDR_ETAG))) {
            return Response.notModified().build();
        }
        final Sequence results;
        if (res == null) {
            results = Sequences.empty();
        } else {
            results = res;
        }
        final Yielder yielder = Yielders.each(results);
        try {
            final Query theQuery = query;
            final QueryToolChest theToolChest = toolChest;
            final ObjectWriter jsonWriter = context.newOutputWriter();
            Response.ResponseBuilder builder = Response.ok(new StreamingOutput() {

                @Override
                public void write(OutputStream outputStream) throws IOException, WebApplicationException {
                    try {
                        // json serializer will always close the yielder
                        CountingOutputStream os = new CountingOutputStream(outputStream);
                        jsonWriter.writeValue(os, yielder);
                        // Some types of OutputStream suppress flush errors in the .close() method.
                        os.flush();
                        os.close();
                        successfulQueryCount.incrementAndGet();
                        final long queryTime = System.currentTimeMillis() - start;
                        emitter.emit(DruidMetrics.makeQueryTimeMetric(theToolChest, jsonMapper, theQuery, req.getRemoteAddr()).setDimension("success", "true").build("query/time", queryTime));
                        emitter.emit(DruidMetrics.makeQueryTimeMetric(theToolChest, jsonMapper, theQuery, req.getRemoteAddr()).build("query/bytes", os.getCount()));
                        requestLogger.log(new RequestLogLine(new DateTime(start), req.getRemoteAddr(), theQuery, new QueryStats(ImmutableMap.<String, Object>of("query/time", queryTime, "query/bytes", os.getCount(), "success", true))));
                    } finally {
                        Thread.currentThread().setName(currThreadName);
                    }
                }
            }, context.getContentType()).header("X-Druid-Query-Id", queryId);
            if (responseContext.get(HDR_ETAG) != null) {
                builder.header(HDR_ETAG, responseContext.get(HDR_ETAG));
                responseContext.remove(HDR_ETAG);
            }
            //Limit the response-context header, see https://github.com/druid-io/druid/issues/2331
            //Note that Response.ResponseBuilder.header(String key,Object value).build() calls value.toString()
            //and encodes the string using ASCII, so 1 char is = 1 byte
            String responseCtxString = jsonMapper.writeValueAsString(responseContext);
            if (responseCtxString.length() > RESPONSE_CTX_HEADER_LEN_LIMIT) {
                log.warn("Response Context truncated for id [%s] . Full context is [%s].", queryId, responseCtxString);
                responseCtxString = responseCtxString.substring(0, RESPONSE_CTX_HEADER_LEN_LIMIT);
            }
            return builder.header("X-Druid-Response-Context", responseCtxString).build();
        } catch (Exception e) {
            // make sure to close yielder if anything happened before starting to serialize the response.
            yielder.close();
            throw Throwables.propagate(e);
        } finally {
        // do not close yielder here, since we do not want to close the yielder prior to
        // StreamingOutput having iterated over all the results
        }
    } catch (QueryInterruptedException e) {
        try {
            log.warn(e, "Exception while processing queryId [%s]", queryId);
            interruptedQueryCount.incrementAndGet();
            final long queryTime = System.currentTimeMillis() - start;
            emitter.emit(DruidMetrics.makeQueryTimeMetric(toolChest, jsonMapper, query, req.getRemoteAddr()).setDimension("success", "false").build("query/time", queryTime));
            requestLogger.log(new RequestLogLine(new DateTime(start), req.getRemoteAddr(), query, new QueryStats(ImmutableMap.<String, Object>of("query/time", queryTime, "success", false, "interrupted", true, "reason", e.toString()))));
        } catch (Exception e2) {
            log.error(e2, "Unable to log query [%s]!", query);
        }
        return context.gotError(e);
    } catch (Exception e) {
        // Input stream has already been consumed by the json object mapper if query == null
        final String queryString = query == null ? "unparsable query" : query.toString();
        log.warn(e, "Exception occurred on request [%s]", queryString);
        failedQueryCount.incrementAndGet();
        try {
            final long queryTime = System.currentTimeMillis() - start;
            emitter.emit(DruidMetrics.makeQueryTimeMetric(toolChest, jsonMapper, query, req.getRemoteAddr()).setDimension("success", "false").build("query/time", queryTime));
            requestLogger.log(new RequestLogLine(new DateTime(start), req.getRemoteAddr(), query, new QueryStats(ImmutableMap.<String, Object>of("query/time", queryTime, "success", false, "exception", e.toString()))));
        } catch (Exception e2) {
            log.error(e2, "Unable to log query [%s]!", queryString);
        }
        log.makeAlert(e, "Exception handling request").addData("exception", e.toString()).addData("query", queryString).addData("peer", req.getRemoteAddr()).emit();
        return context.gotError(e);
    } finally {
        Thread.currentThread().setName(currThreadName);
    }
}
Also used : Query(io.druid.query.Query) CountingOutputStream(com.google.common.io.CountingOutputStream) OutputStream(java.io.OutputStream) Access(io.druid.server.security.Access) StreamingOutput(javax.ws.rs.core.StreamingOutput) QueryToolChest(io.druid.query.QueryToolChest) DateTime(org.joda.time.DateTime) CountingOutputStream(com.google.common.io.CountingOutputStream) ISE(io.druid.java.util.common.ISE) QueryInterruptedException(io.druid.query.QueryInterruptedException) Yielder(io.druid.java.util.common.guava.Yielder) Resource(io.druid.server.security.Resource) MapMaker(com.google.common.collect.MapMaker) ObjectWriter(com.fasterxml.jackson.databind.ObjectWriter) Sequence(io.druid.java.util.common.guava.Sequence) AuthorizationInfo(io.druid.server.security.AuthorizationInfo) WebApplicationException(javax.ws.rs.WebApplicationException) QueryInterruptedException(io.druid.query.QueryInterruptedException) IOException(java.io.IOException) Response(javax.ws.rs.core.Response) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) Consumes(javax.ws.rs.Consumes)

Example 12 with StreamingOutput

use of javax.ws.rs.core.StreamingOutput in project immutables by immutables.

the class GsonMessageBodyProvider method writeTo.

@Override
public void writeTo(Object t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
    // in the form of CharSequence
    if (t instanceof StreamingOutput) {
        ((StreamingOutput) t).write(entityStream);
        return;
    }
    if (t instanceof CharSequence) {
        // UTF-8 used because it should be considered default encoding for the JSON-family
        // of media types
        OutputStreamWriter writer = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8);
        writer.append((CharSequence) t);
        writer.flush();
        return;
    }
    // Standard way of handling writing using gson
    try {
        streamer.write(gson, genericType, t, entityStream);
    } catch (IOException ex) {
        exceptionHandler.onWrite(gson, ex);
        throw ex;
    }
}
Also used : StreamingOutput(javax.ws.rs.core.StreamingOutput) OutputStreamWriter(java.io.OutputStreamWriter) IOException(java.io.IOException)

Example 13 with StreamingOutput

use of javax.ws.rs.core.StreamingOutput in project hadoop by apache.

the class AHSWebServices method sendStreamOutputResponse.

private Response sendStreamOutputResponse(ApplicationId appId, String appOwner, String nodeId, String containerIdStr, String fileName, String format, long bytes, boolean printEmptyLocalContainerLog) {
    String contentType = WebAppUtils.getDefaultLogContentType();
    if (format != null && !format.isEmpty()) {
        contentType = WebAppUtils.getSupportedLogContentType(format);
        if (contentType == null) {
            String errorMessage = "The valid values for the parameter : format " + "are " + WebAppUtils.listSupportedLogContentType();
            return Response.status(Status.BAD_REQUEST).entity(errorMessage).build();
        }
    }
    StreamingOutput stream = null;
    try {
        stream = getStreamingOutput(appId, appOwner, nodeId, containerIdStr, fileName, bytes, printEmptyLocalContainerLog);
    } catch (Exception ex) {
        return createBadResponse(Status.INTERNAL_SERVER_ERROR, ex.getMessage());
    }
    ResponseBuilder response = Response.ok(stream);
    response.header("Content-Type", contentType);
    // Sending the X-Content-Type-Options response header with the value
    // nosniff will prevent Internet Explorer from MIME-sniffing a response
    // away from the declared content-type.
    response.header("X-Content-Type-Options", "nosniff");
    return response.build();
}
Also used : StreamingOutput(javax.ws.rs.core.StreamingOutput) ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder) WebApplicationException(javax.ws.rs.WebApplicationException) UniformInterfaceException(com.sun.jersey.api.client.UniformInterfaceException) NotFoundException(org.apache.hadoop.yarn.webapp.NotFoundException) IOException(java.io.IOException) JSONException(org.codehaus.jettison.json.JSONException) ClientHandlerException(com.sun.jersey.api.client.ClientHandlerException) BadRequestException(org.apache.hadoop.yarn.webapp.BadRequestException)

Example 14 with StreamingOutput

use of javax.ws.rs.core.StreamingOutput in project airpal by airbnb.

the class S3FilesResource method getFile.

@GET
@Path("/{filename}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFile(@PathParam("filename") String filename) {
    val outputKey = getOutputKey(filename);
    val getRequest = new GetObjectRequest(outputBucket, outputKey);
    final val object = s3Client.getObject(getRequest);
    if (object == null) {
        return Response.status(Response.Status.NOT_FOUND).build();
    } else {
        ObjectMetadata objectMetadata = object.getObjectMetadata();
        Response.ResponseBuilder builder = Response.ok().type(objectMetadata.getContentType());
        if (objectMetadata.getContentEncoding() != null) {
            // gzip
            builder = builder.encoding(objectMetadata.getContentEncoding());
        }
        return builder.entity(new StreamingOutput() {

            @Override
            public void write(OutputStream output) throws IOException, WebApplicationException {
                try (InputStream objectData = object.getObjectContent()) {
                    ByteStreams.copy(objectData, output);
                } finally {
                    output.close();
                }
            }
        }).build();
    }
}
Also used : lombok.val(lombok.val) Response(javax.ws.rs.core.Response) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) StreamingOutput(javax.ws.rs.core.StreamingOutput) GetObjectRequest(com.amazonaws.services.s3.model.GetObjectRequest) ObjectMetadata(com.amazonaws.services.s3.model.ObjectMetadata) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Example 15 with StreamingOutput

use of javax.ws.rs.core.StreamingOutput in project neo4j by neo4j.

the class BatchOperationService method batchProcessAndStream.

private Response batchProcessAndStream(final UriInfo uriInfo, final HttpHeaders httpHeaders, final HttpServletRequest req, final InputStream body) {
    try {
        final StreamingOutput stream = new StreamingOutput() {

            @Override
            public void write(final OutputStream output) throws IOException, WebApplicationException {
                try {
                    final ServletOutputStream servletOutputStream = new ServletOutputStream() {

                        @Override
                        public void write(int i) throws IOException {
                            output.write(i);
                        }

                        @Override
                        public boolean isReady() {
                            return true;
                        }

                        @Override
                        public void setWriteListener(WriteListener writeListener) {
                            try {
                                writeListener.onWritePossible();
                            } catch (IOException e) {
                            // Ignore
                            }
                        }
                    };
                    new StreamingBatchOperations(webServer).readAndExecuteOperations(uriInfo, httpHeaders, req, body, servletOutputStream);
                    representationWriteHandler.onRepresentationWritten();
                } catch (Exception e) {
                    LOGGER.warn("Error executing batch request ", e);
                } finally {
                    representationWriteHandler.onRepresentationFinal();
                }
            }
        };
        return Response.ok(stream).type(HttpHeaderUtils.mediaTypeWithCharsetUtf8(MediaType.APPLICATION_JSON_TYPE)).build();
    } catch (Exception e) {
        return output.serverError(e);
    }
}
Also used : ServletOutputStream(javax.servlet.ServletOutputStream) ServletOutputStream(javax.servlet.ServletOutputStream) OutputStream(java.io.OutputStream) StreamingOutput(javax.ws.rs.core.StreamingOutput) IOException(java.io.IOException) NonStreamingBatchOperations(org.neo4j.server.rest.batch.NonStreamingBatchOperations) WriteListener(javax.servlet.WriteListener) IOException(java.io.IOException) WebApplicationException(javax.ws.rs.WebApplicationException)

Aggregations

StreamingOutput (javax.ws.rs.core.StreamingOutput)23 OutputStream (java.io.OutputStream)13 IOException (java.io.IOException)8 Path (javax.ws.rs.Path)7 Produces (javax.ws.rs.Produces)7 WebApplicationException (javax.ws.rs.WebApplicationException)7 Response (javax.ws.rs.core.Response)6 GET (javax.ws.rs.GET)5 JsonGenerator (com.fasterxml.jackson.core.JsonGenerator)4 Consumes (javax.ws.rs.Consumes)4 POST (javax.ws.rs.POST)4 ResponseBuilder (javax.ws.rs.core.Response.ResponseBuilder)4 QueryInterruptedException (io.druid.query.QueryInterruptedException)3 ApiOperation (io.swagger.annotations.ApiOperation)3 ApiResponses (io.swagger.annotations.ApiResponses)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 OutputStreamWriter (java.io.OutputStreamWriter)3 ByteStreams (com.google.common.io.ByteStreams)2 ISE (io.druid.java.util.common.ISE)2 Writer (java.io.Writer)2