From 802524150c317c8a93fbce37d078a9d70133e255 Mon Sep 17 00:00:00 2001 From: Andrew Foss Date: Thu, 9 May 2024 07:15:32 -0700 Subject: [PATCH] feat: move endpoints classes to smithy-swift --- .../Endpoints/AWSEndpoint.swift | 76 ----------- .../AWSEndpointsRequestContext.swift | 26 ---- .../AWSEndpointsResolvedEndpoint.swift | 54 -------- .../AWSEndpointsResolvedEndpointType.swift | 19 --- .../Endpoints/AWSEndpointsRuleEngine.swift | 20 --- .../Endpoints/AuthSchemeResolver.swift | 123 ------------------ .../Endpoints/CredentialScope.swift | 16 --- .../Endpoints/EndpointError.swift | 13 -- .../Endpoints/Partition.swift | 67 ---------- .../Endpoints/ServiceEndpointMetadata.swift | 92 ------------- .../HttpContextBuilder+Extension.swift | 1 - .../Signing/AWSSigningAlgorithm.swift | 28 ---- .../Signing/AWSSigningConfig.swift | 3 +- .../Endpoints/AuthSchemeResolverTests.swift | 73 ----------- .../swift/codegen/AWSClientRuntimeTypes.kt | 1 + .../codegen/AWSHttpProtocolCustomizations.kt | 10 +- .../aws/swift/codegen/AWSServiceConfig.kt | 14 +- .../swift/codegen/EndpointParamsGenerator.kt | 101 -------------- .../codegen/EndpointResolverGenerator.kt | 106 --------------- .../swift/codegen/EndpointTestGenerator.kt | 5 +- .../config/AWSEndpointClientConfiguration.kt | 4 +- .../RulesBasedAuthSchemeResolverGenerator.kt | 7 +- ...re.kt => AWSEndpointResolverMiddleware.kt} | 58 +-------- .../OperationEndpointResolverMiddleware.kt | 4 +- .../swift/codegen/plugins/EndpointPlugin.kt | 8 +- .../codegen/EndpointParamsGeneratorTests.kt | 1 + .../EndpointResolverMiddlewareTests.kt | 6 +- ...esBasedAuthSchemeResolverGeneratorTests.kt | 2 +- 28 files changed, 38 insertions(+), 900 deletions(-) delete mode 100644 Sources/Core/AWSClientRuntime/Endpoints/AWSEndpoint.swift delete mode 100644 Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsRequestContext.swift delete mode 100644 Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsResolvedEndpoint.swift delete mode 100644 Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsResolvedEndpointType.swift delete mode 100644 Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsRuleEngine.swift delete mode 100644 Sources/Core/AWSClientRuntime/Endpoints/AuthSchemeResolver.swift delete mode 100644 Sources/Core/AWSClientRuntime/Endpoints/CredentialScope.swift delete mode 100644 Sources/Core/AWSClientRuntime/Endpoints/EndpointError.swift delete mode 100644 Sources/Core/AWSClientRuntime/Endpoints/Partition.swift delete mode 100644 Sources/Core/AWSClientRuntime/Endpoints/ServiceEndpointMetadata.swift delete mode 100644 Sources/Core/AWSClientRuntime/Signing/AWSSigningAlgorithm.swift delete mode 100644 Tests/Core/AWSClientRuntimeTests/Endpoints/AuthSchemeResolverTests.swift delete mode 100644 codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointParamsGenerator.kt delete mode 100644 codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointResolverGenerator.kt rename codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/{EndpointResolverMiddleware.kt => AWSEndpointResolverMiddleware.kt} (63%) diff --git a/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpoint.swift b/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpoint.swift deleted file mode 100644 index c03c392efc7..00000000000 --- a/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpoint.swift +++ /dev/null @@ -1,76 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -import ClientRuntime - -/** - A structure used by the service client to determine the endpoint. - The SDK will automatically resolve endpoints per API client using an internal resolver. - */ -public struct AWSEndpoint: Equatable { - /** - The endpoint object contains the host name (e.g. "{service-id}.{region}.amazonaws.com"), - the transport protocol (e.g. "HTTPS") and the port to connect to when making requests to this endpoint. - */ - public let endpoint: Endpoint - - /** - Flag indicating that the hostname can be modified by the SDK client. - If the hostname is mutable the SDK clients may modify any part of the hostname based - on the requirements of the API (e.g. adding or removing content in the hostname). If the hostname - is expected to be mutable and the client cannot modify the endpoint correctly, the operation - will likely fail. - */ - public let isHostnameImmutable: Bool - /** - The service name that should be used for signing requests to this endpoint. - This overrides the default signing name used by an SDK client. - */ - public let signingName: String? - /** - The region that should be used for signing requests to this endpoint. - This overrides the default signing region used by an SDK client. - */ - public let signingRegion: String? - - public init(endpoint: Endpoint, - isHostnameImmutable: Bool = false, - signingName: String? = nil, - signingRegion: String? = nil) { - self.endpoint = endpoint - self.isHostnameImmutable = isHostnameImmutable - self.signingName = signingName - self.signingRegion = signingRegion - } - - public static func resolveEndpoint(partitions: [Partition], region: String) throws -> AWSEndpoint { - guard !partitions.isEmpty else { - throw EndpointError.partitionsEmpty( - "The partitions array cannot be empty in order to properly resolve an AWS endpoint") - } - - let candidate = partitions.first { $0.canResolveEndpoint(region: region)} ?? partitions[0] - return try candidate.resolveEndpoint(region: region) - } -} - -/// Keys used to access auth scheme container and auth scheme properties -private enum AuthSchemeKeys { - static let authSchemes = "authSchemes" -} - -extension Endpoint { - /// Returns list of auth schemes - /// This is an internal API and subject to change without notice - /// - Returns: list of auth schemes if present - public func authSchemes() -> [[String: Any]]? { - guard let schemes = properties[AuthSchemeKeys.authSchemes] as? [[String: Any]] else { - return nil - } - - return schemes - } -} diff --git a/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsRequestContext.swift b/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsRequestContext.swift deleted file mode 100644 index 85d5410ffdd..00000000000 --- a/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsRequestContext.swift +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0. - -import AwsCommonRuntimeKit - -/// Wrapper for CRTAWSEndpointsRequestContext -public class AWSEndpointsRequestContext { - - let crtContext: AwsCommonRuntimeKit.EndpointsRequestContext - - public init() throws { - self.crtContext = try AwsCommonRuntimeKit.EndpointsRequestContext() - } - - public func add(name: String, value: String?) throws { - try crtContext.add(name: name, value: value) - } - - public func add(name: String, value: Bool?) throws { - try crtContext.add(name: name, value: value) - } - - public func toCRT() -> AwsCommonRuntimeKit.EndpointsRequestContext { - crtContext - } -} diff --git a/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsResolvedEndpoint.swift b/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsResolvedEndpoint.swift deleted file mode 100644 index bd59307cfd6..00000000000 --- a/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsResolvedEndpoint.swift +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0. - -import AwsCommonRuntimeKit - -/// Wrapper for CRTAWSEndpointResolvedEndpoint -public class AWSEndpointsResolvedEndpoint { - - let crtResolvedEndpoint: AwsCommonRuntimeKit.ResolvedEndpoint - - init(crtResolvedEndpoint: AwsCommonRuntimeKit.ResolvedEndpoint) { - self.crtResolvedEndpoint = crtResolvedEndpoint - } - - public func getType() -> AWSEndpointsResolvedEndpointType { - AWSEndpointsResolvedEndpointType(crtType: crtResolvedEndpoint) - } - - public func getError() -> String? { - switch crtResolvedEndpoint { - case .endpoint: - return nil - case let .error(message): - return message - } - } - - public func getURL() -> String? { - switch crtResolvedEndpoint { - case let .endpoint(url, _, _): - return url - case .error: - return nil - } - } - - public func getProperties() -> [String: AnyHashable]? { - switch crtResolvedEndpoint { - case let .endpoint(_, _, properties): - return properties - case .error: - return nil - } - } - - public func getHeaders() -> [String: [String]]? { - switch crtResolvedEndpoint { - case let .endpoint(_, headers, _): - return headers - case .error: - return nil - } - } -} diff --git a/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsResolvedEndpointType.swift b/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsResolvedEndpointType.swift deleted file mode 100644 index 8ba4951c8d5..00000000000 --- a/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsResolvedEndpointType.swift +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2. - -import AwsCommonRuntimeKit - -/// Wrapper for CRTAWSEndpointsResolvedEndpointType -public enum AWSEndpointsResolvedEndpointType { - case error - case endpoint - - init(crtType: AwsCommonRuntimeKit.ResolvedEndpoint) { - switch crtType { - case .error: - self = .error - case .endpoint: - self = .endpoint - } - } -} diff --git a/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsRuleEngine.swift b/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsRuleEngine.swift deleted file mode 100644 index 4d92b9a0b90..00000000000 --- a/Sources/Core/AWSClientRuntime/Endpoints/AWSEndpointsRuleEngine.swift +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0. - -import AwsCommonRuntimeKit - -/// Wrapper for CRTAWSEndpointsRuleEngine -public class AWSEndpointsRuleEngine { - - let crtEngine: AwsCommonRuntimeKit.EndpointsRuleEngine - - public init(partitions: String = awsPartitionJSON, ruleSet: String) throws { - Utils.setupCRT() // ensures CRT is set up before calling the CRT endpoint rules engine - crtEngine = try AwsCommonRuntimeKit.EndpointsRuleEngine(partitions: partitions, ruleSet: ruleSet) - } - - public func resolve(context: AWSEndpointsRequestContext) throws -> AWSEndpointsResolvedEndpoint? { - let crtResolvedEndpoint = try crtEngine.resolve(context: context.toCRT()) - return AWSEndpointsResolvedEndpoint(crtResolvedEndpoint: crtResolvedEndpoint) - } -} diff --git a/Sources/Core/AWSClientRuntime/Endpoints/AuthSchemeResolver.swift b/Sources/Core/AWSClientRuntime/Endpoints/AuthSchemeResolver.swift deleted file mode 100644 index 8fbbf24ec46..00000000000 --- a/Sources/Core/AWSClientRuntime/Endpoints/AuthSchemeResolver.swift +++ /dev/null @@ -1,123 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// - -/// Supported authentication schemes -public enum AuthScheme: Equatable { - case sigV4(SigV4Parameters) - case sigV4A(SigV4AParameters) - case none - - /// The name of the auth scheme - public var name: String { - switch self { - case .sigV4: return "sigv4" - case .sigV4A: return "sigv4a" - case .none: return "none" - } - } -} - -extension AuthScheme { - /// Initialize an AuthScheme from a dictionary - /// - Parameter dictionary: Dictionary containing the auth scheme - public init(from dictionary: [String: Any]) throws { - guard let name = dictionary["name"] as? String else { - throw EndpointError.authScheme("Invalid auth scheme") - } - switch name { - case "sigv4": - self = .sigV4(try SigV4Parameters(from: dictionary)) - case "sigv4a": - self = .sigV4A(try SigV4AParameters(from: dictionary)) - case "none": - self = .none - default: - throw EndpointError.authScheme("Unknown auth scheme \(name)") - } - } -} - -extension AuthScheme { - /// SigV4 auth scheme - public struct SigV4Parameters: Equatable { - - /// Service name to use for signing - public let signingName: String? - - /// Region to use for signing - public let signingRegion: String? - - /// When true, do not double-escape path during signing - public let disableDoubleEncoding: Bool? - } -} - -extension AuthScheme.SigV4Parameters { - /// Initialize a SigV4AuthScheme from a dictionary - /// - Parameter dictionary: Dictionary containing the auth scheme - init(from dictionary: [String: Any]) throws { - self.signingName = dictionary["signingName"] as? String - self.signingRegion = dictionary["signingRegion"] as? String - self.disableDoubleEncoding = dictionary["disableDoubleEncoding"] as? Bool - } -} - -extension AuthScheme { - /// SigV4a auth scheme - public struct SigV4AParameters: Equatable { - - /// Service name to use for signing - public let signingName: String? - - /// The set of signing regions to use for this endpoint. Currently, - /// this will always be ["*"]. - public let signingRegionSet: [String]? - - /// When true, do not double-escape path during signing - public let disableDoubleEncoding: Bool? - } -} - -extension AuthScheme.SigV4AParameters { - /// Initialize a SigV4AAuthScheme from a dictionary - /// - Parameter dictionary: Dictionary containing the auth scheme - init(from dictionary: [String: Any]) throws { - self.signingName = dictionary["signingName"] as? String - self.signingRegionSet = dictionary["signingRegionSet"] as? [String] - self.disableDoubleEncoding = dictionary["disableDoubleEncoding"] as? Bool - } -} - -/// Resolves the auth scheme to use for a given endpoint -public protocol AuthSchemeResolver { - - /// Resolves the auth scheme to use for a given endpoint - /// If no auth scheme is supported, returns nil and the SDK must throw an error - /// - Parameter authSchemes: auth schemes to resolve - /// - Returns: Auth scheme to use - func resolve(authSchemes: [AuthScheme]) throws -> AuthScheme -} - -/// Default implementation of AuthSchemeResolver -public struct DefaultAuthSchemeResolver: AuthSchemeResolver { - - /// Supported auth schemes by the SDK - let supportedAuthSchemes: Set - - public init(supportedAuthSchemes: Set = ["sigv4", "sigv4a", "none"]) { - self.supportedAuthSchemes = supportedAuthSchemes - } - - public func resolve(authSchemes: [AuthScheme]) throws -> AuthScheme { - guard let authScheme = authSchemes.first(where: { supportedAuthSchemes.contains($0.name) }) else { - throw EndpointError.authScheme("Failed to resolve auth scheme. Supported schemes: \(supportedAuthSchemes)," - + "available schemes: \(authSchemes.map { $0.name })") - } - - return authScheme - } -} diff --git a/Sources/Core/AWSClientRuntime/Endpoints/CredentialScope.swift b/Sources/Core/AWSClientRuntime/Endpoints/CredentialScope.swift deleted file mode 100644 index 39ea57a0fbe..00000000000 --- a/Sources/Core/AWSClientRuntime/Endpoints/CredentialScope.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// - -public struct CredentialScope { - let region: String? - let serviceId: String? - - public init(region: String? = nil, serviceId: String? = nil) { - self.region = region - self.serviceId = serviceId - } -} diff --git a/Sources/Core/AWSClientRuntime/Endpoints/EndpointError.swift b/Sources/Core/AWSClientRuntime/Endpoints/EndpointError.swift deleted file mode 100644 index 4988180ab4f..00000000000 --- a/Sources/Core/AWSClientRuntime/Endpoints/EndpointError.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// - -public enum EndpointError: Error { - case hostnameIsNil(String) - case partitionsEmpty(String) - case unresolved(String?) - case authScheme(String?) -} diff --git a/Sources/Core/AWSClientRuntime/Endpoints/Partition.swift b/Sources/Core/AWSClientRuntime/Endpoints/Partition.swift deleted file mode 100644 index 62c7d22bc43..00000000000 --- a/Sources/Core/AWSClientRuntime/Endpoints/Partition.swift +++ /dev/null @@ -1,67 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// - -public struct Partition { - - /// The partition name/id e.g. "aws" - let id: String - - /// The regular expression that specified the pattern that region names in the endpoint adhere to - let regionRegex: String - - /// Endpoint that works across all regions or if [isRegionalized] is false - let partitionEndpoint: String - - /// Flag indicating whether or not the service is regionalized in the partition. Some services have only a single, - /// partition-global endpoint (e.g. CloudFront). - let isRegionalized: Bool - - /** - Default endpoint values for the partition. Some or all of the defaults specified may be superseded - by an entry in [endpoints]. - */ - let defaults: ServiceEndpointMetadata - - /// Map of endpoint names to their definitions - let endpoints: [String: ServiceEndpointMetadata] - - public init(id: String, - regionRegex: String, - partitionEndpoint: String, - isRegionalized: Bool, - defaults: ServiceEndpointMetadata, - endpoints: [String: ServiceEndpointMetadata]) { - self.id = id - self.regionRegex = regionRegex - self.partitionEndpoint = partitionEndpoint - self.isRegionalized = isRegionalized - self.defaults = defaults - self.endpoints = endpoints - } - - func canResolveEndpoint(region: String) -> Bool { - return endpoints[region] != nil || region.range(of: regionRegex, - options: .regularExpression) != nil - } - - func resolveEndpoint(region: String) throws -> AWSEndpoint { - let shouldUsePartitionEndpoint = region.isEmpty && !partitionEndpoint.isEmpty - let resolvedRegion = shouldUsePartitionEndpoint ? partitionEndpoint : region - let endpointDefinition = endpointDefinitionForRegion(region: resolvedRegion) - return try endpointDefinition.resolve(region: region, defaults: defaults) - } - - func endpointDefinitionForRegion(region: String) -> ServiceEndpointMetadata { - if let endpointMetadata = endpoints[region] { - return endpointMetadata - } else if !isRegionalized { - return endpoints[partitionEndpoint] ?? ServiceEndpointMetadata() - } else { - return ServiceEndpointMetadata() - } - } -} diff --git a/Sources/Core/AWSClientRuntime/Endpoints/ServiceEndpointMetadata.swift b/Sources/Core/AWSClientRuntime/Endpoints/ServiceEndpointMetadata.swift deleted file mode 100644 index 953e7cdcab1..00000000000 --- a/Sources/Core/AWSClientRuntime/Endpoints/ServiceEndpointMetadata.swift +++ /dev/null @@ -1,92 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -import ClientRuntime - -public struct ServiceEndpointMetadata { - private let defaultProtocol = ProtocolType.https.rawValue - private let defaultSigner = "v4" - private let protocolPriority = ProtocolType.allCases.map { $0.rawValue } - private let signerPriority = ["v4"] - /** - A URI **template** used to resolve the hostname of the endpoint. - Templates are of the form `{name}`. e.g. `{service}.{region}.amazonaws.com` - - Variables that may be substituted: - - `service` - the service name - - `region` - the region name - - `dnsSuffix` - the dns suffix of the partition - */ - let hostName: String? - - /// A list of supported protocols for the endpoint - let protocols: [String] - - /// A custom signing constraint for the endpoint - let credentialScope: CredentialScope? - - /// A list of allowable signature versions for the endpoint (e.g. "v4", "v2", "v3", "s3v3", etc) - let signatureVersions: [String] - - public init(hostName: String? = nil, - protocols: [String] = [], - credentialScope: CredentialScope? = nil, - signatureVersions: [String] = []) { - self.hostName = hostName - self.protocols = protocols - self.credentialScope = credentialScope - self.signatureVersions = signatureVersions - } -} - -extension ServiceEndpointMetadata { - func resolve(region: String, defaults: ServiceEndpointMetadata) throws -> AWSEndpoint { - let serviceEndpointMetadata = buildEndpointMetadataIfNotSet(defaults: defaults) - guard let hostname = serviceEndpointMetadata.hostName else { - throw EndpointError.hostnameIsNil("EndpointDefinition.hostname cannot be nil at this point") - } - let editedHostName = hostname.replacingOccurrences(of: "{region}", with: region) - let transportProtocol = getProtocolByPriority(from: serviceEndpointMetadata.protocols) - let signingName = serviceEndpointMetadata.credentialScope?.serviceId - let signingRegion = serviceEndpointMetadata.credentialScope?.region ?? region - - return AWSEndpoint(endpoint: Endpoint(host: editedHostName, - path: "/", - protocolType: ProtocolType(rawValue: transportProtocol)), - signingName: signingName, - signingRegion: signingRegion) - } - - private func buildEndpointMetadataIfNotSet(defaults: ServiceEndpointMetadata) -> ServiceEndpointMetadata { - let hostName = self.hostName ?? defaults.hostName - let protocols = !self.protocols.isEmpty ? self.protocols : defaults.protocols - let credentialScope = CredentialScope( - region: self.credentialScope?.region ?? defaults.credentialScope?.region, - serviceId: self.credentialScope?.serviceId ?? defaults.credentialScope?.serviceId - ) - let signatureVersions = !self.signatureVersions.isEmpty ? self.signatureVersions : defaults.signatureVersions - return ServiceEndpointMetadata( - hostName: hostName, - protocols: protocols, - credentialScope: credentialScope, - signatureVersions: signatureVersions - ) - } - - private func getProtocolByPriority(from: [String]) -> String { - guard from.isEmpty else { - return defaultProtocol - } - - for p in protocolPriority { - if let candidate = from.first(where: { $0 == p}) { - return candidate - } - } - - return defaultProtocol - } -} diff --git a/Sources/Core/AWSClientRuntime/HttpContextBuilder+Extension.swift b/Sources/Core/AWSClientRuntime/HttpContextBuilder+Extension.swift index 4feb97324f7..27d22d5e511 100644 --- a/Sources/Core/AWSClientRuntime/HttpContextBuilder+Extension.swift +++ b/Sources/Core/AWSClientRuntime/HttpContextBuilder+Extension.swift @@ -88,7 +88,6 @@ extension HttpContextBuilder { extension AttributeKeys { // Keys used to store/retrieve AWSSigningConfig fields in/from signingProperties passed to AWSSigV4Signer - public static let signingAlgorithm = AttributeKey(name: "SigningAlgorithm") public static let unsignedBody = AttributeKey(name: "UnsignedBody") public static let signedBodyHeader = AttributeKey(name: "SignedBodyHeader") public static let useDoubleURIEncode = AttributeKey(name: "UseDoubleURIEncode") diff --git a/Sources/Core/AWSClientRuntime/Signing/AWSSigningAlgorithm.swift b/Sources/Core/AWSClientRuntime/Signing/AWSSigningAlgorithm.swift deleted file mode 100644 index 2999d0fe89b..00000000000 --- a/Sources/Core/AWSClientRuntime/Signing/AWSSigningAlgorithm.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// -import AwsCommonRuntimeKit - -/// Type of signing algorithm -/// String raw value used for serialization and deserialization -public enum AWSSigningAlgorithm: String { - /// Signature Version 4 - case sigv4 - /// Signature Version 4 Asymmetric - case sigv4a -} - -extension AWSSigningAlgorithm { - - /// Convert self to CRT SigningAlgorithmType - /// - Returns: SigningAlgorithmType - func toCRTType() -> SigningAlgorithmType { - switch self { - case .sigv4: return .signingV4 - case .sigv4a: return .signingV4Asymmetric - } - } -} diff --git a/Sources/Core/AWSClientRuntime/Signing/AWSSigningConfig.swift b/Sources/Core/AWSClientRuntime/Signing/AWSSigningConfig.swift index e9905d173c1..6286e2409a4 100644 --- a/Sources/Core/AWSClientRuntime/Signing/AWSSigningConfig.swift +++ b/Sources/Core/AWSClientRuntime/Signing/AWSSigningConfig.swift @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 // +import ClientRuntime import AwsCommonRuntimeKit import Foundation @@ -52,7 +53,7 @@ public struct AWSSigningConfig { } extension AWSSigningConfig { - func toCRTType() throws -> SigningConfig { + public func toCRTType() throws -> SigningConfig { // Never include the Transfer-Encoding header in the signature, // since older versions of URLSession will modify this header's value // prior to sending a request. diff --git a/Tests/Core/AWSClientRuntimeTests/Endpoints/AuthSchemeResolverTests.swift b/Tests/Core/AWSClientRuntimeTests/Endpoints/AuthSchemeResolverTests.swift deleted file mode 100644 index b9e4f657079..00000000000 --- a/Tests/Core/AWSClientRuntimeTests/Endpoints/AuthSchemeResolverTests.swift +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright Amazon.com Inc. or its affiliates. -// All Rights Reserved. -// -// SPDX-License-Identifier: Apache-2.0 -// - -import XCTest -@testable import AWSClientRuntime - -final class AuthSchemeResolverTests: XCTestCase { - func testParsing() throws { - let sigV4 = [ - "signingRegion": "us-west-2", - "name": "sigv4", - "signingName": "s3", - "disableDoubleEncoding": true - ] as [String: AnyHashable] - - let actualSigV4 = try AuthScheme(from: sigV4) - if case let .sigV4(data) = actualSigV4 { - XCTAssertEqual(data.signingName, "s3") - XCTAssertEqual(data.signingRegion, "us-west-2") - XCTAssertEqual(data.disableDoubleEncoding, true) - } else { - XCTFail("Failed to decode sigv4") - } - - let sigV4A = [ - "signingRegionSet": [ - "*" - ], - "name": "sigv4a", - "signingName": "s3", - "disableDoubleEncoding": true - ] as [String: AnyHashable] - - let actualSigV4a = try AuthScheme(from: sigV4A) - if case let .sigV4A(data) = actualSigV4a { - XCTAssertEqual(data.signingName, "s3") - XCTAssertEqual(data.signingRegionSet, ["*"]) - XCTAssertEqual(data.disableDoubleEncoding, true) - } else { - XCTFail("Failed to decode sigv4a") - } - } - - func testResolve_givenSupportedScheme_returnsScheme() throws { - let resolver = DefaultAuthSchemeResolver(supportedAuthSchemes: ["sigv4"]) - let sigV4 = AuthScheme.sigV4(AuthScheme.SigV4Parameters(signingName: nil, signingRegion: nil, disableDoubleEncoding: nil)) - let sigV4A = AuthScheme.sigV4A(.init(signingName: nil, signingRegionSet: nil, disableDoubleEncoding: nil)) - let none = AuthScheme.none - - let actualSigV4 = try resolver.resolve(authSchemes: [sigV4, sigV4A, none]) - XCTAssertEqual(actualSigV4, sigV4) - - let actualSigV4A = try resolver.resolve(authSchemes: [sigV4A, sigV4, none]) - XCTAssertEqual(actualSigV4A, sigV4) - - let actualNone = try resolver.resolve(authSchemes: [none, sigV4A, sigV4]) - XCTAssertEqual(actualNone, sigV4) - } - - func testResolve_givenUnsupportedScheme_returnsNil() throws { - let resolver = DefaultAuthSchemeResolver(supportedAuthSchemes: ["sigv4"]) - let sigV4A = AuthScheme.sigV4A(.init(signingName: nil, signingRegionSet: nil, disableDoubleEncoding: nil)) - let none = AuthScheme.none - - XCTAssertThrowsError(try resolver.resolve(authSchemes: [sigV4A, none])) - - XCTAssertThrowsError(try resolver.resolve(authSchemes: [none, sigV4A])) - } -} diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSClientRuntimeTypes.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSClientRuntimeTypes.kt index 7b9b21e03e4..b1d68593514 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSClientRuntimeTypes.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSClientRuntimeTypes.kt @@ -51,6 +51,7 @@ object AWSClientRuntimeTypes { val DefaultAuthSchemeResolver = runtimeSymbol("DefaultAuthSchemeResolver") val AWSRetryErrorInfoProvider = runtimeSymbol("AWSRetryErrorInfoProvider") val AWSRetryMode = runtimeSymbol("AWSRetryMode") + val AWSPartitionDefinition = runtimeSymbol("awsPartitionJSON") } object CRT { diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolCustomizations.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolCustomizations.kt index 6aae12eec14..86737b545ab 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolCustomizations.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolCustomizations.kt @@ -6,10 +6,12 @@ package software.amazon.smithy.aws.swift.codegen import software.amazon.smithy.aws.swift.codegen.customization.RulesBasedAuthSchemeResolverGenerator +import software.amazon.smithy.aws.swift.codegen.middleware.AWSEndpointResolverMiddleware import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.swift.codegen.AuthSchemeResolverGenerator import software.amazon.smithy.swift.codegen.SwiftWriter +import software.amazon.smithy.swift.codegen.endpoints.EndpointResolverGenerator import software.amazon.smithy.swift.codegen.integration.ClientProperty import software.amazon.smithy.swift.codegen.integration.DefaultHttpProtocolCustomizations import software.amazon.smithy.swift.codegen.integration.HttpProtocolServiceClient @@ -45,12 +47,16 @@ abstract class AWSHttpProtocolCustomizations : DefaultHttpProtocolCustomizations } override fun renderInternals(ctx: ProtocolGenerator.GenerationContext) { - super.renderInternals(ctx) + AuthSchemeResolverGenerator().render(ctx) // Generate rules-based auth scheme resolver for services that depend on endpoint resolver for auth scheme resolution if (AuthSchemeResolverGenerator.usesRulesBasedAuthResolver(ctx)) { RulesBasedAuthSchemeResolverGenerator().render(ctx) } - EndpointResolverGenerator().render(ctx) + EndpointResolverGenerator( + partitionDefinition = AWSClientRuntimeTypes.Core.AWSPartitionDefinition, + dependency = AWSSwiftDependency.AWS_CLIENT_RUNTIME, + endpointResolverMiddleware = { w, i, o, oe -> AWSEndpointResolverMiddleware(w, i, o, oe) } + ).render(ctx) } override fun getClientProperties(): List { diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSServiceConfig.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSServiceConfig.kt index 2cca706a389..2e346f166a1 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSServiceConfig.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSServiceConfig.kt @@ -10,6 +10,7 @@ import software.amazon.smithy.model.shapes.ShapeType import software.amazon.smithy.rulesengine.traits.ClientContextParamsTrait import software.amazon.smithy.swift.codegen.SwiftTypes import software.amazon.smithy.swift.codegen.SwiftWriter +import software.amazon.smithy.swift.codegen.endpoints.EndpointTypes import software.amazon.smithy.swift.codegen.integration.ConfigField import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator import software.amazon.smithy.swift.codegen.integration.ServiceConfig @@ -29,7 +30,7 @@ class AWSServiceConfig(writer: SwiftWriter, val ctx: ProtocolGenerator.Generatio var configs = mutableListOf() // service specific EndpointResolver - configs.add(ConfigField(ENDPOINT_RESOLVER, AWSServiceTypes.EndpointResolver, "\$N", "Endpoint resolver")) + configs.add(ConfigField(ENDPOINT_RESOLVER, EndpointTypes.EndpointResolver, "\$N", "Endpoint resolver")) // service specific AuthSchemeResolver configs.add(ConfigField(AUTH_SCHEME_RESOLVER, buildSymbol { this.name = serviceName.clientName() + "AuthSchemeResolver" }, "\$N")) @@ -48,14 +49,3 @@ fun ShapeType.toSwiftType(): Symbol { else -> throw IllegalArgumentException("Unsupported shape type: $this") } } - -object AWSServiceTypes { - val EndpointResolver = symbol("EndpointResolver") - val EndpointParams = symbol("EndpointParams") - val EndpointResolverMiddleware = symbol("EndpointResolverMiddleware") - val DefaultEndpointResolver = symbol("DefaultEndpointResolver") - - private fun symbol(name: String): Symbol = buildSymbol { - this.name = name - } -} diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointParamsGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointParamsGenerator.kt deleted file mode 100644 index 50c8d15d9fe..00000000000 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointParamsGenerator.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ - -package software.amazon.smithy.aws.swift.codegen - -import software.amazon.smithy.codegen.core.CodegenException -import software.amazon.smithy.codegen.core.Symbol -import software.amazon.smithy.rulesengine.language.EndpointRuleSet -import software.amazon.smithy.rulesengine.language.syntax.parameters.Parameter -import software.amazon.smithy.rulesengine.language.syntax.parameters.ParameterType -import software.amazon.smithy.swift.codegen.AuthSchemeResolverGenerator -import software.amazon.smithy.swift.codegen.SwiftTypes -import software.amazon.smithy.swift.codegen.SwiftWriter -import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator -import software.amazon.smithy.swift.codegen.model.boxed -import software.amazon.smithy.swift.codegen.model.defaultValue -import software.amazon.smithy.swift.codegen.utils.clientName -import software.amazon.smithy.swift.codegen.utils.toLowerCamelCase - -/** - * Generates EndpointParams struct for the service - */ -class EndpointParamsGenerator(private val endpointRules: EndpointRuleSet?) { - fun render(writer: SwiftWriter, ctx: ProtocolGenerator.GenerationContext? = null) { - writer.openBlock("public struct EndpointParams {", "}") { - endpointRules?.parameters?.toList()?.sortedBy { it.name.toString() }?.let { sortedParameters -> - renderMembers(writer, sortedParameters) - writer.write("") - renderInit(writer, sortedParameters) - // Convert auth scheme params to endpoint params for rules-based auth scheme resolvers - if (ctx != null && AuthSchemeResolverGenerator.usesRulesBasedAuthResolver(ctx)) { - renderConversionInit(writer, sortedParameters, ctx) - } - } - } - } - - private fun renderInit(writer: SwiftWriter, parameters: List) { - writer.openBlock("public init(", ")") { - for ((index, param) in parameters.withIndex()) { - val memberName = param.name.toString().toLowerCamelCase() - val memberSymbol = param.toSymbol() - val terminator = if (index != parameters.lastIndex) "," else "" - writer.write("$memberName: \$D$terminator", memberSymbol) - } - } - - writer.openBlock("{", "}") { - parameters.forEach { - val memberName = it.name.toString().toLowerCamelCase() - writer.write("self.\$1L = \$1L", memberName) - } - } - } - - private fun renderMembers(writer: SwiftWriter, parameters: List) { - parameters.forEach { param -> - val memberName = param.name.toString().toLowerCamelCase() - val memberSymbol = param.toSymbol() - val optional = if (param.isRequired) "" else "?" - param.documentation.orElse(null)?.let { writer.write("/// $it") } - writer.write("public let \$L: \$L$optional", memberName, memberSymbol) - } - } - - private fun renderConversionInit( - writer: SwiftWriter, - parameters: List, - ctx: ProtocolGenerator.GenerationContext - ) { - writer.apply { - val paramsType = ctx.service.sdkId.clientName() + "AuthSchemeResolverParameters" - openBlock("public init (authSchemeParams: \$L) {", "}", paramsType) { - parameters.forEach { - val memberName = it.name.toString().toLowerCamelCase() - writer.write("self.\$1L = authSchemeParams.\$1L", memberName) - } - } - } - } -} - -fun Parameter.toSymbol(): Symbol { - val swiftType = when (type) { - ParameterType.STRING -> SwiftTypes.String - ParameterType.BOOLEAN -> SwiftTypes.Bool - else -> throw CodegenException("Unsupported parameter type: $type") - } - var builder = Symbol.builder().name(swiftType.fullName) - if (!isRequired) { - builder = builder.boxed() - } - - default.ifPresent { defaultValue -> - builder.defaultValue(defaultValue.toString()) - } - - return builder.build() -} diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointResolverGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointResolverGenerator.kt deleted file mode 100644 index efcb864a043..00000000000 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointResolverGenerator.kt +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ - -package software.amazon.smithy.aws.swift.codegen - -import software.amazon.smithy.aws.swift.codegen.middleware.EndpointResolverMiddleware -import software.amazon.smithy.codegen.core.Symbol -import software.amazon.smithy.model.node.Node -import software.amazon.smithy.rulesengine.language.EndpointRuleSet -import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait -import software.amazon.smithy.swift.codegen.ClientRuntimeTypes -import software.amazon.smithy.swift.codegen.MiddlewareGenerator -import software.amazon.smithy.swift.codegen.SwiftDependency -import software.amazon.smithy.swift.codegen.SwiftWriter -import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator -import software.amazon.smithy.swift.codegen.model.getTrait -import software.amazon.smithy.swift.codegen.utils.toLowerCamelCase - -/** - * Generates a per/service endpoint resolver (internal to the generated SDK) - */ -class EndpointResolverGenerator() { - fun render(ctx: ProtocolGenerator.GenerationContext) { - val rootNamespace = ctx.settings.moduleName - - val ruleSetNode = ctx.service.getTrait()?.ruleSet - val ruleSet = if (ruleSetNode != null) EndpointRuleSet.fromNode(ruleSetNode) else null - - ctx.delegator.useFileWriter("./$rootNamespace/EndpointResolver.swift") { - val endpointParamsGenerator = EndpointParamsGenerator(ruleSet) - endpointParamsGenerator.render(it, ctx) - } - - ctx.delegator.useFileWriter("./$rootNamespace/EndpointResolver.swift") { - renderResolverProtocol(it) - it.write("") - renderResolver(it, ruleSet) - val inputSymbol = Symbol.builder().name("SdkHttpRequestBuilder").build() - val outputSymbol = Symbol.builder().name("OperationStackOutput").build() - val outputErrorSymbol = Symbol.builder().name("OperationStackError").build() - val middleware = EndpointResolverMiddleware(it, inputSymbol, outputSymbol, outputErrorSymbol) - it.addImport(SwiftDependency.CLIENT_RUNTIME.target) - it.write("") - MiddlewareGenerator(it, middleware).generate() - } - } - - private fun renderResolverProtocol(writer: SwiftWriter) { - writer.openBlock("public protocol \$L {", "}", AWSServiceTypes.EndpointResolver) { - writer.write("func resolve(params: EndpointParams) throws -> \$L", ClientRuntimeTypes.Core.Endpoint) - } - } - - private fun renderResolver(writer: SwiftWriter, endpointRules: EndpointRuleSet?) { - writer.openBlock("public struct \$L: \$L {", "}", AWSServiceTypes.DefaultEndpointResolver, AWSServiceTypes.EndpointResolver) { - writer.write("") - endpointRules?.let { - writer.write("private let engine: \$L", AWSClientRuntimeTypes.Core.AWSEndpointsRuleEngine) - writer.write("private let ruleSet = \$S", Node.printJson(endpointRules.toNode())) - } - writer.write("") - writer.openBlock("public init() throws {", "}") { - endpointRules?.let { - writer.write("engine = try \$L(ruleSet: ruleSet)", AWSClientRuntimeTypes.Core.AWSEndpointsRuleEngine) - } - } - writer.write("") - writer.openBlock( - "public func resolve(params: EndpointParams) throws -> \$L {", "}", ClientRuntimeTypes.Core.Endpoint - ) { - endpointRules?.let { - writer.write("let context = try \$L()", AWSClientRuntimeTypes.Core.AWSEndpointsRequestContext) - endpointRules.parameters?.toList()?.sortedBy { it.name.toString() }?.let { sortedParameters -> - sortedParameters.forEach { param -> - val memberName = param.name.toString().toLowerCamelCase() - val paramName = param.name.toString() - writer.write("try context.add(name: \$S, value: params.\$L)", paramName, memberName) - } - writer.write("") - } - writer.openBlock("guard let crtResolvedEndpoint = try engine.resolve(context: context) else {", "}") { - writer.write("throw EndpointError.unresolved(\"Failed to resolved endpoint\")") - }.write("") - - writer.openBlock("if crtResolvedEndpoint.getType() == .error {", "}") { - writer.write("let error = crtResolvedEndpoint.getError()") - writer.write("throw EndpointError.unresolved(error)") - }.write("") - - writer.openBlock("guard let url = crtResolvedEndpoint.getURL() else {", "}") { - writer.write("assertionFailure(\"This must be a bug in either CRT or the rule engine, if the endpoint is not an error, it must have a url\")") - writer.write("throw EndpointError.unresolved(\"Failed to resolved endpoint\")") - }.write("") - - writer.write("let headers = crtResolvedEndpoint.getHeaders() ?? [:]") - writer.write("let properties = crtResolvedEndpoint.getProperties() ?? [:]") - writer.write("return try Endpoint(urlString: url, headers: Headers(headers), properties: properties)") - } ?: run { - writer.write("fatalError(\"EndpointResolver not implemented\")") - } - } - } - } -} diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointTestGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointTestGenerator.kt index 9fc62a6d094..19fff3865bc 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointTestGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointTestGenerator.kt @@ -20,6 +20,7 @@ import software.amazon.smithy.swift.codegen.ClientRuntimeTypes import software.amazon.smithy.swift.codegen.SwiftDependency import software.amazon.smithy.swift.codegen.SwiftWriter import software.amazon.smithy.swift.codegen.XCTestTypes +import software.amazon.smithy.swift.codegen.endpoints.EndpointTypes import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator import software.amazon.smithy.swift.codegen.utils.toLowerCamelCase @@ -57,7 +58,7 @@ class EndpointTestGenerator( endpointTest.testCases.forEach { testCase -> writer.write("/// \$L", testCase.documentation) writer.openBlock("func testResolve${++count}() throws {", "}") { - writer.openBlock("let endpointParams = \$L(", ")", AWSServiceTypes.EndpointParams) { + writer.openBlock("let endpointParams = \$L(", ")", EndpointTypes.EndpointParams) { val applicableParams = testCase.params.members.filter { endpointParamsMembers.contains(it.key.value) } .toSortedMap(compareBy { it.value }).map { (key, value) -> @@ -74,7 +75,7 @@ class EndpointTestGenerator( } } } - writer.write("let resolver = try \$L()", AWSServiceTypes.DefaultEndpointResolver).write("") + writer.write("let resolver = try \$L()", EndpointTypes.DefaultEndpointResolver).write("") testCase.expect.error.ifPresent { error -> writer.openBlock( diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/config/AWSEndpointClientConfiguration.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/config/AWSEndpointClientConfiguration.kt index bab3209dace..2a8329f1695 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/config/AWSEndpointClientConfiguration.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/config/AWSEndpointClientConfiguration.kt @@ -5,13 +5,13 @@ package software.amazon.smithy.aws.swift.codegen.config -import software.amazon.smithy.aws.swift.codegen.AWSServiceTypes import software.amazon.smithy.aws.swift.codegen.ENDPOINT_RESOLVER import software.amazon.smithy.aws.swift.codegen.toSwiftType import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.rulesengine.traits.ClientContextParamsTrait import software.amazon.smithy.swift.codegen.config.ClientConfiguration import software.amazon.smithy.swift.codegen.config.ConfigProperty +import software.amazon.smithy.swift.codegen.endpoints.EndpointTypes import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator import software.amazon.smithy.swift.codegen.model.getTrait import software.amazon.smithy.swift.codegen.model.toOptional @@ -27,7 +27,7 @@ class AWSEndpointClientConfiguration(val ctx: ProtocolGenerator.GenerationContex clientContextParams?.parameters?.forEach { properties.add(ConfigProperty(it.key.toLowerCamelCase(), it.value.type.toSwiftType().toOptional())) } - properties.add(ConfigProperty(ENDPOINT_RESOLVER, AWSServiceTypes.EndpointResolver, "DefaultEndpointResolver()", true)) + properties.add(ConfigProperty(ENDPOINT_RESOLVER, EndpointTypes.EndpointResolver, "DefaultEndpointResolver()", true)) return properties } } diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/RulesBasedAuthSchemeResolverGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/RulesBasedAuthSchemeResolverGenerator.kt index 5b315c6d23c..5f9375d29d2 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/RulesBasedAuthSchemeResolverGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/customization/RulesBasedAuthSchemeResolverGenerator.kt @@ -21,7 +21,6 @@ class RulesBasedAuthSchemeResolverGenerator { renderServiceSpecificDefaultResolver(ctx, it) it.write("") it.addImport(SwiftDependency.CLIENT_RUNTIME.target) - it.addIndividualTypeImport("enum", "AWSClientRuntime", "AuthScheme") } } @@ -79,7 +78,11 @@ class RulesBasedAuthSchemeResolverGenerator { // are returned by endpoint resolver. write("return try InternalModeled${sdkId + AUTH_SCHEME_RESOLVER}().resolveAuthScheme(params: params)") } - writer.write("let schemes = try authSchemes.map { (input) -> AWSClientRuntime.AuthScheme in try AWSClientRuntime.AuthScheme(from: input) }") + writer.write( + "let schemes = try authSchemes.map { (input) -> \$N in try \$N(from: input) }", + ClientRuntimeTypes.Core.EndpointsAuthScheme, + ClientRuntimeTypes.Core.EndpointsAuthScheme + ) // If endpoint resolver returned auth schemes, iterate over them and save each as valid auth option to return openBlock("for scheme in schemes {", "}") { openBlock("switch scheme {", "}") { 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/AWSEndpointResolverMiddleware.kt similarity index 63% rename from codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/EndpointResolverMiddleware.kt rename to codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/AWSEndpointResolverMiddleware.kt index 50fbe95d991..d1778687d4a 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/AWSEndpointResolverMiddleware.kt @@ -5,53 +5,19 @@ package software.amazon.smithy.aws.swift.codegen.middleware -import software.amazon.smithy.aws.swift.codegen.AUTH_SCHEME_RESOLVER -import software.amazon.smithy.aws.swift.codegen.AWSClientRuntimeTypes -import software.amazon.smithy.aws.swift.codegen.AWSServiceTypes -import software.amazon.smithy.aws.swift.codegen.AWSSwiftDependency -import software.amazon.smithy.aws.swift.codegen.ENDPOINT_PARAMS -import software.amazon.smithy.aws.swift.codegen.ENDPOINT_RESOLVER import software.amazon.smithy.codegen.core.Symbol -import software.amazon.smithy.swift.codegen.Middleware -import software.amazon.smithy.swift.codegen.SwiftDependency import software.amazon.smithy.swift.codegen.SwiftWriter -import software.amazon.smithy.swift.codegen.integration.steps.OperationBuildStep +import software.amazon.smithy.swift.codegen.middleware.EndpointResolverMiddleware /** * Generates endpoint middleware for the service. */ -class EndpointResolverMiddleware( +class AWSEndpointResolverMiddleware( private val writer: SwiftWriter, inputSymbol: Symbol, outputSymbol: Symbol, outputErrorSymbol: Symbol -) : Middleware(writer, inputSymbol, OperationBuildStep(outputSymbol, outputErrorSymbol)) { - - override val id: String = "EndpointResolverMiddleware" - - override val typeName = "EndpointResolverMiddleware<$outputSymbol>" - - override val properties: MutableMap = mutableMapOf( - ENDPOINT_RESOLVER to AWSServiceTypes.EndpointResolver, - ENDPOINT_PARAMS to AWSServiceTypes.EndpointParams, - AUTH_SCHEME_RESOLVER to AWSClientRuntimeTypes.Core.AuthSchemeResolver - ) - - override fun generateInit() { - writer.openBlock( - "public init($ENDPOINT_RESOLVER: \$N, $ENDPOINT_PARAMS: \$N, $AUTH_SCHEME_RESOLVER: \$N = \$N()) {", - "}", - AWSServiceTypes.EndpointResolver, - AWSServiceTypes.EndpointParams, - AWSClientRuntimeTypes.Core.AuthSchemeResolver, - AWSClientRuntimeTypes.Core.DefaultAuthSchemeResolver - ) { - writer.write("self.\$L = \$L", ENDPOINT_RESOLVER, ENDPOINT_RESOLVER) - writer.write("self.\$L = \$L", ENDPOINT_PARAMS, ENDPOINT_PARAMS) - writer.write("self.\$L = \$L", AUTH_SCHEME_RESOLVER, AUTH_SCHEME_RESOLVER) - } - } - +) : EndpointResolverMiddleware(writer, inputSymbol, outputSymbol, outputErrorSymbol) { override fun renderExtensions() { writer.write( """ @@ -69,7 +35,7 @@ class EndpointResolverMiddleware( var signingRegion: String? = nil var signingAlgorithm: String? = nil if let authSchemes = endpoint.authSchemes() { - let schemes = try authSchemes.map { try AuthScheme(from: ${'$'}${'$'}0) } + let schemes = try authSchemes.map { try EndpointsAuthScheme(from: ${'$'}${'$'}0) } let authScheme = try authSchemeResolver.resolve(authSchemes: schemes) signingAlgorithm = authScheme.name switch authScheme { @@ -126,20 +92,4 @@ class EndpointResolverMiddleware( """.trimIndent() ) } - - override fun generateMiddlewareClosure() { - writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.write( - """ - let selectedAuthScheme = context.getSelectedAuthScheme() - let request = input.build() - let updatedRequest = try await apply(request: request, selectedAuthScheme: selectedAuthScheme, attributes: context) - """.trimIndent() - ) - } - - override fun renderReturn() { - writer.write("return try await next.handle(context: context, input: updatedRequest.toBuilder())") - } } diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/OperationEndpointResolverMiddleware.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/OperationEndpointResolverMiddleware.kt index c1bd67316cb..7c59af0b3e5 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/OperationEndpointResolverMiddleware.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/OperationEndpointResolverMiddleware.kt @@ -5,7 +5,6 @@ package software.amazon.smithy.aws.swift.codegen.middleware -import software.amazon.smithy.aws.swift.codegen.AWSServiceTypes import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.model.shapes.MemberShape import software.amazon.smithy.model.shapes.OperationShape @@ -20,6 +19,7 @@ import software.amazon.smithy.rulesengine.traits.StaticContextParamDefinition import software.amazon.smithy.rulesengine.traits.StaticContextParamsTrait import software.amazon.smithy.swift.codegen.AuthSchemeResolverGenerator import software.amazon.smithy.swift.codegen.SwiftWriter +import software.amazon.smithy.swift.codegen.endpoints.EndpointTypes import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator import software.amazon.smithy.swift.codegen.integration.middlewares.handlers.MiddlewareShapeUtils import software.amazon.smithy.swift.codegen.middleware.MiddlewarePosition @@ -61,7 +61,7 @@ class OperationEndpointResolverMiddleware( val output = MiddlewareShapeUtils.outputSymbol(ctx.symbolProvider, ctx.model, op) writer.write( "\$N<\$N>(endpointResolver: config.endpointResolver, endpointParams: endpointParams)", - AWSServiceTypes.EndpointResolverMiddleware, + EndpointTypes.EndpointResolverMiddleware, output ) } diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/plugins/EndpointPlugin.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/plugins/EndpointPlugin.kt index 537e6c2d453..9d5d409fafa 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/plugins/EndpointPlugin.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/plugins/EndpointPlugin.kt @@ -1,8 +1,8 @@ package software.amazon.smithy.aws.swift.codegen.plugins -import software.amazon.smithy.aws.swift.codegen.AWSServiceTypes import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.swift.codegen.SwiftWriter +import software.amazon.smithy.swift.codegen.endpoints.EndpointTypes import software.amazon.smithy.swift.codegen.integration.Plugin import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator import software.amazon.smithy.swift.codegen.integration.ServiceConfig @@ -20,12 +20,12 @@ class EndpointPlugin(private val serviceConfig: ServiceConfig) : Plugin { override fun render(ctx: ProtocolGenerator.GenerationContext, writer: SwiftWriter) { writer.openBlock("public class $pluginName: Plugin {", "}") { - writer.write("private var endpointResolver: \$L", AWSServiceTypes.EndpointResolver) - writer.openBlock("public init(endpointResolver: \$L) {", "}", AWSServiceTypes.EndpointResolver) { + writer.write("private var endpointResolver: \$L", EndpointTypes.EndpointResolver) + writer.openBlock("public init(endpointResolver: \$L) {", "}", EndpointTypes.EndpointResolver) { writer.write("self.endpointResolver = endpointResolver") } writer.openBlock("public convenience init() throws {", "}") { - writer.write("self.init(endpointResolver: try \$L())", AWSServiceTypes.DefaultEndpointResolver) + writer.write("self.init(endpointResolver: try \$L())", EndpointTypes.DefaultEndpointResolver) } writer.openBlock("public func configureClient(clientConfiguration: ClientRuntime.ClientConfiguration) throws {", "}") { writer.openBlock("if let config = clientConfiguration as? ${serviceConfig.typeName} {", "}") { diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointParamsGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointParamsGeneratorTests.kt index 717ca5beaf1..518f8b6c760 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointParamsGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EndpointParamsGeneratorTests.kt @@ -12,6 +12,7 @@ import software.amazon.smithy.model.node.Node import software.amazon.smithy.rulesengine.language.EndpointRuleSet import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait import software.amazon.smithy.swift.codegen.SwiftWriter +import software.amazon.smithy.swift.codegen.endpoints.EndpointParamsGenerator import software.amazon.smithy.swift.codegen.model.getTrait class EndpointParamsGeneratorTests { 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 ef36fecee14..84cad158b24 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 @@ -7,11 +7,11 @@ package software.amazon.smithy.aws.swift.codegen import io.kotest.matchers.string.shouldContainOnlyOnce import org.junit.jupiter.api.Test -import software.amazon.smithy.aws.swift.codegen.middleware.EndpointResolverMiddleware import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.swift.codegen.MiddlewareGenerator import software.amazon.smithy.swift.codegen.SwiftDependency import software.amazon.smithy.swift.codegen.SwiftWriter +import software.amazon.smithy.swift.codegen.middleware.EndpointResolverMiddleware class EndpointResolverMiddlewareTests { @Test @@ -32,9 +32,9 @@ public struct EndpointResolverMiddleware: ClientRuntime.Mi let endpointParams: EndpointParams - let authSchemeResolver: AWSClientRuntime.AuthSchemeResolver + let authSchemeResolver: ClientRuntime.EndpointsAuthSchemeResolver - public init(endpointResolver: EndpointResolver, endpointParams: EndpointParams, authSchemeResolver: AWSClientRuntime.AuthSchemeResolver = AWSClientRuntime.DefaultAuthSchemeResolver()) { + public init(endpointResolver: EndpointResolver, endpointParams: EndpointParams, authSchemeResolver: ClientRuntime.EndpointsAuthSchemeResolver = ClientRuntime.DefaultEndpointsAuthSchemeResolver()) { self.endpointResolver = endpointResolver self.endpointParams = endpointParams self.authSchemeResolver = authSchemeResolver diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/RulesBasedAuthSchemeResolverGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/RulesBasedAuthSchemeResolverGeneratorTests.kt index 5bb7a4179c8..0127aa20590 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/RulesBasedAuthSchemeResolverGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/RulesBasedAuthSchemeResolverGeneratorTests.kt @@ -104,7 +104,7 @@ public struct DefaultS3AuthSchemeResolver: S3AuthSchemeResolver { guard let authSchemes = endpoint.authSchemes() else { return try InternalModeledS3AuthSchemeResolver().resolveAuthScheme(params: params) } - let schemes = try authSchemes.map { (input) -> AWSClientRuntime.AuthScheme in try AWSClientRuntime.AuthScheme(from: input) } + let schemes = try authSchemes.map { (input) -> ClientRuntime.EndpointsAuthScheme in try ClientRuntime.EndpointsAuthScheme(from: input) } for scheme in schemes { switch scheme { case .sigV4(let param):