Skip to content

Commit b5b67b3

Browse files
authored
fix: Allow customization of HTTP body members per-protocol (#907)
1 parent edfc55c commit b5b67b3

File tree

7 files changed

+77
-17
lines changed

7 files changed

+77
-17
lines changed

smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/HTTPBindingProtocolGenerator.kt

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -68,22 +68,20 @@ import software.amazon.smithy.swift.codegen.model.hasEventStreamMember
6868
import software.amazon.smithy.swift.codegen.model.hasTrait
6969
import software.amazon.smithy.swift.codegen.model.isInputEventStream
7070
import software.amazon.smithy.swift.codegen.model.isOutputEventStream
71-
import software.amazon.smithy.swift.codegen.model.targetOrSelf
7271
import software.amazon.smithy.swift.codegen.supportsStreamingAndIsRPC
7372
import software.amazon.smithy.swift.codegen.swiftmodules.ClientRuntimeTypes
7473
import software.amazon.smithy.swift.codegen.utils.ModelFileUtils
7574
import software.amazon.smithy.utils.OptionalUtils
7675
import java.util.Optional
7776
import java.util.logging.Logger
7877

79-
private val Shape.isStreaming: Boolean
78+
val Shape.isEventStreaming: Boolean
8079
get() = hasTrait<StreamingTrait>() && isUnionShape
8180

8281
/**
8382
* Checks to see if shape is in the body of the http request
8483
*/
8584
fun Shape.isInHttpBody(): Boolean {
86-
// TODO fix the edge case: a shape which is an operational input (i.e. has members bound to HTTP semantics) could be re-used elsewhere not as an operation input which means everything is in the body
8785
val hasNoHttpTraitsOutsideOfPayload =
8886
!this.hasTrait(HttpLabelTrait::class.java) &&
8987
!this.hasTrait(HttpHeaderTrait::class.java) &&
@@ -171,19 +169,7 @@ abstract class HTTPBindingProtocolGenerator(
171169
.definitionFile(filename)
172170
.name(symbolName)
173171
.build()
174-
var httpBodyMembers =
175-
shape
176-
.members()
177-
.filter { it.isInHttpBody() }
178-
.toList()
179-
if (supportsStreamingAndIsRPC(ctx.protocol)) {
180-
// For RPC protocols that support event streaming, we need to send initial request
181-
// with streaming member excluded during encoding the input struct.
182-
httpBodyMembers =
183-
httpBodyMembers.filter {
184-
!it.targetOrSelf(ctx.model).isStreaming
185-
}
186-
}
172+
val httpBodyMembers = httpBodyMembers(ctx, shape)
187173
if (httpBodyMembers.isNotEmpty() || shouldRenderEncodableConformance) {
188174
ctx.delegator.useShapeWriter(encodeSymbol) { writer ->
189175
writer.openBlock(
@@ -208,7 +194,7 @@ abstract class HTTPBindingProtocolGenerator(
208194
override fun generateCodableConformanceForNestedTypes(ctx: ProtocolGenerator.GenerationContext) {
209195
val nestedShapes =
210196
resolveShapesNeedingCodableConformance(ctx)
211-
.filter { !it.isStreaming }
197+
.filter { !it.isEventStreaming }
212198
for (shape in nestedShapes) {
213199
renderCodableExtension(ctx, shape)
214200
}
@@ -567,6 +553,11 @@ abstract class HTTPBindingProtocolGenerator(
567553
messageUnmarshallableGenerator.render(streamingMember)
568554
}
569555
}
556+
557+
abstract fun httpBodyMembers(
558+
ctx: ProtocolGenerator.GenerationContext,
559+
shape: Shape,
560+
): List<MemberShape>
570561
}
571562

572563
class DefaultServiceConfig(

smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/protocols/rpcv2cbor/RpcV2CborProtocolGenerator.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package software.amazon.smithy.swift.codegen.protocols.rpcv2cbor
22

33
import software.amazon.smithy.codegen.core.Symbol
4+
import software.amazon.smithy.model.shapes.MemberShape
45
import software.amazon.smithy.model.shapes.OperationShape
6+
import software.amazon.smithy.model.shapes.Shape
57
import software.amazon.smithy.model.shapes.ShapeId
68
import software.amazon.smithy.model.traits.StreamingTrait
79
import software.amazon.smithy.model.traits.UnitTypeTrait
@@ -89,6 +91,14 @@ class RpcV2CborProtocolGenerator(
8991
}
9092
}
9193

94+
override fun httpBodyMembers(
95+
ctx: ProtocolGenerator.GenerationContext,
96+
shape: Shape,
97+
): List<MemberShape> =
98+
shape
99+
.members()
100+
.toList()
101+
92102
/**
93103
* @return whether the operation input does _not_ target the unit shape ([UnitTypeTrait.UNIT])
94104
*/

smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/protocolgeneratormocks/MockHTTPAWSJson11ProtocolGenerator.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ package software.amazon.smithy.swift.codegen.protocolgeneratormocks
77

88
import software.amazon.smithy.aws.traits.protocols.AwsJson1_1Trait
99
import software.amazon.smithy.model.pattern.UriPattern
10+
import software.amazon.smithy.model.shapes.MemberShape
1011
import software.amazon.smithy.model.shapes.OperationShape
12+
import software.amazon.smithy.model.shapes.Shape
1113
import software.amazon.smithy.model.shapes.ShapeId
1214
import software.amazon.smithy.model.traits.HttpTrait
1315
import software.amazon.smithy.swift.codegen.SwiftWriter
@@ -19,7 +21,9 @@ import software.amazon.smithy.swift.codegen.integration.HttpProtocolUnitTestErro
1921
import software.amazon.smithy.swift.codegen.integration.HttpProtocolUnitTestRequestGenerator
2022
import software.amazon.smithy.swift.codegen.integration.HttpProtocolUnitTestResponseGenerator
2123
import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator
24+
import software.amazon.smithy.swift.codegen.integration.isEventStreaming
2225
import software.amazon.smithy.swift.codegen.integration.protocols.core.StaticHttpBindingResolver
26+
import software.amazon.smithy.swift.codegen.model.targetOrSelf
2327
import software.amazon.smithy.swift.codegen.requestandresponse.TestHttpProtocolClientGeneratorFactory
2428

2529
class MockJsonHttpBindingResolver(
@@ -87,4 +91,15 @@ class MockHTTPAWSJson11ProtocolGenerator : HTTPBindingProtocolGenerator(MockAWSJ
8791
ctx: ProtocolGenerator.GenerationContext,
8892
defaultContentType: String,
8993
): HttpBindingResolver = MockJsonHttpBindingResolver(ctx, defaultContentType)
94+
95+
override fun httpBodyMembers(
96+
ctx: ProtocolGenerator.GenerationContext,
97+
shape: Shape,
98+
): List<MemberShape> =
99+
shape
100+
.members()
101+
// For RPC protocols that support event streaming, we need to send initial request
102+
// with streaming member excluded during encoding the input struct.
103+
.filter { !it.targetOrSelf(ctx.model).isEventStreaming }
104+
.toList()
90105
}

smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/protocolgeneratormocks/MockHTTPEC2QueryProtocolGenerator.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ package software.amazon.smithy.swift.codegen.protocolgeneratormocks
77

88
import software.amazon.smithy.aws.traits.protocols.Ec2QueryTrait
99
import software.amazon.smithy.model.pattern.UriPattern
10+
import software.amazon.smithy.model.shapes.MemberShape
1011
import software.amazon.smithy.model.shapes.OperationShape
12+
import software.amazon.smithy.model.shapes.Shape
1113
import software.amazon.smithy.model.shapes.ShapeId
1214
import software.amazon.smithy.model.traits.HttpTrait
1315
import software.amazon.smithy.swift.codegen.integration.DefaultHTTPProtocolCustomizations
@@ -77,4 +79,12 @@ class MockHTTPEC2QueryProtocolGenerator : HTTPBindingProtocolGenerator(MockEC2Qu
7779
getProtocolHttpBindingResolver(ctx, defaultContentType),
7880
).generateProtocolTests()
7981
}
82+
83+
override fun httpBodyMembers(
84+
ctx: ProtocolGenerator.GenerationContext,
85+
shape: Shape,
86+
): List<MemberShape> =
87+
shape
88+
.members()
89+
.toList()
8090
}

smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/protocolgeneratormocks/MockHTTPRPCv2CBORProtocolGenerator.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ package software.amazon.smithy.swift.codegen.protocolgeneratormocks
55
* SPDX-License-Identifier: Apache-2.0.
66
*/
77

8+
import software.amazon.smithy.model.shapes.MemberShape
89
import software.amazon.smithy.model.shapes.OperationShape
10+
import software.amazon.smithy.model.shapes.Shape
911
import software.amazon.smithy.model.shapes.ShapeId
1012
import software.amazon.smithy.protocol.traits.Rpcv2CborTrait
1113
import software.amazon.smithy.swift.codegen.integration.DefaultHTTPProtocolCustomizations
@@ -53,4 +55,12 @@ class MockHTTPRPCv2CBORProtocolGenerator : HTTPBindingProtocolGenerator(MockRPCv
5355
getProtocolHttpBindingResolver(ctx, defaultContentType),
5456
).generateProtocolTests()
5557
}
58+
59+
override fun httpBodyMembers(
60+
ctx: ProtocolGenerator.GenerationContext,
61+
shape: Shape,
62+
): List<MemberShape> =
63+
shape
64+
.members()
65+
.toList()
5666
}

smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/protocolgeneratormocks/MockHTTPRestJsonProtocolGenerator.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ package software.amazon.smithy.swift.codegen.protocolgeneratormocks
66
*/
77

88
import software.amazon.smithy.aws.traits.protocols.RestJson1Trait
9+
import software.amazon.smithy.model.shapes.MemberShape
910
import software.amazon.smithy.model.shapes.OperationShape
11+
import software.amazon.smithy.model.shapes.Shape
1012
import software.amazon.smithy.model.shapes.ShapeId
1113
import software.amazon.smithy.swift.codegen.integration.DefaultHTTPProtocolCustomizations
1214
import software.amazon.smithy.swift.codegen.integration.HTTPBindingProtocolGenerator
@@ -15,6 +17,7 @@ import software.amazon.smithy.swift.codegen.integration.HttpProtocolUnitTestErro
1517
import software.amazon.smithy.swift.codegen.integration.HttpProtocolUnitTestRequestGenerator
1618
import software.amazon.smithy.swift.codegen.integration.HttpProtocolUnitTestResponseGenerator
1719
import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator
20+
import software.amazon.smithy.swift.codegen.integration.isInHttpBody
1821
import software.amazon.smithy.swift.codegen.requestandresponse.TestHttpProtocolClientGeneratorFactory
1922

2023
class MockRestJsonHTTPProtocolCustomizations : DefaultHTTPProtocolCustomizations()
@@ -53,4 +56,13 @@ class MockHTTPRestJsonProtocolGenerator : HTTPBindingProtocolGenerator(MockRestJ
5356
getProtocolHttpBindingResolver(ctx, defaultContentType),
5457
).generateProtocolTests()
5558
}
59+
60+
override fun httpBodyMembers(
61+
ctx: ProtocolGenerator.GenerationContext,
62+
shape: Shape,
63+
): List<MemberShape> =
64+
shape
65+
.members()
66+
.filter { it.isInHttpBody() }
67+
.toList()
5668
}

smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/protocolgeneratormocks/MockHTTPRestXMLProtocolGenerator.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ package software.amazon.smithy.swift.codegen.protocolgeneratormocks
66
*/
77

88
import software.amazon.smithy.aws.traits.protocols.RestXmlTrait
9+
import software.amazon.smithy.model.shapes.MemberShape
910
import software.amazon.smithy.model.shapes.OperationShape
11+
import software.amazon.smithy.model.shapes.Shape
1012
import software.amazon.smithy.model.shapes.ShapeId
1113
import software.amazon.smithy.swift.codegen.integration.DefaultHTTPProtocolCustomizations
1214
import software.amazon.smithy.swift.codegen.integration.HTTPBindingProtocolGenerator
@@ -15,6 +17,7 @@ import software.amazon.smithy.swift.codegen.integration.HttpProtocolUnitTestErro
1517
import software.amazon.smithy.swift.codegen.integration.HttpProtocolUnitTestRequestGenerator
1618
import software.amazon.smithy.swift.codegen.integration.HttpProtocolUnitTestResponseGenerator
1719
import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator
20+
import software.amazon.smithy.swift.codegen.integration.isInHttpBody
1821
import software.amazon.smithy.swift.codegen.requestandresponse.TestHttpProtocolClientGeneratorFactory
1922

2023
class MockRestXMLHTTPProtocolCustomizations : DefaultHTTPProtocolCustomizations()
@@ -53,4 +56,13 @@ class MockHTTPRestXMLProtocolGenerator : HTTPBindingProtocolGenerator(MockRestXM
5356
getProtocolHttpBindingResolver(ctx, defaultContentType),
5457
).generateProtocolTests()
5558
}
59+
60+
override fun httpBodyMembers(
61+
ctx: ProtocolGenerator.GenerationContext,
62+
shape: Shape,
63+
): List<MemberShape> =
64+
shape
65+
.members()
66+
.filter { it.isInHttpBody() }
67+
.toList()
5668
}

0 commit comments

Comments
 (0)