-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add EC2 Query protocol support (#475)
* Add EC2 Query protocol support * Centralize serialization logic between AWS Query and EC2 Query
- Loading branch information
Showing
15 changed files
with
877 additions
and
292 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/Ec2Query.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
|
||
package software.amazon.smithy.rust.codegen.smithy.protocols | ||
|
||
import software.amazon.smithy.model.Model | ||
import software.amazon.smithy.model.pattern.UriPattern | ||
import software.amazon.smithy.model.shapes.OperationShape | ||
import software.amazon.smithy.model.traits.HttpTrait | ||
import software.amazon.smithy.model.traits.TimestampFormatTrait | ||
import software.amazon.smithy.rust.codegen.rustlang.CargoDependency | ||
import software.amazon.smithy.rust.codegen.rustlang.asType | ||
import software.amazon.smithy.rust.codegen.rustlang.rust | ||
import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate | ||
import software.amazon.smithy.rust.codegen.smithy.RuntimeType | ||
import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig | ||
import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolGeneratorFactory | ||
import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolSupport | ||
import software.amazon.smithy.rust.codegen.smithy.protocols.parse.Ec2QueryParserGenerator | ||
import software.amazon.smithy.rust.codegen.smithy.protocols.parse.StructuredDataParserGenerator | ||
import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.Ec2QuerySerializerGenerator | ||
import software.amazon.smithy.rust.codegen.smithy.protocols.serialize.StructuredDataSerializerGenerator | ||
import software.amazon.smithy.rust.codegen.smithy.transformers.OperationNormalizer | ||
import software.amazon.smithy.rust.codegen.smithy.transformers.RemoveEventStreamOperations | ||
|
||
class Ec2QueryFactory : ProtocolGeneratorFactory<HttpBoundProtocolGenerator> { | ||
override fun buildProtocolGenerator(protocolConfig: ProtocolConfig): HttpBoundProtocolGenerator = | ||
HttpBoundProtocolGenerator(protocolConfig, Ec2QueryProtocol(protocolConfig)) | ||
|
||
override fun transformModel(model: Model): Model { | ||
return OperationNormalizer(model).transformModel( | ||
inputBodyFactory = OperationNormalizer.NoBody, | ||
outputBodyFactory = OperationNormalizer.NoBody | ||
).let(RemoveEventStreamOperations::transform) | ||
} | ||
|
||
override fun support(): ProtocolSupport { | ||
return ProtocolSupport( | ||
requestSerialization = true, | ||
requestBodySerialization = true, | ||
responseDeserialization = true, | ||
errorDeserialization = true, | ||
) | ||
} | ||
} | ||
|
||
class Ec2QueryProtocol(private val protocolConfig: ProtocolConfig) : Protocol { | ||
private val runtimeConfig = protocolConfig.runtimeConfig | ||
private val ec2QueryErrors: RuntimeType = RuntimeType.ec2QueryErrors(runtimeConfig) | ||
override val httpBindingResolver: HttpBindingResolver = StaticHttpBindingResolver( | ||
protocolConfig.model, | ||
HttpTrait.builder() | ||
.code(200) | ||
.method("POST") | ||
.uri(UriPattern.parse("/")) | ||
.build(), | ||
"application/x-www-form-urlencoded" | ||
) | ||
|
||
override val defaultTimestampFormat: TimestampFormatTrait.Format = TimestampFormatTrait.Format.DATE_TIME | ||
|
||
override fun structuredDataParser(operationShape: OperationShape): StructuredDataParserGenerator = | ||
Ec2QueryParserGenerator(protocolConfig, ec2QueryErrors) | ||
|
||
override fun structuredDataSerializer(operationShape: OperationShape): StructuredDataSerializerGenerator = | ||
Ec2QuerySerializerGenerator(protocolConfig) | ||
|
||
override fun parseGenericError(operationShape: OperationShape): RuntimeType { | ||
/** | ||
fn parse_generic(response: &Response<Bytes>) -> Result<smithy_types::error::Generic, T: Error> | ||
**/ | ||
return RuntimeType.forInlineFun("parse_generic_error", "xml_deser") { | ||
it.rustBlockTemplate( | ||
"pub fn parse_generic_error(response: &#{Response}<#{Bytes}>) -> Result<#{Error}, #{XmlError}>", | ||
"Response" to RuntimeType.http.member("Response"), | ||
"Bytes" to RuntimeType.Bytes, | ||
"Error" to RuntimeType.GenericError(runtimeConfig), | ||
"XmlError" to CargoDependency.smithyXml(runtimeConfig).asType().member("decode::XmlError") | ||
) { | ||
rust("#T::parse_generic_error(response.body().as_ref())", ec2QueryErrors) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
...lin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/Ec2QueryParserGenerator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package software.amazon.smithy.rust.codegen.smithy.protocols.parse | ||
|
||
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate | ||
import software.amazon.smithy.rust.codegen.smithy.RuntimeType | ||
import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig | ||
|
||
/** | ||
* The EC2 query protocol's responses are identical to REST XML's, except that they are wrapped | ||
* in a Response tag: | ||
* | ||
* ``` | ||
* <SomeOperationResponse> | ||
* <ActualData /> <!-- This part is the same as REST XML --> | ||
* </SomeOperationResponse> | ||
* ``` | ||
* | ||
* This class wraps [XmlBindingTraitParserGenerator] and uses it to render the vast majority | ||
* of the response parsing, but it overrides [operationParser] to add the protocol differences. | ||
*/ | ||
class Ec2QueryParserGenerator( | ||
protocolConfig: ProtocolConfig, | ||
xmlErrors: RuntimeType, | ||
private val xmlBindingTraitParserGenerator: XmlBindingTraitParserGenerator = | ||
XmlBindingTraitParserGenerator( | ||
protocolConfig, | ||
xmlErrors | ||
) { context, inner -> | ||
val operationName = protocolConfig.symbolProvider.toSymbol(context.shape).name | ||
val responseWrapperName = operationName + "Response" | ||
rustTemplate( | ||
""" | ||
if !(${XmlBindingTraitParserGenerator.XmlName(responseWrapperName).matchExpression("start_el")}) { | ||
return Err(#{XmlError}::custom(format!("invalid root, expected $responseWrapperName got {:?}", start_el))) | ||
} | ||
""", | ||
"XmlError" to context.xmlErrorType | ||
) | ||
inner("decoder") | ||
} | ||
) : StructuredDataParserGenerator by xmlBindingTraitParserGenerator |
Oops, something went wrong.