Skip to content

Commit 34687a7

Browse files
fix: create MessageDigest when needed (#1906)
### 📝 Description `MessageDiggest` is NOT thread safe, if multiple queries are being executed concurrently it might cause a race condition and send back a `PersistedQueryIdInvalid` error https://opensource.expediagroup.com/graphql-kotlin/docs/server/automatic-persisted-queries/#errors instead we will create a `MessageDigest` instance each time.
1 parent 486bcbd commit 34687a7

File tree

4 files changed

+22
-23
lines changed

4 files changed

+22
-23
lines changed

clients/graphql-kotlin-client/src/main/kotlin/com/expediagroup/graphql/client/extensions/AutomaticPersistedQueriesExtensions.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ import java.math.BigInteger
66
import java.nio.charset.StandardCharsets
77
import java.security.MessageDigest
88

9-
internal val MESSAGE_DIGEST: MessageDigest = MessageDigest.getInstance("SHA-256")
10-
11-
fun GraphQLClientRequest<*>.getQueryId(): String =
12-
String.format(
9+
fun GraphQLClientRequest<*>.getQueryId(): String {
10+
val messageDigest = MessageDigest.getInstance("SHA-256")
11+
return String.format(
1312
"%064x",
14-
BigInteger(1, MESSAGE_DIGEST.digest(this.query?.toByteArray(StandardCharsets.UTF_8)))
15-
).also {
16-
MESSAGE_DIGEST.reset()
17-
}
13+
BigInteger(1, messageDigest.digest(this.query?.toByteArray(StandardCharsets.UTF_8)))
14+
)
15+
}
16+
17+
fun AutomaticPersistedQueriesExtension.toQueryParamString(): String =
18+
"""{"persistedQuery":{"version":$version,"sha256Hash":"$sha256Hash"}}"""
1819

19-
fun AutomaticPersistedQueriesExtension.toQueryParamString() = """{"persistedQuery":{"version":$version,"sha256Hash":"$sha256Hash"}}"""
20-
fun AutomaticPersistedQueriesExtension.toExtentionsBodyMap() = mapOf(
20+
fun AutomaticPersistedQueriesExtension.toExtensionsBodyMap(): Map<String, Map<String, Any>> = mapOf(
2121
"persistedQuery" to mapOf(
2222
"version" to version,
2323
"sha256Hash" to sha256Hash

clients/graphql-kotlin-ktor-client/src/main/kotlin/com/expediagroup/graphql/client/ktor/GraphQLKtorClient.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package com.expediagroup.graphql.client.ktor
1818

1919
import com.expediagroup.graphql.client.GraphQLClient
2020
import com.expediagroup.graphql.client.extensions.getQueryId
21-
import com.expediagroup.graphql.client.extensions.toExtentionsBodyMap
21+
import com.expediagroup.graphql.client.extensions.toExtensionsBodyMap
2222
import com.expediagroup.graphql.client.extensions.toQueryParamString
2323
import com.expediagroup.graphql.client.serializer.GraphQLClientSerializer
2424
import com.expediagroup.graphql.client.serializer.defaultGraphQLSerializer
@@ -60,8 +60,8 @@ open class GraphQLKtorClient(
6060
sha256Hash = queryId
6161
)
6262
val extensions = request.extensions?.let {
63-
automaticPersistedQueriesExtension.toExtentionsBodyMap().plus(it)
64-
} ?: automaticPersistedQueriesExtension.toExtentionsBodyMap()
63+
automaticPersistedQueriesExtension.toExtensionsBodyMap().plus(it)
64+
} ?: automaticPersistedQueriesExtension.toExtensionsBodyMap()
6565

6666
val apqRawResultWithoutQuery: String = when (automaticPersistedQueriesSettings.httpMethod) {
6767
is AutomaticPersistedQueriesSettings.HttpMethod.GET -> {

clients/graphql-kotlin-spring-client/src/main/kotlin/com/expediagroup/graphql/client/spring/GraphQLWebClient.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package com.expediagroup.graphql.client.spring
1818

1919
import com.expediagroup.graphql.client.GraphQLClient
2020
import com.expediagroup.graphql.client.extensions.getQueryId
21-
import com.expediagroup.graphql.client.extensions.toExtentionsBodyMap
21+
import com.expediagroup.graphql.client.extensions.toExtensionsBodyMap
2222
import com.expediagroup.graphql.client.extensions.toQueryParamString
2323
import com.expediagroup.graphql.client.serializer.GraphQLClientSerializer
2424
import com.expediagroup.graphql.client.serializer.defaultGraphQLSerializer
@@ -63,8 +63,8 @@ open class GraphQLWebClient(
6363
sha256Hash = queryId
6464
)
6565
val extensions = request.extensions?.let {
66-
automaticPersistedQueriesExtension.toExtentionsBodyMap().plus(it)
67-
} ?: automaticPersistedQueriesExtension.toExtentionsBodyMap()
66+
automaticPersistedQueriesExtension.toExtensionsBodyMap().plus(it)
67+
} ?: automaticPersistedQueriesExtension.toExtensionsBodyMap()
6868

6969
val apqRawResultWithoutQuery: String = when (automaticPersistedQueriesSettings.httpMethod) {
7070
is AutomaticPersistedQueriesSettings.HttpMethod.GET -> {

executions/graphql-kotlin-automatic-persisted-queries/src/main/kotlin/com/expediagroup/graphql/apq/extensions/executionInputExtensions.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import java.nio.charset.StandardCharsets
2323
import java.security.MessageDigest
2424

2525
internal const val APQ_EXTENSION_KEY: String = "persistedQuery"
26-
internal val MESSAGE_DIGEST: MessageDigest = MessageDigest.getInstance("SHA-256")
2726

2827
@Suppress("UNCHECKED_CAST")
2928
fun ExecutionInput.getAutomaticPersistedQueriesExtension(): AutomaticPersistedQueriesExtension? =
@@ -34,13 +33,13 @@ fun ExecutionInput.getAutomaticPersistedQueriesExtension(): AutomaticPersistedQu
3433
null
3534
}
3635

37-
fun ExecutionInput.getQueryId(): String =
38-
String.format(
36+
fun ExecutionInput.getQueryId(): String {
37+
val messageDigest = MessageDigest.getInstance("SHA-256")
38+
return String.format(
3939
"%064x",
40-
BigInteger(1, MESSAGE_DIGEST.digest(this.query.toByteArray(StandardCharsets.UTF_8)))
41-
).also {
42-
MESSAGE_DIGEST.reset()
43-
}
40+
BigInteger(1, messageDigest.digest(this.query.toByteArray(StandardCharsets.UTF_8)))
41+
)
42+
}
4443

4544
fun ExecutionInput.isAutomaticPersistedQueriesExtensionInvalid(
4645
extension: AutomaticPersistedQueriesExtension

0 commit comments

Comments
 (0)