OkHttpClients { @VisibleForTesting static RemotingOkHttpClient withStableUris( ClientConfiguration config, HostEventsSink hostEventsSink, Class<?> serviceClass) { return createInternal( new OkHttpClient.Builder(), ClientConfiguration.builder() .from(config) .hostEventsSink(hostEventsSink) .build(), serviceClass, !RANDOMIZE, !RESHUFFLE, () -> new ExponentialBackoff(config.maxNumRetries(), config.backoffSlotSize())); } private  OkHttpClients(); static OkHttpClient create(
            ClientConfiguration config, UserAgent userAgent, HostEventsSink hostEventsSink, Class<?> serviceClass); static OkHttpClient create(
            OkHttpClient.Builder client,
            ClientConfiguration config,
            UserAgent userAgent,
            HostEventsSink hostEventsSink,
            Class<?> serviceClass);  }
@Test public void handlesRetryOther_redirectsToOtherUrl() throws Exception { OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder().from(createTestConfig(url, url2)).build(), hostEventsSink, OkHttpClientsTest.class); server.enqueue(new MockResponse().setResponseCode(308).addHeader(HttpHeaders.LOCATION, url2)); server2.enqueue(new MockResponse().setResponseCode(200).setBody("foo")); Call call = client.newCall(new Request.Builder().url(url + "/foo?bar").build()); assertThat(call.execute().body().string()).isEqualTo("foo"); assertThat(server.takeRequest().getPath()).isEqualTo("/foo?bar"); assertThat(server2.takeRequest().getPath()).isEqualTo("/foo?bar"); }
@Test public void propagatesQos_429() throws Exception { server.enqueue(new MockResponse().setResponseCode(429)); OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder() .from(createTestConfig(url)) .serverQoS(ClientConfiguration.ServerQoS.PROPAGATE_429_and_503_TO_CALLER) .build(), hostEventsSink, OkHttpClientsTest.class); Call call = client.newCall(new Request.Builder().url(url).build()); assertThat(call.execute().code()).isEqualTo(429); assertThat(server.getRequestCount()).isEqualTo(1); }
@Test public void propagatesQos_503() throws Exception { server.enqueue(new MockResponse().setResponseCode(503)); OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder() .from(createTestConfig(url)) .serverQoS(ClientConfiguration.ServerQoS.PROPAGATE_429_and_503_TO_CALLER) .build(), hostEventsSink, OkHttpClientsTest.class); Call call = client.newCall(new Request.Builder().url(url).build()); assertThat(call.execute().code()).isEqualTo(503); assertThat(server.getRequestCount()).isEqualTo(1); }
@Test public void handlesTimeouts_failFastByDefault() { server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.NO_RESPONSE)); server2.enqueue(new MockResponse().setResponseCode(200).setBody("foo")); OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder() .from(createTestConfig(url, url2)) .readTimeout(Duration.ofMillis(20)) .maxNumRetries(1) .backoffSlotSize(Duration.ofMillis(10)) .build(), hostEventsSink, OkHttpClientsTest.class); Call call = client.newCall(new Request.Builder().url(url + "/foo?bar").build()); assertThatThrownBy(call::execute) .isInstanceOf(SafeIoException.class) .hasMessageContaining("Failed to complete the request due to an IOException") .hasCauseInstanceOf(SocketTimeoutException.class); }
@Test public void handlesConnectTimeouts_alwaysRetry() throws IOException, InterruptedException { String urlConnectTimeout = "http: server.enqueue(new MockResponse().setResponseCode(200).setBody("foo")); OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder() .from(createTestConfig(urlConnectTimeout, url)) .readTimeout(Duration.ofMillis(20)) .maxNumRetries(1) .backoffSlotSize(Duration.ofMillis(10)) .connectTimeout(Duration.ofMillis(50)) .retryOnTimeout(ClientConfiguration.RetryOnTimeout.DISABLED) .build(), hostEventsSink, OkHttpClientsTest.class); Call call = client.newCall(new Request.Builder().url(url + "/foo?bar").build()); assertThat(call.execute().body().string()).isEqualTo("foo"); assertThat(server.takeRequest().getPath()).isEqualTo("/foo?bar"); }
@Test public void handlesSocketExceptions_disabled() throws IOException { server.shutdown(); server2.enqueue(new MockResponse().setBody("foo")); OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder() .from(createTestConfig(url, url2)) .retryOnSocketException(ClientConfiguration.RetryOnSocketException.DANGEROUS_DISABLED) .build(), hostEventsSink, OkHttpClientsTest.class); Call call = client.newCall(new Request.Builder().url(url + "/foo?bar").build()); assertThatIOException().isThrownBy(() -> call.execute().body().string()); }
@Test public void handlesTimeouts_withRetryOnTimeout() throws IOException, InterruptedException { server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.NO_RESPONSE)); server2.enqueue(new MockResponse().setResponseCode(200).setBody("foo")); OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder() .from(createTestConfig(url, url2)) .readTimeout(Duration.ofMillis(20)) .maxNumRetries(1) .backoffSlotSize(Duration.ofMillis(10)) .retryOnTimeout(ClientConfiguration.RetryOnTimeout.DANGEROUS_ENABLE_AT_RISK_OF_RETRY_STORMS) .build(), hostEventsSink, OkHttpClientsTest.class); Call call = client.newCall(new Request.Builder().url(url + "/foo?bar").build()); assertThat(call.execute().body().string()).isEqualTo("foo"); assertThat(server2.takeRequest().getPath()).isEqualTo("/foo?bar"); }
@Test public void verifyNodeSeletionStrategy_pinUntilErrorUsesCurrentUrl() throws Exception { server.enqueue(new MockResponse().setBody("foo")); server.enqueue(new MockResponse().setBody("bar")); OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder() .from(createTestConfig(url, url2, url3)) .nodeSelectionStrategy(NodeSelectionStrategy.PIN_UNTIL_ERROR) .build(), hostEventsSink, OkHttpClientsTest.class); Call call = client.newCall(new Request.Builder().url(url + "/foo?bar").build()); assertThat(call.execute().body().string()).isEqualTo("foo"); Call call2 = client.newCall(new Request.Builder().url(url + "/foo?bar").build()); assertThat(call2.execute().body().string()).isEqualTo("bar"); assertThat(server.takeRequest().getPath()).isEqualTo("/foo?bar"); assertThat(server.takeRequest().getPath()).isEqualTo("/foo?bar"); }
@Test public void verifyNodeSeletionStrategy_roundRobinUsesNextUrl() throws Exception { server2.enqueue(new MockResponse().setBody("foo")); server3.enqueue(new MockResponse().setBody("bar")); OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder() .from(createTestConfig(url, url2, url3)) .nodeSelectionStrategy(NodeSelectionStrategy.ROUND_ROBIN) .failedUrlCooldown(Duration.ofSeconds(1)) .build(), hostEventsSink, OkHttpClientsTest.class); Call call = client.newCall(new Request.Builder().url(url + "/foo?bar").build()); assertThat(call.execute().body().string()).isEqualTo("foo"); Call call2 = client.newCall(new Request.Builder().url(url + "/foo?bar").build()); assertThat(call2.execute().body().string()).isEqualTo("bar"); assertThat(server2.takeRequest().getPath()).isEqualTo("/foo?bar"); assertThat(server3.takeRequest().getPath()).isEqualTo("/foo?bar"); }
@Test public void timeouts_set_to_all_zero_should_be_treated_as_infinity() throws Exception { server.enqueue(new MockResponse() .setBodyDelay(Duration.ofSeconds(11).toMillis(), TimeUnit.MILLISECONDS) .setBody("Hello, world!")); OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder() .from(createTestConfig(url)) .connectTimeout(Duration.ZERO) .readTimeout(Duration.ZERO) .writeTimeout(Duration.ZERO) .maxNumRetries(0) .backoffSlotSize(Duration.ofMillis(10)) .build(), hostEventsSink, OkHttpClientsTest.class); Request request = new Request.Builder().url(url).build(); Response synchronousCall = client.newCall(request).execute(); assertThat(synchronousCall.body().string()).isEqualTo("Hello, world!"); }
@Test public void sync_call_to_a_slow_endpoint_should_not_time_out_if_read_timeout_is_zero() throws Exception { server.enqueue(new MockResponse() .setBodyDelay(Duration.ofSeconds(11).toMillis(), TimeUnit.MILLISECONDS) .setBody("Hello, world!")); ClientConfiguration clientConf = ClientConfigurations.of(ServiceConfiguration.builder() .addUris(url) .readTimeout(Duration.ZERO) .writeTimeout(Duration.ZERO) .security(SslConfiguration.of(Paths.get("src", "test", "resources", "trustStore.jks"))) .build()); OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder() .from(clientConf) .userAgent(TestBase.AGENT) .build(), hostEventsSink, OkHttpClientsTest.class); Request request = new Request.Builder().url(url).build(); Response synchronousCall = client.newCall(request).execute(); assertThat(synchronousCall.body().string()).isEqualTo("Hello, world!"); }