use of com.hotels.styx.api.LiveHttpResponse in project styx by ExpediaGroup.
the class TestPlugin method intercept.
@Override
public Eventual<LiveHttpResponse> intercept(LiveHttpRequest request, Chain chain) {
String header = xHcomPluginsHeader(request);
LiveHttpRequest newRequest = request.newBuilder().header(X_HCOM_PLUGINS_HEADER, header).header("X-Hcom-Styx-Started", styxStarted).header("X-Hcom-Styx-Stopped", styxStopped).build();
Function<ByteBuf, String> byteBufStringFunction = byteBuf -> byteBuf.toString(UTF_8);
return chain.proceed(newRequest).flatMap(response -> response.aggregate(1 * 1024 * 1024)).map(response -> response.newBuilder().header(X_HCOM_PLUGINS_HEADER, header).header("X-Hcom-Styx-Started", styxStarted).header("X-Hcom-Styx-Stopped", styxStopped).addHeader("X-Plugin-Identifier", config.getId()).build()).map(HttpResponse::stream);
}
use of com.hotels.styx.api.LiveHttpResponse in project styx by ExpediaGroup.
the class HttpAggregatorTest method aggregatesRequestAndStreamsResponses.
@Test
public void aggregatesRequestAndStreamsResponses() {
AtomicReference<String> result = new AtomicReference<>();
WebServiceHandler webServiceHandler = (request, ctx) -> {
result.set(request.bodyAs(UTF_8));
return Eventual.of(response(OK).body("abcdef", UTF_8).build());
};
LiveHttpResponse response = Mono.from(new HttpAggregator(500, webServiceHandler).handle(LiveHttpRequest.post("/").body(ByteStream.from("ABCDEF", UTF_8)).build(), requestContext())).block();
assertThat(result.get(), is("ABCDEF"));
assertThat(Mono.from(response.aggregate(500)).block().bodyAs(UTF_8), is("abcdef"));
}
use of com.hotels.styx.api.LiveHttpResponse in project styx by ExpediaGroup.
the class HttpPipelineHandlerTest method pluginPipelineThrowsAnExceptionInAcceptingRequestsState.
@Test
public void pluginPipelineThrowsAnExceptionInAcceptingRequestsState() throws Exception {
Throwable cause = new RuntimeException("Simulated Styx plugin exception");
pipeline = mock(HttpHandler.class);
when(pipeline.handle(anyObject(), any(HttpInterceptor.Context.class))).thenThrow(cause);
handler = createHandler(pipeline);
assertThat(handler.state(), is(ACCEPTING_REQUESTS));
handler.channelRead0(ctx, request);
ArgumentCaptor<LiveHttpResponse> captor = ArgumentCaptor.forClass(LiveHttpResponse.class);
verify(responseWriter).write(captor.capture());
HttpResponse response = Mono.from(captor.getValue().aggregate(100)).block();
assertThat(response.status(), is(INTERNAL_SERVER_ERROR));
assertThat(response.header(CONNECTION), is(Optional.of("close")));
assertThat(response.header(CONTENT_LENGTH), is(Optional.of("29")));
assertThat(response.bodyAs(UTF_8), is("Site temporarily unavailable."));
verify(responseEnhancer).enhance(any(LiveHttpResponse.Transformer.class), eq(request));
verify(errorListener).proxyErrorOccurred(request, InetSocketAddress.createUnresolved("localhost", 2), INTERNAL_SERVER_ERROR, cause);
verify(statsCollector).onTerminate(request.id());
assertThat(handler.state(), is(TERMINATED));
}
use of com.hotels.styx.api.LiveHttpResponse in project styx by ExpediaGroup.
the class HttpPipelineHandlerTest method mapsStyxClientExceptionToInternalServerErrorInWaitingForResponseState.
@Test
public void mapsStyxClientExceptionToInternalServerErrorInWaitingForResponseState() throws Exception {
// In Waiting For Response state,
// The response observable emits a StyxClientException.
// Then, respond with INTERNAL_SERVER_ERROR and close the channel.
setupHandlerTo(WAITING_FOR_RESPONSE);
responseObservable.onError(new StyxClientException("Client error occurred", new JustATestException()));
assertThat(responseUnsubscribed.get(), is(true));
ArgumentCaptor<LiveHttpResponse> captor = ArgumentCaptor.forClass(LiveHttpResponse.class);
verify(responseWriter).write(captor.capture());
HttpResponse response = Mono.from(captor.getValue().aggregate(100)).block();
assertThat(response.status(), is(INTERNAL_SERVER_ERROR));
assertThat(response.header(CONNECTION), is(Optional.of("close")));
assertThat(response.header(CONTENT_LENGTH), is(Optional.of("29")));
assertThat(response.bodyAs(UTF_8), is("Site temporarily unavailable."));
writerFuture.complete(null);
verify(statsCollector).onComplete(request.id(), 500);
verify(errorListener).proxyErrorOccurred(any(LiveHttpRequest.class), any(InetSocketAddress.class), eq(INTERNAL_SERVER_ERROR), any(RuntimeException.class));
// NOTE: channel closure is not verified. This is because cannot mock channel future.
verify(ctx).close();
assertThat(handler.state(), is(TERMINATED));
}
use of com.hotels.styx.api.LiveHttpResponse in project styx by ExpediaGroup.
the class HttpPipelineHandlerTest method responseObservableEmitsContentOverflowExceptionInWaitingForResponseState.
@Test
public void responseObservableEmitsContentOverflowExceptionInWaitingForResponseState() throws Exception {
// In Waiting For Response state,
// When response observable emits ContentOverflowException.
// Then respond with BAD_GATEWAY and close the channel
setupHandlerTo(WAITING_FOR_RESPONSE);
responseObservable.onError(new ContentOverflowException("Request Send Error"));
assertThat(responseUnsubscribed.get(), is(true));
ArgumentCaptor<LiveHttpResponse> captor = ArgumentCaptor.forClass(LiveHttpResponse.class);
verify(responseWriter).write(captor.capture());
HttpResponse response = Mono.from(captor.getValue().aggregate(100)).block();
assertThat(response.status(), is(BAD_GATEWAY));
assertThat(response.header(CONNECTION), is(Optional.of("close")));
assertThat(response.header(CONTENT_LENGTH), is(Optional.of("29")));
assertThat(response.bodyAs(UTF_8), is("Site temporarily unavailable."));
verify(responseEnhancer).enhance(any(LiveHttpResponse.Transformer.class), eq(request));
writerFuture.complete(null);
verify(statsCollector).onComplete(request.id(), 502);
verify(errorListener).proxyErrorOccurred(any(LiveHttpRequest.class), any(InetSocketAddress.class), eq(BAD_GATEWAY), any(RuntimeException.class));
// NOTE: channel closure is not verified. This is because cannot mock channel future.
verify(ctx).close();
assertThat(handler.state(), is(TERMINATED));
}
Aggregations