Search in sources :

Example 1 with HttpData

use of com.linecorp.armeria.common.HttpData in project curiostack by curioswitch.

the class StorageClient method createFile.

/**
 * Create a new file for uploading data to cloud storage.
 */
public ListenableFuture<FileWriter> createFile(String filename, Map<String, String> metadata, RequestContext ctx) {
    FileRequest request = ImmutableFileRequest.builder().name(filename).metadata(metadata).build();
    ByteBuf buf = ctx.alloc().buffer();
    try (ByteBufOutputStream os = new ByteBufOutputStream(buf)) {
        OBJECT_MAPPER.writeValue((DataOutput) os, request);
    } catch (IOException e) {
        buf.release();
        throw new UncheckedIOException("Could not serialize resource JSON to buffer.", e);
    }
    HttpData data = new ByteBufHttpData(buf, true);
    HttpHeaders headers = HttpHeaders.of(HttpMethod.POST, uploadUrl).contentType(MediaType.JSON_UTF_8);
    HttpResponse res = httpClient.execute(headers, data);
    return CompletableFuturesExtra.toListenableFuture(res.aggregate(ctx.contextAwareEventLoop()).handle((msg, t) -> {
        if (t != null) {
            throw new RuntimeException("Unexpected error creating new file.", t);
        }
        HttpHeaders responseHeaders = msg.headers();
        if (!responseHeaders.status().equals(HttpStatus.OK)) {
            throw new RuntimeException("Non-successful response when creating new file: " + responseHeaders + "\n" + msg.content().toStringUtf8());
        }
        String location = responseHeaders.get(HttpHeaderNames.LOCATION);
        String pathAndQuery = location.substring("https://www.googleapis.com/upload/storage/v1".length());
        return new FileWriter(pathAndQuery, ctx, httpClient);
    }));
}
Also used : ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ForStorage(org.curioswitch.curiostack.gcloud.storage.StorageModule.ForStorage) Singleton(javax.inject.Singleton) HttpHeaderNames(com.linecorp.armeria.common.HttpHeaderNames) MediaType(com.linecorp.armeria.common.MediaType) Inject(javax.inject.Inject) ByteBuf(io.netty.buffer.ByteBuf) HttpStatus(com.linecorp.armeria.common.HttpStatus) JsonSerialize(com.fasterxml.jackson.databind.annotation.JsonSerialize) Map(java.util.Map) HttpData(com.linecorp.armeria.common.HttpData) HttpResponse(com.linecorp.armeria.common.HttpResponse) DataOutput(java.io.DataOutput) CompletableFuturesExtra(com.spotify.futures.CompletableFuturesExtra) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) IOException(java.io.IOException) HttpMethod(com.linecorp.armeria.common.HttpMethod) Immutable(org.immutables.value.Value.Immutable) ByteBufHttpData(com.linecorp.armeria.unsafe.ByteBufHttpData) ByteBufOutputStream(io.netty.buffer.ByteBufOutputStream) RequestContext(com.linecorp.armeria.common.RequestContext) UncheckedIOException(java.io.UncheckedIOException) HttpClient(com.linecorp.armeria.client.HttpClient) HttpHeaders(com.linecorp.armeria.common.HttpHeaders) JsonDeserialize(com.fasterxml.jackson.databind.annotation.JsonDeserialize) HttpHeaders(com.linecorp.armeria.common.HttpHeaders) ByteBufOutputStream(io.netty.buffer.ByteBufOutputStream) HttpResponse(com.linecorp.armeria.common.HttpResponse) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) ByteBuf(io.netty.buffer.ByteBuf) HttpData(com.linecorp.armeria.common.HttpData) ByteBufHttpData(com.linecorp.armeria.unsafe.ByteBufHttpData) ByteBufHttpData(com.linecorp.armeria.unsafe.ByteBufHttpData)

Example 2 with HttpData

use of com.linecorp.armeria.common.HttpData in project zipkin by openzipkin.

the class ScribeInboundHandler method channelRead.

@Override
public void channelRead(ChannelHandlerContext ctx, Object payload) {
    assert payload instanceof ByteBuf;
    HttpRequest request = HttpRequest.of(THRIFT_HEADERS, HttpData.wrap((ByteBuf) payload));
    ServiceRequestContextBuilder requestContextBuilder = ServiceRequestContext.builder(request).service(scribeService).alloc(ctx.alloc());
    if (ctx.executor() instanceof EventLoop) {
        requestContextBuilder.eventLoop((EventLoop) ctx.executor());
    }
    ServiceRequestContext requestContext = requestContextBuilder.build();
    final HttpResponse response;
    try (SafeCloseable unused = requestContext.push()) {
        response = HttpResponse.of(scribeService.serve(requestContext, request));
    } catch (Throwable t) {
        propagateIfFatal(t);
        exceptionCaught(ctx, t);
        return;
    }
    int responseIndex = nextResponseIndex++;
    response.aggregateWithPooledObjects(ctx.executor(), ctx.alloc()).handle((msg, t) -> {
        if (t != null) {
            exceptionCaught(ctx, t);
            return null;
        }
        try (HttpData content = msg.content()) {
            ByteBuf returned = ctx.alloc().buffer(content.length() + 4);
            returned.writeInt(content.length());
            returned.writeBytes(content.byteBuf());
            if (responseIndex == previouslySentResponseIndex + 1) {
                ctx.writeAndFlush(returned);
                previouslySentResponseIndex++;
                flushResponses(ctx);
            } else {
                pendingResponses.put(responseIndex, returned);
            }
        }
        return null;
    });
}
Also used : HttpRequest(com.linecorp.armeria.common.HttpRequest) ServiceRequestContextBuilder(com.linecorp.armeria.server.ServiceRequestContextBuilder) EventLoop(io.netty.channel.EventLoop) ServiceRequestContext(com.linecorp.armeria.server.ServiceRequestContext) HttpData(com.linecorp.armeria.common.HttpData) HttpResponse(com.linecorp.armeria.common.HttpResponse) ByteBuf(io.netty.buffer.ByteBuf) SafeCloseable(com.linecorp.armeria.common.util.SafeCloseable)

Example 3 with HttpData

use of com.linecorp.armeria.common.HttpData in project curiostack by curioswitch.

the class FileWriter method doUploadChunk.

private CompletableFuture<Void> doUploadChunk(ByteBuf chunk, boolean endOfFile) {
    int length = chunk.readableBytes();
    long limit = filePosition + length;
    StringBuilder range = new StringBuilder("bytes ");
    if (length == 0) {
        range.append('*');
    } else {
        range.append(filePosition).append('-').append(limit - 1);
    }
    range.append('/');
    if (endOfFile) {
        range.append(limit);
    } else {
        range.append('*');
    }
    RequestHeaders headers = RequestHeaders.of(HttpMethod.PUT, uploadUrl, HttpHeaderNames.CONTENT_RANGE, range.toString());
    HttpData data = HttpData.wrap(chunk).withEndOfStream();
    chunk.retain();
    return httpClient.execute(headers, data).aggregate(eventLoop).thenComposeAsync(msg -> {
        ResponseHeaders responseHeaders = msg.headers();
        if (!responseHeaders.status().codeClass().equals(HttpStatusClass.SUCCESS) && responseHeaders.status().code() != 308) {
            chunk.release();
            throw new RuntimeException("Unsuccessful response uploading chunk: endOfFile: " + endOfFile + " Request headers: " + headers + "\n" + " Response headers: " + responseHeaders + "\n" + msg.content().toStringUtf8());
        }
        String responseRange = responseHeaders.get(HttpHeaderNames.RANGE);
        if (responseRange == null) {
            chunk.release();
            return completedFuture(null);
        }
        long responseLimit = rangeHeaderLimit(responseHeaders.get(HttpHeaderNames.RANGE));
        filePosition = responseLimit + 1;
        int notUploaded = (int) (limit - 1 - responseLimit);
        if (notUploaded > 0) {
            chunk.readerIndex(chunk.writerIndex() - notUploaded);
            if (endOfFile) {
                return doUploadChunk(chunk, true);
            }
            if (unfinishedChunk == null) {
                copyUnfinishedBuffer(chunk);
            } else {
                ByteBuf newUnfinished = alloc.buffer(chunk.readableBytes() + unfinishedChunk.readableBytes());
                newUnfinished.writeBytes(chunk).writeBytes(unfinishedChunk);
                unfinishedChunk.release();
                unfinishedChunk = newUnfinished;
            }
        }
        chunk.release();
        return completedFuture(null);
    }, eventLoop);
}
Also used : HttpData(com.linecorp.armeria.common.HttpData) ByteString(com.google.protobuf.ByteString) RequestHeaders(com.linecorp.armeria.common.RequestHeaders) ResponseHeaders(com.linecorp.armeria.common.ResponseHeaders) ByteBuf(io.netty.buffer.ByteBuf)

Example 4 with HttpData

use of com.linecorp.armeria.common.HttpData in project zipkin by openzipkin.

the class UnzippingBytesRequestConverter method validateAndStoreSpans.

/**
 * This synchronously decodes the message so that users can see data errors.
 */
@SuppressWarnings("FutureReturnValueIgnored")
// check? Say it is somehow canceled, would we take action? Would callback.onError() be redundant?
HttpResponse validateAndStoreSpans(SpanBytesDecoder decoder, ServiceRequestContext ctx, HttpRequest req) {
    CompletableCallback result = new CompletableCallback();
    req.aggregateWithPooledObjects(ctx.eventLoop(), ctx.alloc()).handle((msg, t) -> {
        if (t != null) {
            result.onError(t);
            return null;
        }
        final HttpData requestContent;
        try {
            requestContent = UnzippingBytesRequestConverter.convertRequest(ctx, msg);
        } catch (Throwable t1) {
            propagateIfFatal(t1);
            result.onError(t1);
            return null;
        }
        try (HttpData content = requestContent) {
            // logging already handled upstream in UnzippingBytesRequestConverter where request context exists
            if (content.isEmpty()) {
                result.onSuccess(null);
                return null;
            }
            final ByteBuffer nioBuffer = content.byteBuf().nioBuffer();
            try {
                SpanBytesDecoderDetector.decoderForListMessage(nioBuffer);
            } catch (IllegalArgumentException e) {
                result.onError(new IllegalArgumentException("Expected a " + decoder + " encoded list\n"));
                return null;
            } catch (Throwable t1) {
                result.onError(t1);
                return null;
            }
            SpanBytesDecoder unexpectedDecoder = testForUnexpectedFormat(decoder, nioBuffer);
            if (unexpectedDecoder != null) {
                result.onError(new IllegalArgumentException("Expected a " + decoder + " encoded list, but received: " + unexpectedDecoder + "\n"));
                return null;
            }
            // collector.accept might block so need to move off the event loop. We make sure the
            // callback is context aware to continue the trace.
            Executor executor = ctx.makeContextAware(ctx.blockingTaskExecutor());
            try {
                collector.acceptSpans(nioBuffer, decoder, result, executor);
            } catch (Throwable t1) {
                result.onError(t1);
                return null;
            }
        }
        return null;
    });
    return HttpResponse.from(result);
}
Also used : Executor(java.util.concurrent.Executor) HttpData(com.linecorp.armeria.common.HttpData) SpanBytesDecoder(zipkin2.codec.SpanBytesDecoder) ByteBuffer(java.nio.ByteBuffer)

Example 5 with HttpData

use of com.linecorp.armeria.common.HttpData in project zipkin by openzipkin.

the class UnzippingBytesRequestConverter method convertRequest.

static HttpData convertRequest(ServiceRequestContext ctx, AggregatedHttpRequest request) {
    ZipkinHttpCollector.metrics.incrementMessages();
    String encoding = request.headers().get(HttpHeaderNames.CONTENT_ENCODING);
    HttpData content = request.content();
    if (!content.isEmpty() && encoding != null && encoding.contains("gzip")) {
        content = StreamDecoderFactory.gzip().newDecoder(ctx.alloc()).decode(content);
        // The implementation of the armeria decoder is to return an empty body on failure
        if (content.isEmpty()) {
            ZipkinHttpCollector.maybeLog("Malformed gzip body", ctx, request);
            content.close();
            throw new IllegalArgumentException("Cannot gunzip spans");
        }
    }
    if (content.isEmpty())
        ZipkinHttpCollector.maybeLog("Empty POST body", ctx, request);
    if (content.length() == 2 && "[]".equals(content.toStringAscii())) {
        ZipkinHttpCollector.maybeLog("Empty JSON list POST body", ctx, request);
        content.close();
        content = HttpData.empty();
    }
    ZipkinHttpCollector.metrics.incrementBytes(content.length());
    return content;
}
Also used : HttpData(com.linecorp.armeria.common.HttpData)

Aggregations

HttpData (com.linecorp.armeria.common.HttpData)11 HttpResponse (com.linecorp.armeria.common.HttpResponse)5 RequestHeaders (com.linecorp.armeria.common.RequestHeaders)4 ByteBuf (io.netty.buffer.ByteBuf)4 ResponseHeaders (com.linecorp.armeria.common.ResponseHeaders)3 HttpHeaderNames (com.linecorp.armeria.common.HttpHeaderNames)2 HttpHeaders (com.linecorp.armeria.common.HttpHeaders)2 HttpMethod (com.linecorp.armeria.common.HttpMethod)2 HttpRequest (com.linecorp.armeria.common.HttpRequest)2 HttpStatus (com.linecorp.armeria.common.HttpStatus)2 IOException (java.io.IOException)2 ByteBuffer (java.nio.ByteBuffer)2 Map (java.util.Map)2 JsonParser (com.fasterxml.jackson.core.JsonParser)1 JsonNode (com.fasterxml.jackson.databind.JsonNode)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 JsonDeserialize (com.fasterxml.jackson.databind.annotation.JsonDeserialize)1 JsonSerialize (com.fasterxml.jackson.databind.annotation.JsonSerialize)1 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)1 ByteString (com.google.protobuf.ByteString)1