diff --git a/CHANGELOG.md b/CHANGELOG.md index 29e53ee59e947029bbf407a92a09af771a5e25a4..fc57df15bfa042308deb9a3cf73bde02e3118dbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ vNext (Month Day, Year) ======================= **New this week** - Fix typos in module documentation for generated crates (smithy-rs#920) +- Avoid serializing repetitive `xmlns` attributes in generated XML serializers. (aws-sdk-rust#301, smithy-rs#892) **Breaking changes** @@ -15,6 +16,7 @@ v0.31.0 (December 2nd, 2021) **New this week** - Add docs.rs metadata section to all crates to document all features + v0.30.0-alpha (November 23rd, 2021) =================================== diff --git a/aws/SDK_CHANGELOG.md b/aws/SDK_CHANGELOG.md index 33d1bdcbfe96b6df4b818ea8b0e6b971403d6ecd..87edcbe9b911748e6a4ef845a725f2e462e71067 100644 --- a/aws/SDK_CHANGELOG.md +++ b/aws/SDK_CHANGELOG.md @@ -2,6 +2,8 @@ vNext (Month Day, Year) ======================= **New this release** - Fix typos in module documentation for generated crates (smithy-rs#920) +- Avoid serializing repetitive `xmlns` attributes in generated XML serializers. This reduces the length of serialized requests and should improve compatibility with localstack. (aws-sdk-rust#301, smithy-rs#892) + v0.2.0 (December 2nd, 2021) =========================== diff --git a/aws/sdk/aws-models/s3-tests.smithy b/aws/sdk/aws-models/s3-tests.smithy index 93b90ef34e7f6b834ba30590b7e06a39d0d4b441..60368d0604388cd4d0d441ba3183e9fb76ab95f8 100644 --- a/aws/sdk/aws-models/s3-tests.smithy +++ b/aws/sdk/aws-models/s3-tests.smithy @@ -111,17 +111,17 @@ apply PutBucketLifecycleConfiguration @httpRequestTests([ headers: { // we can assert this, but when this test is promoted, it can't assert // on the exact contents - "content-md5": "sUu+uAZPkTtAxJdaA+9uSg==", + "content-md5": "JP8DTuCSH6yDC8wNGg4+mA==", }, bodyMediaType: "application/xml", body: """ - - - 1 + + + 1 - Expire - Enabled + Expire + Enabled """, diff --git a/aws/sdk/integration-tests/s3/Cargo.toml b/aws/sdk/integration-tests/s3/Cargo.toml index 73c99df8a750b0d61c8b85d7b2df82d5470ecccf..f0e0b12df8761d055f8c23cb976e9e66a6055e6b 100644 --- a/aws/sdk/integration-tests/s3/Cargo.toml +++ b/aws/sdk/integration-tests/s3/Cargo.toml @@ -15,6 +15,7 @@ aws-smithy-async = { path = "../../build/aws-sdk/sdk/aws-smithy-async" } aws-smithy-client = { path = "../../build/aws-sdk/sdk/aws-smithy-client", features = ["test-util"] } aws-smithy-http = { path = "../../build/aws-sdk/sdk/aws-smithy-http" } aws-smithy-types = { path = "../../build/aws-sdk/sdk/aws-smithy-types" } +aws-smithy-protocol-test = { path = "../../build/aws-sdk/sdk/aws-smithy-protocol-test" } bytes = "1" http = "0.2.3" serde_json = "1" diff --git a/aws/sdk/integration-tests/s3/tests/select-object-content.json b/aws/sdk/integration-tests/s3/tests/select-object-content.json index 9434df269b5d532fcd7161a6e9c69a1779aeae61..481b120d4ddfa10b2278cd03bf384c2d6f523e17 100644 --- a/aws/sdk/integration-tests/s3/tests/select-object-content.json +++ b/aws/sdk/integration-tests/s3/tests/select-object-content.json @@ -7,25 +7,25 @@ "uri": "https://s3.us-east-2.amazonaws.com/aws-rust-sdk/sample_data.csv?select&select-type=2&x-id=SelectObjectContent", "headers": { "x-amz-date": [ - "20210831T010050Z" + "20211126T205841Z" + ], + "x-amz-content-sha256": [ + "591d6c5a9bb1019b499d65fb01a6e473346ad65f2b513f03e17e388b3c788f53" ], "content-type": [ "application/xml" ], - "x-amz-content-sha256": [ - "3e2ed0bf97f28640f16193df06b497374232511cd2112b48985a306d40fb16d3" + "user-agent": [ + "aws-sdk-rust/0.0.26-alpha os/macos lang/rust/1.53.0" ], - "content-length": [ - "799" + "x-amz-user-agent": [ + "aws-sdk-rust/0.0.26-alpha api/s3/0.0.26-alpha os/macos lang/rust/1.53.0" ], "authorization": [ - "AWS4-HMAC-SHA256 Credential=test/test/us-east-2/s3/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-user-agent, Signature=test" + "AWS4-HMAC-SHA256 Credential=test/20211126/us-east-2/s3/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-user-agent, Signature=c7fd94cc4ec7b902c0d606919a350927c0cdcd625e7a0135c4bfa213dcedd4c1" ], - "user-agent": [ - "aws-sdk-rust/0.1.0 os/linux lang/rust/1.52.1" - ], - "x-amz-user-agent": [ - "aws-sdk-rust/0.1.0 api/s3/0.0.16-alpha os/linux lang/rust/1.52.1" + "content-length": [ + "415" ] }, "method": "POST" @@ -38,7 +38,7 @@ "action": { "Data": { "data": { - "Utf8": "SELECT * FROM s3object s WHERE s."Name" = 'Jane'SQLUSENONE" + "Utf8": "SELECT * FROM s3object s WHERE s."Name" = 'Jane'SQLUSENONE" }, "direction": "Request" } @@ -62,20 +62,20 @@ "status": 200, "version": "HTTP/1.1", "headers": { - "x-amz-request-id": [ - "NVKMNP55BP15194G" + "server": [ + "AmazonS3" ], "x-amz-id-2": [ "geaWcKlzoJpu+EJLNG+t9uaD/9EOuQzGqcxL41SguR9xoDOVMFnjw7CFLm/yHQc3AVpHqHCo3a0=" ], + "date": [ + "Tue, 31 Aug 2021 01:00:52 GMT" + ], "transfer-encoding": [ "chunked" ], - "server": [ - "AmazonS3" - ], - "date": [ - "Tue, 31 Aug 2021 01:00:52 GMT" + "x-amz-request-id": [ + "NVKMNP55BP15194G" ] } } diff --git a/aws/sdk/integration-tests/s3/tests/select-object-content.rs b/aws/sdk/integration-tests/s3/tests/select-object-content.rs index e754b5011ecf20c6ce01f989f604d3bc61ef69a9..a034830a5606ed749227350e135b3520310d264d 100644 --- a/aws/sdk/integration-tests/s3/tests/select-object-content.rs +++ b/aws/sdk/integration-tests/s3/tests/select-object-content.rs @@ -9,6 +9,7 @@ use aws_sdk_s3::model::{ }; use aws_sdk_s3::{Client, Config, Credentials, Region}; use aws_smithy_client::dvr::{Event, ReplayingConnection}; +use aws_smithy_protocol_test::{assert_ok, validate_body, MediaType}; use std::error::Error as StdError; #[tokio::test] @@ -82,14 +83,14 @@ async fn test_success() { // Validate the requests replayer - .validate(&["content-type", "content-length"], validate_body) + .validate(&["content-type", "content-length"], body_validator) .await .unwrap(); } -fn validate_body(expected_body: &[u8], actual_body: &[u8]) -> Result<(), Box> { +fn body_validator(expected_body: &[u8], actual_body: &[u8]) -> Result<(), Box> { let expected = std::str::from_utf8(expected_body).unwrap(); let actual = std::str::from_utf8(actual_body).unwrap(); - assert_eq!(expected, actual); + assert_ok(validate_body(actual, expected, MediaType::Xml)); Ok(()) } diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/serialize/XmlBindingTraitSerializerGenerator.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/serialize/XmlBindingTraitSerializerGenerator.kt index 198797415923e4436e5ed1aa9b6e6ef5799409f4..d285c24664c5b02a30f00eb97f70a8e69077fec0 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/serialize/XmlBindingTraitSerializerGenerator.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/serialize/XmlBindingTraitSerializerGenerator.kt @@ -43,6 +43,7 @@ import software.amazon.smithy.rust.codegen.smithy.generators.UnionGenerator import software.amazon.smithy.rust.codegen.smithy.generators.renderUnknownVariant import software.amazon.smithy.rust.codegen.smithy.generators.serializationError import software.amazon.smithy.rust.codegen.smithy.isOptional +import software.amazon.smithy.rust.codegen.smithy.letIf import software.amazon.smithy.rust.codegen.smithy.protocols.HttpBindingResolver import software.amazon.smithy.rust.codegen.smithy.protocols.HttpLocation import software.amazon.smithy.rust.codegen.smithy.protocols.XmlMemberIndex @@ -123,7 +124,7 @@ class XmlBindingTraitSerializerGenerator( """ let mut writer = #{XmlWriter}::new(&mut out); ##[allow(unused_mut)] - let mut root = writer.start_el(${operationXmlName.dq()})${inputShape.xmlNamespace().apply()}; + let mut root = writer.start_el(${operationXmlName.dq()})${inputShape.xmlNamespace(root = true).apply()}; """, *codegenScope ) @@ -156,7 +157,7 @@ class XmlBindingTraitSerializerGenerator( let mut writer = #{XmlWriter}::new(&mut out); ##[allow(unused_mut)] let mut root = writer.start_el(${xmlIndex.payloadShapeName(member).dq()})${ - target.xmlNamespace().apply() + target.xmlNamespace(root = true).apply() }; """, *codegenScope @@ -255,7 +256,7 @@ class XmlBindingTraitSerializerGenerator( private fun RustWriter.serializeMember(memberShape: MemberShape, ctx: Ctx.Scope, rootNameOverride: String? = null) { val target = model.expectShape(memberShape.target) val xmlName = rootNameOverride ?: xmlIndex.memberName(memberShape) - val ns = memberShape.xmlNamespace().apply() + val ns = memberShape.xmlNamespace(root = false).apply() handleOptional(memberShape, ctx) { ctx -> when (target) { is StringShape, is BooleanShape, is NumberShape, is TimestampShape, is BlobShape -> { @@ -411,7 +412,7 @@ class XmlBindingTraitSerializerGenerator( private fun OperationShape.operationXmlMembers(): XmlMemberIndex = XmlMemberIndex.fromMembers(httpBindingResolver.requestMembers(this, HttpLocation.DOCUMENT)) - private fun Shape.xmlNamespace(): XmlNamespaceTrait? { - return this.getTrait() ?: rootNamespace + private fun Shape.xmlNamespace(root: Boolean): XmlNamespaceTrait? { + return this.getTrait().letIf(root) { it ?: rootNamespace } } }