Skip to content

Commit 1b85d3d

Browse files
authored
[plugin] change httpclient from CIO to Apache for tasks (ExpediaGroup#1162)
It looks like using CIO engine causes some issues with the classpath (ExpediaGroup#1084). Unsure what is the root cause of the classpath issue - it looks like CIO engine relies on coroutines-core `native-mt` vs regular artifact that we pull in. Switching to a different engine seems to resolve the classpath issue.
1 parent 4c23dda commit 1b85d3d

File tree

7 files changed

+45
-31
lines changed

7 files changed

+45
-31
lines changed

plugins/client/graphql-kotlin-client-generator/build.gradle.kts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ description = "GraphQL Kotlin common utilities to generate a client."
22

33
val compileTestingVersion: String by project
44
val graphQLJavaVersion: String by project
5+
val jacksonVersion: String by project
56
val junitVersion: String by project
67
val kotlinPoetVersion: String by project
78
val kotlinxSerializationVersion: String by project
@@ -15,8 +16,12 @@ dependencies {
1516
}
1617
api("com.squareup:kotlinpoet:$kotlinPoetVersion")
1718
api("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinxSerializationVersion")
18-
implementation("io.ktor:ktor-client-cio:$ktorVersion")
19-
implementation("io.ktor:ktor-client-jackson:$ktorVersion")
19+
implementation("io.ktor:ktor-client-apache:$ktorVersion")
20+
implementation("io.ktor:ktor-client-jackson:$ktorVersion") {
21+
exclude("com.fasterxml.jackson.core", "jackson-databind")
22+
exclude("com.fasterxml.jackson.module", "jackson-module-kotlin")
23+
}
24+
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion")
2025
testImplementation(project(path = ":graphql-kotlin-client-jackson"))
2126
testImplementation("com.github.tomakehurst:wiremock-jre8:$wireMockVersion")
2227
testImplementation("com.github.tschuchortdev:kotlin-compile-testing:$compileTestingVersion")

plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/downloadSchema.kt

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ package com.expediagroup.graphql.plugin.client
1818

1919
import graphql.schema.idl.SchemaParser
2020
import io.ktor.client.HttpClient
21-
import io.ktor.client.engine.cio.CIO
22-
import io.ktor.client.engine.cio.endpoint
21+
import io.ktor.client.engine.apache.Apache
2322
import io.ktor.client.features.ClientRequestException
23+
import io.ktor.client.features.HttpRequestTimeoutException
24+
import io.ktor.client.features.HttpTimeout
2425
import io.ktor.client.request.get
2526
import io.ktor.client.request.header
26-
import kotlinx.coroutines.TimeoutCancellationException
2727
import kotlinx.coroutines.runBlocking
28+
import java.net.UnknownHostException
2829

2930
/**
3031
* Downloads GraphQL SDL from the specified endpoint and verifies whether the result is a valid GraphQL schema.
@@ -34,12 +35,10 @@ fun downloadSchema(
3435
httpHeaders: Map<String, Any> = emptyMap(),
3536
connectTimeout: Long = 5_000,
3637
readTimeout: Long = 15_000
37-
): String = HttpClient(engineFactory = CIO) {
38-
engine {
39-
this.requestTimeout = readTimeout
40-
endpoint {
41-
this.connectTimeout = connectTimeout
42-
}
38+
): String = HttpClient(engineFactory = Apache) {
39+
install(HttpTimeout) {
40+
connectTimeoutMillis = connectTimeout
41+
requestTimeoutMillis = readTimeout
4342
}
4443
}.use { client ->
4544
runBlocking {
@@ -51,7 +50,7 @@ fun downloadSchema(
5150
}
5251
} catch (e: Throwable) {
5352
when (e) {
54-
is ClientRequestException, is TimeoutCancellationException -> throw e
53+
is ClientRequestException, is HttpRequestTimeoutException, is UnknownHostException -> throw e
5554
else -> throw RuntimeException("Unable to download SDL from specified endpoint=$endpoint", e)
5655
}
5756
}

plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/introspectSchema.kt

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,18 @@ package com.expediagroup.graphql.plugin.client
1919
import graphql.introspection.IntrospectionResultToSchema
2020
import graphql.schema.idl.SchemaPrinter
2121
import io.ktor.client.HttpClient
22-
import io.ktor.client.engine.cio.CIO
23-
import io.ktor.client.engine.cio.endpoint
22+
import io.ktor.client.engine.apache.Apache
2423
import io.ktor.client.features.ClientRequestException
24+
import io.ktor.client.features.HttpRequestTimeoutException
25+
import io.ktor.client.features.HttpTimeout
2526
import io.ktor.client.features.json.JsonFeature
2627
import io.ktor.client.request.header
2728
import io.ktor.client.request.post
2829
import io.ktor.client.request.url
2930
import io.ktor.http.ContentType
3031
import io.ktor.http.contentType
31-
import kotlinx.coroutines.TimeoutCancellationException
3232
import kotlinx.coroutines.runBlocking
33+
import java.net.UnknownHostException
3334

3435
private const val INTROSPECTION_QUERY =
3536
"""
@@ -131,12 +132,10 @@ fun introspectSchema(
131132
httpHeaders: Map<String, Any> = emptyMap(),
132133
connectTimeout: Long = 5_000,
133134
readTimeout: Long = 15_000
134-
): String = HttpClient(engineFactory = CIO) {
135-
engine {
136-
requestTimeout = readTimeout
137-
endpoint {
138-
this.connectTimeout = connectTimeout
139-
}
135+
): String = HttpClient(engineFactory = Apache) {
136+
install(HttpTimeout) {
137+
connectTimeoutMillis = connectTimeout
138+
requestTimeoutMillis = readTimeout
140139
}
141140
install(feature = JsonFeature)
142141
}.use { client ->
@@ -155,7 +154,7 @@ fun introspectSchema(
155154
}
156155
} catch (e: Throwable) {
157156
when (e) {
158-
is ClientRequestException, is TimeoutCancellationException -> throw e
157+
is ClientRequestException, is HttpRequestTimeoutException, is UnknownHostException -> throw e
159158
else -> throw RuntimeException("Unable to run introspection query against the specified endpoint=$endpoint", e)
160159
}
161160
}

plugins/client/graphql-kotlin-client-generator/src/test/kotlin/com/expediagroup/graphql/plugin/client/DownloadSchemaTest.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ import com.github.tomakehurst.wiremock.client.WireMock.stubFor
2424
import com.github.tomakehurst.wiremock.core.WireMockConfiguration
2525
import graphql.schema.idl.errors.SchemaProblem
2626
import io.ktor.client.features.ClientRequestException
27+
import io.ktor.client.features.HttpRequestTimeoutException
2728
import io.ktor.util.KtorExperimentalAPI
28-
import kotlinx.coroutines.TimeoutCancellationException
2929
import kotlinx.coroutines.runBlocking
3030
import org.junit.jupiter.api.AfterAll
3131
import org.junit.jupiter.api.BeforeAll
3232
import org.junit.jupiter.api.BeforeEach
3333
import org.junit.jupiter.api.Test
3434
import org.junit.jupiter.api.assertThrows
35-
import java.nio.channels.UnresolvedAddressException
35+
import java.net.UnknownHostException
3636
import kotlin.test.assertEquals
3737
import kotlin.test.assertTrue
3838

@@ -97,12 +97,11 @@ class DownloadSchemaTest {
9797
@Test
9898
@KtorExperimentalAPI
9999
fun `verify downloadSchema will throw exception if URL is not valid`() {
100-
val exception = assertThrows<RuntimeException> {
100+
assertThrows<UnknownHostException> {
101101
runBlocking {
102102
downloadSchema("https://non-existent-graphql-url.com/should_404")
103103
}
104104
}
105-
assertTrue(exception.cause is UnresolvedAddressException)
106105
}
107106

108107
@Test
@@ -147,7 +146,7 @@ class DownloadSchemaTest {
147146
.withFixedDelay(1_000)
148147
)
149148
)
150-
assertThrows<TimeoutCancellationException> {
149+
assertThrows<HttpRequestTimeoutException> {
151150
runBlocking {
152151
downloadSchema(endpoint = "${wireMockServer.baseUrl()}/sdl", connectTimeout = 100, readTimeout = 100)
153152
}

plugins/client/graphql-kotlin-client-generator/src/test/kotlin/com/expediagroup/graphql/plugin/client/IntrospectSchemaTest.kt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@ import com.github.tomakehurst.wiremock.WireMockServer
2020
import com.github.tomakehurst.wiremock.client.WireMock
2121
import com.github.tomakehurst.wiremock.core.WireMockConfiguration
2222
import io.ktor.client.features.ClientRequestException
23+
import io.ktor.client.features.HttpRequestTimeoutException
2324
import io.ktor.util.KtorExperimentalAPI
24-
import kotlinx.coroutines.TimeoutCancellationException
2525
import kotlinx.coroutines.runBlocking
2626
import org.junit.jupiter.api.AfterAll
2727
import org.junit.jupiter.api.BeforeAll
2828
import org.junit.jupiter.api.BeforeEach
2929
import org.junit.jupiter.api.Test
3030
import org.junit.jupiter.api.assertThrows
3131
import java.io.BufferedReader
32+
import java.net.UnknownHostException
3233
import kotlin.test.assertEquals
3334

3435
class IntrospectSchemaTest {
@@ -129,13 +130,23 @@ class IntrospectSchemaTest {
129130
.withFixedDelay(1_000)
130131
)
131132
)
132-
assertThrows<TimeoutCancellationException> {
133+
assertThrows<HttpRequestTimeoutException> {
133134
runBlocking {
134135
introspectSchema(endpoint = "${wireMockServer.baseUrl()}/graphql", connectTimeout = 100, readTimeout = 100)
135136
}
136137
}
137138
}
138139

140+
@Test
141+
@KtorExperimentalAPI
142+
fun `verify introspectSchema will throw exception if URL is not valid`() {
143+
assertThrows<UnknownHostException> {
144+
runBlocking {
145+
downloadSchema("https://non-existent-graphql-url.com/should_404")
146+
}
147+
}
148+
}
149+
139150
companion object {
140151
private val wireMockServer: WireMockServer = WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort())
141152

plugins/graphql-kotlin-gradle-plugin/src/test/kotlin/com/expediagroup/graphql/plugin/gradle/tasks/GraphQLDownloadSDLTaskIT.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ class GraphQLDownloadSDLTaskIT : GraphQLGradlePluginAbstractIT() {
154154
.withArguments(DOWNLOAD_SDL_TASK_NAME, "--stacktrace")
155155
.buildAndFail()
156156

157+
println(result.output)
157158
assertEquals(TaskOutcome.FAILED, result.task(":$DOWNLOAD_SDL_TASK_NAME")?.outcome)
158-
assertTrue(result.output.contains("Timed out waiting for 100 ms", ignoreCase = true))
159+
assertTrue(result.output.contains("Request timeout has been expired", ignoreCase = true))
159160
}
160161
}

plugins/graphql-kotlin-gradle-plugin/src/test/kotlin/com/expediagroup/graphql/plugin/gradle/tasks/GraphQLIntrospectSchemaTaskIT.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,6 @@ class GraphQLIntrospectSchemaTaskIT : GraphQLGradlePluginAbstractIT() {
152152
.buildAndFail()
153153

154154
assertEquals(TaskOutcome.FAILED, result.task(":$INTROSPECT_SCHEMA_TASK_NAME")?.outcome)
155-
assertTrue(result.output.contains("Timed out waiting for 100 ms", ignoreCase = true))
155+
assertTrue(result.output.contains("Request timeout has been expired", ignoreCase = true))
156156
}
157157
}

0 commit comments

Comments
 (0)