@@ -6,17 +6,23 @@ package aws.sdk.kotlin.codegen.customization.flexiblechecksums
66
77import software.amazon.smithy.aws.traits.HttpChecksumTrait
88import software.amazon.smithy.kotlin.codegen.KotlinSettings
9+ import software.amazon.smithy.kotlin.codegen.core.CodegenContext
910import software.amazon.smithy.kotlin.codegen.core.KotlinWriter
1011import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes
1112import software.amazon.smithy.kotlin.codegen.core.withBlock
1213import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration
1314import software.amazon.smithy.kotlin.codegen.model.*
1415import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolGenerator
1516import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolMiddleware
17+ import software.amazon.smithy.kotlin.codegen.rendering.util.ConfigProperty
18+ import software.amazon.smithy.kotlin.codegen.rendering.util.ConfigPropertyType
1619import software.amazon.smithy.kotlin.codegen.utils.getOrNull
1720import software.amazon.smithy.model.Model
1821import software.amazon.smithy.model.shapes.OperationShape
22+ import software.amazon.smithy.model.shapes.ShapeId
1923import software.amazon.smithy.model.shapes.StructureShape
24+ import software.amazon.smithy.model.traits.HttpPayloadTrait
25+ import software.amazon.smithy.model.traits.StreamingTrait
2026
2127/* *
2228 * Adds a middleware that enables sending flexible checksums during an HTTP request
@@ -26,8 +32,61 @@ class FlexibleChecksumsRequest : KotlinIntegration {
2632 .shapes<OperationShape >()
2733 .any { it.hasTrait<HttpChecksumTrait >() }
2834
35+ override fun additionalServiceConfigProps (ctx : CodegenContext ): List <ConfigProperty > =
36+ listOf (
37+ ConfigProperty {
38+ name = " requestChecksumCalculation"
39+ symbol = RuntimeTypes .SmithyClient .Config .ChecksumConfigOption
40+ baseClass = RuntimeTypes .SmithyClient .Config .HttpChecksumClientConfig
41+ useNestedBuilderBaseClass()
42+ documentation = " " // todo
43+ propertyType = ConfigPropertyType .RequiredWithDefault (" ChecksumConfigOption.WHEN_SUPPORTED" )
44+ },
45+ )
46+
47+ private val operationsWithStreamingPayloads = mutableListOf<ShapeId >()
48+
49+ override fun preprocessModel (model : Model , settings : KotlinSettings ): Model {
50+ model.operationShapes.forEach { operationShape ->
51+
52+ val operationInput = model.expectShape<StructureShape >(operationShape.inputShape)
53+
54+ operationInput.members().find { it.hasTrait<HttpPayloadTrait >() }?.let { httpPayload ->
55+ if (model.getShape(httpPayload.target).get().hasTrait<StreamingTrait >()) {
56+ operationsWithStreamingPayloads.add(operationShape.id)
57+ }
58+ }
59+ }
60+
61+ return model
62+ }
63+
2964 override fun customizeMiddleware (ctx : ProtocolGenerator .GenerationContext , resolved : List <ProtocolMiddleware >) =
30- resolved + flexibleChecksumsRequestMiddleware
65+ resolved + flexibleChecksumsRequestMiddleware + configBusinessMetrics
66+
67+ private val configBusinessMetrics = object : ProtocolMiddleware {
68+ override val name: String = " requestChecksumCalculationBusinessMetric"
69+
70+ override fun isEnabledFor (ctx : ProtocolGenerator .GenerationContext , op : OperationShape ): Boolean =
71+ op.hasTrait<HttpChecksumTrait >()
72+
73+ override fun render (ctx : ProtocolGenerator .GenerationContext , op : OperationShape , writer : KotlinWriter ) {
74+ writer.withBlock(" when(config.requestChecksumCalculation) {" , " }" ) {
75+ writer.write(
76+ " #T.WHEN_SUPPORTED -> op.context.#T(#T.FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED)" ,
77+ RuntimeTypes .SmithyClient .Config .ChecksumConfigOption ,
78+ RuntimeTypes .Core .BusinessMetrics .emitBusinessMetric,
79+ RuntimeTypes .Core .BusinessMetrics .SmithyBusinessMetric ,
80+ )
81+ writer.write(
82+ " #T.WHEN_REQUIRED -> op.context.#T(#T.FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED)" ,
83+ RuntimeTypes .SmithyClient .Config .ChecksumConfigOption ,
84+ RuntimeTypes .Core .BusinessMetrics .emitBusinessMetric,
85+ RuntimeTypes .Core .BusinessMetrics .SmithyBusinessMetric ,
86+ )
87+ }
88+ }
89+ }
3190
3291 private val flexibleChecksumsRequestMiddleware = object : ProtocolMiddleware {
3392 override val name: String = " FlexibleChecksumsRequest"
@@ -42,22 +101,25 @@ class FlexibleChecksumsRequest : KotlinIntegration {
42101 }
43102
44103 override fun render (ctx : ProtocolGenerator .GenerationContext , op : OperationShape , writer : KotlinWriter ) {
45- val interceptorSymbol = RuntimeTypes .HttpClient .Interceptors .FlexibleChecksumsRequestInterceptor
46- val inputSymbol = ctx.symbolProvider.toSymbol(ctx.model.expectShape(op.inputShape))
47-
48104 val httpChecksumTrait = op.getTrait<HttpChecksumTrait >()!!
49105
50106 val requestAlgorithmMember = ctx.model.expectShape<StructureShape >(op.input.get())
51107 .members()
52108 .first { it.memberName == httpChecksumTrait.requestAlgorithmMember.get() }
53109
54- val requestAlgorithmMemberName = ctx.symbolProvider.toMemberName(requestAlgorithmMember)
110+ val userSelectedChecksumAlgorithm = ctx.symbolProvider.toMemberName(requestAlgorithmMember)
111+ val requestChecksumRequired = httpChecksumTrait.isRequestChecksumRequired
112+ val streamingPayload = operationsWithStreamingPayloads.contains(op.id)
55113
56- writer.withBlock(" op.interceptors.add(#T<#T>() {" , " })" , interceptorSymbol, inputSymbol) {
57- writer.write(" input.#L?.value" , requestAlgorithmMemberName)
58- }
59- writer.withBlock(" input.#L?.let {" , " }" , requestAlgorithmMemberName) {
60- writer.write(" op.context[#T.ChecksumAlgorithm] = it.value" , RuntimeTypes .HttpClient .Operation .HttpOperationContext )
114+ writer.withBlock(
115+ " op.interceptors.add(#T(" ,
116+ " ))" ,
117+ RuntimeTypes .HttpClient .Interceptors .FlexibleChecksumsRequestInterceptor ,
118+ ) {
119+ writer.write(" requestChecksumRequired = #L," , requestChecksumRequired)
120+ writer.write(" requestChecksumCalculation = config.requestChecksumCalculation," )
121+ writer.write(" userSelectedChecksumAlgorithm = input.#L?.value," , userSelectedChecksumAlgorithm)
122+ writer.write(" streamingPayload = #L," , streamingPayload)
61123 }
62124 }
63125 }
0 commit comments