Search in sources :

Example 1 with DataChunk

use of io.helidon.common.http.DataChunk in project helidon by oracle.

the class RestApiBase method requestBytesPayload.

/**
 * Create a supplier for a response with publisher request.
 * Defaults to "{@code () -> clientRequest.submit(publisher)}".
 * Also configures content type and accept headers.
 *
 * @param path path requested
 * @param request API request
 * @param method HTTP method
 * @param requestId ID of this request
 * @param requestBuilder {@link io.helidon.webclient.WebClient} request builder
 * @param publisher publisher to be used as request entity
 *
 * @return supplier of a web client response
 */
protected Supplier<Single<WebClientResponse>> requestBytesPayload(String path, ApiRequest<?> request, Http.RequestMethod method, String requestId, WebClientRequestBuilder requestBuilder, Flow.Publisher<DataChunk> publisher) {
    requestBuilder.accept(request.responseMediaType().orElse(MediaType.APPLICATION_JSON));
    requestBuilder.contentType(request.requestMediaType().orElse(MediaType.APPLICATION_OCTET_STREAM));
    AtomicBoolean updated = new AtomicBoolean();
    return () -> {
        if (updated.compareAndSet(false, true)) {
            return updateRequestBuilderBytesPayload(requestBuilder, path, request, method, requestId).flatMapSingle(it -> it.submit(publisher));
        } else {
            return requestBuilder.submit(publisher);
        }
    };
}
Also used : JsonWriterFactory(jakarta.json.JsonWriterFactory) ByteArrayOutputStream(java.io.ByteArrayOutputStream) WebClient(io.helidon.webclient.WebClient) WebClientResponse(io.helidon.webclient.WebClientResponse) JsonReaderFactory(jakarta.json.JsonReaderFactory) DataChunk(io.helidon.common.http.DataChunk) JsonBuilderFactory(jakarta.json.JsonBuilderFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Supplier(java.util.function.Supplier) MediaType(io.helidon.common.http.MediaType) Flow(java.util.concurrent.Flow) JsonObject(jakarta.json.JsonObject) Single(io.helidon.common.reactive.Single) Http(io.helidon.common.http.Http) Multi(io.helidon.common.reactive.Multi) FtHandler(io.helidon.faulttolerance.FtHandler) Collector(io.helidon.common.reactive.Collector) UUID(java.util.UUID) Logger(java.util.logging.Logger) WebClientRequestHeaders(io.helidon.webclient.WebClientRequestHeaders) Contexts(io.helidon.common.context.Contexts) SpanContext(io.opentracing.SpanContext) StringReader(java.io.StringReader) Optional(java.util.Optional) WebClientRequestBuilder(io.helidon.webclient.WebClientRequestBuilder) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 2 with DataChunk

use of io.helidon.common.http.DataChunk in project helidon by oracle.

the class RestApiBase method handleBytesResponse.

/**
 * Handle bytes response for optional bytes entity.
 * This method checks if this was a success and if the response should contain an entity.
 * For success, it returns a response using the provided response builder.
 * For failures, returns an error.
 *
 * @param path requested path
 * @param request API request
 * @param method HTTP method
 * @param requestId request ID
 * @param response the web client response
 * @param responseBuilder builder to configure success response
 * @param <R> type of the optional part of the response
 * @param <T> type of the response
 *
 * @return future with response
 */
protected <R, T extends ApiOptionalResponse<R>> Single<T> handleBytesResponse(String path, ApiRequest<?> request, Http.RequestMethod method, String requestId, WebClientResponse response, ApiOptionalResponse.BuilderBase<?, T, byte[], R> responseBuilder) {
    Http.ResponseStatus status = response.status();
    boolean success = (Http.Status.Family.of(status.code()) == Http.ResponseStatus.Family.SUCCESSFUL) || isSuccess(path, request, method, requestId, status);
    boolean isEntityExpected = (Http.Status.Family.of(status.code()) == Http.ResponseStatus.Family.SUCCESSFUL) || isEntityExpected(path, request, method, requestId, status);
    if (success) {
        if (isEntityExpected) {
            return response.content().map(DataChunk::bytes).collect(new Collector<byte[], byte[]>() {

                private final ByteArrayOutputStream baos = new ByteArrayOutputStream();

                @Override
                public void collect(byte[] item) {
                    baos.writeBytes(item);
                }

                @Override
                public byte[] value() {
                    return baos.toByteArray();
                }
            }).map(it -> responseBuilder.headers(response.headers()).status(status).requestId(requestId).entity(it).build());
        } else {
            return emptyResponse(path, request, method, requestId, response, responseBuilder);
        }
    } else {
        return errorResponse(path, request, method, requestId, response);
    }
}
Also used : Collector(io.helidon.common.reactive.Collector) Http(io.helidon.common.http.Http) DataChunk(io.helidon.common.http.DataChunk) ByteArrayOutputStream(java.io.ByteArrayOutputStream)

Example 3 with DataChunk

use of io.helidon.common.http.DataChunk in project helidon by oracle.

the class JacksonBodyStreamWriter method write.

@Override
public Multi<DataChunk> write(Flow.Publisher<?> publisher, GenericType<?> type, MessageBodyWriterContext context) {
    MediaType contentType = context.findAccepted(MediaType.JSON_PREDICATE, MediaType.APPLICATION_JSON);
    context.contentType(contentType);
    AtomicBoolean first = new AtomicBoolean(true);
    JacksonBodyWriter.ObjectToChunks objectToChunks = new JacksonBodyWriter.ObjectToChunks(objectMapper, context.charset());
    return Multi.create(publisher).flatMap(objectToChunks).flatMap(it -> {
        if (first.getAndSet(false)) {
            // first record, do not prepend a comma
            return Multi.just(DataChunk.create(ARRAY_JSON_BEGIN_BYTES), it);
        } else {
            // any subsequent record starts with a comma
            return Multi.just(DataChunk.create(COMMA_BYTES), it);
        }
    }).onCompleteResume(DataChunk.create(ARRAY_JSON_END_BYTES));
}
Also used : Objects(java.util.Objects) Flow(java.util.concurrent.Flow) DataChunk(io.helidon.common.http.DataChunk) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) MessageBodyStreamWriter(io.helidon.media.common.MessageBodyStreamWriter) GenericType(io.helidon.common.GenericType) StandardCharsets(java.nio.charset.StandardCharsets) Multi(io.helidon.common.reactive.Multi) MessageBodyWriterContext(io.helidon.media.common.MessageBodyWriterContext) MediaType(io.helidon.common.http.MediaType) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) MediaType(io.helidon.common.http.MediaType)

Example 4 with DataChunk

use of io.helidon.common.http.DataChunk in project helidon by oracle.

the class JsonpStreamWriterTest method write.

private JsonArray write(Multi<? extends JsonStructure> publisher, GenericType<? extends JsonStructure> type) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    WRITER.write(publisher, type, CONTEXT).map(DataChunk::bytes).forEach(it -> {
        try {
            baos.write(it);
        } catch (IOException ignored) {
        // ignored
        }
    }).await();
    return JSON_PARSER.createReader(new ByteArrayInputStream(baos.toByteArray())).readArray();
}
Also used : CoreMatchers.is(org.hamcrest.CoreMatchers.is) ByteArrayOutputStream(java.io.ByteArrayOutputStream) JsonReaderFactory(jakarta.json.JsonReaderFactory) DataChunk(io.helidon.common.http.DataChunk) JsonArrayBuilder(jakarta.json.JsonArrayBuilder) JsonBuilderFactory(jakarta.json.JsonBuilderFactory) IOException(java.io.IOException) HashParameters(io.helidon.common.http.HashParameters) GenericType(io.helidon.common.GenericType) MessageBodyWriterContext(io.helidon.media.common.MessageBodyWriterContext) Json(jakarta.json.Json) IsCollectionWithSize.hasSize(org.hamcrest.collection.IsCollectionWithSize.hasSize) Test(org.junit.jupiter.api.Test) JsonStructure(jakarta.json.JsonStructure) ByteArrayInputStream(java.io.ByteArrayInputStream) MessageBodyOperator(io.helidon.media.common.MessageBodyOperator) Map(java.util.Map) JsonObject(jakarta.json.JsonObject) Assertions.assertAll(org.junit.jupiter.api.Assertions.assertAll) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) JsonArray(jakarta.json.JsonArray) Multi(io.helidon.common.reactive.Multi) ByteArrayInputStream(java.io.ByteArrayInputStream) DataChunk(io.helidon.common.http.DataChunk) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException)

Example 5 with DataChunk

use of io.helidon.common.http.DataChunk in project helidon by oracle.

the class MultiPartDecoder method createPartChunk.

private BodyPartChunk createPartChunk(BufferEntry entry) {
    ByteBuffer data = entry.buffer();
    int id = entry.id();
    DataChunk chunk = chunksByIds.get(id);
    if (chunk == null) {
        throw new IllegalStateException("Parent chunk not found, id=" + id);
    }
    ByteBuffer[] originalBuffers = chunk.data();
    // FIXME: the current resource management is not implemented properly and needs to be fixed
    boolean release = data.limit() == originalBuffers[originalBuffers.length - 1].limit();
    if (release) {
        chunksByIds.remove(id);
    }
    return new BodyPartChunk(data, release ? chunk : null);
}
Also used : DataChunk(io.helidon.common.http.DataChunk) ByteBuffer(java.nio.ByteBuffer)

Aggregations

DataChunk (io.helidon.common.http.DataChunk)43 Test (org.junit.jupiter.api.Test)18 Multi (io.helidon.common.reactive.Multi)12 Flow (java.util.concurrent.Flow)11 GenericType (io.helidon.common.GenericType)9 CompletableFuture (java.util.concurrent.CompletableFuture)9 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)9 Http (io.helidon.common.http.Http)8 Single (io.helidon.common.reactive.Single)8 ByteBuffer (java.nio.ByteBuffer)8 MediaType (io.helidon.common.http.MediaType)7 MessageBodyWriterContext (io.helidon.media.common.MessageBodyWriterContext)7 WebClient (io.helidon.webclient.WebClient)7 WebClientResponse (io.helidon.webclient.WebClientResponse)7 IOException (java.io.IOException)7 List (java.util.List)7 Optional (java.util.Optional)7 TimeUnit (java.util.concurrent.TimeUnit)7 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)7 Logger (java.util.logging.Logger)6