diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/EndpointResolverMiddleware.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/EndpointResolverMiddleware.kt index 3bb8d5357ca..79c32ef8179 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/EndpointResolverMiddleware.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/EndpointResolverMiddleware.kt @@ -93,7 +93,7 @@ class EndpointResolverMiddleware( .indent() .write(".withHost(host)") .write(".withPort(awsEndpoint.endpoint.port)") - .write(".withPath(context.getPath())") + .write(".withPath(awsEndpoint.endpoint.path.appendingPathComponent(context.getPath()))") .write(""".withHeader(name: "Host", value: host)""") .dedent() .write("") diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/model/AWSEndpointTraitTransformer.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/model/AWSEndpointTraitTransformer.kt new file mode 100644 index 00000000000..37f4e93bc94 --- /dev/null +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/model/AWSEndpointTraitTransformer.kt @@ -0,0 +1,56 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +package software.amazon.smithy.aws.swift.codegen.model + +import software.amazon.smithy.model.Model +import software.amazon.smithy.model.shapes.OperationShape +import software.amazon.smithy.model.traits.EndpointTrait +import software.amazon.smithy.model.transform.ModelTransformer +import software.amazon.smithy.rulesengine.traits.StaticContextParamsTrait +import software.amazon.smithy.swift.codegen.SwiftSettings +import software.amazon.smithy.swift.codegen.integration.SwiftIntegration +import software.amazon.smithy.swift.codegen.model.getTrait + +/** + * This integration is responsible for removing the EndpointTrait from the operation + * - For S3 Control, if hostPrefix is {AccountId}., then remove the Endpoint Trait because it is already handled + * within the EndpointResolver + */ +class AWSEndpointTraitTransformer : SwiftIntegration { + override fun preprocessModel(model: Model, settings: SwiftSettings): Model { + return when (settings.service.namespace) { + "com.amazonaws.s3control" -> { + ModelTransformer.create().mapShapes(model) { shape -> + when (shape) { + is OperationShape -> { + val shapeBuilder = shape.toBuilder() + shape.getTrait()?.let { staticContextParamsTrait -> + val requiresAccountId = + staticContextParamsTrait.parameters["RequiresAccountId"]?.value + .toString() + .toBoolean() + if (requiresAccountId) { + shape.getTrait()?.let { endpointTrait -> + val hostPrefix = endpointTrait.hostPrefix.toString() + if (hostPrefix == "{AccountId}.") { + shapeBuilder.removeTrait(endpointTrait.toShapeId()) + } + } + } + } + + shapeBuilder.build() + } + + else -> shape + } + } + } + + else -> model + } + } +} diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/model/AWSHttpTraitTransformer.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/model/AWSHttpTraitTransformer.kt new file mode 100644 index 00000000000..291bfc9ee19 --- /dev/null +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/model/AWSHttpTraitTransformer.kt @@ -0,0 +1,67 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +package software.amazon.smithy.aws.swift.codegen.model + +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.HttpLabelTrait +import software.amazon.smithy.model.traits.HttpTrait +import software.amazon.smithy.model.transform.ModelTransformer +import software.amazon.smithy.rulesengine.traits.ContextParamTrait +import software.amazon.smithy.swift.codegen.SwiftSettings +import software.amazon.smithy.swift.codegen.getOrNull +import software.amazon.smithy.swift.codegen.integration.SwiftIntegration +import software.amazon.smithy.swift.codegen.model.getTrait +import software.amazon.smithy.swift.codegen.model.hasTrait + +/** + * This integration is responsible for updating the `@httpLabel` trait to the input shape of an operation + * - For S3, if the HttpLabel is /{BucketName}{Suffix} then update the trait with /{Suffix} because + * the bucket name is already handled within the EndpointResolver + */ +class AWSHttpTraitTransformer : SwiftIntegration { + override fun preprocessModel(model: Model, settings: SwiftSettings): Model { + return when (settings.service.namespace) { + "com.amazonaws.s3" -> { + ModelTransformer.create().mapShapes(model) { shape -> + when (shape) { + is OperationShape -> { + val shapeBuilder = shape.toBuilder() + shape.input.getOrNull()?.let { input -> + val inputShape = model.expectShape(input.toShapeId()) + shape.getTrait()?.let { httpTrait -> + val uriPattern = httpTrait.uri.toString() + val httpTraitBuilder = httpTrait.toBuilder() + val members = inputShape.members() ?: emptyList() + members.forEach { member -> + if (member.hasTrait() && + member.hasTrait() && + member.memberName == "Bucket" && + uriPattern.startsWith("/{Bucket}") + ) { + var newPattern = uriPattern.substring("/{Bucket}".length) + if (!newPattern.startsWith("/")) { + newPattern = "/$newPattern" + } + httpTraitBuilder.uri(UriPattern.parse(newPattern)) + shapeBuilder.addTrait(httpTraitBuilder.build()) + } + } + } + } + shapeBuilder.build() + } + + else -> shape + } + } + } + + else -> model + } + } +} diff --git a/codegen/smithy-aws-swift-codegen/src/main/resources/META-INF/services/software.amazon.smithy.swift.codegen.integration.SwiftIntegration b/codegen/smithy-aws-swift-codegen/src/main/resources/META-INF/services/software.amazon.smithy.swift.codegen.integration.SwiftIntegration index 7acb85d025c..29090bc0d3b 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/resources/META-INF/services/software.amazon.smithy.swift.codegen.integration.SwiftIntegration +++ b/codegen/smithy-aws-swift-codegen/src/main/resources/META-INF/services/software.amazon.smithy.swift.codegen.integration.SwiftIntegration @@ -13,4 +13,6 @@ software.amazon.smithy.aws.swift.codegen.customization.presignable.PresignableUr software.amazon.smithy.aws.swift.codegen.customization.DisabledAuth software.amazon.smithy.aws.swift.codegen.PresignerGenerator software.amazon.smithy.aws.swift.codegen.model.AWSClientContextParamsTransformer -software.amazon.smithy.aws.swift.codegen.customization.ServiceGeneratorIntegration \ No newline at end of file +software.amazon.smithy.aws.swift.codegen.customization.ServiceGeneratorIntegration +software.amazon.smithy.aws.swift.codegen.model.AWSHttpTraitTransformer +software.amazon.smithy.aws.swift.codegen.model.AWSEndpointTraitTransformer \ No newline at end of file diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointResolverMiddlewareTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointResolverMiddlewareTests.kt index 6a34a8f0cb0..7b1a5deca83 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointResolverMiddlewareTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointResolverMiddlewareTests.kt @@ -79,7 +79,7 @@ class EndpointResolverMiddlewareTests { input.withMethod(context.getMethod()) .withHost(host) .withPort(awsEndpoint.endpoint.port) - .withPath(context.getPath()) + .withPath(awsEndpoint.endpoint.path.appendingPathComponent(context.getPath())) .withHeader(name: "Host", value: host) return try await next.handle(context: updatedContext, input: input)