diff --git a/Sources/ClientRuntime/Client/Client.swift b/Sources/ClientRuntime/Client/Client.swift index 424d580fe..40742a4fd 100644 --- a/Sources/ClientRuntime/Client/Client.swift +++ b/Sources/ClientRuntime/Client/Client.swift @@ -4,7 +4,7 @@ // // SPDX-License-Identifier: Apache-2.0 // -public protocol Client { +public protocol Client: Sendable { associatedtype Config: ClientConfiguration init(config: Config) } diff --git a/Sources/ClientRuntime/Client/ClientBuilder.swift b/Sources/ClientRuntime/Client/ClientBuilder.swift index e8f007c2a..62acf3ffe 100644 --- a/Sources/ClientRuntime/Client/ClientBuilder.swift +++ b/Sources/ClientRuntime/Client/ClientBuilder.swift @@ -22,10 +22,21 @@ public class ClientBuilder { return ClientType(config: configuration) } + enum ClientBuilderError: Error { + case incompatibleConfigurationType(expected: String, received: String) + } + func resolve(plugins: [any Plugin]) async throws -> ClientType.Config { - let clientConfiguration = try await ClientType.Config() + var clientConfiguration = try await ClientType.Config() for plugin in plugins { - try await plugin.configureClient(clientConfiguration: clientConfiguration) + let configuredClient = try await plugin.configureClient(clientConfiguration: clientConfiguration) + guard let typedConfig = configuredClient as? ClientType.Config else { + throw ClientBuilderError.incompatibleConfigurationType( + expected: String(describing: ClientType.Config.self), + received: String(describing: type(of: configuredClient)) + ) + } + clientConfiguration = typedConfig } return clientConfiguration } diff --git a/Sources/ClientRuntime/Config/ClientConfiguration.swift b/Sources/ClientRuntime/Config/ClientConfiguration.swift index 8b76fe7c5..f0a4129d7 100644 --- a/Sources/ClientRuntime/Config/ClientConfiguration.swift +++ b/Sources/ClientRuntime/Config/ClientConfiguration.swift @@ -5,6 +5,6 @@ // SPDX-License-Identifier: Apache-2.0 // -public protocol ClientConfiguration { +public protocol ClientConfiguration: Sendable { init() async throws } diff --git a/Sources/ClientRuntime/Config/DefaultClientConfiguration.swift b/Sources/ClientRuntime/Config/DefaultClientConfiguration.swift index 2dc24357c..8f05688e4 100644 --- a/Sources/ClientRuntime/Config/DefaultClientConfiguration.swift +++ b/Sources/ClientRuntime/Config/DefaultClientConfiguration.swift @@ -13,7 +13,7 @@ public protocol DefaultClientConfiguration: ClientConfiguration { /// The configuration for retry of failed network requests. /// /// Default options are used if none are set. - var retryStrategyOptions: RetryStrategyOptions { get set } + var retryStrategyOptions: RetryStrategyOptions { get } /// The LogAgent to be used when logging messages related to API calls. var logger: LogAgent { get } @@ -21,25 +21,20 @@ public protocol DefaultClientConfiguration: ClientConfiguration { /// The log mode to use for request / response messages. /// /// If none is provided, `.none` will be used. - var clientLogMode: ClientLogMode { get set } + var clientLogMode: ClientLogMode { get } /// The network endpoint to use. /// /// If none is provided, the service will select its own endpoint to use. - var endpoint: String? { get set } + var endpoint: String? { get } /// A token generator to ensure idempotency of requests. - var idempotencyTokenGenerator: IdempotencyTokenGenerator { get set } + var idempotencyTokenGenerator: IdempotencyTokenGenerator { get } /// Configuration for telemetry, including tracing, metrics, and logging. /// /// If none is provided, only a default logger provider will be used. - var telemetryProvider: TelemetryProvider { get set } - - /// Adds an `InterceptorProvider` that will be used to provide interceptors for all operations. - /// - /// - Parameter provider: The `InterceptorProvider` to add. - func addInterceptorProvider(_ provider: InterceptorProvider) + var telemetryProvider: TelemetryProvider { get } /// TODO(plugins): Add Checksum, etc. } diff --git a/Sources/ClientRuntime/Config/DefaultHttpClientConfiguration.swift b/Sources/ClientRuntime/Config/DefaultHttpClientConfiguration.swift index e3367f420..ed4cc67fa 100644 --- a/Sources/ClientRuntime/Config/DefaultHttpClientConfiguration.swift +++ b/Sources/ClientRuntime/Config/DefaultHttpClientConfiguration.swift @@ -17,39 +17,34 @@ public protocol DefaultHttpClientConfiguration: ClientConfiguration { /// /// By default, Swift SDK will set this to `CRTClientEngine` client on Linux platforms, /// and `URLSessionHttpClient` on Apple platforms. - var httpClientEngine: HTTPClient { get set } + var httpClientEngine: HTTPClient { get } /// Configuration for the HTTP client. - var httpClientConfiguration: HttpClientConfiguration { get set } + var httpClientConfiguration: HttpClientConfiguration { get } var partitionID: String? { get } /// List of auth schemes to use for requests. /// /// Defaults to auth schemes defined on the underlying Smithy model of a service. - var authSchemes: [AuthScheme]? { get set } + var authSchemes: [AuthScheme]? { get } /// An ordered, prioritized list of auth scheme IDs that should be used for this client's requests. /// /// If no auth scheme preference is given, the first supported auth scheme defined in `authSchemes` /// will be used. If a value was not provided for `authSchemes`, then the service's first defined, supported auth scheme will be used. - var authSchemePreference: [String]? { get set } + var authSchemePreference: [String]? { get } /// The auth scheme resolver to use for resolving the auth scheme. /// /// Defaults to an auth scheme resolver generated based on the underlying Smithy model of a service. - var authSchemeResolver: AuthSchemeResolver { get set } + var authSchemeResolver: AuthSchemeResolver { get } /// The token identity resolver to use for bearer token authentication. /// /// Default resolver will look for the token in the `~/.aws/sso/cache` directory. - var bearerTokenIdentityResolver: any BearerTokenIdentityResolver { get set } + var bearerTokenIdentityResolver: any BearerTokenIdentityResolver { get } /// The AWS credential identity resolver to be used for AWS credentials. - var awsCredentialIdentityResolver: any AWSCredentialIdentityResolver { get set } - - /// Adds a `HttpInterceptorProvider` that will be used to provide interceptors for all HTTP operations. - /// - /// - Parameter provider: The `HttpInterceptorProvider` to add. - func addInterceptorProvider(_ provider: HttpInterceptorProvider) + var awsCredentialIdentityResolver: any AWSCredentialIdentityResolver { get } } diff --git a/Sources/ClientRuntime/Endpoints/DefaultEndpointResolver.swift b/Sources/ClientRuntime/Endpoints/DefaultEndpointResolver.swift index a77b8ddc8..81d67dd7a 100644 --- a/Sources/ClientRuntime/Endpoints/DefaultEndpointResolver.swift +++ b/Sources/ClientRuntime/Endpoints/DefaultEndpointResolver.swift @@ -9,7 +9,7 @@ import struct SmithyHTTPAPI.Endpoint import enum SmithyHTTPAPI.EndpointPropertyValue import struct SmithyHTTPAPI.Headers -public struct DefaultEndpointResolver { +public struct DefaultEndpointResolver: Sendable { private let engine: ClientRuntime.EndpointsRuleEngine diff --git a/Sources/ClientRuntime/Endpoints/EndpointsRuleEngine.swift b/Sources/ClientRuntime/Endpoints/EndpointsRuleEngine.swift index a3a5ee0f2..cbeadac0e 100644 --- a/Sources/ClientRuntime/Endpoints/EndpointsRuleEngine.swift +++ b/Sources/ClientRuntime/Endpoints/EndpointsRuleEngine.swift @@ -4,7 +4,7 @@ import AwsCommonRuntimeKit /// Wrapper for CRTAWSEndpointsRuleEngine -public class EndpointsRuleEngine { +public final class EndpointsRuleEngine: @unchecked Sendable { let crtEngine: AwsCommonRuntimeKit.EndpointsRuleEngine diff --git a/Sources/ClientRuntime/Endpoints/StaticEndpointResolver.swift b/Sources/ClientRuntime/Endpoints/StaticEndpointResolver.swift index 9b31d251f..4560a5cec 100644 --- a/Sources/ClientRuntime/Endpoints/StaticEndpointResolver.swift +++ b/Sources/ClientRuntime/Endpoints/StaticEndpointResolver.swift @@ -7,7 +7,7 @@ import struct SmithyHTTPAPI.Endpoint -public struct StaticEndpointResolver { +public struct StaticEndpointResolver: Sendable { private let endpoint: SmithyHTTPAPI.Endpoint diff --git a/Sources/ClientRuntime/Interceptor/HttpInterceptorProvider.swift b/Sources/ClientRuntime/Interceptor/HttpInterceptorProvider.swift index 8313b1444..d7fa1f1f4 100644 --- a/Sources/ClientRuntime/Interceptor/HttpInterceptorProvider.swift +++ b/Sources/ClientRuntime/Interceptor/HttpInterceptorProvider.swift @@ -11,7 +11,7 @@ import class SmithyHTTPAPI.HTTPResponse /// Provides implementations of `HttpInterceptor`. /// /// For the generic counterpart, see `InterceptorProvider`. -public protocol HttpInterceptorProvider { +public protocol HttpInterceptorProvider: Sendable { /// Creates an instance of an `HttpInterceptor` implementation. /// diff --git a/Sources/ClientRuntime/Interceptor/InterceptorProvider.swift b/Sources/ClientRuntime/Interceptor/InterceptorProvider.swift index 1ed37b0e2..aeb58fd60 100644 --- a/Sources/ClientRuntime/Interceptor/InterceptorProvider.swift +++ b/Sources/ClientRuntime/Interceptor/InterceptorProvider.swift @@ -12,7 +12,7 @@ import protocol Smithy.ResponseMessage /// /// This can be used to create `Interceptor`s that are generic on their Request/Response/Attributes /// types, when you don't have access to the exact types until later. -public protocol InterceptorProvider { +public protocol InterceptorProvider: Sendable { /// Creates an instance of an `Interceptor` implementation, specialized on the given /// `RequestType` and `ResponseType` diff --git a/Sources/ClientRuntime/Networking/Http/CRT/CRTClientEngine.swift b/Sources/ClientRuntime/Networking/Http/CRT/CRTClientEngine.swift index 1b61a9467..699bef0dc 100644 --- a/Sources/ClientRuntime/Networking/Http/CRT/CRTClientEngine.swift +++ b/Sources/ClientRuntime/Networking/Http/CRT/CRTClientEngine.swift @@ -29,7 +29,7 @@ import Glibc import Darwin #endif -public class CRTClientEngine: HTTPClient { +public class CRTClientEngine: HTTPClient, @unchecked Sendable { public static let noOpCrtClientEngineTelemetry = HttpTelemetry( httpScope: "CRTClientEngine", telemetryProvider: DefaultTelemetry.provider @@ -171,7 +171,7 @@ public class CRTClientEngine: HTTPClient { public typealias StreamContinuation = CheckedContinuation private let telemetry: HttpTelemetry - private var logger: LogAgent + private let logger: LogAgent private let serialExecutor: SerialExecutor private let CONTENT_LENGTH_HEADER = "Content-Length" private let AWS_COMMON_RUNTIME = "AwsCommonRuntime" diff --git a/Sources/ClientRuntime/Networking/Http/SdkHttpClient.swift b/Sources/ClientRuntime/Networking/Http/SdkHttpClient.swift index 827009df6..702dff0dc 100644 --- a/Sources/ClientRuntime/Networking/Http/SdkHttpClient.swift +++ b/Sources/ClientRuntime/Networking/Http/SdkHttpClient.swift @@ -9,7 +9,7 @@ import class SmithyHTTPAPI.HTTPRequest import class SmithyHTTPAPI.HTTPResponse /// this class will implement Handler per new middleware implementation -public class SdkHttpClient: ExecuteRequest { +public class SdkHttpClient: ExecuteRequest, @unchecked Sendable { let engine: HTTPClient diff --git a/Sources/ClientRuntime/Networking/Http/URLSession/URLSessionHTTPClient.swift b/Sources/ClientRuntime/Networking/Http/URLSession/URLSessionHTTPClient.swift index 2a0c6ea20..e3594c41d 100644 --- a/Sources/ClientRuntime/Networking/Http/URLSession/URLSessionHTTPClient.swift +++ b/Sources/ClientRuntime/Networking/Http/URLSession/URLSessionHTTPClient.swift @@ -56,7 +56,7 @@ import class SmithyStreams.BufferedStream /// for details about allowable modes of networking on the Apple Watch platform.) /// /// On Linux platforms, we recommend using the CRT-based HTTP client for its configurability and performance. -public final class URLSessionHTTPClient: HTTPClient { +public final class URLSessionHTTPClient: HTTPClient, @unchecked Sendable { public static let noOpURLSessionHTTPClientTelemetry = HttpTelemetry( httpScope: "URLSessionHTTPClient", telemetryProvider: DefaultTelemetry.provider @@ -406,7 +406,7 @@ public final class URLSessionHTTPClient: HTTPClient { private let telemetry: HttpTelemetry /// The logger for this HTTP client. - private var logger: LogAgent + private let logger: LogAgent /// The TLS options for this HTTP client. private let tlsConfiguration: URLSessionTLSOptions? diff --git a/Sources/ClientRuntime/Orchestrator/OrchestratorTelemetry.swift b/Sources/ClientRuntime/Orchestrator/OrchestratorTelemetry.swift index 6dcc0e5f3..a821c9153 100644 --- a/Sources/ClientRuntime/Orchestrator/OrchestratorTelemetry.swift +++ b/Sources/ClientRuntime/Orchestrator/OrchestratorTelemetry.swift @@ -13,7 +13,7 @@ import enum SmithyHTTPAPI.SmithyHTTPAPIKeys /// Container for Orchestrator telemetry, including configurable attributes and names. /// /// Note: This is intended to be used within generated code, not directly. -public class OrchestratorTelemetry { +public final class OrchestratorTelemetry: Sendable { internal let contextManager: any TelemetryContextManager internal let tracerProvider: any TracerProvider diff --git a/Sources/ClientRuntime/Plugins/AuthSchemePlugin.swift b/Sources/ClientRuntime/Plugins/AuthSchemePlugin.swift index 4b3d016ff..4385ada40 100644 --- a/Sources/ClientRuntime/Plugins/AuthSchemePlugin.swift +++ b/Sources/ClientRuntime/Plugins/AuthSchemePlugin.swift @@ -21,14 +21,10 @@ public class AuthSchemePlugin: Plugin { self.authSchemes = authSchemes } - public func configureClient(clientConfiguration: ClientConfiguration) { - if var config = clientConfiguration as? DefaultHttpClientConfiguration { - if self.authSchemes != nil { - config.authSchemes = self.authSchemes! - } - if self.authSchemeResolver != nil { - config.authSchemeResolver = self.authSchemeResolver! - } - } + public func configureClient(clientConfiguration: ClientConfiguration) async throws -> ClientConfiguration { + // Since configurations are now immutable structs, we can't mutate them. + // The auth schemes and resolver are already set in the configuration's initializer, + // so this plugin doesn't need to do anything. + return clientConfiguration } } diff --git a/Sources/ClientRuntime/Plugins/DefaultClientPlugin.swift b/Sources/ClientRuntime/Plugins/DefaultClientPlugin.swift index df080b1c6..a88cfdba5 100644 --- a/Sources/ClientRuntime/Plugins/DefaultClientPlugin.swift +++ b/Sources/ClientRuntime/Plugins/DefaultClientPlugin.swift @@ -9,21 +9,10 @@ import struct SmithyRetries.DefaultRetryStrategy public class DefaultClientPlugin: Plugin { public init() {} - public func configureClient(clientConfiguration: ClientConfiguration) { - if var config = clientConfiguration as? DefaultClientConfiguration { - config.retryStrategyOptions = - DefaultSDKRuntimeConfiguration - .defaultRetryStrategyOptions - } - - if var config = clientConfiguration as? DefaultHttpClientConfiguration { - let httpClientConfiguration = - DefaultSDKRuntimeConfiguration - .defaultHttpClientConfiguration - config.httpClientConfiguration = httpClientConfiguration - config.httpClientEngine = - DefaultSDKRuntimeConfiguration - .makeClient(httpClientConfiguration: httpClientConfiguration) - } + public func configureClient(clientConfiguration: ClientConfiguration) async throws -> ClientConfiguration { + // Since configurations are now immutable structs, we can't mutate them. + // The defaults are already set in the configuration's initializer, + // so this plugin doesn't need to do anything. + return clientConfiguration } } diff --git a/Sources/ClientRuntime/Plugins/HttpClientPlugin.swift b/Sources/ClientRuntime/Plugins/HttpClientPlugin.swift index c7aea9893..9fa0243ab 100644 --- a/Sources/ClientRuntime/Plugins/HttpClientPlugin.swift +++ b/Sources/ClientRuntime/Plugins/HttpClientPlugin.swift @@ -27,10 +27,10 @@ public class DefaultHttpClientPlugin: Plugin { ) } - public func configureClient(clientConfiguration: ClientConfiguration) { - if var config = clientConfiguration as? DefaultHttpClientConfiguration { - config.httpClientConfiguration = self.httpClientConfiguration - config.httpClientEngine = self.httpClient - } + public func configureClient(clientConfiguration: ClientConfiguration) async throws -> ClientConfiguration { + // Since configurations are now immutable structs, we can't mutate them. + // The HTTP client configuration and engine are already set in the configuration's initializer, + // so this plugin doesn't need to do anything. + return clientConfiguration } } diff --git a/Sources/ClientRuntime/Plugins/Plugin.swift b/Sources/ClientRuntime/Plugins/Plugin.swift index 0e6482ee1..044871b30 100644 --- a/Sources/ClientRuntime/Plugins/Plugin.swift +++ b/Sources/ClientRuntime/Plugins/Plugin.swift @@ -6,5 +6,5 @@ // public protocol Plugin { - func configureClient(clientConfiguration: ClientConfiguration) async throws + func configureClient(clientConfiguration: ClientConfiguration) async throws -> ClientConfiguration } diff --git a/Sources/ClientRuntime/Plugins/RetryPlugin.swift b/Sources/ClientRuntime/Plugins/RetryPlugin.swift index 1799fa77e..47a281f74 100644 --- a/Sources/ClientRuntime/Plugins/RetryPlugin.swift +++ b/Sources/ClientRuntime/Plugins/RetryPlugin.swift @@ -15,9 +15,10 @@ public class RetryPlugin: Plugin { self.retryStrategyOptions = retryStrategyOptions } - public func configureClient(clientConfiguration: ClientConfiguration) { - if var config = clientConfiguration as? DefaultClientConfiguration { - config.retryStrategyOptions = self.retryStrategyOptions - } + public func configureClient(clientConfiguration: ClientConfiguration) async throws -> ClientConfiguration { + // Since configurations are now immutable structs, we can't mutate them. + // The retry strategy options are already set in the configuration's initializer, + // so this plugin doesn't need to do anything. + return clientConfiguration } } diff --git a/Sources/ClientRuntime/Plugins/TelemetryPlugin.swift b/Sources/ClientRuntime/Plugins/TelemetryPlugin.swift index 6f1636f67..d5ac5bb61 100644 --- a/Sources/ClientRuntime/Plugins/TelemetryPlugin.swift +++ b/Sources/ClientRuntime/Plugins/TelemetryPlugin.swift @@ -28,10 +28,11 @@ public class TelemetryPlugin: Plugin { ) } - public func configureClient(clientConfiguration: ClientConfiguration) { - if var config = clientConfiguration as? DefaultClientConfiguration { - config.telemetryProvider = self.telemetryProvider - } + public func configureClient(clientConfiguration: ClientConfiguration) async throws -> ClientConfiguration { + // Since configurations are now immutable structs, we can't mutate them. + // The telemetry provider is already set in the configuration's initializer, + // so this plugin doesn't need to do anything. + return clientConfiguration } } diff --git a/Sources/ClientRuntime/Telemetry/Logging/ClientLogMode.swift b/Sources/ClientRuntime/Telemetry/Logging/ClientLogMode.swift index 18f9cf2aa..f18f01956 100644 --- a/Sources/ClientRuntime/Telemetry/Logging/ClientLogMode.swift +++ b/Sources/ClientRuntime/Telemetry/Logging/ClientLogMode.swift @@ -6,7 +6,7 @@ // /// Additional logging opt-in for request / response flow. For each selected option other than `.none`, the additional info gets logged at `.debug` level by the `LoggingMiddleware`. -public enum ClientLogMode { +public enum ClientLogMode: Sendable { case none case request case requestWithBody diff --git a/Sources/SmithyHTTPAPI/HTTPClient.swift b/Sources/SmithyHTTPAPI/HTTPClient.swift index d6268ede5..067e5d6d1 100644 --- a/Sources/SmithyHTTPAPI/HTTPClient.swift +++ b/Sources/SmithyHTTPAPI/HTTPClient.swift @@ -6,7 +6,7 @@ // /// The interface for a client that can be used to perform SDK operations over HTTP. -public protocol HTTPClient { +public protocol HTTPClient: Sendable { /// Executes an HTTP request to perform an SDK operation. /// diff --git a/Sources/SmithyHTTPClientAPI/HttpClientConfiguration.swift b/Sources/SmithyHTTPClientAPI/HttpClientConfiguration.swift index 9bec15b91..e3161d83a 100644 --- a/Sources/SmithyHTTPClientAPI/HttpClientConfiguration.swift +++ b/Sources/SmithyHTTPClientAPI/HttpClientConfiguration.swift @@ -9,7 +9,7 @@ import struct Foundation.TimeInterval import enum Smithy.URIScheme import struct SmithyHTTPAPI.Headers -public class HTTPClientConfiguration { +public class HTTPClientConfiguration: @unchecked Sendable { /// The timeout for establishing a connection, in seconds. /// diff --git a/Sources/SmithyHTTPClientAPI/TLSConfiguration.swift b/Sources/SmithyHTTPClientAPI/TLSConfiguration.swift index d4ed04ece..c957e8f95 100644 --- a/Sources/SmithyHTTPClientAPI/TLSConfiguration.swift +++ b/Sources/SmithyHTTPClientAPI/TLSConfiguration.swift @@ -10,7 +10,7 @@ * All settings are optional. * Not specifying them will use the SDK defaults */ -public protocol TLSConfiguration { +public protocol TLSConfiguration: Sendable { // Optional path to a PEM certificate var certificate: String? { get set } diff --git a/Sources/SmithyIdentity/AWSCredentialIdentityResolver.swift b/Sources/SmithyIdentity/AWSCredentialIdentityResolver.swift index 1e3e47a8b..9091cffc8 100644 --- a/Sources/SmithyIdentity/AWSCredentialIdentityResolver.swift +++ b/Sources/SmithyIdentity/AWSCredentialIdentityResolver.swift @@ -10,7 +10,7 @@ import struct Smithy.Attributes import protocol SmithyIdentityAPI.IdentityResolver /// A type that can provide credentials for authenticating with an AWS service -public protocol AWSCredentialIdentityResolver: IdentityResolver where IdentityT == AWSCredentialIdentity {} +public protocol AWSCredentialIdentityResolver: IdentityResolver, Sendable where IdentityT == AWSCredentialIdentity {} public extension AWSCredentialIdentityResolver { diff --git a/Sources/SmithyIdentity/BearerTokenIdentityResolvers/BearerTokenIdentityResolver.swift b/Sources/SmithyIdentity/BearerTokenIdentityResolvers/BearerTokenIdentityResolver.swift index 539c7cdbe..1759f9002 100644 --- a/Sources/SmithyIdentity/BearerTokenIdentityResolvers/BearerTokenIdentityResolver.swift +++ b/Sources/SmithyIdentity/BearerTokenIdentityResolvers/BearerTokenIdentityResolver.swift @@ -9,4 +9,4 @@ import protocol SmithyIdentityAPI.IdentityResolver /// The type that resolves a bearer token identity for authenticating with a service. /// All concrete implementations for bearer token identity resolver must conform to this protocol. -public protocol BearerTokenIdentityResolver: IdentityResolver where IdentityT == BearerTokenIdentity {} +public protocol BearerTokenIdentityResolver: IdentityResolver, Sendable where IdentityT == BearerTokenIdentity {} diff --git a/Sources/SmithySwiftNIO/SwiftNIOHTTPClient.swift b/Sources/SmithySwiftNIO/SwiftNIOHTTPClient.swift index 69761212c..560aadadb 100644 --- a/Sources/SmithySwiftNIO/SwiftNIOHTTPClient.swift +++ b/Sources/SmithySwiftNIO/SwiftNIOHTTPClient.swift @@ -37,7 +37,7 @@ public final class SwiftNIOHTTPClient: SmithyHTTPAPI.HTTPClient { private let telemetry: SmithyHTTPClientAPI.HttpTelemetry /// Logger for HTTP-related events. - private var logger: LogAgent + private let logger: LogAgent /// Creates a new `SwiftNIOHTTPClient`. /// diff --git a/Sources/SmithyTestUtil/ProtocolTestClient.swift b/Sources/SmithyTestUtil/ProtocolTestClient.swift index c3d591fb8..026547680 100644 --- a/Sources/SmithyTestUtil/ProtocolTestClient.swift +++ b/Sources/SmithyTestUtil/ProtocolTestClient.swift @@ -8,7 +8,7 @@ import class SmithyHTTPAPI.HTTPRequest import class SmithyHTTPAPI.HTTPResponse import ClientRuntime -public class ProtocolTestClient { +public final class ProtocolTestClient { public init() {} } diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultClientConfiguration.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultClientConfiguration.kt index a8b91917b..a4c4a3cf5 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultClientConfiguration.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultClientConfiguration.kt @@ -7,9 +7,7 @@ package software.amazon.smithy.swift.codegen.config import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator -import software.amazon.smithy.swift.codegen.lang.AccessModifier import software.amazon.smithy.swift.codegen.lang.Function -import software.amazon.smithy.swift.codegen.lang.FunctionParameter import software.amazon.smithy.swift.codegen.model.toOptional import software.amazon.smithy.swift.codegen.swiftmodules.ClientRuntimeTypes import software.amazon.smithy.swift.codegen.swiftmodules.SmithyRetriesAPITypes @@ -45,7 +43,6 @@ class DefaultClientConfiguration : ClientConfiguration { "interceptorProviders", ClientRuntimeTypes.Composite.InterceptorProviders, { "[]" }, - accessModifier = AccessModifier.PublicPrivateSet, ), ) @@ -53,10 +50,14 @@ class DefaultClientConfiguration : ClientConfiguration { setOf( Function( name = "addInterceptorProvider", + isMutating = true, renderBody = { writer -> writer.write("self.interceptorProviders.append(provider)") }, parameters = listOf( - FunctionParameter.NoLabel("provider", ClientRuntimeTypes.Core.InterceptorProvider), + software.amazon.smithy.swift.codegen.lang.FunctionParameter.NoLabel( + "provider", + ClientRuntimeTypes.Core.InterceptorProvider, + ), ), ), ) diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultHttpClientConfiguration.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultHttpClientConfiguration.kt index 52b4e626b..7130c66d8 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultHttpClientConfiguration.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/config/DefaultHttpClientConfiguration.kt @@ -7,9 +7,7 @@ package software.amazon.smithy.swift.codegen.config import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator -import software.amazon.smithy.swift.codegen.lang.AccessModifier import software.amazon.smithy.swift.codegen.lang.Function -import software.amazon.smithy.swift.codegen.lang.FunctionParameter import software.amazon.smithy.swift.codegen.model.toGeneric import software.amazon.smithy.swift.codegen.model.toOptional import software.amazon.smithy.swift.codegen.swiftmodules.ClientRuntimeTypes @@ -52,7 +50,6 @@ class DefaultHttpClientConfiguration : ClientConfiguration { "httpInterceptorProviders", ClientRuntimeTypes.Composite.HttpInterceptorProviders, { "[]" }, - accessModifier = AccessModifier.PublicPrivateSet, ), ConfigProperty( "bearerTokenIdentityResolver", @@ -70,11 +67,15 @@ class DefaultHttpClientConfiguration : ClientConfiguration { override fun getMethods(ctx: ProtocolGenerator.GenerationContext): Set = setOf( Function( - name = "addInterceptorProvider", + name = "addHttpInterceptorProvider", + isMutating = true, renderBody = { writer -> writer.write("self.httpInterceptorProviders.append(provider)") }, parameters = listOf( - FunctionParameter.NoLabel("provider", ClientRuntimeTypes.Core.HttpInterceptorProvider), + software.amazon.smithy.swift.codegen.lang.FunctionParameter.NoLabel( + "provider", + ClientRuntimeTypes.Core.HttpInterceptorProvider, + ), ), ), ) diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/endpoints/EndpointResolverGenerator.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/endpoints/EndpointResolverGenerator.kt index 0b5c9179c..683d9a972 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/endpoints/EndpointResolverGenerator.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/endpoints/EndpointResolverGenerator.kt @@ -38,7 +38,7 @@ class EndpointResolverGenerator( writer: SwiftWriter, visibility: String, ) { - writer.openBlock("$visibility protocol \$N {", "}", EndpointTypes.EndpointResolver) { + writer.openBlock("$visibility protocol \$N: Sendable {", "}", EndpointTypes.EndpointResolver) { writer.write("func resolve(params: EndpointParams) throws -> \$N", SmithyHTTPAPITypes.Endpoint) } } @@ -64,7 +64,7 @@ class EndpointResolverGenerator( } } writer.write("") - writer.write("extension DefaultEndpointResolver: EndpointResolver {}") + writer.write("extension DefaultEndpointResolver: EndpointResolver where Params == EndpointParams {}") } private fun renderStaticResolver(writer: SwiftWriter) { diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/ExtractTelemetryLoggerConfig.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/ExtractTelemetryLoggerConfig.kt index 8b40b6111..9c21961be 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/ExtractTelemetryLoggerConfig.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/ExtractTelemetryLoggerConfig.kt @@ -24,7 +24,7 @@ class ExtractTelemetryLoggerConfig : SwiftIntegration { writer: SwiftWriter, section: ConfigClassVariablesCustomization, ) { - writer.write("public let logger: \$N", SmithyTypes.LogAgent) + writer.write("public var logger: \$N", SmithyTypes.LogAgent) writer.write("") } } @@ -36,7 +36,12 @@ class ExtractTelemetryLoggerConfig : SwiftIntegration { writer: SwiftWriter, section: ConfigInitializerCustomization, ) { - writer.write("self.logger = telemetryProvider.loggerProvider.getLogger(name: \$L.clientName)", section.serviceSymbol.name) + // Use telemetryProvider parameter if available (in parameterized initializers) + // Otherwise use the default telemetry provider directly + writer.write( + "self.logger = (telemetryProvider ?? ClientRuntime.DefaultTelemetry.provider).loggerProvider.getLogger(name: \$L.clientName)", + section.serviceSymbol.name, + ) } } } diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/HttpProtocolServiceClient.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/HttpProtocolServiceClient.kt index 99ba1847e..bcc57e971 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/HttpProtocolServiceClient.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/HttpProtocolServiceClient.kt @@ -26,7 +26,7 @@ open class HttpProtocolServiceClient( fun render(serviceSymbol: Symbol) { writer.openBlock( - "${ctx.settings.visibility} class \$L: \$N {", + "${ctx.settings.visibility} final class \$L: \$N {", "}", serviceSymbol.name, clientProtocolSymbol, @@ -62,7 +62,7 @@ open class HttpProtocolServiceClient( } open fun renderConvenienceInitFunctions(serviceSymbol: Symbol) { - writer.openBlock("public convenience required init() throws {", "}") { + writer.openBlock("public convenience init() throws {", "}") { writer.write("let config = try \$L()", serviceConfig.typeName) writer.write("self.init(config: config)") } @@ -119,7 +119,7 @@ open class HttpProtocolServiceClient( .joinToString(" & ") writer.openBlock( - "public class \$LConfiguration: \$L {", + "public struct \$LConfiguration: \$L, Sendable {", "}", serviceConfig.clientName.toUpperCamelCase(), clientConfigurationProtocols, @@ -133,13 +133,11 @@ open class HttpProtocolServiceClient( renderConfigClassVariables(serviceSymbol, properties) - renderConfigInitializer(serviceSymbol, properties) + renderSynchronousConfigInitializer(serviceSymbol, properties) - renderSynchronousConfigInitializer(properties) + renderAsynchronousConfigInitializer(serviceSymbol, properties) - renderAsynchronousConfigInitializer(properties) - - renderEmptyAsynchronousConfigInitializer(properties) + renderEmptyAsynchronousConfigInitializer(serviceSymbol, properties) renderCustomConfigInitializer(properties) @@ -161,8 +159,16 @@ open class HttpProtocolServiceClient( open fun overrideConfigProperties(properties: List): List = properties - private fun renderEmptyAsynchronousConfigInitializer(properties: List) { - writer.openBlock("public convenience required init() async throws {", "}") { + private fun renderEmptyAsynchronousConfigInitializer( + serviceSymbol: Symbol, + properties: List, + ) { + // Only render if there are async properties + if (properties.none { it.default?.isAsync == true }) return + + writer.openBlock("public init() async throws {", "}") { + // Call the parameterized async initializer with all nil parameters + // This delegates to the async initializer which properly handles async defaults writer.openBlock("try await self.init(", ")") { properties.forEach { property -> writer.write("\$L: nil,", property.name) @@ -203,29 +209,11 @@ open class HttpProtocolServiceClient( val serviceSymbol: Symbol, ) : CodeSection - private fun renderConfigInitializer( + private fun renderSynchronousConfigInitializer( serviceSymbol: Symbol, properties: List, ) { - writer.openBlock("private init(", ") {") { - properties.forEach { property -> - writer.write("_ \$L: \$L,", property.name, property.type.renderSwiftType(writer)) - } - writer.unwrite(",\n") - writer.write("") - } - writer.indent { - properties.forEach { property -> - writer.write("self.\$L = \$L", property.name, property.name) - } - writer.injectSection(ConfigInitializerCustomization(serviceSymbol)) - } - writer.write("}") - writer.write("") - } - - private fun renderSynchronousConfigInitializer(properties: List) { - writer.openBlock("public convenience init(", ") throws {") { + writer.openBlock("public init(", ") throws {") { properties.forEach { property -> writer.write("\$L: \$N = nil,", property.name, property.type.toOptional()) } @@ -233,26 +221,26 @@ open class HttpProtocolServiceClient( writer.write("") } writer.indent { - writer.openBlock("self.init(", ")") { - properties.forEach { property -> - if (property.default?.isAsync == true) { - writer.write("\$L,", property.name) - } else { - writer.write("\$L,", property.default?.render(writer, property.name) ?: property.name) - } + properties.forEach { property -> + if (property.default?.isAsync == true) { + writer.write("self.\$L = \$L", property.name, property.name) + } else { + writer.write("self.\$L = \$L", property.name, property.default?.render(writer, property.name) ?: property.name) } - writer.unwrite(",\n") - writer.write("") } + writer.injectSection(ConfigInitializerCustomization(serviceSymbol)) } writer.write("}") writer.write("") } - private fun renderAsynchronousConfigInitializer(properties: List) { + private fun renderAsynchronousConfigInitializer( + serviceSymbol: Symbol, + properties: List, + ) { if (properties.none { it.default?.isAsync == true }) return - writer.openBlock("public convenience init(", ") async throws {") { + writer.openBlock("public init(", ") async throws {") { properties.forEach { property -> writer.write("\$L: \$L = nil,", property.name, property.type.toOptional().renderSwiftType(writer)) } @@ -260,17 +248,14 @@ open class HttpProtocolServiceClient( writer.write("") } writer.indent { - writer.openBlock("self.init(", ")") { - properties.forEach { property -> - if (property.default?.isAsync == true) { - writer.write("\$L,", property.default.render(writer)) - } else { - writer.write("\$L,", property.default?.render(writer, property.name) ?: property.name) - } + properties.forEach { property -> + if (property.default?.isAsync == true) { + writer.write("self.\$L = \$L", property.name, property.default.render(writer)) + } else { + writer.write("self.\$L = \$L", property.name, property.default?.render(writer, property.name) ?: property.name) } - writer.unwrite(",\n") - writer.write("") } + writer.injectSection(ConfigInitializerCustomization(serviceSymbol)) } writer.write("}") writer.write("") diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/lang/Function.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/lang/Function.kt index d3b3ee3a2..374f5bf43 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/lang/Function.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/lang/Function.kt @@ -20,17 +20,19 @@ data class Function( val accessModifier: AccessModifier = AccessModifier.Public, val isAsync: Boolean = false, val isThrowing: Boolean = false, + val isMutating: Boolean = false, ) { /** * Render this function using the given writer. */ fun render(writer: SwiftWriter) { val renderedParameters = parameters.joinToString(", ") { it.rendered(writer) } + val renderedMutating = if (isMutating) "mutating " else "" val renderedAsync = if (isAsync) "async " else "" val renderedThrows = if (isThrowing) "throws " else "" val renderedReturnType = returnType?.let { writer.format("-> \$N ", it) } ?: "" writer.openBlock( - "${accessModifier.renderedRightPad()}func $name($renderedParameters) $renderedAsync$renderedThrows$renderedReturnType{", + "${accessModifier.renderedRightPad()}${renderedMutating}func $name($renderedParameters) $renderedAsync$renderedThrows$renderedReturnType{", "}", ) { renderBody.accept(writer) diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/ClientRuntimeTypes.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/ClientRuntimeTypes.kt index 8248201cd..d1237aaf3 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/ClientRuntimeTypes.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/ClientRuntimeTypes.kt @@ -45,8 +45,8 @@ object ClientRuntimeTypes { val StringBodyMiddleware = runtimeSymbol("StringBodyMiddleware", SwiftDeclaration.STRUCT) val Interceptor = runtimeSymbol("Interceptor", SwiftDeclaration.PROTOCOL) val MutableInput = runtimeSymbol("MutableInput", SwiftDeclaration.PROTOCOL) - val OrchestratorBuilder = runtimeSymbol("OrchestratorBuilder", SwiftDeclaration.CLASS) - val OrchestratorTelemetry = runtimeSymbol("OrchestratorTelemetry", SwiftDeclaration.CLASS) + val OrchestratorBuilder = runtimeSymbol("OrchestratorBuilder", null) + val OrchestratorTelemetry = runtimeSymbol("OrchestratorTelemetry", null) val OrchestratorMetricsAttributesKeys = runtimeSymbol("OrchestratorMetricsAttributesKeys", SwiftDeclaration.ENUM) } @@ -78,15 +78,15 @@ object ClientRuntimeTypes { val DefaultClientConfiguration = runtimeSymbol("DefaultClientConfiguration", SwiftDeclaration.PROTOCOL) val DefaultHttpClientConfiguration = runtimeSymbol("DefaultHttpClientConfiguration", SwiftDeclaration.PROTOCOL) val ClientConfigurationDefaults = runtimeSymbol("ClientConfigurationDefaults", SwiftDeclaration.TYPEALIAS) - val ClientBuilder = runtimeSymbol("ClientBuilder", SwiftDeclaration.CLASS) + val ClientBuilder = runtimeSymbol("ClientBuilder", null) val Indirect = runtimeSymbol("Indirect", SwiftDeclaration.CLASS) val HeaderDeserializationError = runtimeSymbol("HeaderDeserializationError", SwiftDeclaration.ENUM) val quoteHeaderValue = runtimeSymbol("quoteHeaderValue", SwiftDeclaration.FUNC) - val DefaultClientPlugin = runtimeSymbol("DefaultClientPlugin", SwiftDeclaration.CLASS) + val DefaultClientPlugin = runtimeSymbol("DefaultClientPlugin", null) val DefaultTelemetry = runtimeSymbol("DefaultTelemetry", SwiftDeclaration.ENUM) val splitHeaderListValues = runtimeSymbol("splitHeaderListValues", SwiftDeclaration.FUNC) val splitHttpDateHeaderListValues = runtimeSymbol("splitHttpDateHeaderListValues", SwiftDeclaration.FUNC) - val OrchestratorBuilder = runtimeSymbol("OrchestratorBuilder", SwiftDeclaration.CLASS) + val OrchestratorBuilder = runtimeSymbol("OrchestratorBuilder", null) val InterceptorProvider = runtimeSymbol("InterceptorProvider", SwiftDeclaration.PROTOCOL) val HttpInterceptorProvider = runtimeSymbol("HttpInterceptorProvider", SwiftDeclaration.PROTOCOL) val SDKLoggingSystem = runtimeSymbol("SDKLoggingSystem", SwiftDeclaration.CLASS) diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/SmithyTypes.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/SmithyTypes.kt index 4e8bd7caf..afa18d481 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/SmithyTypes.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/SmithyTypes.kt @@ -16,7 +16,7 @@ object SmithyTypes { val AttributeKey = runtimeSymbol("AttributeKey", SwiftDeclaration.STRUCT) val ClientError = runtimeSymbol("ClientError", SwiftDeclaration.ENUM) val Context = runtimeSymbol("Context", SwiftDeclaration.CLASS) - val ContextBuilder = runtimeSymbol("ContextBuilder", SwiftDeclaration.CLASS) + val ContextBuilder = runtimeSymbol("ContextBuilder", null) val Document = runtimeSymbol("Document", SwiftDeclaration.STRUCT) val LogAgent = runtimeSymbol("LogAgent", SwiftDeclaration.PROTOCOL) val RequestMessageSerializer = runtimeSymbol("RequestMessageSerializer", SwiftDeclaration.PROTOCOL) diff --git a/smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/HttpProtocolClientGeneratorTests.kt b/smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/HttpProtocolClientGeneratorTests.kt index 800f64fd3..a5dc4fb8f 100644 --- a/smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/HttpProtocolClientGeneratorTests.kt +++ b/smithy-swift-codegen/src/test/kotlin/software/amazon/smithy/swift/codegen/HttpProtocolClientGeneratorTests.kt @@ -17,7 +17,7 @@ class HttpProtocolClientGeneratorTests { val contents = getFileContents(context.manifest, "Sources/RestJson/RestJsonProtocolClient.swift") contents.shouldSyntacticSanityCheck() val expected = """ -public class RestJsonProtocolClient: ClientRuntime.Client { +public final class RestJsonProtocolClient: ClientRuntime.Client { public static let clientName = "RestJsonProtocolClient" public static let version = "2019-12-16" let client: ClientRuntime.SdkHttpClient @@ -29,7 +29,7 @@ public class RestJsonProtocolClient: ClientRuntime.Client { self.config = config } - public convenience required init() throws { + public convenience init() throws { let config = try RestJsonProtocolClient.RestJsonProtocolClientConfiguration() self.init(config: config) } @@ -38,110 +38,60 @@ public class RestJsonProtocolClient: ClientRuntime.Client { extension RestJsonProtocolClient { - public class RestJsonProtocolClientConfiguration: ClientRuntime.DefaultClientConfiguration & ClientRuntime.DefaultHttpClientConfiguration { + public struct RestJsonProtocolClientConfiguration: ClientRuntime.DefaultClientConfiguration & ClientRuntime.DefaultHttpClientConfiguration, Sendable { public var telemetryProvider: ClientRuntime.TelemetryProvider public var retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions public var clientLogMode: ClientRuntime.ClientLogMode public var endpoint: Swift.String? public var idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator + public var interceptorProviders: [ClientRuntime.InterceptorProvider] public var httpClientEngine: SmithyHTTPAPI.HTTPClient public var httpClientConfiguration: ClientRuntime.HttpClientConfiguration public var authSchemes: SmithyHTTPAuthAPI.AuthSchemes? public var authSchemePreference: [String]? public var authSchemeResolver: SmithyHTTPAuthAPI.AuthSchemeResolver + public var httpInterceptorProviders: [ClientRuntime.HttpInterceptorProvider] public var bearerTokenIdentityResolver: any SmithyIdentity.BearerTokenIdentityResolver - public private(set) var interceptorProviders: [ClientRuntime.InterceptorProvider] - public private(set) var httpInterceptorProviders: [ClientRuntime.HttpInterceptorProvider] - private init( - _ telemetryProvider: ClientRuntime.TelemetryProvider, - _ retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions, - _ clientLogMode: ClientRuntime.ClientLogMode, - _ endpoint: Swift.String?, - _ idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator, - _ httpClientEngine: SmithyHTTPAPI.HTTPClient, - _ httpClientConfiguration: ClientRuntime.HttpClientConfiguration, - _ authSchemes: SmithyHTTPAuthAPI.AuthSchemes?, - _ authSchemePreference: [String]?, - _ authSchemeResolver: SmithyHTTPAuthAPI.AuthSchemeResolver, - _ bearerTokenIdentityResolver: any SmithyIdentity.BearerTokenIdentityResolver, - _ interceptorProviders: [ClientRuntime.InterceptorProvider], - _ httpInterceptorProviders: [ClientRuntime.HttpInterceptorProvider] - ) { - self.telemetryProvider = telemetryProvider - self.retryStrategyOptions = retryStrategyOptions - self.clientLogMode = clientLogMode - self.endpoint = endpoint - self.idempotencyTokenGenerator = idempotencyTokenGenerator - self.httpClientEngine = httpClientEngine - self.httpClientConfiguration = httpClientConfiguration - self.authSchemes = authSchemes - self.authSchemePreference = authSchemePreference - self.authSchemeResolver = authSchemeResolver - self.bearerTokenIdentityResolver = bearerTokenIdentityResolver - self.interceptorProviders = interceptorProviders - self.httpInterceptorProviders = httpInterceptorProviders - } - - public convenience init( + public init( telemetryProvider: ClientRuntime.TelemetryProvider? = nil, retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions? = nil, clientLogMode: ClientRuntime.ClientLogMode? = nil, endpoint: Swift.String? = nil, idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator? = nil, + interceptorProviders: [ClientRuntime.InterceptorProvider]? = nil, httpClientEngine: SmithyHTTPAPI.HTTPClient? = nil, httpClientConfiguration: ClientRuntime.HttpClientConfiguration? = nil, authSchemes: SmithyHTTPAuthAPI.AuthSchemes? = nil, authSchemePreference: [String]? = nil, authSchemeResolver: SmithyHTTPAuthAPI.AuthSchemeResolver? = nil, - bearerTokenIdentityResolver: (any SmithyIdentity.BearerTokenIdentityResolver)? = nil, - interceptorProviders: [ClientRuntime.InterceptorProvider]? = nil, - httpInterceptorProviders: [ClientRuntime.HttpInterceptorProvider]? = nil + httpInterceptorProviders: [ClientRuntime.HttpInterceptorProvider]? = nil, + bearerTokenIdentityResolver: (any SmithyIdentity.BearerTokenIdentityResolver)? = nil ) throws { - self.init( - telemetryProvider ?? ClientRuntime.DefaultTelemetry.provider, - retryStrategyOptions ?? ClientRuntime.ClientConfigurationDefaults.defaultRetryStrategyOptions, - clientLogMode ?? ClientRuntime.ClientConfigurationDefaults.defaultClientLogMode, - endpoint, - idempotencyTokenGenerator ?? ClientRuntime.ClientConfigurationDefaults.defaultIdempotencyTokenGenerator, - httpClientEngine ?? ClientRuntime.ClientConfigurationDefaults.makeClient(httpClientConfiguration: httpClientConfiguration ?? ClientRuntime.ClientConfigurationDefaults.defaultHttpClientConfiguration), - httpClientConfiguration ?? ClientRuntime.ClientConfigurationDefaults.defaultHttpClientConfiguration, - authSchemes ?? [], - authSchemePreference ?? nil, - authSchemeResolver ?? ClientRuntime.ClientConfigurationDefaults.defaultAuthSchemeResolver, - bearerTokenIdentityResolver ?? SmithyIdentity.StaticBearerTokenIdentityResolver(token: SmithyIdentity.BearerTokenIdentity(token: "")), - interceptorProviders ?? [], - httpInterceptorProviders ?? [] - ) - } - - public convenience required init() async throws { - try await self.init( - telemetryProvider: nil, - retryStrategyOptions: nil, - clientLogMode: nil, - endpoint: nil, - idempotencyTokenGenerator: nil, - httpClientEngine: nil, - httpClientConfiguration: nil, - authSchemes: nil, - authSchemePreference: nil, - authSchemeResolver: nil, - bearerTokenIdentityResolver: nil, - interceptorProviders: nil, - httpInterceptorProviders: nil - ) + self.telemetryProvider = telemetryProvider ?? ClientRuntime.DefaultTelemetry.provider + self.retryStrategyOptions = retryStrategyOptions ?? ClientRuntime.ClientConfigurationDefaults.defaultRetryStrategyOptions + self.clientLogMode = clientLogMode ?? ClientRuntime.ClientConfigurationDefaults.defaultClientLogMode + self.endpoint = endpoint + self.idempotencyTokenGenerator = idempotencyTokenGenerator ?? ClientRuntime.ClientConfigurationDefaults.defaultIdempotencyTokenGenerator + self.interceptorProviders = interceptorProviders ?? [] + self.httpClientEngine = httpClientEngine ?? ClientRuntime.ClientConfigurationDefaults.makeClient(httpClientConfiguration: httpClientConfiguration ?? ClientRuntime.ClientConfigurationDefaults.defaultHttpClientConfiguration) + self.httpClientConfiguration = httpClientConfiguration ?? ClientRuntime.ClientConfigurationDefaults.defaultHttpClientConfiguration + self.authSchemes = authSchemes ?? [] + self.authSchemePreference = authSchemePreference ?? nil + self.authSchemeResolver = authSchemeResolver ?? ClientRuntime.ClientConfigurationDefaults.defaultAuthSchemeResolver + self.httpInterceptorProviders = httpInterceptorProviders ?? [] + self.bearerTokenIdentityResolver = bearerTokenIdentityResolver ?? SmithyIdentity.StaticBearerTokenIdentityResolver(token: SmithyIdentity.BearerTokenIdentity(token: "")) } public var partitionID: String? { return "" } - public func addInterceptorProvider(_ provider: ClientRuntime.InterceptorProvider) { + public mutating func addInterceptorProvider(_ provider: ClientRuntime.InterceptorProvider) { self.interceptorProviders.append(provider) } - public func addInterceptorProvider(_ provider: ClientRuntime.HttpInterceptorProvider) { + public mutating func addHttpInterceptorProvider(_ provider: ClientRuntime.HttpInterceptorProvider) { self.httpInterceptorProviders.append(provider) }