From 32d1dd58795f8488bc41c9dc5c598e049a7bd11b Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 16 Dec 2024 10:50:58 -0500 Subject: [PATCH 1/7] Upgrade to Kotlin 2.1.0 --- gradle/libs.versions.toml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2e086d1301c..748c74c03b1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] -kotlin-version = "2.0.21" -ksp-version = "2.0.21-1.0.25" # Keep in sync with kotlin-version +kotlin-version = "2.1.0" +ksp-version = "2.1.0-1.0.29" # Keep in sync with kotlin-version dokka-version = "1.9.10" @@ -8,7 +8,8 @@ aws-kotlin-repo-tools-version = "0.4.14" # libs coroutines-version = "1.9.0" -atomicfu-version = "0.25.0" +atomicfu-version = "0.26.1" +binary-compatibility-validator-version = "0.16.3" # smithy-kotlin codegen and runtime are versioned separately smithy-kotlin-runtime-version = "1.3.29" @@ -140,7 +141,7 @@ dokka = { id = "org.jetbrains.dokka", version.ref = "dokka-version"} kotlin-jvm = {id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin-version" } kotlin-multiplatform = {id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin-version" } kotlinx-benchmark = { id = "org.jetbrains.kotlinx.benchmark", version.ref = "kotlinx-benchmark-version" } -kotlinx-binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.13.2" } +kotlinx-binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-compatibility-validator-version" } kotlinx-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin-version"} ksp = { id = "com.google.devtools.ksp", version.ref = "ksp-version" } aws-kotlin-repo-tools-kmp = { id = "aws.sdk.kotlin.gradle.kmp", version.ref = "aws-kotlin-repo-tools-version" } From fa2f7c5657abe557993618a5ef8c6982c40e8341 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 16 Dec 2024 10:53:41 -0500 Subject: [PATCH 2/7] Changelog --- .changes/0833e425-f3e6-4bea-a4ce-c2b73f7f39b6.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/0833e425-f3e6-4bea-a4ce-c2b73f7f39b6.json diff --git a/.changes/0833e425-f3e6-4bea-a4ce-c2b73f7f39b6.json b/.changes/0833e425-f3e6-4bea-a4ce-c2b73f7f39b6.json new file mode 100644 index 00000000000..4acb26b7b54 --- /dev/null +++ b/.changes/0833e425-f3e6-4bea-a4ce-c2b73f7f39b6.json @@ -0,0 +1,6 @@ +{ + "id": "0833e425-f3e6-4bea-a4ce-c2b73f7f39b6", + "type": "misc", + "description": "⚠️ **IMPORTANT**: Upgrade to Kotlin 2.1.0", + "requiresMinorVersionBump": true +} \ No newline at end of file From b1a58e52f970e996365ea7c197ad0e197296c181 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 16 Dec 2024 11:02:25 -0500 Subject: [PATCH 3/7] Downgrade atomicfu version to match internal import --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 748c74c03b1..83039ccfedf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ aws-kotlin-repo-tools-version = "0.4.14" # libs coroutines-version = "1.9.0" -atomicfu-version = "0.26.1" +atomicfu-version = "0.23.1" binary-compatibility-validator-version = "0.16.3" # smithy-kotlin codegen and runtime are versioned separately From f45e405aefd61e45e2d273fa78c02a8141e81051 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 16 Dec 2024 13:40:06 -0500 Subject: [PATCH 4/7] Bump to latest aws-kotlin-repo-tools version --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 83039ccfedf..98b26fa9ca6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ ksp-version = "2.1.0-1.0.29" # Keep in sync with kotlin-version dokka-version = "1.9.10" -aws-kotlin-repo-tools-version = "0.4.14" +aws-kotlin-repo-tools-version = "0.4.17" # libs coroutines-version = "1.9.0" From 98e652f0715cf923a2547a636182cea8c16715aa Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 16 Dec 2024 13:45:35 -0500 Subject: [PATCH 5/7] Revert atomicfu version --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 98b26fa9ca6..39e0af010ea 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ aws-kotlin-repo-tools-version = "0.4.17" # libs coroutines-version = "1.9.0" -atomicfu-version = "0.23.1" +atomicfu-version = "0.25.0" binary-compatibility-validator-version = "0.16.3" # smithy-kotlin codegen and runtime are versioned separately From 26e6b6657e1acf3a579b68b7e9fce09ef2165e9e Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 16 Dec 2024 14:43:20 -0500 Subject: [PATCH 6/7] Correct sync of BusinessMetricsInterceptor from v1.4 --- aws-runtime/aws-http/api/aws-http.api | 12 +-- .../BusinessMetricsInterceptor.kt | 88 ------------------- .../AwsBusinessMetricsUtils.kt | 22 ++++- .../BusinessMetricsInterceptor.kt | 6 +- 4 files changed, 26 insertions(+), 102 deletions(-) delete mode 100644 aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/BusinessMetricsInterceptor.kt diff --git a/aws-runtime/aws-http/api/aws-http.api b/aws-runtime/aws-http/api/aws-http.api index d677ed9a9dc..2c157dc2266 100644 --- a/aws-runtime/aws-http/api/aws-http.api +++ b/aws-runtime/aws-http/api/aws-http.api @@ -140,16 +140,6 @@ public final class aws/sdk/kotlin/runtime/http/interceptors/AddUserAgentMetadata public fun readBeforeTransmit (Laws/smithy/kotlin/runtime/client/ProtocolRequestInterceptorContext;)V } -public final class aws/sdk/kotlin/runtime/http/interceptors/AwsBusinessMetric : java/lang/Enum, aws/smithy/kotlin/runtime/businessmetrics/BusinessMetric { - public static final field DDB_MAPPER Laws/sdk/kotlin/runtime/http/interceptors/AwsBusinessMetric; - public static final field S3_EXPRESS_BUCKET Laws/sdk/kotlin/runtime/http/interceptors/AwsBusinessMetric; - public static fun getEntries ()Lkotlin/enums/EnumEntries; - public fun getIdentifier ()Ljava/lang/String; - public fun toString ()Ljava/lang/String; - public static fun valueOf (Ljava/lang/String;)Laws/sdk/kotlin/runtime/http/interceptors/AwsBusinessMetric; - public static fun values ()[Laws/sdk/kotlin/runtime/http/interceptors/AwsBusinessMetric; -} - public final class aws/sdk/kotlin/runtime/http/interceptors/AwsSpanInterceptor : aws/smithy/kotlin/runtime/client/Interceptor { public static final field INSTANCE Laws/sdk/kotlin/runtime/http/interceptors/AwsSpanInterceptor; public fun modifyBeforeAttemptCompletion-gIAlu-s (Laws/smithy/kotlin/runtime/client/ResponseInterceptorContext;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -197,9 +187,11 @@ public final class aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAl } public final class aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetric : java/lang/Enum, aws/smithy/kotlin/runtime/businessmetrics/BusinessMetric { + public static final field DDB_MAPPER Laws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetric; public static final field S3_EXPRESS_BUCKET Laws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetric; public static fun getEntries ()Lkotlin/enums/EnumEntries; public fun getIdentifier ()Ljava/lang/String; + public fun toString ()Ljava/lang/String; public static fun valueOf (Ljava/lang/String;)Laws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetric; public static fun values ()[Laws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetric; } diff --git a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/BusinessMetricsInterceptor.kt b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/BusinessMetricsInterceptor.kt deleted file mode 100644 index 5115ddf47cc..00000000000 --- a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/BusinessMetricsInterceptor.kt +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.sdk.kotlin.runtime.http.interceptors - -import aws.sdk.kotlin.runtime.http.BUSINESS_METRICS_MAX_LENGTH -import aws.sdk.kotlin.runtime.http.middleware.USER_AGENT -import aws.smithy.kotlin.runtime.InternalApi -import aws.smithy.kotlin.runtime.businessmetrics.BusinessMetric -import aws.smithy.kotlin.runtime.businessmetrics.BusinessMetrics -import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext -import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor -import aws.smithy.kotlin.runtime.http.request.HttpRequest -import aws.smithy.kotlin.runtime.http.request.toBuilder -import aws.smithy.kotlin.runtime.telemetry.logging.Logger -import aws.smithy.kotlin.runtime.telemetry.logging.logger -import kotlin.coroutines.coroutineContext - -/** - * Appends business metrics to the `User-Agent` header. - */ -public class BusinessMetricsInterceptor : HttpInterceptor { - override suspend fun modifyBeforeTransmit(context: ProtocolRequestInterceptorContext): HttpRequest { - val logger = coroutineContext.logger() - - context.executionContext.getOrNull(BusinessMetrics)?.let { metrics -> - val metricsString = formatMetrics(metrics, logger) - val currentUserAgentHeader = context.protocolRequest.headers[USER_AGENT] - val modifiedRequest = context.protocolRequest.toBuilder() - - modifiedRequest.headers[USER_AGENT] = currentUserAgentHeader + metricsString - - return modifiedRequest.build() - } - return context.protocolRequest - } -} - -/** - * Makes sure the metrics do not exceed the maximum size and truncates them if so. - * Makes sure that metric identifiers are not > 2 chars in length. Skips them if so. - */ -private fun formatMetrics(metrics: MutableSet, logger: Logger): String { - val allowedMetrics = metrics.filter { - if (it.identifier.length > 2) { - logger.warn { - "Business metric '${it.identifier}' will be skipped due to length being > 2. " + - "This is likely a bug. Please raise an issue at https://github.com/awslabs/aws-sdk-kotlin/issues/new/choose" - } - false - } else { - true - } - } - if (allowedMetrics.isEmpty()) return "" - val metricsString = allowedMetrics.joinToString(",", "m/") { it.identifier } - val metricsByteArray = metricsString.encodeToByteArray() - - if (metricsByteArray.size <= BUSINESS_METRICS_MAX_LENGTH) return metricsString - - val lastCommaIndex = metricsByteArray - .sliceArray(0 until 1024) - .indexOfLast { it == ','.code.toByte() } - .takeIf { it != -1 } - - lastCommaIndex?.let { - return metricsByteArray.decodeToString( - 0, - lastCommaIndex, - true, - ) - } - - throw IllegalStateException("Business metrics are incorrectly formatted: $metricsString") -} - -/** - * AWS SDK specific business metrics - */ -@InternalApi -public enum class AwsBusinessMetric(public override val identifier: String) : BusinessMetric { - S3_EXPRESS_BUCKET("J"), - DDB_MAPPER("d"), - ; - - override fun toString(): String = identifier -} diff --git a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetricsUtils.kt b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetricsUtils.kt index cf3d8586b3e..3be7620d27a 100644 --- a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetricsUtils.kt +++ b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetricsUtils.kt @@ -8,13 +8,26 @@ import aws.smithy.kotlin.runtime.businessmetrics.BusinessMetric import aws.smithy.kotlin.runtime.businessmetrics.emitBusinessMetric import aws.smithy.kotlin.runtime.collections.MutableAttributes import aws.smithy.kotlin.runtime.collections.toMutableAttributes +import aws.smithy.kotlin.runtime.telemetry.logging.Logger /** * Makes sure the metrics do not exceed the maximum size and truncates them if so. + * Makes sure that metric identifiers are not > 2 chars in length. Skips them if so. */ -internal fun formatMetrics(metrics: MutableSet): String { - if (metrics.isEmpty()) return "" - val metricsString = metrics.joinToString(",", "m/") { it.identifier } +internal fun formatMetrics(metrics: MutableSet, logger: Logger): String { + val allowedMetrics = metrics.filter { + if (it.identifier.length > 2) { + logger.warn { + "Business metric '${it.identifier}' will be skipped due to length being > 2. " + + "This is likely a bug. Please raise an issue at https://github.com/awslabs/aws-sdk-kotlin/issues/new/choose" + } + false + } else { + true + } + } + if (allowedMetrics.isEmpty()) return "" + val metricsString = allowedMetrics.joinToString(",", "m/") { it.identifier } val metricsByteArray = metricsString.encodeToByteArray() if (metricsByteArray.size <= BUSINESS_METRICS_MAX_LENGTH) return metricsString @@ -41,6 +54,7 @@ internal fun formatMetrics(metrics: MutableSet): String { @InternalApi public enum class AwsBusinessMetric(public override val identifier: String) : BusinessMetric { S3_EXPRESS_BUCKET("J"), + DDB_MAPPER("d"), ; @InternalApi @@ -64,6 +78,8 @@ public enum class AwsBusinessMetric(public override val identifier: String) : Bu CREDENTIALS_HTTP("z"), CREDENTIALS_IMDS("0"), } + + override fun toString(): String = identifier } /** diff --git a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/BusinessMetricsInterceptor.kt b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/BusinessMetricsInterceptor.kt index 43bed2aecf1..3e92416afe7 100644 --- a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/BusinessMetricsInterceptor.kt +++ b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/BusinessMetricsInterceptor.kt @@ -10,14 +10,18 @@ import aws.smithy.kotlin.runtime.client.ProtocolRequestInterceptorContext import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor import aws.smithy.kotlin.runtime.http.request.HttpRequest import aws.smithy.kotlin.runtime.http.request.toBuilder +import aws.smithy.kotlin.runtime.telemetry.logging.logger +import kotlin.coroutines.coroutineContext /** * Appends business metrics to the `User-Agent` header. */ public class BusinessMetricsInterceptor : HttpInterceptor { override suspend fun modifyBeforeTransmit(context: ProtocolRequestInterceptorContext): HttpRequest { + val logger = coroutineContext.logger() + context.executionContext.getOrNull(BusinessMetrics)?.let { metrics -> - val metricsString = formatMetrics(metrics) + val metricsString = formatMetrics(metrics, logger) val currentUserAgentHeader = context.protocolRequest.headers[USER_AGENT] val modifiedRequest = context.protocolRequest.toBuilder() From 2ba7e006dcf8aedc9bcab535b8d9571ffd7d6992 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Mon, 16 Dec 2024 14:47:06 -0500 Subject: [PATCH 7/7] ktlint --- .../interceptors/businessmetrics/AwsBusinessMetricsUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetricsUtils.kt b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetricsUtils.kt index 3be7620d27a..56f88433456 100644 --- a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetricsUtils.kt +++ b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/businessmetrics/AwsBusinessMetricsUtils.kt @@ -19,7 +19,7 @@ internal fun formatMetrics(metrics: MutableSet, logger: Logger): if (it.identifier.length > 2) { logger.warn { "Business metric '${it.identifier}' will be skipped due to length being > 2. " + - "This is likely a bug. Please raise an issue at https://github.com/awslabs/aws-sdk-kotlin/issues/new/choose" + "This is likely a bug. Please raise an issue at https://github.com/awslabs/aws-sdk-kotlin/issues/new/choose" } false } else {