From 272aec649f0888e048d4bd13ba00eae06b905545 Mon Sep 17 00:00:00 2001 From: Chan Yoo <55515281+sichanyoo@users.noreply.github.com> Date: Mon, 9 Oct 2023 13:52:12 -0700 Subject: [PATCH] chore: Add signer protocol. (#598) * Add signer protocol & refactor HttpContext --------- Co-authored-by: Sichan Yoo --- .../Auth/HTTPAuthAPI/Signer.swift | 16 ++ .../Networking/Http/HttpContext.swift | 150 +++++++++--------- 2 files changed, 94 insertions(+), 72 deletions(-) create mode 100644 Sources/ClientRuntime/Auth/HTTPAuthAPI/Signer.swift diff --git a/Sources/ClientRuntime/Auth/HTTPAuthAPI/Signer.swift b/Sources/ClientRuntime/Auth/HTTPAuthAPI/Signer.swift new file mode 100644 index 000000000..9079e90aa --- /dev/null +++ b/Sources/ClientRuntime/Auth/HTTPAuthAPI/Signer.swift @@ -0,0 +1,16 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +import Foundation + +public protocol Signer { + func sign( + requestBuilder: SdkHttpRequestBuilder, + identity: IdentityT, + signingProperties: Attributes + ) async throws -> SdkHttpRequestBuilder +} diff --git a/Sources/ClientRuntime/Networking/Http/HttpContext.swift b/Sources/ClientRuntime/Networking/Http/HttpContext.swift index 27c78c453..4542a3eb8 100644 --- a/Sources/ClientRuntime/Networking/Http/HttpContext.swift +++ b/Sources/ClientRuntime/Networking/Http/HttpContext.swift @@ -9,41 +9,45 @@ public class HttpContext: MiddlewareContext { public init(attributes: Attributes) { self.attributes = attributes } - // FIXME: Move all defined keys to separate file as constants to be used elsewhere - public func getPath() -> String { - return attributes.get(key: AttributeKey(name: "Path"))! - } - public func getMethod() -> HttpMethodType { - return attributes.get(key: AttributeKey(name: "Method"))! + public func getDecoder() -> ResponseDecoder { + return attributes.get(key: AttributeKeys.decoder)! } public func getEncoder() -> RequestEncoder { - return attributes.get(key: AttributeKey(name: "Encoder"))! - } - - public func getDecoder() -> ResponseDecoder { - return attributes.get(key: AttributeKey(name: "Decoder"))! + return attributes.get(key: AttributeKeys.encoder)! } public func getHost() -> String? { - return attributes.get(key: AttributeKey(name: "Host")) + return attributes.get(key: AttributeKeys.host) } - public func getServiceName() -> String { - return attributes.get(key: AttributeKey(name: "ServiceName"))! + public func getHostPrefix() -> String? { + return attributes.get(key: AttributeKeys.hostPrefix) } public func getIdempotencyTokenGenerator() -> IdempotencyTokenGenerator { - return attributes.get(key: AttributeKey(name: "IdempotencyTokenGenerator"))! + return attributes.get(key: AttributeKeys.idempotencyTokenGenerator)! } - public func getHostPrefix() -> String? { - return attributes.get(key: AttributeKey(name: "HostPrefix")) + public func getIdentityResolvers() -> Attributes { + return attributes.get(key: AttributeKeys.identityResolvers)! } public func getLogger() -> LogAgent? { - return attributes.get(key: AttributeKey(name: "Logger")) + return attributes.get(key: AttributeKeys.logger) + } + + public func getMessageEncoder() -> MessageEncoder? { + return attributes.get(key: AttributeKeys.messageEncoder) + } + + public func getMessageSigner() -> MessageSigner? { + return attributes.get(key: AttributeKeys.messageSigner) + } + + public func getMethod() -> HttpMethodType { + return attributes.get(key: AttributeKeys.method)! } /// The partition ID to be used for this context. @@ -51,19 +55,19 @@ public class HttpContext: MiddlewareContext { /// Requests made with the same partition ID will be grouped together for retry throttling purposes. /// If no partition ID is provided, requests will be partitioned based on the hostname. public func getPartitionID() -> String? { - return attributes.get(key: AttributeKey(name: "PartitionID")) + return attributes.get(key: AttributeKeys.partitionId) } - public func getMessageEncoder() -> MessageEncoder? { - return attributes.get(key: HttpContext.messageEncoder) + public func getPath() -> String { + return attributes.get(key: AttributeKeys.path)! } - public func getMessageSigner() -> MessageSigner? { - return attributes.get(key: HttpContext.messageSigner) + public func getServiceName() -> String { + return attributes.get(key: AttributeKeys.serviceName)! } public func isBidirectionalStreamingEnabled() -> Bool { - return attributes.get(key: HttpContext.bidirectionalStreaming) ?? false + return attributes.get(key: AttributeKeys.bidirectionalStreaming) ?? false } /// Returns `true` if the request should use `http2` and only `http2` without falling back to `http1` @@ -72,29 +76,11 @@ public class HttpContext: MiddlewareContext { } } -extension HttpContext { - public static let messageEncoder = AttributeKey(name: "MessageEncoder") - public static let messageSigner = AttributeKey(name: "MessageSigner") - public static let bidirectionalStreaming = AttributeKey(name: "BidirectionalStreaming") -} - public class HttpContextBuilder { - public init() {} public var attributes: Attributes = Attributes() - let encoder = AttributeKey(name: "Encoder") - let method = AttributeKey(name: "Method") - let path = AttributeKey(name: "Path") - let operation = AttributeKey(name: "Operation") - let host = AttributeKey(name: "Host") - let serviceName = AttributeKey(name: "ServiceName") var response: HttpResponse = HttpResponse() - let decoder = AttributeKey(name: "Decoder") - let idempotencyTokenGenerator = AttributeKey(name: "IdempotencyTokenGenerator") - let hostPrefix = AttributeKey(name: "HostPrefix") - let logger = AttributeKey(name: "Logger") - let partitionID = AttributeKey(name: "PartitionID") // We follow the convention of returning the builder object // itself from any configuration methods, and by adding the @@ -108,80 +94,80 @@ public class HttpContextBuilder { } @discardableResult - public func withEncoder(value: RequestEncoder) -> HttpContextBuilder { - self.attributes.set(key: encoder, value: value) + public func withDecoder(value: ResponseDecoder) -> HttpContextBuilder { + self.attributes.set(key: AttributeKeys.decoder, value: value) return self } @discardableResult - public func withMethod(value: HttpMethodType) -> HttpContextBuilder { - self.attributes.set(key: method, value: value) + public func withEncoder(value: RequestEncoder) -> HttpContextBuilder { + self.attributes.set(key: AttributeKeys.encoder, value: value) return self } @discardableResult - public func withPath(value: String) -> HttpContextBuilder { - self.attributes.set(key: path, value: value) + public func withHost(value: String) -> HttpContextBuilder { + self.attributes.set(key: AttributeKeys.host, value: value) return self } @discardableResult - public func withHost(value: String) -> HttpContextBuilder { - self.attributes.set(key: host, value: value) + public func withHostPrefix(value: String) -> HttpContextBuilder { + self.attributes.set(key: AttributeKeys.hostPrefix, value: value) return self } @discardableResult - public func withHostPrefix(value: String) -> HttpContextBuilder { - self.attributes.set(key: hostPrefix, value: value) + public func withIdempotencyTokenGenerator(value: IdempotencyTokenGenerator) -> HttpContextBuilder { + self.attributes.set(key: AttributeKeys.idempotencyTokenGenerator, value: value) return self } @discardableResult - public func withOperation(value: String) -> HttpContextBuilder { - self.attributes.set(key: operation, value: value) + public func withLogger(value: LogAgent) -> HttpContextBuilder { + self.attributes.set(key: AttributeKeys.logger, value: value) return self } @discardableResult - public func withServiceName(value: String) -> HttpContextBuilder { - self.attributes.set(key: serviceName, value: value) + public func withMethod(value: HttpMethodType) -> HttpContextBuilder { + self.attributes.set(key: AttributeKeys.method, value: value) return self } @discardableResult - public func withDecoder(value: ResponseDecoder) -> HttpContextBuilder { - self.attributes.set(key: decoder, value: value) + public func withOperation(value: String) -> HttpContextBuilder { + self.attributes.set(key: AttributeKeys.operation, value: value) return self } + /// Sets the partition ID on the context builder. + /// + /// Requests made with the same partition ID will be grouped together for retry throttling purposes. + /// If no partition ID is provided, requests will be partitioned based on the hostname. + /// - Parameter value: The partition ID to be set on this builder, or `nil`. + /// - Returns: `self`, after the partition ID is set as specified. @discardableResult - public func withResponse(value: HttpResponse) -> HttpContextBuilder { - self.response = value + public func withPartitionID(value: String?) -> HttpContextBuilder { + self.attributes.set(key: AttributeKeys.partitionId, value: value) return self } @discardableResult - public func withIdempotencyTokenGenerator(value: IdempotencyTokenGenerator) -> HttpContextBuilder { - self.attributes.set(key: idempotencyTokenGenerator, value: value) + public func withPath(value: String) -> HttpContextBuilder { + self.attributes.set(key: AttributeKeys.path, value: value) return self } @discardableResult - public func withLogger(value: LogAgent) -> HttpContextBuilder { - self.attributes.set(key: logger, value: value) + public func withResponse(value: HttpResponse) -> HttpContextBuilder { + self.response = value return self } - /// Sets the partition ID on the context builder. - /// - /// Requests made with the same partition ID will be grouped together for retry throttling purposes. - /// If no partition ID is provided, requests will be partitioned based on the hostname. - /// - Parameter value: The partition ID to be set on this builder, or `nil`. - /// - Returns: `self`, after the partition ID is set as specified. @discardableResult - public func withPartitionID(value: String?) -> HttpContextBuilder { - self.attributes.set(key: partitionID, value: value) + public func withServiceName(value: String) -> HttpContextBuilder { + self.attributes.set(key: AttributeKeys.serviceName, value: value) return self } @@ -189,3 +175,23 @@ public class HttpContextBuilder { return HttpContext(attributes: attributes) } } + +public enum AttributeKeys { + public static let bidirectionalStreaming = AttributeKey(name: "BidirectionalStreaming") + public static let decoder = AttributeKey(name: "Decoder") + public static let encoder = AttributeKey(name: "Encoder") + public static let host = AttributeKey(name: "Host") + public static let hostPrefix = AttributeKey(name: "HostPrefix") + public static let idempotencyTokenGenerator = AttributeKey( + name: "IdempotencyTokenGenerator" + ) + public static let identityResolvers = AttributeKey(name: "IdentityResolvers") + public static let logger = AttributeKey(name: "Logger") + public static let messageEncoder = AttributeKey(name: "MessageEncoder") + public static let messageSigner = AttributeKey(name: "MessageSigner") + public static let method = AttributeKey(name: "Method") + public static let operation = AttributeKey(name: "Operation") + public static let partitionId = AttributeKey(name: "PartitionID") + public static let path = AttributeKey(name: "Path") + public static let serviceName = AttributeKey(name: "ServiceName") +}