use of io.helidon.common.http.DataChunk in project helidon by oracle.
the class HelidonEntity method submit.
/**
* Convert Jersey {@code OutputStream} to an entity based on the client request use case and submits to the provided
* {@code WebClientRequestBuilder}.
* @param type the type of the Helidon entity.
* @param requestContext Jersey {@link ClientRequest} providing the entity {@code OutputStream}.
* @param requestBuilder Helidon {@code WebClientRequestBuilder} which is used to submit the entity
* @param executorService {@link ExecutorService} that fills the entity instance for Helidon with data from Jersey
* {@code OutputStream}.
* @return Helidon Client response completion stage.
*/
static CompletionStage<WebClientResponse> submit(HelidonEntityType type, ClientRequest requestContext, WebClientRequestBuilder requestBuilder, ExecutorService executorService) {
CompletionStage<WebClientResponse> stage = null;
if (type != null) {
final int bufferSize = requestContext.resolveProperty(ClientProperties.OUTBOUND_CONTENT_LENGTH_BUFFER, 8192);
switch(type) {
case BYTE_ARRAY_OUTPUT_STREAM:
final ByteArrayOutputStream baos = new ByteArrayOutputStream(bufferSize);
requestContext.setStreamProvider(contentLength -> baos);
((ProcessingRunnable) requestContext::writeEntity).run();
stage = requestBuilder.submit(baos);
break;
case READABLE_BYTE_CHANNEL:
final OutputStreamChannel channel = new OutputStreamChannel(bufferSize);
requestContext.setStreamProvider(contentLength -> channel);
executorService.execute((ProcessingRunnable) requestContext::writeEntity);
stage = requestBuilder.submit(channel);
break;
case OUTPUT_STREAM_MULTI:
final OutputStreamMulti publisher = IoMulti.outputStreamMulti();
requestContext.setStreamProvider(contentLength -> publisher);
executorService.execute((ProcessingRunnable) () -> {
requestContext.writeEntity();
publisher.close();
});
stage = requestBuilder.submit(Multi.create(publisher).map(DataChunk::create));
break;
default:
}
}
return stage;
}
use of io.helidon.common.http.DataChunk in project helidon by oracle.
the class FormParamsBodyReader method read.
@Override
@SuppressWarnings("unchecked")
public <U extends FormParams> Single<U> read(Flow.Publisher<DataChunk> publisher, GenericType<U> type, MessageBodyReaderContext context) {
MediaType mediaType = context.contentType().orElseThrow();
Charset charset = mediaType.charset().map(Charset::forName).orElse(StandardCharsets.UTF_8);
Function<String, String> decoder = decoder(mediaType, charset);
return (Single<U>) ContentReaders.readString(publisher, charset).map(formStr -> create(formStr, mediaType, decoder));
}
use of io.helidon.common.http.DataChunk in project helidon by oracle.
the class ContentWriters method writeStackTrace.
/**
* Create a a publisher {@link DataChunk} with the given
* {@link Throwable} / {@link Charset} and return a {@link Single}.
*
* @param throwable the {@link Throwable}
* @param charset the charset to use to encode the stack trace
* @return Single
* @since 2.0.0
*/
public static Single<DataChunk> writeStackTrace(Throwable throwable, Charset charset) {
final StringWriter stringWriter = new StringWriter();
final PrintWriter printWriter = new PrintWriter(stringWriter);
String stackTraceString = null;
try {
throwable.printStackTrace(printWriter);
stackTraceString = stringWriter.toString();
} finally {
printWriter.close();
}
final Single<DataChunk> returnValue;
if (stackTraceString.isEmpty()) {
returnValue = Single.<DataChunk>empty();
} else {
returnValue = writeCharSequence(stackTraceString, charset);
}
return returnValue;
}
use of io.helidon.common.http.DataChunk in project helidon by oracle.
the class MultiPartDecoderTest method testPartContentSubscriberThrottling.
@Test
public void testPartContentSubscriberThrottling() {
String boundary = "boundary";
final byte[] chunk1 = ("--" + boundary + "\n" + "Content-Id: part1\n" + "\n" + "body 1.aaaa\n").getBytes();
final byte[] chunk2 = "body 1.bbbb\n".getBytes();
final byte[] chunk3 = ("body 1.cccc\n" + "--" + boundary + "\n" + "Content-Id: part2\n" + "\n" + "This is the 2nd").getBytes();
final byte[] chunk4 = ("body.\n" + "--" + boundary + "--").getBytes();
final CountDownLatch latch = new CountDownLatch(3);
Consumer<BodyPart> consumer = (part) -> {
latch.countDown();
if (latch.getCount() == 2) {
assertThat(part.headers().values("Content-Id"), hasItems("part1"));
}
part.content().subscribe(new Subscriber<DataChunk>() {
@Override
public void onSubscribe(Subscription subscription) {
subscription.request(1);
}
@Override
public void onNext(DataChunk item) {
latch.countDown();
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
}
});
};
BodyPartSubscriber testSubscriber = new BodyPartSubscriber(SUBSCRIBER_TYPE.ONE_BY_ONE, consumer);
partsPublisher(boundary, List.of(chunk1, chunk2, chunk3, chunk4)).subscribe(testSubscriber);
waitOnLatchNegative(latch, "the 2nd part should not be processed");
assertThat(latch.getCount(), is(equalTo(1L)));
try {
testSubscriber.complete.orTimeout(200, TimeUnit.MILLISECONDS).join();
throw new IllegalStateException("Not expecting to make progress, unless the part is consumed");
} catch (CompletionException e) {
Throwable error = e.getCause();
// This is the expected outcome - the testSubcriber is not making progress
assertThat(error.getClass(), is(equalTo(TimeoutException.class)));
}
}
use of io.helidon.common.http.DataChunk in project helidon by oracle.
the class RequestContentSubscriber method sendData.
private void sendData(DataChunk data) {
LOGGER.finest(() -> "(client reqID: " + requestId + ") Sending data chunk");
DefaultHttpContent httpContent = new DefaultHttpContent(Unpooled.wrappedBuffer(data.data()));
channel.write(true, httpContent, f -> f.addListener(future -> {
data.release();
subscription.request(1);
LOGGER.finest(() -> "(client reqID: " + requestId + ") Data chunk sent with result: " + future.isSuccess());
}).addListener(completeOnFailureListener("(client reqID: " + requestId + ") Failure when sending a content!")).addListener(ChannelFutureListener.CLOSE_ON_FAILURE));
}
Aggregations