/** * Creates an OkHttp client from the given {@link ClientConfiguration}. Note that the configured {@link * ClientConfiguration#uris URIs} are initialized in random order. */ public static OkHttpClient create( ClientConfiguration config, UserAgent userAgent, HostEventsSink hostEventsSink, Class<?> serviceClass) { return createInternal(config, userAgent, hostEventsSink, serviceClass, true /* randomize URLs */); }
public <T> T build(Class<T> serviceClass, UserAgent userAgent) { Preconditions.checkNotNull(hostEventsSink, "hostEventsSink must be set"); okhttp3.OkHttpClient client = OkHttpClients.create(config, userAgent, hostEventsSink, serviceClass); Retrofit retrofit = new Retrofit.Builder() .client(client) .baseUrl(addTrailingSlash(config.uris().get(0))) .addConverterFactory( new CborConverterFactory( new NeverReturnNullConverterFactory( new CoerceNullCollectionsConverterFactory( JacksonConverterFactory.create(OBJECT_MAPPER))), CBOR_OBJECT_MAPPER)) .addConverterFactory(OptionalObjectToStringConverterFactory.INSTANCE) .addCallAdapterFactory(new CoerceNullCollectionsCallAdapterFactory( AsyncSerializableErrorCallAdapterFactory.INSTANCE)) .build(); return retrofit.create(serviceClass); }
client.addInterceptor(InstrumentedInterceptor.create(registry, hostEventsSink, serviceClass)); client.addInterceptor(OkhttpTraceInterceptor.INSTANCE); client.addInterceptor(UserAgentInterceptor.of(augmentUserAgent(userAgent, serviceClass))); client.connectionSpecs(createConnectionSpecs(config.enableGcmCipherSuites()));
@Test public void handlesRetryOther_redirectsToOtherUrl() throws Exception { OkHttpClient client = OkHttpClients.withStableUris( ClientConfiguration.builder().from(createTestConfig(url, url2)).build(), AGENT, 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 meshProxyClientChangesTargetAndInjectHostHeader() throws Exception { server.enqueue(new MockResponse().setBody("foo")); String serviceUrl = "http://foo.com/"; ClientConfiguration proxiedConfig = ClientConfiguration.builder() .from(createTestConfig(serviceUrl)) .meshProxy(HostAndPort.fromParts("localhost", server.getPort())) .maxNumRetries(0) .build(); OkHttpClient client = OkHttpClients.create(proxiedConfig, AGENT, hostEventsSink, OkHttpClientsTest.class); assertThat(client.newCall(new Request.Builder().url(serviceUrl).build()).execute().body().string()) .isEqualTo("foo"); assertThat(server.takeRequest().getHeader(HttpHeaders.HOST)).isEqualTo("foo.com"); }
client.addInterceptor(InstrumentedInterceptor.create(registry, hostEventsSink, serviceClass)); client.addInterceptor(OkhttpTraceInterceptor.INSTANCE); client.addInterceptor(UserAgentInterceptor.of(augmentUserAgent(userAgent, serviceClass))); client.connectionSpecs(createConnectionSpecs(config.enableGcmCipherSuites()));
@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!")); OkHttpClient client = OkHttpClients.withStableUris( ClientConfigurations.of( ServiceConfiguration.builder() .addUris(url) // ClientConfigurations has a connectTimeout default of 10 seconds .readTimeout(Duration.ZERO) // unlimited pls .writeTimeout(Duration.ZERO) // unlimited pls .security(SslConfiguration.of(Paths.get("src", "test", "resources", "trustStore.jks"))) .build() ), AGENT, 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(timeout = 10_000) public void randomizesUrls() throws IOException { boolean server2WasHit = false; server.shutdown(); server2.enqueue(new MockResponse().setResponseCode(200).setBody("foo")); while (!server2WasHit) { OkHttpClient client = OkHttpClients.create( ClientConfiguration.builder() .from(createTestConfig(url, url2)) .maxNumRetries(0) .build(), AGENT, hostEventsSink, OkHttpClientsTest.class); Call call = client.newCall(new Request.Builder().url(url).build()); String response = null; try { response = call.execute().body().string(); } catch (Exception e) { System.out.println("Failed to talk to shutdown server (this is expected with p=1/2)"); assertThat(e.getCause().toString()).contains(Integer.toString(server.getPort())); } if (response != null) { assertThat(response).isEqualTo("foo"); server2WasHit = true; } } }
/** * Creates an OkHttp client from the given {@link ClientConfiguration}. Note that the configured {@link * ClientConfiguration#uris URIs} are initialized in random order. */ public static OkHttpClient create( ClientConfiguration config, UserAgent userAgent, HostEventsSink hostEventsSink, Class<?> serviceClass) { return createInternal(config, userAgent, hostEventsSink, serviceClass, true /* randomize URLs */); }
@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) // want to allow unlimited time for uploads .maxNumRetries(0) .backoffSlotSize(Duration.ofMillis(10)) .build(), AGENT, hostEventsSink, OkHttpClientsTest.class); Request request = new Request.Builder() .url(url) .build(); Response synchronousCall = client.newCall(request).execute(); assertThat(synchronousCall.body().string()).isEqualTo("Hello, world!"); }
public final <T> T build(Class<T> serviceClass, UserAgent userAgent) { ObjectMapper objectMapper = getObjectMapper(); ObjectMapper cborObjectMapper = getCborObjectMapper(); Preconditions.checkNotNull(hostEventsSink, "hostEventsSink must be set"); okhttp3.OkHttpClient okHttpClient = OkHttpClients.create(config, userAgent, hostEventsSink, serviceClass); return Feign.builder() .contract(createContract()) .encoder( new ConjureInputStreamDelegateEncoder( new ConjureTextDelegateEncoder( new ConjureCborDelegateEncoder( cborObjectMapper, new JacksonEncoder(objectMapper))))) .decoder(createDecoder(objectMapper, cborObjectMapper)) .client(new OkHttpClient(okHttpClient)) .options(createRequestOptions()) .logLevel(Logger.Level.NONE) // we use OkHttp interceptors for logging. (note that NONE is the default) .retryer(new Retryer.Default(0, 0, 1)) // use OkHttp retry mechanism only .target(serviceClass, primaryUri); }
@VisibleForTesting static RemotingOkHttpClient withStableUris( ClientConfiguration config, UserAgent userAgent, HostEventsSink hostEventsSink, Class<?> serviceClass) { return createInternal(config, userAgent, hostEventsSink, serviceClass, false); }
private OkHttpClient createRetryingClient(int maxNumRetries, Duration backoffSlotSize, String... urls) { return OkHttpClients.withStableUris( ClientConfiguration.builder() .from(createTestConfig(urls)) .maxNumRetries(maxNumRetries) .backoffSlotSize(backoffSlotSize) .build(), AGENT, hostEventsSink, OkHttpClientsTest.class); } }
public final <T> T build(Class<T> serviceClass, UserAgent userAgent) { ObjectMapper objectMapper = getObjectMapper(); ObjectMapper cborObjectMapper = getCborObjectMapper(); Preconditions.checkNotNull(hostEventsSink, "hostEventsSink must be set"); okhttp3.OkHttpClient okHttpClient = OkHttpClients.create(config, userAgent, hostEventsSink, serviceClass); return Feign.builder() .contract(createContract()) .encoder( new ConjureInputStreamDelegateEncoder( new ConjureTextDelegateEncoder( new ConjureCborDelegateEncoder( cborObjectMapper, new JacksonEncoder(objectMapper))))) .decoder(createDecoder(objectMapper, cborObjectMapper)) .client(new OkHttpClient(okHttpClient)) .options(createRequestOptions()) .logLevel(Logger.Level.NONE) // we use OkHttp interceptors for logging. (note that NONE is the default) .retryer(new Retryer.Default(0, 0, 1)) // use OkHttp retry mechanism only .target(serviceClass, primaryUri); }
@VisibleForTesting static RemotingOkHttpClient withStableUris( ClientConfiguration config, UserAgent userAgent, HostEventsSink hostEventsSink, Class<?> serviceClass) { return createInternal(config, userAgent, hostEventsSink, serviceClass, false); }