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);
}
};
}
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);
}
}
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));
}
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();
}
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);
}
Aggregations