Skip to content

Commit c3e8597

Browse files
committed
Merge remote-tracking branch 'origin/v1.5-main' into fix-overhaul-ep-discovery
2 parents af8c49d + ed95d7b commit c3e8597

File tree

41 files changed

+1105
-396
lines changed

Some content is hidden

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

41 files changed

+1105
-396
lines changed

.brazil.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
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",

CHANGELOG.md

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

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

516
## [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
@@ -82,7 +82,7 @@ object RuntimeTypes {
8282
val ContinueInterceptor = symbol("ContinueInterceptor")
8383
val DiscoveredEndpointErrorInterceptor = symbol("DiscoveredEndpointErrorInterceptor")
8484
val HttpInterceptor = symbol("HttpInterceptor")
85-
val Md5ChecksumInterceptor = symbol("Md5ChecksumInterceptor")
85+
val HttpChecksumRequiredInterceptor = symbol("HttpChecksumRequiredInterceptor")
8686
val FlexibleChecksumsRequestInterceptor = symbol("FlexibleChecksumsRequestInterceptor")
8787
val FlexibleChecksumsResponseInterceptor = symbol("FlexibleChecksumsResponseInterceptor")
8888
val ResponseLengthValidationInterceptor = symbol("ResponseLengthValidationInterceptor")
@@ -233,6 +233,9 @@ object RuntimeTypes {
233233
object Config : RuntimeTypePackage(KotlinDependency.SMITHY_CLIENT, "config") {
234234
val RequestCompressionConfig = symbol("RequestCompressionConfig")
235235
val CompressionClientConfig = symbol("CompressionClientConfig")
236+
val HttpChecksumConfig = symbol("HttpChecksumConfig")
237+
val RequestHttpChecksumConfig = symbol("RequestHttpChecksumConfig")
238+
val ResponseHttpChecksumConfig = symbol("ResponseHttpChecksumConfig")
236239
}
237240

238241
object Endpoints : RuntimeTypePackage(KotlinDependency.SMITHY_CLIENT, "endpoints") {
@@ -397,6 +400,7 @@ object RuntimeTypes {
397400
val TelemetryContextElement = symbol("TelemetryContextElement", "context")
398401
val TraceSpan = symbol("TraceSpan", "trace")
399402
val withSpan = symbol("withSpan", "trace")
403+
val warn = symbol("warn", "logging")
400404
}
401405
object TelemetryDefaults : RuntimeTypePackage(KotlinDependency.TELEMETRY_DEFAULTS) {
402406
val Global = symbol("Global")
@@ -411,6 +415,7 @@ object RuntimeTypes {
411415

412416
val CompletableDeferred = "kotlinx.coroutines.CompletableDeferred".toSymbol()
413417
val job = "kotlinx.coroutines.job".toSymbol()
418+
val runBlocking = "kotlinx.coroutines.runBlocking".toSymbol()
414419

415420
object Flow {
416421
// 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
@@ -40,7 +40,7 @@ class ServiceWaitersGeneratorTest {
4040
/**
4141
* Wait until a foo exists with optional input
4242
*/
43-
public suspend fun TestClient.waitUntilFooOptionalExists(request: DescribeFooOptionalRequest = DescribeFooOptionalRequest { }): Outcome<DescribeFooOptionalResponse> {
43+
public suspend fun TestClient.waitUntilFooOptionalExists(request: DescribeFooOptionalRequest = DescribeFooOptionalRequest { }, retryStrategy: RetryStrategy? = null): Outcome<DescribeFooOptionalResponse> {
4444
""".trimIndent()
4545
val methodFooter = """
4646
val policy = AcceptorRetryPolicy(request, acceptors)
@@ -56,7 +56,7 @@ class ServiceWaitersGeneratorTest {
5656
/**
5757
* Wait until a foo exists with required input
5858
*/
59-
public suspend fun TestClient.waitUntilFooRequiredExists(request: DescribeFooRequiredRequest): Outcome<DescribeFooRequiredResponse> {
59+
public suspend fun TestClient.waitUntilFooRequiredExists(request: DescribeFooRequiredRequest, retryStrategy: RetryStrategy? = null): Outcome<DescribeFooRequiredResponse> {
6060
""".trimIndent()
6161
listOf(
6262
generateService("simple-service-with-operation-waiter.smithy"),
@@ -102,7 +102,7 @@ class ServiceWaitersGeneratorTest {
102102
@Test
103103
fun testRetryStrategy() {
104104
val expected = """
105-
val strategy = StandardRetryStrategy {
105+
val strategy = retryStrategy ?: StandardRetryStrategy {
106106
maxAttempts = 20
107107
tokenBucket = InfiniteTokenBucket
108108
delayProvider {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class WaiterGeneratorTest {
2828
@Test
2929
fun testDefaultDelays() {
3030
val expected = """
31-
val strategy = StandardRetryStrategy {
31+
val strategy = retryStrategy ?: StandardRetryStrategy {
3232
maxAttempts = 20
3333
tokenBucket = InfiniteTokenBucket
3434
delayProvider {
@@ -45,7 +45,7 @@ class WaiterGeneratorTest {
4545
@Test
4646
fun testCustomDelays() {
4747
val expected = """
48-
val strategy = StandardRetryStrategy {
48+
val strategy = retryStrategy ?: StandardRetryStrategy {
4949
maxAttempts = 20
5050
tokenBucket = InfiniteTokenBucket
5151
delayProvider {

0 commit comments

Comments
 (0)