Skip to content

Commit 70b841d

Browse files
committed
Allow users to configure a custom OkHttpClient
1 parent 23d869a commit 70b841d

File tree

3 files changed

+43
-23
lines changed

3 files changed

+43
-23
lines changed

runtime/protocol/http-client-engines/http-client-engine-okhttp/api/http-client-engine-okhttp.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public final class aws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpEngine : a
5353
public static final field Companion Laws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpEngine$Companion;
5454
public fun <init> ()V
5555
public fun <init> (Laws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpEngineConfig;)V
56+
public fun <init> (Lokhttp3/OkHttpClient;)V
5657
public synthetic fun getConfig ()Laws/smithy/kotlin/runtime/http/engine/HttpClientEngineConfig;
5758
public fun getConfig ()Laws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpEngineConfig;
5859
public fun roundTrip (Laws/smithy/kotlin/runtime/operation/ExecutionContext;Laws/smithy/kotlin/runtime/http/request/HttpRequest;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;

runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/src/aws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpEngine.kt

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,27 @@ public class OkHttpEngine(
3838
override val config: OkHttpEngineConfig,
3939
) : HttpClientEngineBase("OkHttp") {
4040
public constructor() : this(OkHttpEngineConfig.Default)
41+
public constructor(client: OkHttpClient) : this(OkHttpEngineConfig.Default) {
42+
this.manageClient = false
43+
44+
// destroy our client
45+
this.client.apply {
46+
connectionPool.evictAll()
47+
dispatcher.executorService.shutdown()
48+
}
49+
50+
// use the user-provided client, configured with metrics collection
51+
this.client = client.newBuilder().apply {
52+
eventListenerFactory { call ->
53+
EventListenerChain(
54+
listOf(
55+
HttpEngineEventListener(client.connectionPool, config.hostResolver, client.dispatcher, metrics, call)
56+
)
57+
)
58+
}
59+
addInterceptor(MetricsInterceptor)
60+
}.build()
61+
}
4162

4263
public companion object : EngineFactory<OkHttpEngineConfig.Builder, OkHttpEngine> {
4364
/**
@@ -57,7 +78,8 @@ public class OkHttpEngine(
5778
}
5879

5980
private val metrics = HttpClientMetrics(TELEMETRY_SCOPE, config.telemetryProvider)
60-
private val client = config.buildClient(metrics, connectionMonitoringListener)
81+
private var client = config.buildClient(metrics, connectionMonitoringListener)
82+
private var manageClient = true // whether the SDK should manage the underlying OkHttpClient client
6183

6284
@OptIn(ExperimentalCoroutinesApi::class)
6385
override suspend fun roundTrip(context: ExecutionContext, request: HttpRequest): HttpCall {
@@ -85,9 +107,11 @@ public class OkHttpEngine(
85107

86108
override fun shutdown() {
87109
connectionMonitoringListener?.closeIfCloseable()
88-
client.connectionPool.evictAll()
89-
client.dispatcher.executorService.shutdown()
90110
metrics.close()
111+
if (manageClient) {
112+
client.connectionPool.evictAll()
113+
client.dispatcher.executorService.shutdown()
114+
}
91115
}
92116
}
93117

runtime/protocol/http-client-engines/http-client-engine-okhttp/jvm/test/aws/smithy/kotlin/runtime/http/engine/okhttp/OkHttpEngineConfigTest.kt

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,38 @@ package aws.smithy.kotlin.runtime.http.engine.okhttp
66

77
import aws.smithy.kotlin.runtime.content.ByteStream
88
import aws.smithy.kotlin.runtime.http.Headers
9+
import aws.smithy.kotlin.runtime.http.HttpException
910
import aws.smithy.kotlin.runtime.http.HttpMethod
10-
import aws.smithy.kotlin.runtime.http.engine.internal.HttpClientMetrics
11+
import aws.smithy.kotlin.runtime.http.SdkHttpClient
1112
import aws.smithy.kotlin.runtime.http.request.HttpRequest
1213
import aws.smithy.kotlin.runtime.http.toHttpBody
1314
import aws.smithy.kotlin.runtime.net.url.Url
14-
import aws.smithy.kotlin.runtime.operation.ExecutionContext
15-
import aws.smithy.kotlin.runtime.telemetry.TelemetryProvider
1615
import kotlinx.coroutines.test.runTest
17-
import okhttp3.coroutines.executeAsync
18-
import java.util.concurrent.ExecutorService
19-
import java.util.concurrent.Executors
16+
import okhttp3.OkHttpClient
17+
import java.io.IOException
2018
import kotlin.test.Test
2119
import kotlin.test.assertFailsWith
20+
import kotlin.test.assertTrue
2221

2322
class OkHttpEngineConfigTest {
2423
@Test
25-
fun testExecutorService() = runTest {
26-
val config = OkHttpEngineConfig {
27-
executorService = DummyExecutorService
28-
}
24+
fun testUserClient() = runTest {
25+
val userClient = OkHttpClient.Builder().apply {
26+
addInterceptor { throw DummyOkHttpClientException() }
27+
}.build()
2928

30-
val metrics = HttpClientMetrics("foo", TelemetryProvider.None)
31-
val engine = config.buildClient(metrics)
29+
val engine = OkHttpEngine(userClient)
30+
val sdkClient = SdkHttpClient(engine)
3231

3332
val data = "a".repeat(100)
3433
val url = Url.parse("https://aws.amazon.com")
3534
val request = HttpRequest(HttpMethod.POST, url, Headers.Empty, ByteStream.fromString(data).toHttpBody())
36-
val okRequest = request.toOkHttpRequest(ExecutionContext(), coroutineContext, metrics)
3735

38-
assertFailsWith<DummyExecutorException> {
39-
engine.newCall(okRequest).executeAsync()
36+
val ex = assertFailsWith<HttpException> {
37+
sdkClient.call(request)
4038
}
39+
assertTrue(ex.cause is DummyOkHttpClientException)
4140
}
4241

43-
private object DummyExecutorService : ExecutorService by Executors.newSingleThreadExecutor() {
44-
override fun execute(command: Runnable?) = throw DummyExecutorException()
45-
}
46-
47-
private class DummyExecutorException : Exception()
42+
private class DummyOkHttpClientException : IOException("Custom OkHttpClient interceptor was called")
4843
}

0 commit comments

Comments
 (0)