Skip to content

fix: always serialize defaults #1302

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
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"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was originally set to WHEN_DIFFERENT because serializing defaults caused problems with S3, can we double-check those model issues are now resolved?

): KotlinSettings {
val serviceId = if (serviceName == null) {
this.inferService()
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,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"
Expand Down Expand Up @@ -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() -> {
Expand Down Expand Up @@ -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 }}"
Comment on lines +276 to +277
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this comparison need to change?

}
}
}

Expand All @@ -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<ShapeId> = DEFAULT_PROTOCOL_RESOLUTION_PRIORITY,
) {
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<SymbolDependency> {
Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these tests were updated to use the previous value WHEN_DIFFERENT. Do we have tests for the new value ALWAYS?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Original file line number Diff line number Diff line change
Expand Up @@ -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 = """
Expand All @@ -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 = """
Expand Down Expand Up @@ -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 = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
Loading