Skip to content

Commit aae827c

Browse files
authored
fix: idempotency tokens being code-generated for nested structures (#1248)
1 parent 03a8e62 commit aae827c

File tree

7 files changed

+433
-3
lines changed

7 files changed

+433
-3
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"id": "a928feea-f455-4263-8bae-cf50676a551a",
3+
"type": "bugfix",
4+
"description": "Idempotency tokens are no longer code-generated for nested structures. See: https://smithy.io/2.0/spec/behavior-traits.html#smithy-api-idempotencytoken-trait"
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package software.amazon.smithy.kotlin.codegen.aws.protocols
2+
3+
import software.amazon.smithy.kotlin.codegen.test.*
4+
import kotlin.test.Test
5+
6+
class AwsQueryTest {
7+
@Test
8+
fun testNonNestedIdempotencyToken() {
9+
val ctx = model.newTestContext("Example")
10+
11+
val generator = AwsQuery()
12+
generator.generateProtocolClient(ctx.generationCtx)
13+
14+
ctx.generationCtx.delegator.finalize()
15+
ctx.generationCtx.delegator.flushWriters()
16+
17+
val expected = """
18+
serializer.serializeStruct(OBJ_DESCRIPTOR) {
19+
input.bar?.let { field(BAR_DESCRIPTOR, it) } ?: field(BAR_DESCRIPTOR, context.idempotencyTokenProvider.generateToken())
20+
}
21+
""".trimIndent()
22+
23+
val actual = ctx
24+
.manifest
25+
.expectFileString("/src/main/kotlin/com/test/serde/GetBarUnNestedOperationSerializer.kt")
26+
.lines(" serializer.serializeStruct(OBJ_DESCRIPTOR) {", " }")
27+
.trimIndent()
28+
29+
actual.shouldContainOnlyOnceWithDiff(expected)
30+
}
31+
32+
@Test
33+
fun testNestedIdempotencyToken() {
34+
val ctx = model.newTestContext("Example")
35+
36+
val generator = AwsQuery()
37+
generator.generateProtocolClient(ctx.generationCtx)
38+
39+
ctx.generationCtx.delegator.finalize()
40+
ctx.generationCtx.delegator.flushWriters()
41+
42+
val expected = """
43+
serializer.serializeStruct(OBJ_DESCRIPTOR) {
44+
input.baz?.let { field(BAZ_DESCRIPTOR, it) }
45+
}
46+
""".trimIndent()
47+
48+
val actual = ctx
49+
.manifest
50+
.expectFileString("/src/main/kotlin/com/test/serde/NestDocumentSerializer.kt")
51+
.lines(" serializer.serializeStruct(OBJ_DESCRIPTOR) {", " }")
52+
.trimIndent()
53+
54+
actual.shouldContainOnlyOnceWithDiff(expected)
55+
56+
val unexpected = """
57+
serializer.serializeStruct(OBJ_DESCRIPTOR) {
58+
input.baz?.let { field(BAZ_DESCRIPTOR, it) } ?: field(BAR_DESCRIPTOR, context.idempotencyTokenProvider.generateToken())
59+
}
60+
""".trimIndent()
61+
62+
actual.shouldNotContainOnlyOnceWithDiff(unexpected)
63+
}
64+
65+
private val model = """
66+
${"$"}version: "2"
67+
68+
namespace com.test
69+
70+
use aws.protocols#awsQuery
71+
use aws.api#service
72+
73+
@awsQuery
74+
@service(sdkId: "Example")
75+
@xmlNamespace(uri: "http://foo.com")
76+
service Example {
77+
version: "1.0.0",
78+
operations: [GetBarUnNested, GetBarNested]
79+
}
80+
81+
@http(method: "POST", uri: "/get-bar-un-nested")
82+
operation GetBarUnNested {
83+
input: BarUnNested
84+
}
85+
86+
structure BarUnNested {
87+
@idempotencyToken
88+
bar: String
89+
}
90+
91+
@http(method: "POST", uri: "/get-bar-nested")
92+
operation GetBarNested {
93+
input: BarNested
94+
}
95+
96+
structure BarNested {
97+
bar: Nest
98+
}
99+
100+
structure Nest {
101+
@idempotencyToken
102+
baz: String
103+
}
104+
""".toSmithyModel()
105+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package software.amazon.smithy.kotlin.codegen.aws.protocols
2+
3+
import software.amazon.smithy.kotlin.codegen.test.*
4+
import kotlin.test.Test
5+
6+
class RestJson1Test {
7+
@Test
8+
fun testNonNestedIdempotencyToken() {
9+
val ctx = model.newTestContext("Example")
10+
11+
val generator = RestJson1()
12+
generator.generateProtocolClient(ctx.generationCtx)
13+
14+
ctx.generationCtx.delegator.finalize()
15+
ctx.generationCtx.delegator.flushWriters()
16+
17+
val expected = """
18+
serializer.serializeStruct(OBJ_DESCRIPTOR) {
19+
input.bar?.let { field(BAR_DESCRIPTOR, it) } ?: field(BAR_DESCRIPTOR, context.idempotencyTokenProvider.generateToken())
20+
}
21+
""".trimIndent()
22+
23+
val actual = ctx
24+
.manifest
25+
.expectFileString("/src/main/kotlin/com/test/serde/GetBarUnNestedOperationSerializer.kt")
26+
.lines(" serializer.serializeStruct(OBJ_DESCRIPTOR) {", " }")
27+
.trimIndent()
28+
29+
actual.shouldContainOnlyOnceWithDiff(expected)
30+
}
31+
32+
@Test
33+
fun testNestedIdempotencyToken() {
34+
val ctx = model.newTestContext("Example")
35+
36+
val generator = RestJson1()
37+
generator.generateProtocolClient(ctx.generationCtx)
38+
39+
ctx.generationCtx.delegator.finalize()
40+
ctx.generationCtx.delegator.flushWriters()
41+
42+
val expected = """
43+
serializer.serializeStruct(OBJ_DESCRIPTOR) {
44+
input.baz?.let { field(BAZ_DESCRIPTOR, it) }
45+
}
46+
""".trimIndent()
47+
48+
val actual = ctx
49+
.manifest
50+
.expectFileString("/src/main/kotlin/com/test/serde/NestDocumentSerializer.kt")
51+
.lines(" serializer.serializeStruct(OBJ_DESCRIPTOR) {", " }")
52+
.trimIndent()
53+
54+
actual.shouldContainOnlyOnceWithDiff(expected)
55+
56+
val unexpected = """
57+
serializer.serializeStruct(OBJ_DESCRIPTOR) {
58+
input.baz?.let { field(BAZ_DESCRIPTOR, it) } ?: field(BAR_DESCRIPTOR, context.idempotencyTokenProvider.generateToken())
59+
}
60+
""".trimIndent()
61+
62+
actual.shouldNotContainOnlyOnceWithDiff(unexpected)
63+
}
64+
65+
private val model = """
66+
${"$"}version: "2"
67+
68+
namespace com.test
69+
70+
use aws.protocols#restJson1
71+
use aws.api#service
72+
73+
@restJson1
74+
@service(sdkId: "Example")
75+
service Example {
76+
version: "1.0.0",
77+
operations: [GetBarUnNested, GetBarNested]
78+
}
79+
80+
@http(method: "POST", uri: "/get-bar-un-nested")
81+
operation GetBarUnNested {
82+
input: BarUnNested
83+
}
84+
85+
structure BarUnNested {
86+
@idempotencyToken
87+
bar: String
88+
}
89+
90+
@http(method: "POST", uri: "/get-bar-nested")
91+
operation GetBarNested {
92+
input: BarNested
93+
}
94+
95+
structure BarNested {
96+
bar: Nest
97+
}
98+
99+
structure Nest {
100+
@idempotencyToken
101+
baz: String
102+
}
103+
""".toSmithyModel()
104+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package software.amazon.smithy.kotlin.codegen.aws.protocols
2+
3+
import software.amazon.smithy.kotlin.codegen.test.*
4+
import kotlin.test.Test
5+
6+
class RestXmlTest {
7+
@Test
8+
fun testNonNestedIdempotencyToken() {
9+
val ctx = model.newTestContext("Example")
10+
11+
val generator = RestXml()
12+
generator.generateProtocolClient(ctx.generationCtx)
13+
14+
ctx.generationCtx.delegator.finalize()
15+
ctx.generationCtx.delegator.flushWriters()
16+
17+
val expected = """
18+
serializer.serializeStruct(OBJ_DESCRIPTOR) {
19+
input.bar?.let { field(BAR_DESCRIPTOR, it) } ?: field(BAR_DESCRIPTOR, context.idempotencyTokenProvider.generateToken())
20+
}
21+
""".trimIndent()
22+
23+
val actual = ctx
24+
.manifest
25+
.expectFileString("/src/main/kotlin/com/test/serde/GetBarUnNestedOperationSerializer.kt")
26+
.lines(" serializer.serializeStruct(OBJ_DESCRIPTOR) {", " }")
27+
.trimIndent()
28+
29+
actual.shouldContainOnlyOnceWithDiff(expected)
30+
}
31+
32+
@Test
33+
fun testNestedIdempotencyToken() {
34+
val ctx = model.newTestContext("Example")
35+
36+
val generator = RestXml()
37+
generator.generateProtocolClient(ctx.generationCtx)
38+
39+
ctx.generationCtx.delegator.finalize()
40+
ctx.generationCtx.delegator.flushWriters()
41+
42+
val expected = """
43+
serializer.serializeStruct(OBJ_DESCRIPTOR) {
44+
input.baz?.let { field(BAZ_DESCRIPTOR, it) }
45+
}
46+
""".trimIndent()
47+
48+
val actual = ctx
49+
.manifest
50+
.expectFileString("/src/main/kotlin/com/test/serde/NestDocumentSerializer.kt")
51+
.lines(" serializer.serializeStruct(OBJ_DESCRIPTOR) {", " }")
52+
.trimIndent()
53+
54+
actual.shouldContainOnlyOnceWithDiff(expected)
55+
56+
val unexpected = """
57+
serializer.serializeStruct(OBJ_DESCRIPTOR) {
58+
input.baz?.let { field(BAZ_DESCRIPTOR, it) } ?: field(BAR_DESCRIPTOR, context.idempotencyTokenProvider.generateToken())
59+
}
60+
""".trimIndent()
61+
62+
actual.shouldNotContainOnlyOnceWithDiff(unexpected)
63+
}
64+
65+
private val model = """
66+
${"$"}version: "2"
67+
68+
namespace com.test
69+
70+
use aws.protocols#restXml
71+
use aws.api#service
72+
73+
@restXml
74+
@service(sdkId: "Example")
75+
service Example {
76+
version: "1.0.0",
77+
operations: [GetBarUnNested, GetBarNested]
78+
}
79+
80+
@http(method: "POST", uri: "/get-bar-un-nested")
81+
operation GetBarUnNested {
82+
input: BarUnNested
83+
}
84+
85+
structure BarUnNested {
86+
@idempotencyToken
87+
bar: String
88+
}
89+
90+
@http(method: "POST", uri: "/get-bar-nested")
91+
operation GetBarNested {
92+
input: BarNested
93+
}
94+
95+
structure BarNested {
96+
bar: Nest
97+
}
98+
99+
structure Nest {
100+
@idempotencyToken
101+
baz: String
102+
}
103+
""".toSmithyModel()
104+
}

0 commit comments

Comments
 (0)