use of io.servicetalk.http.api.StreamingHttpServiceFilterFactory in project servicetalk by apple.
the class ErrorHandlingTest method setUp.
private void setUp(TestMode testMode, GrpcExecutionStrategy serverStrategy, GrpcExecutionStrategy clientStrategy) throws Exception {
this.testMode = testMode;
cannedResponse = TestResponse.newBuilder().setMessage("foo").build();
ServiceFactory serviceFactory;
StreamingHttpServiceFilterFactory serviceFilterFactory = IDENTITY_FILTER;
StreamingHttpClientFilterFactory clientFilterFactory = IDENTITY_CLIENT_FILTER;
Publisher<TestRequest> requestPublisher = from(TestRequest.newBuilder().build());
switch(testMode) {
case HttpClientFilterThrows:
clientFilterFactory = new ErrorProducingClientFilter(true, DELIBERATE_EXCEPTION);
serviceFactory = setupForSuccess();
break;
case HttpClientFilterThrowsGrpcException:
clientFilterFactory = new ErrorProducingClientFilter(true, cannedException);
serviceFactory = setupForSuccess();
break;
case HttpClientFilterEmitsError:
clientFilterFactory = new ErrorProducingClientFilter(false, DELIBERATE_EXCEPTION);
serviceFactory = setupForSuccess();
break;
case HttpClientFilterEmitsGrpcException:
clientFilterFactory = new ErrorProducingClientFilter(false, cannedException);
serviceFactory = setupForSuccess();
break;
case HttpFilterThrows:
serviceFilterFactory = new ErrorProducingSvcFilter(true, DELIBERATE_EXCEPTION);
serviceFactory = setupForSuccess();
break;
case HttpFilterThrowsGrpcException:
serviceFilterFactory = new ErrorProducingSvcFilter(true, cannedException);
serviceFactory = setupForSuccess();
break;
case HttpFilterEmitsError:
serviceFilterFactory = new ErrorProducingSvcFilter(false, DELIBERATE_EXCEPTION);
serviceFactory = setupForSuccess();
break;
case HttpFilterEmitsGrpcException:
serviceFilterFactory = new ErrorProducingSvcFilter(false, cannedException);
serviceFactory = setupForSuccess();
break;
case ServiceThrows:
serviceFactory = setupForServiceThrows(DELIBERATE_EXCEPTION);
break;
case ServiceThrowsGrpcException:
serviceFactory = setupForServiceThrows(cannedException);
break;
case ServiceOperatorThrows:
serviceFactory = setupForServiceOperatorThrows(DELIBERATE_EXCEPTION);
break;
case ServiceOperatorThrowsGrpcException:
serviceFactory = setupForServiceOperatorThrows(cannedException);
break;
case ServiceSecondOperatorThrowsGrpcException:
serviceFactory = setupForServiceSecondOperatorThrows(cannedException);
requestPublisher = from(TestRequest.newBuilder().build(), TestRequest.newBuilder().setName(REQ_THROW_NAME).build());
break;
case ServiceEmitsError:
serviceFactory = setupForServiceEmitsError(DELIBERATE_EXCEPTION);
break;
case ServiceEmitsGrpcException:
serviceFactory = setupForServiceEmitsError(cannedException);
break;
case ServiceEmitsDataThenError:
serviceFactory = setupForServiceEmitsDataThenError(DELIBERATE_EXCEPTION);
break;
case ServiceEmitsDataThenGrpcException:
serviceFactory = setupForServiceEmitsDataThenError(cannedException);
break;
case BlockingServiceThrows:
serviceFactory = setupForBlockingServiceThrows(DELIBERATE_EXCEPTION);
break;
case BlockingServiceThrowsGrpcException:
serviceFactory = setupForBlockingServiceThrows(cannedException);
break;
case BlockingServiceWritesThenThrows:
serviceFactory = setupForBlockingServiceWritesThenThrows(DELIBERATE_EXCEPTION);
break;
case BlockingServiceWritesThenThrowsGrpcException:
serviceFactory = setupForBlockingServiceWritesThenThrows(cannedException);
break;
default:
throw new IllegalArgumentException("Unknown mode: " + testMode);
}
this.requestPublisher = requestPublisher;
final StreamingHttpServiceFilterFactory filterFactory = serviceFilterFactory;
serverContext = GrpcServers.forAddress(localAddress(0)).initializeHttp(builder -> builder.appendServiceFilter(filterFactory).executionStrategy(serverStrategy)).listenAndAwait(serviceFactory);
final StreamingHttpClientFilterFactory pickedClientFilterFactory = clientFilterFactory;
GrpcClientBuilder<HostAndPort, InetSocketAddress> clientBuilder = GrpcClients.forAddress(serverHostAndPort(serverContext)).initializeHttp(builder -> builder.appendClientFilter(pickedClientFilterFactory).executionStrategy(clientStrategy));
client = clientBuilder.build(new ClientFactory());
blockingClient = clientBuilder.buildBlocking(new ClientFactory());
}
use of io.servicetalk.http.api.StreamingHttpServiceFilterFactory in project servicetalk by apple.
the class H2PriorKnowledgeFeatureParityTest method bindHttpEchoServer.
private InetSocketAddress bindHttpEchoServer(@Nullable StreamingHttpServiceFilterFactory filterFactory, @Nullable CountDownLatch connectionOnClosingLatch) throws Exception {
HttpServerBuilder serverBuilder = HttpServers.forAddress(localAddress(0)).protocols(h2PriorKnowledge ? h2Default() : h1Default());
if (filterFactory != null) {
serverBuilder.appendServiceFilter(filterFactory);
}
if (connectionOnClosingLatch != null) {
serverBuilder.appendConnectionAcceptorFilter(original -> new DelegatingConnectionAcceptor(original) {
@Override
public Completable accept(final ConnectionContext context) {
((NettyConnectionContext) context).onClosing().whenFinally(connectionOnClosingLatch::countDown).subscribe();
return completed();
}
});
}
h1ServerContext = serverBuilder.listenStreaming((ctx, request, responseFactory) -> {
StreamingHttpResponse resp;
if (request.headers().contains(EXPECT, CONTINUE)) {
if (request.headers().contains(EXPECT_FAIL_HEADER)) {
return succeeded(responseFactory.expectationFailed());
} else {
resp = responseFactory.continueResponse();
}
} else {
resp = responseFactory.ok();
}
resp = resp.transformMessageBody(pub -> pub.ignoreElements().merge(request.messageBody())).transform(new StatelessTrailersTransformer<>());
CharSequence contentType = request.headers().get(CONTENT_TYPE);
if (contentType != null) {
resp.setHeader(CONTENT_TYPE, contentType);
}
CharSequence contentLength = request.headers().get(CONTENT_LENGTH);
if (contentLength != null) {
resp.setHeader(CONTENT_LENGTH, contentLength);
}
CharSequence transferEncoding = request.headers().get(TRANSFER_ENCODING);
if (transferEncoding != null) {
resp.setHeader(TRANSFER_ENCODING, transferEncoding);
}
resp.headers().set(COOKIE, request.headers().valuesIterator(COOKIE));
return succeeded(resp);
}).toFuture().get();
return (InetSocketAddress) h1ServerContext.listenAddress();
}
use of io.servicetalk.http.api.StreamingHttpServiceFilterFactory in project servicetalk by apple.
the class AbstractHttpServiceAsyncContextTest method filterFactory.
private StreamingHttpServiceFilterFactory filterFactory(final boolean useImmediate, final boolean asyncFilter, final Queue<Throwable> errorQueue) {
return service -> new StreamingHttpServiceFilter(service) {
@Override
public Single<StreamingHttpResponse> handle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory factory) {
return asyncFilter ? defer(() -> doHandle(ctx, request, factory).shareContextOnSubscribe()) : doHandle(ctx, request, factory);
}
private Single<StreamingHttpResponse> doHandle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory factory) {
if (useImmediate && !currentThread().getName().startsWith(IO_THREAD_PREFIX)) {
// verify that if we expect to be offloaded, that we actually are
return succeeded(factory.internalServerError());
}
CharSequence requestId = request.headers().getAndRemove(REQUEST_ID_HEADER);
if (requestId != null) {
AsyncContext.put(K1, requestId);
}
final StreamingHttpRequest filteredRequest = request.transformMessageBody(pub -> pub.afterSubscriber(assertAsyncContextSubscriber(requestId, errorQueue)));
return delegate().handle(ctx, filteredRequest, factory).map(resp -> {
assertAsyncContext(requestId, errorQueue);
return resp.transformMessageBody(pub -> pub.afterSubscriber(assertAsyncContextSubscriber(requestId, errorQueue)));
});
}
};
}
use of io.servicetalk.http.api.StreamingHttpServiceFilterFactory in project servicetalk by apple.
the class DefaultHttpServerBuilder method listenForService.
/**
* Starts this server and returns the {@link HttpServerContext} after the server has been successfully started.
* <p>
* If the underlying protocol (e.g. TCP) supports it this should result in a socket bind/listen on {@code address}.
* <p>/p>
* The execution path for a request will be offloaded from the IO thread as required to ensure safety. The
* <dl>
* <dt>read side</dt>
* <dd>IO thread → request → non-offload filters → offload filters → raw service</dd>
* <dt>subscribe/request side</dt>
* <dd>IO thread → subscribe/request/cancel → non-offload filters → offload filters → raw service</dd>
* </dl>
*
* @param rawService {@link StreamingHttpService} to use for the server.
* @param strategy the {@link HttpExecutionStrategy} to use for the service.
* @return A {@link Single} that completes when the server is successfully started or terminates with an error if
* the server could not be started.
*/
private Single<HttpServerContext> listenForService(final StreamingHttpService rawService, final HttpExecutionStrategy strategy) {
InfluencerConnectionAcceptor connectionAcceptor = connectionAcceptorFactory == null ? null : InfluencerConnectionAcceptor.withStrategy(connectionAcceptorFactory.create(ACCEPT_ALL), connectionAcceptorFactory.requiredOffloads());
final StreamingHttpService filteredService;
final HttpExecutionContext executionContext;
if (noOffloadServiceFilters.isEmpty()) {
filteredService = serviceFilters.isEmpty() ? rawService : buildService(serviceFilters.stream(), rawService);
executionContext = buildExecutionContext(strategy);
} else {
Stream<StreamingHttpServiceFilterFactory> nonOffloadingFilters = noOffloadServiceFilters.stream();
if (strategy.isRequestResponseOffloaded()) {
executionContext = buildExecutionContext(REQRESP_OFFLOADS.missing(strategy));
BooleanSupplier shouldOffload = executionContext.ioExecutor().shouldOffloadSupplier();
// We are going to have to offload, even if just to the raw service
OffloadingFilter offloadingFilter = new OffloadingFilter(strategy, buildFactory(serviceFilters), shouldOffload);
nonOffloadingFilters = Stream.concat(nonOffloadingFilters, Stream.of(offloadingFilter));
} else {
// All the filters can be appended.
nonOffloadingFilters = Stream.concat(nonOffloadingFilters, serviceFilters.stream());
executionContext = buildExecutionContext(strategy);
}
filteredService = buildService(nonOffloadingFilters, rawService);
}
return doBind(executionContext, connectionAcceptor, filteredService).afterOnSuccess(serverContext -> LOGGER.debug("Server for address {} uses strategy {}", serverContext.listenAddress(), strategy));
}
use of io.servicetalk.http.api.StreamingHttpServiceFilterFactory in project servicetalk by apple.
the class ServiceTalkContentCodingTest method newServiceTalkServer.
private ServerContext newServiceTalkServer(final Scenario scenario, final Queue<Throwable> errors) throws Exception {
HttpServerBuilder httpServerBuilder = HttpServers.forAddress(localAddress(0));
StreamingHttpService service = (ctx, request, responseFactory) -> succeeded(buildResponse(responseFactory));
StreamingHttpServiceFilterFactory filterFactory = REQ_FILTER.apply(scenario, errors);
return httpServerBuilder.executionStrategy(defaultStrategy()).protocols(scenario.protocol.config).appendServiceFilter(new ContentCodingHttpServiceFilter(scenario.serverSupported, scenario.serverSupported)).appendServiceFilter(filterFactory).listenStreamingAndAwait(service);
}
Aggregations