Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .brazil.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

"com.squareup.okhttp3:okhttp-coroutines:5.*": "OkHttp3Coroutines-5.x",
"com.squareup.okhttp3:okhttp:5.*": "OkHttp3-5.x",
"com.squareup.okhttp3:okhttp-jvm:5.*": "OkHttp3-5.x",
"com.squareup.okio:okio-jvm:3.*": "OkioJvm-3.x",
"io.opentelemetry:opentelemetry-api:1.*": "Maven-io-opentelemetry_opentelemetry-api-1.x",
"io.opentelemetry:opentelemetry-extension-kotlin:1.*": "Maven-io-opentelemetry_opentelemetry-extension-kotlin-1.x",
Expand Down
5 changes: 5 additions & 0 deletions .changes/2ec4ad9a-f964-4cf1-be58-d0229493bb81.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"id": "2ec4ad9a-f964-4cf1-be58-d0229493bb81",
"type": "feature",
"description": "Upgrade to Kotlin 2.2.0"
}
9 changes: 9 additions & 0 deletions .changes/49af01b8-6fed-4add-ace0-9f027e83425a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"id": "49af01b8-6fed-4add-ace0-9f027e83425a",
"type": "feature",
"description": "⚠️ **IMPORTANT**: Refactor endpoint discoverer classes into interfaces so custom implementations may be provided",
"issues": [
"awslabs/aws-sdk-kotlin#1413"
],
"requiresMinorVersionBump": true
}
5 changes: 5 additions & 0 deletions .changes/d3ce7511-6fb2-4435-8f46-db724551b384.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"id": "d3ce7511-6fb2-4435-8f46-db724551b384",
"type": "misc",
"description": "Add telemetry provider configuration to `DefaultAwsSigner`"
}
8 changes: 8 additions & 0 deletions .changes/d4f09e32-8bcc-406e-96e0-2743280c13d9.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "d4f09e32-8bcc-406e-96e0-2743280c13d9",
"type": "bugfix",
"description": "Switch to always serialize defaults in requests. Previously fields were not serialized in requests if they weren't `@required` and hadn't been changed from the default value.",
"issues": [
"https://github.com/awslabs/aws-sdk-kotlin/issues/1608"
]
}
8 changes: 8 additions & 0 deletions .changes/db001c20-3788-4cfe-9ec2-284fd86a80bd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "db001c20-3788-4cfe-9ec2-284fd86a80bd",
"type": "bugfix",
"description": "Reimplement idle connection monitoring using `okhttp3.EventListener` instead of now-internal `okhttp3.ConnectionListener`",
"issues": [
"https://github.com/smithy-lang/smithy-kotlin/issues/1311"
]
}
8 changes: 8 additions & 0 deletions .changes/e6515649-dab5-4be9-b4b4-b289369960d5.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "e6515649-dab5-4be9-b4b4-b289369960d5",
"type": "bugfix",
"description": "Favor `endpointUrl` instead of endpoint discovery if both are provided",
"issues": [
"awslabs/aws-sdk-kotlin#1413"
]
}
2 changes: 1 addition & 1 deletion .github/workflows/merge-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ jobs:
uses: awslabs/aws-kotlin-repo-tools/.github/actions/merge-main@main
with:
ci-user-pat: ${{ secrets.CI_USER_PAT }}
exempt-branches: # Add any if required
exempt-branches: # Add any if required
3 changes: 0 additions & 3 deletions bom/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
import java.util.*

plugins {
`maven-publish`
Expand Down Expand Up @@ -52,7 +50,6 @@ fun createBomConstraintsAndVersionCatalog() {

fun Project.artifactId(target: KotlinTarget): String = when (target) {
is KotlinMetadataTarget -> name
is KotlinJsTarget -> "$name-js"
else -> "$name-${target.targetName.lowercase()}"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,27 @@ class RegionSupport : KotlinIntegration {
name = "region"
symbol = KotlinTypes.String.toBuilder().nullable().build()
documentation = """
The region to sign with and make requests to.
The AWS region to sign with and make requests to. When specified, this static region configuration
takes precedence over other region resolution methods.

The region resolution order is:
1. Static region (if specified)
2. Custom region provider (if configured)
3. Default region provider chain
""".trimIndent()
}

val RegionProviderProp: ConfigProperty = ConfigProperty {
name = "regionProvider"
symbol = RuntimeTypes.SmithyClient.Region.RegionProvider
documentation = """
An optional region provider that determines the AWS region for client operations. When specified, this provider
takes precedence over the default region provider chain, unless a static region is explicitly configured.

The region resolution order is:
1. Static region (if specified)
2. Custom region provider (if configured)
3. Default region provider chain
""".trimIndent()
}
}
Expand All @@ -57,7 +77,7 @@ class RegionSupport : KotlinIntegration {
return supportsSigv4 || hasRegionBuiltin || isAwsSdk
}

override fun additionalServiceConfigProps(ctx: CodegenContext): List<ConfigProperty> = listOf(RegionProp)
override fun additionalServiceConfigProps(ctx: CodegenContext): List<ConfigProperty> = listOf(RegionProp, RegionProviderProp)

override fun customizeEndpointResolution(ctx: ProtocolGenerator.GenerationContext): EndpointCustomization =
object : EndpointCustomization {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,23 @@ import software.amazon.smithy.kotlin.codegen.aws.protocols.core.AbstractQueryFor
import software.amazon.smithy.kotlin.codegen.aws.protocols.core.AwsHttpBindingProtocolGenerator
import software.amazon.smithy.kotlin.codegen.aws.protocols.core.QueryHttpBindingProtocolGenerator
import software.amazon.smithy.kotlin.codegen.aws.protocols.formurl.QuerySerdeFormUrlDescriptorGenerator
import software.amazon.smithy.kotlin.codegen.core.*
import software.amazon.smithy.kotlin.codegen.core.KotlinWriter
import software.amazon.smithy.kotlin.codegen.core.RenderingContext
import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes
import software.amazon.smithy.kotlin.codegen.core.withBlock
import software.amazon.smithy.kotlin.codegen.lang.KotlinTypes
import software.amazon.smithy.kotlin.codegen.model.*
import software.amazon.smithy.kotlin.codegen.rendering.protocol.*
import software.amazon.smithy.kotlin.codegen.rendering.serde.*
import software.amazon.smithy.kotlin.codegen.model.buildSymbol
import software.amazon.smithy.kotlin.codegen.model.getTrait
import software.amazon.smithy.kotlin.codegen.model.hasTrait
import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolGenerator
import software.amazon.smithy.kotlin.codegen.rendering.protocol.toRenderingContext
import software.amazon.smithy.kotlin.codegen.rendering.serde.FormUrlSerdeDescriptorGenerator
import software.amazon.smithy.kotlin.codegen.rendering.serde.StructuredDataParserGenerator
import software.amazon.smithy.kotlin.codegen.rendering.serde.StructuredDataSerializerGenerator
import software.amazon.smithy.kotlin.codegen.rendering.serde.XmlParserGenerator
import software.amazon.smithy.model.shapes.*
import software.amazon.smithy.model.traits.*
import software.amazon.smithy.model.traits.XmlFlattenedTrait
import software.amazon.smithy.model.traits.XmlNameTrait

/**
* Handles generating the aws.protocols#awsQuery protocol for services.
Expand Down Expand Up @@ -45,7 +55,7 @@ class AwsQuery : QueryHttpBindingProtocolGenerator() {
writer: KotlinWriter,
) {
writer.write("""checkNotNull(payload){ "unable to parse error from empty response" }""")
writer.write("#T(payload)", RuntimeTypes.AwsXmlProtocols.parseRestXmlErrorResponseNoSuspend)
writer.write("#T(payload)", RuntimeTypes.AwsXmlProtocols.parseRestXmlErrorResponse)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import software.amazon.smithy.codegen.core.Symbol
import software.amazon.smithy.kotlin.codegen.aws.protocols.core.AbstractQueryFormUrlSerializerGenerator
import software.amazon.smithy.kotlin.codegen.aws.protocols.core.QueryHttpBindingProtocolGenerator
import software.amazon.smithy.kotlin.codegen.aws.protocols.formurl.QuerySerdeFormUrlDescriptorGenerator
import software.amazon.smithy.kotlin.codegen.core.*
import software.amazon.smithy.kotlin.codegen.core.KotlinWriter
import software.amazon.smithy.kotlin.codegen.core.RenderingContext
import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes
import software.amazon.smithy.kotlin.codegen.core.withBlock
import software.amazon.smithy.kotlin.codegen.model.buildSymbol
import software.amazon.smithy.kotlin.codegen.model.getTrait
import software.amazon.smithy.kotlin.codegen.model.isNullable
Expand Down Expand Up @@ -39,7 +42,7 @@ class Ec2Query : QueryHttpBindingProtocolGenerator() {
writer: KotlinWriter,
) {
writer.write("""checkNotNull(payload){ "unable to parse error from empty response" }""")
writer.write("#T(payload)", RuntimeTypes.AwsXmlProtocols.parseEc2QueryErrorResponseNoSuspend)
writer.write("#T(payload)", RuntimeTypes.AwsXmlProtocols.parseEc2QueryErrorResponse)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ open class RestXml : AwsHttpBindingProtocolGenerator() {
writer: KotlinWriter,
) {
writer.write("""checkNotNull(payload){ "unable to parse error from empty response" }""")
writer.write("#T(payload)", RuntimeTypes.AwsXmlProtocols.parseRestXmlErrorResponseNoSuspend)
writer.write("#T(payload)", RuntimeTypes.AwsXmlProtocols.parseRestXmlErrorResponse)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package software.amazon.smithy.kotlin.codegen.aws.customization

import org.junit.jupiter.api.Test
import software.amazon.smithy.kotlin.codegen.core.KotlinWriter
import software.amazon.smithy.kotlin.codegen.model.expectShape
import software.amazon.smithy.kotlin.codegen.rendering.ServiceClientConfigGenerator
import software.amazon.smithy.kotlin.codegen.test.*
import software.amazon.smithy.model.shapes.ServiceShape

class RegionSupportTest {
@Test
fun testRegionSupportProperties() {
val model = """
namespace com.test

use aws.protocols#awsJson1_1
use aws.api#service
use aws.auth#sigv4

@service(sdkId: "service with overrides", endpointPrefix: "service-with-overrides")
@sigv4(name: "example")
@awsJson1_1
service Example {
version: "1.0.0",
operations: [GetFoo]
}

operation GetFoo {}
""".toSmithyModel()

val serviceShape = model.expectShape<ServiceShape>("com.test#Example")

val testCtx = model.newTestContext(serviceName = "Example")
val writer = KotlinWriter("com.test")

val renderingCtx = testCtx.toRenderingContext(writer, serviceShape)
.copy(integrations = listOf(RegionSupport()))

ServiceClientConfigGenerator(serviceShape, detectDefaultProps = false).render(renderingCtx, renderingCtx.writer)
val contents = writer.toString()

val expectedProps = """
public val region: String? = builder.region
public val regionProvider: RegionProvider? = builder.regionProvider
""".formatForTest()
contents.shouldContainOnlyOnceWithDiff(expectedProps)

val expectedImpl = """
/**
* The AWS region to sign with and make requests to. When specified, this static region configuration
* takes precedence over other region resolution methods.
*
* The region resolution order is:
* 1. Static region (if specified)
* 2. Custom region provider (if configured)
* 3. Default region provider chain
*/
public var region: String? = null

/**
* An optional region provider that determines the AWS region for client operations. When specified, this provider
* takes precedence over the default region provider chain, unless a static region is explicitly configured.
*
* The region resolution order is:
* 1. Static region (if specified)
* 2. Custom region provider (if configured)
* 3. Default region provider chain
*/
public var regionProvider: RegionProvider? = null
""".formatForTest(indent = " ")
contents.shouldContainOnlyOnceWithDiff(expectedImpl)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import software.amazon.smithy.build.MockManifest
import software.amazon.smithy.codegen.core.SymbolProvider
import software.amazon.smithy.kotlin.codegen.*
import software.amazon.smithy.kotlin.codegen.core.CodegenContext
import software.amazon.smithy.kotlin.codegen.core.GenerationContext
import software.amazon.smithy.kotlin.codegen.core.KotlinDelegator
import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration
import software.amazon.smithy.kotlin.codegen.model.OperationNormalizer
Expand Down Expand Up @@ -122,9 +123,11 @@ fun Model.newTestContext(
val manifest = MockManifest()
val provider: SymbolProvider = KotlinCodegenPlugin.createSymbolProvider(model = this, rootNamespace = packageName, serviceName = serviceName, settings = settings)
val service = this.getShape(ShapeId.from("$packageName#$serviceName")).get().asServiceShape().get()
val delegator = KotlinDelegator(settings, this, manifest, provider, integrations)

val ctx = ProtocolGenerator.GenerationContext(
val codegenCtx = GenerationContext(this, provider, settings, generator, integrations)
val delegator = KotlinDelegator(codegenCtx, manifest, integrations)

val generationCtx = ProtocolGenerator.GenerationContext(
settings,
this,
service,
Expand All @@ -133,7 +136,8 @@ fun Model.newTestContext(
generator.protocol,
delegator,
)
return TestContext(ctx, manifest, generator)

return TestContext(generationCtx, manifest, generator)
}

fun TestContext.toCodegenContext() = object : CodegenContext {
Expand Down Expand Up @@ -173,7 +177,7 @@ fun Model.defaultSettings(
sdkId: String = TestModelDefault.SDK_ID,
generateDefaultBuildFiles: Boolean = false,
nullabilityCheckMode: CheckMode = CheckMode.CLIENT_CAREFUL,
defaultValueSerializationMode: DefaultValueSerializationMode = DefaultValueSerializationMode.WHEN_DIFFERENT,
defaultValueSerializationMode: DefaultValueSerializationMode = DefaultValueSerializationMode.DEFAULT,
): KotlinSettings {
val serviceId = if (serviceName == null) {
this.inferService()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ class CodegenVisitor(context: PluginContext) : ShapeVisitor.Default<Unit>() {
integration.decorateSymbolProvider(settings, model, provider)
}

writers = KotlinDelegator(settings, model, fileManifest, symbolProvider, integrations)

protocolGenerator = resolveProtocolGenerator(integrations, model, service, settings)
applicationProtocol = protocolGenerator?.applicationProtocol ?: ApplicationProtocol.createDefaultHttpApplicationProtocol()

baseGenerationContext = GenerationContext(model, symbolProvider, settings, protocolGenerator, integrations)

writers = KotlinDelegator(baseGenerationContext, fileManifest, integrations)

applicationProtocol = protocolGenerator?.applicationProtocol ?: ApplicationProtocol.createDefaultHttpApplicationProtocol()
}

private fun resolveProtocolGenerator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@

package software.amazon.smithy.kotlin.codegen

import software.amazon.smithy.aws.traits.protocols.AwsJson1_0Trait
import software.amazon.smithy.aws.traits.protocols.AwsJson1_1Trait
import software.amazon.smithy.aws.traits.protocols.AwsQueryTrait
import software.amazon.smithy.aws.traits.protocols.Ec2QueryTrait
import software.amazon.smithy.aws.traits.protocols.RestJson1Trait
import software.amazon.smithy.aws.traits.protocols.RestXmlTrait
import software.amazon.smithy.aws.traits.protocols.*
import software.amazon.smithy.codegen.core.CodegenException
import software.amazon.smithy.kotlin.codegen.lang.isValidPackageName
import software.amazon.smithy.kotlin.codegen.utils.getOrNull
Expand All @@ -24,10 +19,10 @@ import software.amazon.smithy.model.shapes.ServiceShape
import software.amazon.smithy.model.shapes.Shape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.protocol.traits.Rpcv2CborTrait
import java.util.Optional
import java.util.*
import java.util.logging.Logger
import java.util.stream.Collectors
import kotlin.IllegalArgumentException
import kotlin.streams.toList

// shapeId of service from which to generate an SDK
private const val SERVICE = "service"
Expand Down Expand Up @@ -164,7 +159,7 @@ fun Model.inferService(): ShapeId {
val services = shapes(ServiceShape::class.java)
.map(Shape::getId)
.sorted()
.toList()
.collect(Collectors.toList())

return when {
services.isEmpty() -> {
Expand Down Expand Up @@ -273,10 +268,15 @@ enum class DefaultValueSerializationMode(val value: String) {

override fun toString(): String = value
companion object {
/**
* The default value serialization mode, which is [ALWAYS]
*/
val DEFAULT = ALWAYS

fun fromValue(value: String): DefaultValueSerializationMode =
values().find {
it.value == value
} ?: throw IllegalArgumentException("$value is not a valid DefaultValueSerializationMode, expected one of ${values().map { it.value }}")
requireNotNull(entries.find { it.value.equals(value, ignoreCase = true) }) {
"$value is not a valid DefaultValueSerializationMode, expected one of ${values().map { it.value }}"
}
}
}

Expand All @@ -291,7 +291,7 @@ enum class DefaultValueSerializationMode(val value: String) {
data class ApiSettings(
val visibility: Visibility = Visibility.PUBLIC,
val nullabilityCheckMode: CheckMode = CheckMode.CLIENT_CAREFUL,
val defaultValueSerializationMode: DefaultValueSerializationMode = DefaultValueSerializationMode.WHEN_DIFFERENT,
val defaultValueSerializationMode: DefaultValueSerializationMode = DefaultValueSerializationMode.DEFAULT,
val enableEndpointAuthProvider: Boolean = false,
val protocolResolutionPriority: Set<ShapeId> = DEFAULT_PROTOCOL_RESOLUTION_PRIORITY,
) {
Expand All @@ -315,7 +315,7 @@ data class ApiSettings(
node.get()
.getStringMemberOrDefault(
DEFAULT_VALUE_SERIALIZATION_MODE,
DefaultValueSerializationMode.WHEN_DIFFERENT.value,
DefaultValueSerializationMode.DEFAULT.value,
),
)
val enableEndpointAuthProvider = node.get().getBooleanMemberOrDefault(ENABLE_ENDPOINT_AUTH_PROVIDER, false)
Expand Down
Loading
Loading