use of io.servicetalk.concurrent.api.Single in project servicetalk by apple.
the class HttpLifecycleObserverTest method testConnectionFailsRequestBeforeWrite.
@ParameterizedTest(name = "{displayName} [{index}] protocol={0}")
@EnumSource(HttpProtocol.class)
void testConnectionFailsRequestBeforeWrite(HttpProtocol protocol) throws Exception {
connectionFilterFactory(client -> new StreamingHttpConnectionFilter(client) {
@Override
public Single<StreamingHttpResponse> request(StreamingHttpRequest request) {
return failed(DELIBERATE_EXCEPTION);
}
});
setUp(protocol);
ExecutionException e = assertThrows(ExecutionException.class, () -> makeRequestAndAssertResponse(SVC_ECHO, protocol, OK, CONTENT.readableBytes()));
assertThat(e.getCause(), sameInstance(DELIBERATE_EXCEPTION));
// server is not involved in this test, count down manually
bothTerminate.countDown();
bothTerminate.await();
clientInOrder.verify(clientLifecycleObserver).onNewExchange();
clientInOrder.verify(clientExchangeObserver).onRequest(any(StreamingHttpRequest.class));
clientInOrder.verify(clientExchangeObserver).onConnectionSelected(any(ConnectionInfo.class));
clientInOrder.verify(clientExchangeObserver).onResponseError(e.getCause());
clientInOrder.verify(clientExchangeObserver).onExchangeFinally();
verifyNoMoreInteractions(clientLifecycleObserver, clientExchangeObserver);
verifyNoInteractions(clientRequestObserver, clientResponseObserver, serverLifecycleObserver, serverExchangeObserver, serverRequestObserver, serverResponseObserver);
}
use of io.servicetalk.concurrent.api.Single in project servicetalk by apple.
the class TrailersOnlyErrorTest method testServiceFilterThrows.
@Test
void testServiceFilterThrows() throws Exception {
final BlockingQueue<Throwable> asyncErrors = new LinkedBlockingDeque<>();
final TesterService service = mockTesterService();
final GrpcServerBuilder serverBuilder = GrpcServers.forAddress(localAddress(0)).initializeHttp(builder -> builder.appendServiceFilter(svc -> new StreamingHttpServiceFilter(svc) {
@Override
public Single<StreamingHttpResponse> handle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory responseFactory) {
throw DELIBERATE_EXCEPTION;
}
}));
try (ServerContext serverContext = serverBuilder.listenAndAwait(new Tester.ServiceFactory(service))) {
final GrpcClientBuilder<HostAndPort, InetSocketAddress> clientBuilder = GrpcClients.forAddress(serverHostAndPort(serverContext)).initializeHttp(builder -> builder.appendClientFilter(__ -> true, setupResponseVerifierFilter(asyncErrors)));
try (TesterClient client = clientBuilder.build(new Tester.ClientFactory())) {
verifyException(client.test(TestRequest.newBuilder().build()).toFuture(), UNKNOWN);
assertNoAsyncErrors(asyncErrors);
verifyException(client.testRequestStream(Publisher.from(TestRequest.newBuilder().build())).toFuture(), UNKNOWN);
assertNoAsyncErrors(asyncErrors);
verifyException(client.testResponseStream(TestRequest.newBuilder().build()).toFuture(), UNKNOWN);
assertNoAsyncErrors(asyncErrors);
verifyException(client.testBiDiStream(from(TestRequest.newBuilder().build()).concat(never())).toFuture(), UNKNOWN);
assertNoAsyncErrors(asyncErrors);
verifyException(client.testBiDiStream(from(TestRequest.newBuilder().build())).toFuture(), UNKNOWN);
assertNoAsyncErrors(asyncErrors);
}
}
}
use of io.servicetalk.concurrent.api.Single in project servicetalk by apple.
the class ContentEncodingHttpRequesterFilter method applyEncodingAndDecoding.
private Single<StreamingHttpResponse> applyEncodingAndDecoding(final StreamingHttpRequester delegate, final StreamingHttpRequest request) {
return Single.defer(() -> {
boolean decompressResponse = false;
CharSequence encodings = decompressors.advertisedMessageEncoding();
if (encodings != null && !request.headers().contains(ACCEPT_ENCODING)) {
request.headers().set(ACCEPT_ENCODING, encodings);
decompressResponse = true;
}
BufferEncoder encoder = request.contentEncoding();
final StreamingHttpRequest encodedRequest;
if (encoder != null && !identityEncoder().equals(encoder)) {
addContentEncoding(request.headers(), encoder.encodingName());
encodedRequest = request.transformPayloadBody(pub -> encoder.streamingEncoder().serialize(pub, delegate.executionContext().bufferAllocator()));
} else {
encodedRequest = request;
}
Single<StreamingHttpResponse> respSingle = delegate.request(encodedRequest);
return (decompressResponse ? respSingle.map(response -> {
Iterator<? extends CharSequence> contentEncodingItr = response.headers().valuesIterator(CONTENT_ENCODING);
final boolean hasContentEncoding = contentEncodingItr.hasNext();
if (!hasContentEncoding) {
return response;
}
BufferDecoder decoder = matchAndRemoveEncoding(decompressors.decoders(), BufferDecoder::encodingName, contentEncodingItr, response.headers());
if (decoder == null) {
throw new UnsupportedContentEncodingException(response.headers().get(CONTENT_ENCODING, "<null>").toString());
}
return response.transformPayloadBody(pub -> decoder.streamingDecoder().deserialize(pub, delegate.executionContext().bufferAllocator()));
}) : respSingle).shareContextOnSubscribe();
});
}
Aggregations