Skip to content

Commit f0fd110

Browse files
committed
Merge branch 'kn-main' into kn-merge
2 parents 81d7e6a + 9d7c834 commit f0fd110

File tree

88 files changed

+1666
-1393
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+1666
-1393
lines changed

.brazil.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{
22
"dependencies": {
3-
"org.jetbrains.kotlin:kotlin-stdlib:2.0.*": "KotlinStdlib-2.x",
3+
"org.jetbrains.kotlin:kotlin-stdlib:2.*": "KotlinStdlib-2.x",
44
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.*": "KotlinxCoroutinesCoreJvm-1.x",
55

66
"com.squareup.okhttp3:okhttp-coroutines:5.*": "OkHttp3Coroutines-5.x",
77
"com.squareup.okhttp3:okhttp:5.*": "OkHttp3-5.x",
88
"com.squareup.okio:okio-jvm:3.*": "OkioJvm-3.x",
99
"io.opentelemetry:opentelemetry-api:1.*": "Maven-io-opentelemetry_opentelemetry-api-1.x",
1010
"org.slf4j:slf4j-api:2.*": "Maven-org-slf4j_slf4j-api-2.x",
11+
"aws.sdk.kotlin.crt:aws-crt-kotlin:0.9.*": "AwsCrtKotlin-0.9.x",
1112
"aws.sdk.kotlin.crt:aws-crt-kotlin:0.8.*": "AwsCrtKotlin-0.8.x",
1213
"com.squareup.okhttp3:okhttp:4.*": "OkHttp3-4.x"
1314
},

.github/workflows/continuous-integration.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ jobs:
170170
171171
- name: Save Test Reports
172172
if: failure()
173-
uses: actions/upload-artifact@v3
173+
uses: actions/upload-artifact@v4
174174
with:
175175
name: test-reports-${{ matrix.os }}
176176
path: '**/build/reports'

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## [1.4.1] - 01/16/2025
4+
5+
## [1.4.0] - 01/15/2025
6+
7+
### Features
8+
* [#1431](https://github.com/awslabs/aws-sdk-kotlin/issues/1431) ⚠️ **IMPORTANT**: Add `retryStrategy` configuration option for waiters
9+
10+
### Fixes
11+
* [#1321](https://github.com/awslabs/aws-sdk-kotlin/issues/1321) Include more information when retry strategy halts early due to token bucket capacity errors
12+
13+
### Miscellaneous
14+
* ⚠️ **IMPORTANT**: Upgrade to Kotlin 2.1.0
15+
316
## [1.3.34] - 01/10/2025
417

518
## [1.3.33] - 01/10/2025

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinDependency.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ private fun getDefaultRuntimeVersion(): String {
3737
// publishing info
3838
const val RUNTIME_GROUP: String = "aws.smithy.kotlin"
3939
val RUNTIME_VERSION: String = System.getProperty("smithy.kotlin.codegen.clientRuntimeVersion", getDefaultRuntimeVersion())
40-
val KOTLIN_COMPILER_VERSION: String = System.getProperty("smithy.kotlin.codegen.kotlinCompilerVersion", "2.0.10")
40+
val KOTLIN_COMPILER_VERSION: String = System.getProperty("smithy.kotlin.codegen.kotlinCompilerVersion", "2.1.0")
4141

4242
enum class SourceSet {
4343
CommonMain,

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ object RuntimeTypes {
8181
object Interceptors : RuntimeTypePackage(KotlinDependency.HTTP, "interceptors") {
8282
val ContinueInterceptor = symbol("ContinueInterceptor")
8383
val HttpInterceptor = symbol("HttpInterceptor")
84-
val Md5ChecksumInterceptor = symbol("Md5ChecksumInterceptor")
84+
val HttpChecksumRequiredInterceptor = symbol("HttpChecksumRequiredInterceptor")
8585
val FlexibleChecksumsRequestInterceptor = symbol("FlexibleChecksumsRequestInterceptor")
8686
val FlexibleChecksumsResponseInterceptor = symbol("FlexibleChecksumsResponseInterceptor")
8787
val ResponseLengthValidationInterceptor = symbol("ResponseLengthValidationInterceptor")
@@ -231,6 +231,9 @@ object RuntimeTypes {
231231
object Config : RuntimeTypePackage(KotlinDependency.SMITHY_CLIENT, "config") {
232232
val RequestCompressionConfig = symbol("RequestCompressionConfig")
233233
val CompressionClientConfig = symbol("CompressionClientConfig")
234+
val HttpChecksumConfig = symbol("HttpChecksumConfig")
235+
val RequestHttpChecksumConfig = symbol("RequestHttpChecksumConfig")
236+
val ResponseHttpChecksumConfig = symbol("ResponseHttpChecksumConfig")
234237
}
235238

236239
object Endpoints : RuntimeTypePackage(KotlinDependency.SMITHY_CLIENT, "endpoints") {
@@ -395,6 +398,7 @@ object RuntimeTypes {
395398
val TelemetryContextElement = symbol("TelemetryContextElement", "context")
396399
val TraceSpan = symbol("TraceSpan", "trace")
397400
val withSpan = symbol("withSpan", "trace")
401+
val warn = symbol("warn", "logging")
398402
}
399403
object TelemetryDefaults : RuntimeTypePackage(KotlinDependency.TELEMETRY_DEFAULTS) {
400404
val Global = symbol("Global")
@@ -409,6 +413,7 @@ object RuntimeTypes {
409413

410414
val CompletableDeferred = "kotlinx.coroutines.CompletableDeferred".toSymbol()
411415
val job = "kotlinx.coroutines.job".toSymbol()
416+
val runBlocking = "kotlinx.coroutines.runBlocking".toSymbol()
412417

413418
object Flow {
414419
// NOTE: smithy-kotlin core has an API dependency on this already
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package software.amazon.smithy.kotlin.codegen.rendering.checksums
2+
3+
import software.amazon.smithy.aws.traits.HttpChecksumTrait
4+
import software.amazon.smithy.kotlin.codegen.KotlinSettings
5+
import software.amazon.smithy.kotlin.codegen.core.KotlinWriter
6+
import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes
7+
import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration
8+
import software.amazon.smithy.kotlin.codegen.model.hasTrait
9+
import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolGenerator
10+
import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolMiddleware
11+
import software.amazon.smithy.model.Model
12+
import software.amazon.smithy.model.shapes.OperationShape
13+
import software.amazon.smithy.model.traits.HttpChecksumRequiredTrait
14+
15+
/**
16+
* Handles the `httpChecksumRequired` trait.
17+
* See: https://smithy.io/2.0/spec/http-bindings.html#httpchecksumrequired-trait
18+
*/
19+
class HttpChecksumRequiredIntegration : KotlinIntegration {
20+
override fun enabledForService(model: Model, settings: KotlinSettings): Boolean =
21+
model.isTraitApplied(HttpChecksumRequiredTrait::class.java)
22+
23+
override fun customizeMiddleware(
24+
ctx: ProtocolGenerator.GenerationContext,
25+
resolved: List<ProtocolMiddleware>,
26+
): List<ProtocolMiddleware> = resolved + httpChecksumRequiredDefaultAlgorithmMiddleware + httpChecksumRequiredMiddleware
27+
}
28+
29+
/**
30+
* Adds default checksum algorithm to the execution context
31+
*/
32+
private val httpChecksumRequiredDefaultAlgorithmMiddleware = object : ProtocolMiddleware {
33+
override val name: String = "httpChecksumRequiredDefaultAlgorithmMiddleware"
34+
override val order: Byte = -2 // Before S3 Express (possibly) changes the default (-1) and before calculating checksum (0)
35+
36+
override fun isEnabledFor(ctx: ProtocolGenerator.GenerationContext, op: OperationShape): Boolean =
37+
op.hasTrait<HttpChecksumRequiredTrait>() && !op.hasTrait<HttpChecksumTrait>()
38+
39+
override fun render(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, writer: KotlinWriter) {
40+
writer.write(
41+
"op.context[#T.DefaultChecksumAlgorithm] = #S",
42+
RuntimeTypes.HttpClient.Operation.HttpOperationContext,
43+
"MD5",
44+
)
45+
}
46+
}
47+
48+
/**
49+
* Adds interceptor to calculate request checksums.
50+
* The `httpChecksum` trait supersedes the `httpChecksumRequired` trait. If both are applied to an operation use `httpChecksum`.
51+
*
52+
* See: https://smithy.io/2.0/aws/aws-core.html#behavior-with-httpchecksumrequired
53+
*/
54+
private val httpChecksumRequiredMiddleware = object : ProtocolMiddleware {
55+
override val name: String = "httpChecksumRequiredMiddleware"
56+
57+
override fun isEnabledFor(ctx: ProtocolGenerator.GenerationContext, op: OperationShape): Boolean =
58+
op.hasTrait<HttpChecksumRequiredTrait>() && !op.hasTrait<HttpChecksumTrait>()
59+
60+
override fun render(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, writer: KotlinWriter) {
61+
writer.write(
62+
"op.interceptors.add(#T())",
63+
RuntimeTypes.HttpClient.Interceptors.HttpChecksumRequiredInterceptor,
64+
)
65+
}
66+
}

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpProtocolClientGenerator.kt

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
package software.amazon.smithy.kotlin.codegen.rendering.protocol
66

7-
import software.amazon.smithy.aws.traits.HttpChecksumTrait
87
import software.amazon.smithy.codegen.core.Symbol
98
import software.amazon.smithy.kotlin.codegen.core.*
109
import software.amazon.smithy.kotlin.codegen.integration.SectionId
@@ -22,7 +21,6 @@ import software.amazon.smithy.model.knowledge.OperationIndex
2221
import software.amazon.smithy.model.knowledge.TopDownIndex
2322
import software.amazon.smithy.model.shapes.OperationShape
2423
import software.amazon.smithy.model.traits.EndpointTrait
25-
import software.amazon.smithy.model.traits.HttpChecksumRequiredTrait
2624

2725
/**
2826
* Renders an implementation of a service interface for HTTP protocol
@@ -318,8 +316,6 @@ open class HttpProtocolClientGenerator(
318316
.forEach { middleware ->
319317
middleware.render(ctx, op, writer)
320318
}
321-
322-
op.renderIsMd5ChecksumRequired(writer)
323319
}
324320

325321
/**
@@ -336,27 +332,6 @@ open class HttpProtocolClientGenerator(
336332
*/
337333
protected open fun renderAdditionalMethods(writer: KotlinWriter) { }
338334

339-
/**
340-
* Render optionally installing Md5ChecksumMiddleware.
341-
* The Md5 middleware will only be installed if the operation requires a checksum and the user has not opted-in to flexible checksums.
342-
*/
343-
private fun OperationShape.renderIsMd5ChecksumRequired(writer: KotlinWriter) {
344-
val httpChecksumTrait = getTrait<HttpChecksumTrait>()
345-
346-
// the checksum requirement can be modeled in either HttpChecksumTrait's `requestChecksumRequired` or the HttpChecksumRequired trait
347-
if (!hasTrait<HttpChecksumRequiredTrait>() && httpChecksumTrait == null) {
348-
return
349-
}
350-
351-
if (hasTrait<HttpChecksumRequiredTrait>() || httpChecksumTrait?.isRequestChecksumRequired == true) {
352-
val interceptorSymbol = RuntimeTypes.HttpClient.Interceptors.Md5ChecksumInterceptor
353-
val inputSymbol = ctx.symbolProvider.toSymbol(ctx.model.expectShape(inputShape))
354-
writer.withBlock("op.interceptors.add(#T<#T> {", "})", interceptorSymbol, inputSymbol) {
355-
writer.write("op.context.getOrNull(#T.ChecksumAlgorithm) == null", RuntimeTypes.HttpClient.Operation.HttpOperationContext)
356-
}
357-
}
358-
}
359-
360335
/**
361336
* render a utility function to populate an operation's ExecutionContext with defaults from service config, environment, etc
362337
*/

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/WaiterGenerator.kt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import java.text.DecimalFormatSymbols
1717
* Renders the top-level retry strategy for a waiter.
1818
*/
1919
private fun KotlinWriter.renderRetryStrategy(wi: WaiterInfo, asValName: String) {
20-
withBlock("val #L = #T {", "}", asValName, RuntimeTypes.Core.Retries.StandardRetryStrategy) {
20+
withBlock("val #L = retryStrategy ?: #T {", "}", asValName, RuntimeTypes.Core.Retries.StandardRetryStrategy) {
2121
write("maxAttempts = 20")
2222
write("tokenBucket = #T", RuntimeTypes.Core.Retries.Delay.InfiniteTokenBucket)
2323
withBlock("delayProvider {", "}") {
@@ -35,18 +35,21 @@ private fun KotlinWriter.renderRetryStrategy(wi: WaiterInfo, asValName: String)
3535
internal fun KotlinWriter.renderWaiter(wi: WaiterInfo) {
3636
write("")
3737
wi.waiter.documentation.ifPresent(::dokka)
38-
val inputParameter = if (wi.input.hasAllOptionalMembers) {
39-
format("request: #1T = #1T { }", wi.inputSymbol)
38+
39+
val requestType = if (wi.input.hasAllOptionalMembers) {
40+
format("#1T = #1T { }", wi.inputSymbol)
4041
} else {
41-
format("request: #T", wi.inputSymbol)
42+
format("#T", wi.inputSymbol)
4243
}
44+
4345
withBlock(
44-
"#L suspend fun #T.#L(#L): #T<#T> {",
46+
"#L suspend fun #T.#L(request: #L, retryStrategy: #T? = null): #T<#T> {",
4547
"}",
4648
wi.ctx.settings.api.visibility,
4749
wi.serviceSymbol,
4850
wi.methodName,
49-
inputParameter,
51+
requestType,
52+
RuntimeTypes.Core.Retries.RetryStrategy,
5053
RuntimeTypes.Core.Retries.Outcome,
5154
wi.outputSymbol,
5255
) {

codegen/smithy-kotlin-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ software.amazon.smithy.kotlin.codegen.rendering.endpoints.SdkEndpointBuiltinInte
1313
software.amazon.smithy.kotlin.codegen.rendering.compression.RequestCompressionIntegration
1414
software.amazon.smithy.kotlin.codegen.rendering.auth.SigV4AsymmetricAuthSchemeIntegration
1515
software.amazon.smithy.kotlin.codegen.rendering.smoketests.SmokeTestsIntegration
16+
software.amazon.smithy.kotlin.codegen.rendering.checksums.HttpChecksumRequiredIntegration

codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/waiters/ServiceWaitersGeneratorTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class ServiceWaitersGeneratorTest {
4343
/**
4444
* Wait until a foo exists with optional input
4545
*/
46-
public suspend fun TestClient.waitUntilFooOptionalExists(request: DescribeFooOptionalRequest = DescribeFooOptionalRequest { }): Outcome<DescribeFooOptionalResponse> {
46+
public suspend fun TestClient.waitUntilFooOptionalExists(request: DescribeFooOptionalRequest = DescribeFooOptionalRequest { }, retryStrategy: RetryStrategy? = null): Outcome<DescribeFooOptionalResponse> {
4747
""".trimIndent()
4848
val methodFooter = """
4949
val policy = AcceptorRetryPolicy(request, acceptors)
@@ -59,7 +59,7 @@ class ServiceWaitersGeneratorTest {
5959
/**
6060
* Wait until a foo exists with required input
6161
*/
62-
public suspend fun TestClient.waitUntilFooRequiredExists(request: DescribeFooRequiredRequest): Outcome<DescribeFooRequiredResponse> {
62+
public suspend fun TestClient.waitUntilFooRequiredExists(request: DescribeFooRequiredRequest, retryStrategy: RetryStrategy? = null): Outcome<DescribeFooRequiredResponse> {
6363
""".trimIndent()
6464
listOf(
6565
generateService("simple-service-with-operation-waiter.smithy"),
@@ -105,7 +105,7 @@ class ServiceWaitersGeneratorTest {
105105
@Test
106106
fun testRetryStrategy() {
107107
val expected = """
108-
val strategy = StandardRetryStrategy {
108+
val strategy = retryStrategy ?: StandardRetryStrategy {
109109
maxAttempts = 20
110110
tokenBucket = InfiniteTokenBucket
111111
delayProvider {

0 commit comments

Comments
 (0)