-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: move endpoints classes to smithy-swift
- Loading branch information
1 parent
8d38691
commit c4cee9e
Showing
20 changed files
with
968 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// | ||
// 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) | ||
} | ||
} |
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,16 @@ | ||
// | ||
// 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 | ||
} | ||
} |
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,13 @@ | ||
// | ||
// 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?) | ||
} |
123 changes: 123 additions & 0 deletions
123
Sources/ClientRuntime/Endpoints/EndpointsAuthSchemeResolver.swift
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,123 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
/// Supported authentication schemes | ||
public enum EndpointsAuthScheme: 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 EndpointsAuthScheme { | ||
/// 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 EndpointsAuthScheme { | ||
/// 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 EndpointsAuthScheme.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 EndpointsAuthScheme { | ||
/// 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 EndpointsAuthScheme.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 EndpointsAuthSchemeResolver { | ||
|
||
/// 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: [EndpointsAuthScheme]) throws -> EndpointsAuthScheme | ||
} | ||
|
||
/// Default implementation of AuthSchemeResolver | ||
public struct DefaultEndpointsAuthSchemeResolver: EndpointsAuthSchemeResolver { | ||
|
||
/// Supported auth schemes by the SDK | ||
let supportedAuthSchemes: Set<String> | ||
|
||
public init(supportedAuthSchemes: Set<String> = ["sigv4", "sigv4a", "none"]) { | ||
self.supportedAuthSchemes = supportedAuthSchemes | ||
} | ||
|
||
public func resolve(authSchemes: [EndpointsAuthScheme]) throws -> EndpointsAuthScheme { | ||
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 | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
Sources/ClientRuntime/Endpoints/EndpointsRequestContext.swift
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,26 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0. | ||
|
||
import AwsCommonRuntimeKit | ||
|
||
/// Wrapper for CRTAWSEndpointsRequestContext | ||
public class EndpointsRequestContext { | ||
|
||
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 | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
Sources/ClientRuntime/Endpoints/EndpointsResolvedEndpoint.swift
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,54 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0. | ||
|
||
import AwsCommonRuntimeKit | ||
|
||
/// Wrapper for CRTAWSEndpointResolvedEndpoint | ||
public class EndpointsResolvedEndpoint { | ||
|
||
let crtResolvedEndpoint: AwsCommonRuntimeKit.ResolvedEndpoint | ||
|
||
init(crtResolvedEndpoint: AwsCommonRuntimeKit.ResolvedEndpoint) { | ||
self.crtResolvedEndpoint = crtResolvedEndpoint | ||
} | ||
|
||
public func getType() -> EndpointsResolvedEndpointType { | ||
EndpointsResolvedEndpointType(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 | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
Sources/ClientRuntime/Endpoints/EndpointsResolvedEndpointType.swift
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,19 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2. | ||
|
||
import AwsCommonRuntimeKit | ||
|
||
/// Wrapper for CRTAWSEndpointsResolvedEndpointType | ||
public enum EndpointsResolvedEndpointType { | ||
case error | ||
case endpoint | ||
|
||
init(crtType: AwsCommonRuntimeKit.ResolvedEndpoint) { | ||
switch crtType { | ||
case .error: | ||
self = .error | ||
case .endpoint: | ||
self = .endpoint | ||
} | ||
} | ||
} |
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,20 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0. | ||
|
||
import AwsCommonRuntimeKit | ||
|
||
/// Wrapper for CRTAWSEndpointsRuleEngine | ||
public class EndpointsRuleEngine { | ||
|
||
let crtEngine: AwsCommonRuntimeKit.EndpointsRuleEngine | ||
|
||
public init(partitions: String = partitionJSON, ruleSet: String) throws { | ||
CommonRuntimeKit.initialize() // ensures CRT is set up before calling the CRT endpoint rules engine | ||
crtEngine = try AwsCommonRuntimeKit.EndpointsRuleEngine(partitions: partitions, ruleSet: ruleSet) | ||
} | ||
|
||
public func resolve(context: EndpointsRequestContext) throws -> EndpointsResolvedEndpoint? { | ||
let crtResolvedEndpoint = try crtEngine.resolve(context: context.toCRT()) | ||
return EndpointsResolvedEndpoint(crtResolvedEndpoint: crtResolvedEndpoint) | ||
} | ||
} |
Oops, something went wrong.