use of com.palantir.dialogue.Response in project dialogue by palantir.
the class LargeResponseTest method large_response.
@ParameterizedTest
@MethodSource("responseTestArguments")
public void large_response(CloseType closeType, TransferEncoding encoding) throws Exception {
AtomicBoolean used = new AtomicBoolean();
Undertow server = startServer(new BlockingHandler(exchange -> {
long responseBytes = 300 * 1024 * 1024;
encoding.apply(exchange, responseBytes);
String sessionId = Base64.getEncoder().encodeToString(exchange.getConnection().getSslSession().getId());
exchange.getResponseHeaders().put(HttpString.tryFromString("TlsSessionId"), sessionId);
if (!used.getAndSet(true)) {
OutputStream out = exchange.getOutputStream();
for (int i = 0; i < responseBytes; i++) {
out.write(7);
// Flush + pause 100ms every 1M for a response time of 30 seconds
if (i % (1024 * 1024) == 0) {
out.flush();
Thread.sleep(100);
}
}
}
}));
try {
String uri = "https://localhost:" + getPort(server);
ClientConfiguration conf = TestConfigurations.create(uri);
Meter closedConns = DialogueClientMetrics.of(conf.taggedMetricRegistry()).connectionClosedPartiallyConsumedResponse("client");
String firstSession;
Channel channel;
assertThat(closedConns.getCount()).isZero();
try (ApacheHttpClientChannels.CloseableClient client = ApacheHttpClientChannels.createCloseableHttpClient(conf, "client")) {
channel = ApacheHttpClientChannels.createSingleUri(uri, client);
ListenableFuture<Response> response = channel.execute(TestEndpoint.POST, Request.builder().build());
Response resp = response.get();
firstSession = resp.getFirstHeader("TlsSessionId").orElseThrow();
assertThat(resp.code()).isEqualTo(200);
try (InputStream responseStream = resp.body()) {
assertThat(responseStream.read()).isEqualTo(7);
long beforeClose = System.nanoTime();
closeType.close(responseStream, resp);
Duration closeDuration = Duration.ofNanos(System.nanoTime() - beforeClose);
assertThat(closeDuration).isLessThan(Duration.ofSeconds(2));
assertThat(closedConns.getCount()).isOne();
}
}
// Ensure that the client isn't left in a bad state (connection has been discarded, not incorrectly added
// back to the pool in an ongoing request state)
ListenableFuture<Response> response = channel.execute(TestEndpoint.POST, Request.builder().build());
try (Response resp = response.get()) {
assertThat(resp.code()).isEqualTo(200);
assertThat(resp.body()).isEmpty();
assertThat(resp.getFirstHeader("TlsSessionId").orElseThrow()).as("Expected a new connection").isNotEqualTo(firstSession);
assertThat(closedConns.getCount()).isOne();
}
} finally {
server.stop();
}
}
use of com.palantir.dialogue.Response in project dialogue by palantir.
the class LargeResponseTest method small_response.
@ParameterizedTest
@MethodSource("responseTestArguments")
public void small_response(CloseType closeType, TransferEncoding encoding) throws Exception {
Undertow server = startServer(new BlockingHandler(exchange -> {
long responseBytes = 300;
encoding.apply(exchange, responseBytes);
OutputStream out = exchange.getOutputStream();
for (int i = 0; i < responseBytes; i++) {
out.write(7);
out.flush();
}
}));
try {
String uri = "https://localhost:" + getPort(server);
ClientConfiguration conf = TestConfigurations.create(uri);
Meter closedConns = DialogueClientMetrics.of(conf.taggedMetricRegistry()).connectionClosedPartiallyConsumedResponse("client");
assertThat(closedConns.getCount()).isZero();
try (ApacheHttpClientChannels.CloseableClient client = ApacheHttpClientChannels.createCloseableHttpClient(conf, "client")) {
Channel channel = ApacheHttpClientChannels.createSingleUri(uri, client);
ListenableFuture<Response> response = channel.execute(TestEndpoint.POST, Request.builder().build());
Response resp = response.get();
assertThat(resp.code()).isEqualTo(200);
try (InputStream responseStream = resp.body()) {
assertThat(responseStream.read()).isEqualTo(7);
long beforeClose = System.nanoTime();
closeType.close(responseStream, resp);
Duration closeDuration = Duration.ofNanos(System.nanoTime() - beforeClose);
assertThat(closeDuration).isLessThan(Duration.ofSeconds(2));
assertThat(closedConns.getCount()).as("Small responses below the threshold should not trigger closure").isZero();
}
}
} finally {
server.stop();
}
}
use of com.palantir.dialogue.Response in project dialogue by palantir.
the class ResponseLeakDetectorTest method before.
@BeforeEach
public void before() {
mockEndpoint = mock(Endpoint.class);
response = mock(Response.class);
metrics = DialogueClientMetrics.of(new DefaultTaggedMetricRegistry());
lenient().when(mockEndpoint.serviceName()).thenReturn(SERVICE);
lenient().when(mockEndpoint.endpointName()).thenReturn(ENDPOINT);
lenient().when(response.body()).thenReturn(new ByteArrayInputStream(new byte[0]));
}
use of com.palantir.dialogue.Response in project dialogue by palantir.
the class ApacheHttpClientChannelsTest method close_doesnt_fail_inflight_requests.
@Test
public void close_doesnt_fail_inflight_requests() throws Exception {
ClientConfiguration conf = TestConfigurations.create("http://foo");
Channel channel;
try (ApacheHttpClientChannels.CloseableClient client = ApacheHttpClientChannels.createCloseableHttpClient(conf, "client")) {
channel = ApacheHttpClientChannels.createSingleUri("http://foo", client);
ListenableFuture<Response> response = channel.execute(TestEndpoint.POST, Request.builder().build());
assertThatThrownBy(() -> Futures.getUnchecked(response)).getCause().isInstanceOfSatisfying(UnknownHostException.class, throwable -> assertThat(throwable.getSuppressed()[0]).satisfies(diagnosticThrowable -> assertThat(diagnosticThrowable.getStackTrace()).as("Diagnostic exception should have an empty stack trace").isEmpty()).isInstanceOfSatisfying(SafeLoggable.class, safeLoggable -> {
assertThat(Lists.transform(safeLoggable.getArgs(), Arg::getName)).as("Expected a diagnostic exception").containsExactlyInAnyOrder("durationMillis", "connectTimeout", "socketTimeout", "clientName", "serviceName", "endpointName", "requestTraceId", "requestSpanId", "hostIndex");
}));
}
ListenableFuture<Response> again = channel.execute(TestEndpoint.POST, Request.builder().build());
assertThatThrownBy(() -> Futures.getUnchecked(again)).hasCauseInstanceOf(UnknownHostException.class);
}
use of com.palantir.dialogue.Response in project dialogue by palantir.
the class ApacheHttpClientChannelsTest method countsUnknownHostExceptions.
@Test
public void countsUnknownHostExceptions() throws Exception {
ClientConfiguration conf = TestConfigurations.create("http://unused");
try (ApacheHttpClientChannels.CloseableClient client = ApacheHttpClientChannels.createCloseableHttpClient(conf, "testClient")) {
Meter connectionResolutionError = DialogueClientMetrics.of(conf.taggedMetricRegistry()).connectionResolutionError("testClient");
assertThat(connectionResolutionError.getCount()).isZero();
Channel channel = ApacheHttpClientChannels.createSingleUri("http://unknown-host-for-testing.unused", client);
ListenableFuture<Response> future = channel.execute(TestEndpoint.GET, Request.builder().build());
try (Response response = Futures.getUnchecked(future)) {
fail("This request should have failed with an unknown host exception! (code: %d)", response.code());
} catch (UncheckedExecutionException exception) {
assertThat(exception.getCause()).isInstanceOf(UnknownHostException.class);
}
assertThat(connectionResolutionError.getCount()).isEqualTo(1L);
}
}
Aggregations