From 2f2db5a637736c78dbecd3bf0c0c7e362516b30e Mon Sep 17 00:00:00 2001 From: Zelda Hessler Date: Thu, 16 Jun 2022 14:37:01 -0500 Subject: [PATCH] =?UTF-8?q?rename:=20hosted=5Fzone=5Fpreprocessor.rs=20to?= =?UTF-8?q?=20route53=5Fresource=5Fid=5Fpreprocess=E2=80=A6=20(#1472)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * rename: hosted_zone_preprocessor.rs to route53_resource_id_preprocessor.rs update: trim_hosted_zone to work for more resource ids add: new Route53 protocol test for GetChange resource id trimming update: InlineDependency.forRustFile to accept filenames with a ".rs" extension add: CHANGELOG.next.toml entry --- CHANGELOG.next.toml | 10 +++ .../src/hosted_zone_preprocessor.rs | 61 -------------- aws/rust-runtime/aws-inlineable/src/lib.rs | 4 +- .../src/route53_resource_id_preprocessor.rs | 82 +++++++++++++++++++ .../customize/route53/Route53Decorator.kt | 28 ++++--- .../{TrimHostedZone.kt => TrimResourceId.kt} | 6 +- aws/sdk/aws-models/route53-tests.smithy | 32 +++++++- aws/sdk/integration-tests/Cargo.toml | 2 +- .../rust/codegen/rustlang/CargoDependency.kt | 2 +- 9 files changed, 146 insertions(+), 81 deletions(-) delete mode 100644 aws/rust-runtime/aws-inlineable/src/hosted_zone_preprocessor.rs create mode 100644 aws/rust-runtime/aws-inlineable/src/route53_resource_id_preprocessor.rs rename aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/route53/{TrimHostedZone.kt => TrimResourceId.kt} (63%) diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index 05fa4cd30..69f79589c 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -37,3 +37,13 @@ message = "Fix RustWriter bugs for `rustTemplate` and `docs` utility methods" references = ["smithy-rs#1427", "smithy-rs#1465", "smithy-rs#1459"] meta = { "breaking" = false, "tada" = false, "bug" = true } author = "rcoh" + +[[smithy-rs]] +message = """ +Requests to Route53 that return `ResourceId`s often come with a prefix. When passing those IDs directly into another +request, the request would fail unless they manually stripped the prefix. Now, when making a request with a prefixed ID, +the prefix will be stripped automatically. +""" +references = ["aws-sdk-rust#554"] +meta = { "breaking" = false, "tada" = false, "bug" = true } +author = "Velfi" diff --git a/aws/rust-runtime/aws-inlineable/src/hosted_zone_preprocessor.rs b/aws/rust-runtime/aws-inlineable/src/hosted_zone_preprocessor.rs deleted file mode 100644 index 0bfd184e4..000000000 --- a/aws/rust-runtime/aws-inlineable/src/hosted_zone_preprocessor.rs +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -/// Strip the /hostedzone/ prefix from zone-id -pub fn trim_hosted_zone(zone: &mut Option) { - const PREFIXES: &[&str; 2] = &["/hostedzone/", "hostedzone/"]; - - for prefix in PREFIXES { - if let Some(core_zone) = zone.as_deref().unwrap_or_default().strip_prefix(prefix) { - *zone = Some(core_zone.to_string()); - return; - } - } -} - -#[cfg(test)] -mod test { - use crate::hosted_zone_preprocessor::trim_hosted_zone; - - struct OperationInput { - hosted_zone: Option, - } - - #[test] - fn does_not_change_regular_zones() { - let mut operation = OperationInput { - hosted_zone: Some("Z0441723226OZ66S5ZCNZ".to_string()), - }; - trim_hosted_zone(&mut operation.hosted_zone); - assert_eq!( - &operation.hosted_zone.unwrap_or_default(), - "Z0441723226OZ66S5ZCNZ" - ); - } - - #[test] - fn sanitizes_prefixed_zone() { - let mut operation = OperationInput { - hosted_zone: Some("/hostedzone/Z0441723226OZ66S5ZCNZ".to_string()), - }; - trim_hosted_zone(&mut operation.hosted_zone); - assert_eq!( - &operation.hosted_zone.unwrap_or_default(), - "Z0441723226OZ66S5ZCNZ" - ); - } - - #[test] - fn allow_no_leading_slash() { - let mut operation = OperationInput { - hosted_zone: Some("hostedzone/Z0441723226OZ66S5ZCNZ".to_string()), - }; - trim_hosted_zone(&mut operation.hosted_zone); - assert_eq!( - &operation.hosted_zone.unwrap_or_default(), - "Z0441723226OZ66S5ZCNZ" - ); - } -} diff --git a/aws/rust-runtime/aws-inlineable/src/lib.rs b/aws/rust-runtime/aws-inlineable/src/lib.rs index 567722714..76b285f70 100644 --- a/aws/rust-runtime/aws-inlineable/src/lib.rs +++ b/aws/rust-runtime/aws-inlineable/src/lib.rs @@ -33,5 +33,5 @@ pub mod glacier_checksums; /// Default middleware stack for AWS services pub mod middleware; -/// Strip `hostedzone/` from hosted zone ids -pub mod hosted_zone_preprocessor; +/// Strip prefixes from IDs returned by Route53 operations when those IDs are used to construct requests +pub mod route53_resource_id_preprocessor; diff --git a/aws/rust-runtime/aws-inlineable/src/route53_resource_id_preprocessor.rs b/aws/rust-runtime/aws-inlineable/src/route53_resource_id_preprocessor.rs new file mode 100644 index 000000000..b1827f065 --- /dev/null +++ b/aws/rust-runtime/aws-inlineable/src/route53_resource_id_preprocessor.rs @@ -0,0 +1,82 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +// This function is only used to strip prefixes from resource IDs at the time they're passed as +// input to a request. Resource IDs returned in responses may or may not include a prefix. +/// Strip the resource type prefix from resource ID return +pub fn trim_resource_id(resource_id: &mut Option) { + const PREFIXES: &[&str] = &[ + "/hostedzone/", + "hostedzone/", + "/change/", + "change/", + "/delegationset/", + "delegationset/", + ]; + + for prefix in PREFIXES { + if let Some(id) = resource_id + .as_deref() + .unwrap_or_default() + .strip_prefix(prefix) + { + *resource_id = Some(id.to_string()); + return; + } + } +} + +#[cfg(test)] +mod test { + use crate::route53_resource_id_preprocessor::trim_resource_id; + + #[test] + fn does_not_change_regular_zones() { + struct OperationInput { + resource: Option, + } + + let mut operation = OperationInput { + resource: Some("Z0441723226OZ66S5ZCNZ".to_string()), + }; + trim_resource_id(&mut operation.resource); + assert_eq!( + &operation.resource.unwrap_or_default(), + "Z0441723226OZ66S5ZCNZ" + ); + } + + #[test] + fn sanitizes_prefixed_zone() { + struct OperationInput { + change_id: Option, + } + + let mut operation = OperationInput { + change_id: Some("/change/Z0441723226OZ66S5ZCNZ".to_string()), + }; + trim_resource_id(&mut operation.change_id); + assert_eq!( + &operation.change_id.unwrap_or_default(), + "Z0441723226OZ66S5ZCNZ" + ); + } + + #[test] + fn allow_no_leading_slash() { + struct OperationInput { + hosted_zone: Option, + } + + let mut operation = OperationInput { + hosted_zone: Some("hostedzone/Z0441723226OZ66S5ZCNZ".to_string()), + }; + trim_resource_id(&mut operation.hosted_zone); + assert_eq!( + &operation.hosted_zone.unwrap_or_default(), + "Z0441723226OZ66S5ZCNZ" + ); + } +} diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/route53/Route53Decorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/route53/Route53Decorator.kt index 7a0338fb4..ff8b617ae 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/route53/Route53Decorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/route53/Route53Decorator.kt @@ -37,9 +37,9 @@ class Route53Decorator : RustCodegenDecorator { override fun transformModel(service: ServiceShape, model: Model): Model { return model.letIf(applies(service)) { ModelTransformer.create().mapShapes(model) { shape -> - shape.letIf(isHostId(shape)) { - logger.info("Adding TrimHostedZone trait to $shape") - (shape as MemberShape).toBuilder().addTrait(TrimHostedZone()).build() + shape.letIf(isResourceId(shape)) { + logger.info("Adding TrimResourceId trait to $shape") + (shape as MemberShape).toBuilder().addTrait(TrimResourceId()).build() } } } @@ -50,29 +50,35 @@ class Route53Decorator : RustCodegenDecorator { operation: OperationShape, baseCustomizations: List ): List { - val hostedZoneMember = operation.inputShape(codegenContext.model).members().find { it.hasTrait() } + val hostedZoneMember = + operation.inputShape(codegenContext.model).members().find { it.hasTrait() } return if (hostedZoneMember != null) { - baseCustomizations + TrimHostedZoneCustomization(codegenContext.symbolProvider.toMemberName(hostedZoneMember)) + baseCustomizations + TrimResourceIdCustomization(codegenContext.symbolProvider.toMemberName(hostedZoneMember)) } else baseCustomizations } - private fun isHostId(shape: Shape): Boolean { + private fun isResourceId(shape: Shape): Boolean { return (shape is MemberShape && shape.target == ShapeId.from("com.amazonaws.route53#ResourceId")) && shape.hasTrait() } } -class TrimHostedZoneCustomization(private val fieldName: String) : OperationCustomization() { +class TrimResourceIdCustomization(private val fieldName: String) : OperationCustomization() { override fun mutSelf(): Boolean = true override fun consumesSelf(): Boolean = true - private val trimZone = - RuntimeType.forInlineDependency(InlineAwsDependency.forRustFile("hosted_zone_preprocessor")) - .member("trim_hosted_zone") + private val trimResourceId = + RuntimeType.forInlineDependency( + InlineAwsDependency.forRustFile("route53_resource_id_preprocessor") + ) + .member("trim_resource_id") override fun section(section: OperationSection): Writable { return when (section) { is OperationSection.MutateInput -> writable { - rustTemplate("#{trim_hosted_zone}(&mut ${section.input}.$fieldName);", "trim_hosted_zone" to trimZone) + rustTemplate( + "#{trim_resource_id}(&mut ${section.input}.$fieldName);", + "trim_resource_id" to trimResourceId + ) } else -> emptySection } diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/route53/TrimHostedZone.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/route53/TrimResourceId.kt similarity index 63% rename from aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/route53/TrimHostedZone.kt rename to aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/route53/TrimResourceId.kt index 59a4bb687..1c61667fe 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/route53/TrimHostedZone.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/route53/TrimResourceId.kt @@ -10,10 +10,10 @@ import software.amazon.smithy.model.shapes.ShapeId import software.amazon.smithy.model.traits.AnnotationTrait /** - * Indicates that a member should have the `hostedzone` prefix stripped + * Indicates that a member should have their resource ID prefix stripped */ -class TrimHostedZone() : AnnotationTrait(ID, Node.objectNode()) { +class TrimResourceId() : AnnotationTrait(ID, Node.objectNode()) { companion object { - val ID = ShapeId.from("aws.api.internal#trimHostedZone") + val ID: ShapeId = ShapeId.from("aws.api.internal#trimResourceId") } } diff --git a/aws/sdk/aws-models/route53-tests.smithy b/aws/sdk/aws-models/route53-tests.smithy index d55d67d0b..36e3e234e 100644 --- a/aws/sdk/aws-models/route53-tests.smithy +++ b/aws/sdk/aws-models/route53-tests.smithy @@ -7,8 +7,8 @@ use smithy.test#httpRequestTests apply ListResourceRecordSets @httpRequestTests([ { - id: "ListResourceRecordSetsTrimHostdZone", - documentation: "This test validates that that hosted zone is correctly trimmed", + id: "ListResourceRecordSetsTrimHostedZone", + documentation: "This test validates that hosted zone is correctly trimmed", method: "GET", protocol: "aws.protocols#restXml", uri: "/2013-04-01/hostedzone/IDOFMYHOSTEDZONE/rrset", @@ -18,3 +18,31 @@ apply ListResourceRecordSets @httpRequestTests([ } } ]) + +apply GetChange @httpRequestTests([ + { + id: "GetChangeTrimChangeId", + documentation: "This test validates that change id is correctly trimmed", + method: "GET", + protocol: "aws.protocols#restXml", + uri: "/2013-04-01/change/SOMECHANGEID", + bodyMediaType: "application/xml", + params: { + "Id": "/change/SOMECHANGEID" + } + }, +]) + +apply GetReusableDelegationSet @httpRequestTests([ + { + id: "GetReusableDelegationSetTrimDelegationSetId", + documentation: "This test validates that delegation set id is correctly trimmed", + method: "GET", + protocol: "aws.protocols#restXml", + uri: "/2013-04-01/delegationset/DELEGATIONSETID", + bodyMediaType: "application/xml", + params: { + "Id": "/delegationset/DELEGATIONSETID" + } + }, +]) diff --git a/aws/sdk/integration-tests/Cargo.toml b/aws/sdk/integration-tests/Cargo.toml index ae426a1fb..06e119e43 100644 --- a/aws/sdk/integration-tests/Cargo.toml +++ b/aws/sdk/integration-tests/Cargo.toml @@ -4,6 +4,7 @@ members = [ "dynamodb", "ec2", + "glacier", "iam", "kms", "polly", @@ -12,5 +13,4 @@ members = [ "s3control", "sts", "transcribestreaming", - "glacier" ] diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/rustlang/CargoDependency.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/rustlang/CargoDependency.kt index 9189492ab..a804112f9 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/rustlang/CargoDependency.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/rustlang/CargoDependency.kt @@ -83,7 +83,7 @@ class InlineDependency( vararg additionalDependencies: RustDependency ): InlineDependency { val module = RustModule.default(name, visibility) - val filename = "$name.rs" + val filename = if (name.endsWith(".rs")) { name } else { "$name.rs" } // The inline crate is loaded as a dependency on the runtime classpath val rustFile = this::class.java.getResource("/$baseDir/src/$filename") check(rustFile != null) { "Rust file /$baseDir/src/$filename was missing from the resource bundle!" } -- GitLab