diff --git a/.changes/d4f09e32-8bcc-406e-96e0-2743280c13d9.json b/.changes/d4f09e32-8bcc-406e-96e0-2743280c13d9.json new file mode 100644 index 000000000..2d09a6ce5 --- /dev/null +++ b/.changes/d4f09e32-8bcc-406e-96e0-2743280c13d9.json @@ -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" + ] +} diff --git a/codegen/smithy-kotlin-codegen-testutils/src/main/kotlin/software/amazon/smithy/kotlin/codegen/test/ModelTestUtils.kt b/codegen/smithy-kotlin-codegen-testutils/src/main/kotlin/software/amazon/smithy/kotlin/codegen/test/ModelTestUtils.kt index e857f91fe..d3b8960d4 100644 --- a/codegen/smithy-kotlin-codegen-testutils/src/main/kotlin/software/amazon/smithy/kotlin/codegen/test/ModelTestUtils.kt +++ b/codegen/smithy-kotlin-codegen-testutils/src/main/kotlin/software/amazon/smithy/kotlin/codegen/test/ModelTestUtils.kt @@ -173,7 +173,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() diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/KotlinSettings.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/KotlinSettings.kt index 3ee6e0633..e72712281 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/KotlinSettings.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/KotlinSettings.kt @@ -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 @@ -24,10 +19,9 @@ 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 kotlin.IllegalArgumentException -import kotlin.streams.toList +import java.util.stream.Collectors // shapeId of service from which to generate an SDK private const val SERVICE = "service" @@ -164,7 +158,7 @@ fun Model.inferService(): ShapeId { val services = shapes(ServiceShape::class.java) .map(Shape::getId) .sorted() - .toList() + .collect(Collectors.toList()) return when { services.isEmpty() -> { @@ -273,10 +267,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 }}" + } } } @@ -291,7 +290,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 = DEFAULT_PROTOCOL_RESOLUTION_PRIORITY, ) { @@ -315,7 +314,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) diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinDependency.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinDependency.kt index b575efae6..de8f29413 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinDependency.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/KotlinDependency.kt @@ -134,6 +134,7 @@ data class KotlinDependency( // External third-party dependencies val KOTLIN_STDLIB = KotlinDependency(GradleConfiguration.Implementation, "kotlin", "org.jetbrains.kotlin", "kotlin-stdlib", KOTLIN_COMPILER_VERSION) val KOTLIN_TEST = KotlinDependency(GradleConfiguration.TestImplementation, "kotlin.test", "org.jetbrains.kotlin", "kotlin-test", KOTLIN_COMPILER_VERSION) + val KOTLIN_TEST_IMPL = KOTLIN_TEST.copy(config = GradleConfiguration.Implementation) } override fun getDependencies(): List { diff --git a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpStringValuesMapSerializerTest.kt b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpStringValuesMapSerializerTest.kt index 95138ad52..097db4b4c 100644 --- a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpStringValuesMapSerializerTest.kt +++ b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/protocol/HttpStringValuesMapSerializerTest.kt @@ -53,7 +53,8 @@ class HttpStringValuesMapSerializerTest { @Test fun `it handles primitive header shapes when different mode`() { - val contents = getTestContents(defaultModel, "com.test#PrimitiveShapesOperation", HttpBinding.Location.HEADER) + val settings = defaultModel.defaultSettings(defaultValueSerializationMode = DefaultValueSerializationMode.WHEN_DIFFERENT) + val contents = getTestContents(defaultModel, "com.test#PrimitiveShapesOperation", HttpBinding.Location.HEADER, settings) contents.assertBalancedBracesAndParens() val expectedContents = """ @@ -68,7 +69,8 @@ class HttpStringValuesMapSerializerTest { @Test fun `it handles primitive query shapes when different mode`() { - val contents = getTestContents(defaultModel, "com.test#PrimitiveShapesOperation", HttpBinding.Location.QUERY) + val settings = defaultModel.defaultSettings(defaultValueSerializationMode = DefaultValueSerializationMode.WHEN_DIFFERENT) + val contents = getTestContents(defaultModel, "com.test#PrimitiveShapesOperation", HttpBinding.Location.QUERY, settings) contents.assertBalancedBracesAndParens() val expectedContents = """ @@ -129,7 +131,8 @@ class HttpStringValuesMapSerializerTest { } """.prependNamespaceAndService(operations = listOf("Foo")).toSmithyModel() - val contents = getTestContents(model, "com.test#Foo", HttpBinding.Location.HEADER) + val settings = defaultModel.defaultSettings(defaultValueSerializationMode = DefaultValueSerializationMode.WHEN_DIFFERENT) + val contents = getTestContents(model, "com.test#Foo", HttpBinding.Location.HEADER, settings) contents.assertBalancedBracesAndParens() val expectedContents = """ diff --git a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGeneratorTest.kt b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGeneratorTest.kt index 347da007c..c0eae1f05 100644 --- a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGeneratorTest.kt +++ b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/serde/SerializeStructGeneratorTest.kt @@ -72,7 +72,8 @@ class SerializeStructGeneratorTest { } """.trimIndent() - val actual = codegenSerializerForShape(model, "com.test#Foo") + val settings = model.defaultSettings(defaultValueSerializationMode = DefaultValueSerializationMode.WHEN_DIFFERENT) + val actual = codegenSerializerForShape(model, "com.test#Foo", settings = settings) actual.shouldContainOnlyOnceWithDiff(expected) }