Skip to content

Commit

Permalink
Remove defaults for some shapes in some services
Browse files Browse the repository at this point in the history
Adds an integration that removes the default value from certain
shapes in some services where the default value is 0, but the
service expects a value > 0.
  • Loading branch information
milesziemer committed Nov 16, 2023
1 parent 6a0857b commit dacde52
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changes/190be92b-a106-476b-99b3-224a80f81d7d.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"id": "190be92b-a106-476b-99b3-224a80f81d7d",
"type": "bugfix",
"description": "**Breaking**: Make some types for EMR Serverless optional by removing default values",
"requiresMinorVersionBump": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package aws.sdk.kotlin.codegen.customization

import software.amazon.smithy.codegen.core.CodegenException
import software.amazon.smithy.kotlin.codegen.KotlinSettings
import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration
import software.amazon.smithy.kotlin.codegen.model.hasTrait
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.AbstractShapeBuilder
import software.amazon.smithy.model.shapes.MemberShape
import software.amazon.smithy.model.shapes.Shape
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.model.traits.DefaultTrait
import software.amazon.smithy.model.transform.ModelTransformer
import software.amazon.smithy.utils.ToSmithyBuilder

/**
* Removes the default value of certain shapes, and any member that target
* those shapes,for certain services. These default values may cause
* serialization, validation, or other unexpected issues.
*/
class RemoveDefaults : KotlinIntegration {
// Service shape id -> Shape id of each root shape to remove default values from.
private val removeDefaultsFrom = mapOf(
ShapeId.from("com.amazonaws.emrserverless#AwsToledoWebService") to setOf(
// Service expects value > 0
ShapeId.from("com.amazonaws.emrserverless#WorkerCounts"),
),
)

override val order: Byte = 0

override fun enabledForService(model: Model, settings: KotlinSettings): Boolean {
val serviceId = settings.service
return serviceId in removeDefaultsFrom
}

override fun preprocessModel(model: Model, settings: KotlinSettings): Model {
val serviceId = settings.service
val removeDefaultsFromShapes = removeDefaultsFrom[serviceId]
?: throw CodegenException("expected $serviceId in removed defaults map")
return removeDefaults(model, removeDefaultsFromShapes)
}

fun removeDefaults(model: Model, fromShapes: Set<ShapeId>): Model {
val removedRootDefaults: MutableSet<ShapeId> = HashSet()
val removedRootDefaultsModel = ModelTransformer.create().mapShapes(model) {
if (shouldRemoveRootDefault(it, fromShapes)) {
removedRootDefaults.add(it.id)
removeDefault(it)
} else {
it
}
}

return ModelTransformer.create().mapShapes(removedRootDefaultsModel) {
if (shouldRemoveMemberDefault(it, removedRootDefaults)) {
removeDefault(it)
} else {
it
}
}
}

private fun shouldRemoveRootDefault(shape: Shape, removeDefaultsFrom: Set<ShapeId>): Boolean =
shape !is MemberShape && removeDefaultsFrom.contains(shape.id) && shape.hasTrait<DefaultTrait>()

private fun shouldRemoveMemberDefault(shape: Shape, removeDefaultsFrom: Set<ShapeId>): Boolean =
shape is MemberShape && removeDefaultsFrom.contains(shape.target) && shape.hasTrait<DefaultTrait>()

private fun removeDefault(shape: Shape): Shape =
((shape as ToSmithyBuilder<*>).toBuilder() as AbstractShapeBuilder<*, *>)
.removeTrait(DefaultTrait.ID)
.build()
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ aws.sdk.kotlin.codegen.customization.s3.HostPrefixRequestRouteFilter
aws.sdk.kotlin.codegen.customization.s3.UnwrappedXmlOutputIntegration
aws.sdk.kotlin.codegen.customization.ClockSkew
aws.sdk.kotlin.codegen.customization.ec2.EC2MakePrimitivesOptional
aws.sdk.kotlin.codegen.customization.RemoveDefaults
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package aws.sdk.kotlin.codegen.customization

import org.junit.jupiter.api.Test
import software.amazon.smithy.kotlin.codegen.model.hasTrait
import software.amazon.smithy.kotlin.codegen.test.toSmithyModel
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.model.traits.DefaultTrait
import kotlin.test.assertFalse

class RemoveDefaultsTest {
@Test
fun removesDefaults() {
val model = """
${"$"}version: "2.0"
namespace test
structure Foo {
bar: Bar = 0
}
@default(0)
integer Bar
""".toSmithyModel()

val transformed = RemoveDefaults().removeDefaults(model, setOf(ShapeId.from("test#Bar")))
val member = transformed.expectShape(ShapeId.from("test#Foo\$bar"))
assertFalse(member.hasTrait<DefaultTrait>())
val root = transformed.expectShape(ShapeId.from("test#Bar"))
assertFalse(root.hasTrait<DefaultTrait>())
}
}

0 comments on commit dacde52

Please sign in to comment.