diff --git a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Resources/Package.Base.swift b/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Resources/Package.Base.swift index 9389453696e..8716a1c9302 100644 --- a/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Resources/Package.Base.swift +++ b/AWSSDKSwiftCLI/Sources/AWSSDKSwiftCLI/Resources/Package.Base.swift @@ -111,7 +111,7 @@ func addServiceTarget(_ name: String) { package.targets += [ .target( name: name, - dependencies: [.clientRuntime, .awsClientRuntime], + dependencies: [.clientRuntime, .awsClientRuntime, .smithyRetriesAPI, .smithyRetries], path: "./Sources/Services/\(name)" ) ] diff --git a/Package.swift b/Package.swift index f564e68ddfd..557274f6ea3 100644 --- a/Package.swift +++ b/Package.swift @@ -111,7 +111,7 @@ func addServiceTarget(_ name: String) { package.targets += [ .target( name: name, - dependencies: [.clientRuntime, .awsClientRuntime], + dependencies: [.clientRuntime, .awsClientRuntime, .smithyRetriesAPI, .smithyRetries], path: "./Sources/Services/\(name)" ) ] diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolServiceClient.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolServiceClient.kt index 61f7a45d4bc..8bb38cd2513 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolServiceClient.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolServiceClient.kt @@ -9,6 +9,7 @@ import software.amazon.smithy.aws.swift.codegen.SigV4Utils.Companion.getModeledA import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.swift.codegen.AuthSchemeResolverGenerator 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.config.ConfigProperty import software.amazon.smithy.swift.codegen.config.DefaultProvider @@ -17,6 +18,7 @@ import software.amazon.smithy.swift.codegen.integration.HttpProtocolServiceClien import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator import software.amazon.smithy.swift.codegen.integration.ServiceConfig import software.amazon.smithy.swift.codegen.model.toOptional +import software.amazon.smithy.swift.codegen.swiftmodules.SmithyRetriesAPITypes import software.amazon.smithy.swift.codegen.utils.toUpperCamelCase class AWSHttpProtocolServiceClient( @@ -47,7 +49,8 @@ class AWSHttpProtocolServiceClient( ConfigProperty("authSchemes", ClientRuntimeTypes.Auth.AuthSchemes.toOptional(), authSchemesDefaultProvider) } "retryStrategyOptions" -> { - ConfigProperty("retryStrategyOptions", ClientRuntimeTypes.Core.RetryStrategyOptions, "AWSClientConfigDefaultsProvider.retryStrategyOptions()", true) + writer.addImport(SwiftDependency.SMITHY_RETRIES_API.target) + ConfigProperty("retryStrategyOptions", SmithyRetriesAPITypes.RetryStrategyOptions, "AWSClientConfigDefaultsProvider.retryStrategyOptions()", true) } "clientLogMode" -> { ConfigProperty("clientLogMode", ClientRuntimeTypes.Core.ClientLogMode, "AWSClientConfigDefaultsProvider.clientLogMode") diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EventStreamTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EventStreamTests.kt index 23ad73e697e..8c9e9fa75c5 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EventStreamTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/EventStreamTests.kt @@ -188,27 +188,6 @@ extension EventStreamTestClientTypes.TestStream: ClientRuntime.MessageUnmarshall val context = setupTests("eventstream.smithy", "aws.protocoltests.restjson#TestService") val contents = getFileContents(context.manifest, "/Example/EventStreamTestClient.swift") var expected = """ - public func testStreamOp(input: TestStreamOpInput) async throws -> TestStreamOpOutput { - let context = ClientRuntime.HttpContextBuilder() - .withEncoder(value: encoder) - .withDecoder(value: decoder) - .withMethod(value: .post) - .withServiceName(value: serviceName) - .withOperation(value: "testStreamOp") - .withIdempotencyTokenGenerator(value: config.idempotencyTokenGenerator) - .withLogger(value: config.logger) - .withPartitionID(value: config.partitionID) - .withAuthSchemes(value: config.authSchemes ?? []) - .withAuthSchemeResolver(value: config.authSchemeResolver) - .withUnsignedPayloadTrait(value: false) - .withSocketTimeout(value: config.httpClientConfiguration.socketTimeout) - .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4") - .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4a") - .withRegion(value: config.region) - .withSigningName(value: "event-stream-test") - .withSigningRegion(value: config.signingRegion) - .build() - try context.setupBidirectionalStreaming() var operation = ClientRuntime.OperationStack(id: "testStreamOp") operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLPathMiddleware(TestStreamOpInput.urlPathProvider(_:))) operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLHostMiddleware()) @@ -219,20 +198,16 @@ extension EventStreamTestClientTypes.TestStream: ClientRuntime.MessageUnmarshall operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/json")) operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.EventStreamBodyMiddleware(keyPath: \.value, defaultBody: "{}", marshalClosure: jsonMarshalClosure(requestEncoder: encoder))) operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) - operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) + operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.SignerMiddleware()) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware(responseClosure(decoder: decoder), responseErrorClosure(TestStreamOpOutputError.self, decoder: decoder))) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) - let result = try await operation.handleMiddleware(context: context, input: input, next: client.getHandler()) - return result - } """ contents.shouldContainOnlyOnce(expected) } private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext { val context = TestUtils.executeDirectedCodegen(smithyFile, serviceShapeId, RestJson1Trait.ID) - val generator = AWSRestJson1ProtocolGenerator() generator.generateProtocolUnitTests(context.ctx) context.ctx.delegator.flushWriters() diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt index d84ac775b22..2498bb36e2c 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt @@ -50,7 +50,7 @@ extension GetFooInput { operation.buildStep.intercept(position: .before, middleware: EndpointResolverMiddleware(endpointResolver: config.endpointResolver, endpointParams: endpointParams)) operation.buildStep.intercept(position: .before, middleware: AWSClientRuntime.UserAgentMiddleware(metadata: AWSClientRuntime.AWSUserAgentMetadata.fromConfig(serviceID: serviceName, version: "1.0.0", config: config))) operation.buildStep.intercept(position: .before, middleware: ClientRuntime.AuthSchemeMiddleware()) - operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) + operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.SignerMiddleware()) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware(responseClosure(decoder: decoder), responseErrorClosure(GetFooOutputError.self, decoder: decoder))) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) @@ -111,7 +111,7 @@ extension PostFooInput { operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/json")) operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.BodyMiddleware(documentWritingClosure: ClientRuntime.JSONReadWrite.documentWritingClosure(encoder: encoder), inputWritingClosure: JSONReadWrite.writingClosure())) operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) - operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) + operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.SignerMiddleware()) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware(responseClosure(decoder: decoder), responseErrorClosure(PostFooOutputError.self, decoder: decoder))) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) @@ -172,7 +172,7 @@ extension PutFooInput { operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/json")) operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.BodyMiddleware(documentWritingClosure: ClientRuntime.JSONReadWrite.documentWritingClosure(encoder: encoder), inputWritingClosure: JSONReadWrite.writingClosure())) operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) - operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) + operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.SignerMiddleware()) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware(responseClosure(decoder: decoder), responseErrorClosure(PutFooOutputError.self, decoder: decoder))) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) @@ -232,7 +232,7 @@ extension PutObjectInput { operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/json")) operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.BodyMiddleware(documentWritingClosure: SmithyXML.XMLReadWrite.documentWritingClosure(rootNodeInfo: "PutObjectInput"), inputWritingClosure: PutObjectInput.writingClosure(_:to:))) operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) - operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) + operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.SignerMiddleware()) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware(responseClosure(PutObjectOutput.httpBinding, responseDocumentBinding), responseErrorClosure(PutObjectOutputError.httpBinding, responseDocumentBinding))) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsquery/AWSQueryOperationStackTest.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsquery/AWSQueryOperationStackTest.kt index 73fd9c20348..9a1f096459c 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsquery/AWSQueryOperationStackTest.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsquery/AWSQueryOperationStackTest.kt @@ -20,23 +20,6 @@ class AWSQueryOperationStackTest { val contents = getFileContents(context.manifest, "/Example/QueryProtocolClient.swift") contents.shouldSyntacticSanityCheck() val expectedContents = """ - public func noInputAndOutput(input: NoInputAndOutputInput) async throws -> NoInputAndOutputOutput { - let context = ClientRuntime.HttpContextBuilder() - .withEncoder(value: encoder) - .withMethod(value: .post) - .withServiceName(value: serviceName) - .withOperation(value: "noInputAndOutput") - .withIdempotencyTokenGenerator(value: config.idempotencyTokenGenerator) - .withLogger(value: config.logger) - .withPartitionID(value: config.partitionID) - .withAuthSchemes(value: config.authSchemes ?? []) - .withAuthSchemeResolver(value: config.authSchemeResolver) - .withUnsignedPayloadTrait(value: false) - .withSocketTimeout(value: config.httpClientConfiguration.socketTimeout) - .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4") - .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4a") - .withRegion(value: config.region) - .build() var operation = ClientRuntime.OperationStack(id: "noInputAndOutput") operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLPathMiddleware(NoInputAndOutputInput.urlPathProvider(_:))) operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLHostMiddleware()) @@ -47,13 +30,10 @@ class AWSQueryOperationStackTest { operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.BodyMiddleware(documentWritingClosure: ClientRuntime.FormURLReadWrite.documentWritingClosure(encoder: encoder), inputWritingClosure: FormURLReadWrite.writingClosure())) operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/x-www-form-urlencoded")) operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) - operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) + operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.SignerMiddleware()) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware(responseClosure(NoInputAndOutputOutput.httpBinding, responseDocumentBinding), responseErrorClosure(NoInputAndOutputOutputError.httpBinding, responseDocumentBinding))) operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) - let result = try await operation.handleMiddleware(context: context, input: input, next: client.getHandler()) - return result - } """ contents.shouldContainOnlyOnce(expectedContents) } diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt index ff88398ef3b..67c40d32ad3 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt @@ -76,147 +76,141 @@ class RestJsonProtocolGeneratorTests { val context = setupTests("http-binding-protocol-generator-test.smithy", "com.test#Example") val contents = getClientFileContents("Example", "ExampleClient.swift", context.manifest) contents.shouldSyntacticSanityCheck() - val expectedContents = - """ - @_spi(FileBasedConfig) import AWSClientRuntime - import ClientRuntime - import Foundation - import Logging - - public class ExampleClient: Client { - public static let clientName = "ExampleClient" - let client: ClientRuntime.SdkHttpClient - let config: ExampleClient.ExampleClientConfiguration - let serviceName = "Example" - let encoder: ClientRuntime.RequestEncoder - let decoder: ClientRuntime.ResponseDecoder - - public required init(config: ExampleClient.ExampleClientConfiguration) { - client = ClientRuntime.SdkHttpClient(engine: config.httpClientEngine, config: config.httpClientConfiguration) - let encoder = ClientRuntime.JSONEncoder() - encoder.dateEncodingStrategy = .secondsSince1970 - encoder.nonConformingFloatEncodingStrategy = .convertToString(positiveInfinity: "Infinity", negativeInfinity: "-Infinity", nan: "NaN") - self.encoder = encoder - let decoder = ClientRuntime.JSONDecoder() - decoder.dateDecodingStrategy = .secondsSince1970 - decoder.nonConformingFloatDecodingStrategy = .convertFromString(positiveInfinity: "Infinity", negativeInfinity: "-Infinity", nan: "NaN") - self.decoder = decoder - self.config = config - } - - public convenience init(region: Swift.String) throws { - let config = try ExampleClient.ExampleClientConfiguration(region: region) - self.init(config: config) - } - - public convenience required init() async throws { - let config = try await ExampleClient.ExampleClientConfiguration() - self.init(config: config) - } - } - - extension ExampleClient { - public class ExampleClientConfiguration: AWSDefaultClientConfiguration & AWSRegionClientConfiguration & DefaultClientConfiguration & DefaultHttpClientConfiguration { - public var useFIPS: Swift.Bool? - - public var useDualStack: Swift.Bool? - - public var appID: Swift.String? - - public var awsCredentialIdentityResolver: any AWSClientRuntime.AWSCredentialIdentityResolver - - public var awsRetryMode: AWSClientRuntime.AWSRetryMode - - public var region: Swift.String? - - public var signingRegion: Swift.String? - - public var endpointResolver: EndpointResolver - - public var telemetryProvider: ClientRuntime.TelemetryProvider - - public var retryStrategyOptions: ClientRuntime.RetryStrategyOptions - - public var clientLogMode: ClientRuntime.ClientLogMode - - public var endpoint: Swift.String? - - public var idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator - - public var httpClientEngine: ClientRuntime.HTTPClient - - public var httpClientConfiguration: ClientRuntime.HttpClientConfiguration - - public var authSchemes: [ClientRuntime.AuthScheme]? - - public var authSchemeResolver: ClientRuntime.AuthSchemeResolver - - internal let logger: ClientRuntime.LogAgent - - private init(_ useFIPS: Swift.Bool?, _ useDualStack: Swift.Bool?, _ appID: Swift.String?, _ awsCredentialIdentityResolver: any AWSClientRuntime.AWSCredentialIdentityResolver, _ awsRetryMode: AWSClientRuntime.AWSRetryMode, _ region: Swift.String?, _ signingRegion: Swift.String?, _ endpointResolver: EndpointResolver, _ telemetryProvider: ClientRuntime.TelemetryProvider, _ retryStrategyOptions: ClientRuntime.RetryStrategyOptions, _ clientLogMode: ClientRuntime.ClientLogMode, _ endpoint: Swift.String?, _ idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator, _ httpClientEngine: ClientRuntime.HTTPClient, _ httpClientConfiguration: ClientRuntime.HttpClientConfiguration, _ authSchemes: [ClientRuntime.AuthScheme]?, _ authSchemeResolver: ClientRuntime.AuthSchemeResolver) { - self.useFIPS = useFIPS - self.useDualStack = useDualStack - self.appID = appID - self.awsCredentialIdentityResolver = awsCredentialIdentityResolver - self.awsRetryMode = awsRetryMode - self.region = region - self.signingRegion = signingRegion - self.endpointResolver = endpointResolver - 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.authSchemeResolver = authSchemeResolver - self.logger = telemetryProvider.loggerProvider.getLogger(name: ExampleClient.clientName) - } - - public convenience init(useFIPS: Swift.Bool? = nil, useDualStack: Swift.Bool? = nil, appID: Swift.String? = nil, awsCredentialIdentityResolver: (any AWSClientRuntime.AWSCredentialIdentityResolver)? = nil, awsRetryMode: AWSClientRuntime.AWSRetryMode? = nil, region: Swift.String? = nil, signingRegion: Swift.String? = nil, endpointResolver: EndpointResolver? = nil, telemetryProvider: ClientRuntime.TelemetryProvider? = nil, retryStrategyOptions: ClientRuntime.RetryStrategyOptions? = nil, clientLogMode: ClientRuntime.ClientLogMode? = nil, endpoint: Swift.String? = nil, idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator? = nil, httpClientEngine: ClientRuntime.HTTPClient? = nil, httpClientConfiguration: ClientRuntime.HttpClientConfiguration? = nil, authSchemes: [ClientRuntime.AuthScheme]? = nil, authSchemeResolver: ClientRuntime.AuthSchemeResolver? = nil) throws { - self.init(useFIPS, useDualStack, try appID ?? AWSClientConfigDefaultsProvider.appID(), try awsCredentialIdentityResolver ?? AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(awsCredentialIdentityResolver), try awsRetryMode ?? AWSClientConfigDefaultsProvider.retryMode(), region, signingRegion, try endpointResolver ?? DefaultEndpointResolver(), telemetryProvider ?? ClientRuntime.DefaultTelemetry.provider, try retryStrategyOptions ?? AWSClientConfigDefaultsProvider.retryStrategyOptions(), clientLogMode ?? AWSClientConfigDefaultsProvider.clientLogMode, endpoint, idempotencyTokenGenerator ?? AWSClientConfigDefaultsProvider.idempotencyTokenGenerator, httpClientEngine ?? AWSClientConfigDefaultsProvider.httpClientEngine, httpClientConfiguration ?? AWSClientConfigDefaultsProvider.httpClientConfiguration, authSchemes ?? [SigV4AuthScheme()], authSchemeResolver ?? DefaultExampleAuthSchemeResolver()) - } - - public convenience init(useFIPS: Swift.Bool? = nil, useDualStack: Swift.Bool? = nil, appID: Swift.String? = nil, awsCredentialIdentityResolver: (any AWSClientRuntime.AWSCredentialIdentityResolver)? = nil, awsRetryMode: AWSClientRuntime.AWSRetryMode? = nil, region: Swift.String? = nil, signingRegion: Swift.String? = nil, endpointResolver: EndpointResolver? = nil, telemetryProvider: ClientRuntime.TelemetryProvider? = nil, retryStrategyOptions: ClientRuntime.RetryStrategyOptions? = nil, clientLogMode: ClientRuntime.ClientLogMode? = nil, endpoint: Swift.String? = nil, idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator? = nil, httpClientEngine: ClientRuntime.HTTPClient? = nil, httpClientConfiguration: ClientRuntime.HttpClientConfiguration? = nil, authSchemes: [ClientRuntime.AuthScheme]? = nil, authSchemeResolver: ClientRuntime.AuthSchemeResolver? = nil) async throws { - self.init(useFIPS, useDualStack, try appID ?? AWSClientConfigDefaultsProvider.appID(), try awsCredentialIdentityResolver ?? AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(awsCredentialIdentityResolver), try awsRetryMode ?? AWSClientConfigDefaultsProvider.retryMode(), try await AWSClientConfigDefaultsProvider.region(region), try await AWSClientConfigDefaultsProvider.region(region), try endpointResolver ?? DefaultEndpointResolver(), telemetryProvider ?? ClientRuntime.DefaultTelemetry.provider, try retryStrategyOptions ?? AWSClientConfigDefaultsProvider.retryStrategyOptions(), clientLogMode ?? AWSClientConfigDefaultsProvider.clientLogMode, endpoint, idempotencyTokenGenerator ?? AWSClientConfigDefaultsProvider.idempotencyTokenGenerator, httpClientEngine ?? AWSClientConfigDefaultsProvider.httpClientEngine, httpClientConfiguration ?? AWSClientConfigDefaultsProvider.httpClientConfiguration, authSchemes ?? [SigV4AuthScheme()], authSchemeResolver ?? DefaultExampleAuthSchemeResolver()) - } - - public convenience required init() async throws { - try await self.init(useFIPS: nil, useDualStack: nil, appID: nil, awsCredentialIdentityResolver: nil, awsRetryMode: nil, region: nil, signingRegion: nil, endpointResolver: nil, telemetryProvider: nil, retryStrategyOptions: nil, clientLogMode: nil, endpoint: nil, idempotencyTokenGenerator: nil, httpClientEngine: nil, httpClientConfiguration: nil, authSchemes: nil, authSchemeResolver: nil) - } - - public convenience init(region: String) throws { - self.init(nil, nil, try AWSClientConfigDefaultsProvider.appID(), try AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(), try AWSClientConfigDefaultsProvider.retryMode(), region, region, try DefaultEndpointResolver(), ClientRuntime.DefaultTelemetry.provider, try AWSClientConfigDefaultsProvider.retryStrategyOptions(), AWSClientConfigDefaultsProvider.clientLogMode, nil, AWSClientConfigDefaultsProvider.idempotencyTokenGenerator, AWSClientConfigDefaultsProvider.httpClientEngine, AWSClientConfigDefaultsProvider.httpClientConfiguration, [SigV4AuthScheme()], DefaultExampleAuthSchemeResolver()) - } - - public var partitionID: String? { - return "\(ExampleClient.clientName) - \(region ?? "")" - } - } - - public static func builder() -> ClientBuilder { - return ClientBuilder(defaultPlugins: [ - ClientRuntime.DefaultClientPlugin(), - AWSClientRuntime.DefaultAWSClientPlugin(clientName: self.clientName), - DefaultAWSAuthSchemePlugin() - ]) - } - } - - public struct ExampleClientLogHandlerFactory: ClientRuntime.SDKLogHandlerFactory { - public var label = "ExampleClient" - let logLevel: ClientRuntime.SDKLogLevel - public func construct(label: String) -> LogHandler { - var handler = StreamLogHandler.standardOutput(label: label) - handler.logLevel = logLevel.toLoggerType() - return handler - } - public init(logLevel: ClientRuntime.SDKLogLevel) { - self.logLevel = logLevel - } - } - """.trimIndent() + val expectedContents = """ +public class ExampleClient: Client { + public static let clientName = "ExampleClient" + let client: ClientRuntime.SdkHttpClient + let config: ExampleClient.ExampleClientConfiguration + let serviceName = "Example" + let encoder: ClientRuntime.RequestEncoder + let decoder: ClientRuntime.ResponseDecoder + + public required init(config: ExampleClient.ExampleClientConfiguration) { + client = ClientRuntime.SdkHttpClient(engine: config.httpClientEngine, config: config.httpClientConfiguration) + let encoder = ClientRuntime.JSONEncoder() + encoder.dateEncodingStrategy = .secondsSince1970 + encoder.nonConformingFloatEncodingStrategy = .convertToString(positiveInfinity: "Infinity", negativeInfinity: "-Infinity", nan: "NaN") + self.encoder = encoder + let decoder = ClientRuntime.JSONDecoder() + decoder.dateDecodingStrategy = .secondsSince1970 + decoder.nonConformingFloatDecodingStrategy = .convertFromString(positiveInfinity: "Infinity", negativeInfinity: "-Infinity", nan: "NaN") + self.decoder = decoder + self.config = config + } + + public convenience init(region: Swift.String) throws { + let config = try ExampleClient.ExampleClientConfiguration(region: region) + self.init(config: config) + } + + public convenience required init() async throws { + let config = try await ExampleClient.ExampleClientConfiguration() + self.init(config: config) + } +} + +extension ExampleClient { + public class ExampleClientConfiguration: AWSDefaultClientConfiguration & AWSRegionClientConfiguration & DefaultClientConfiguration & DefaultHttpClientConfiguration { + public var useFIPS: Swift.Bool? + + public var useDualStack: Swift.Bool? + + public var appID: Swift.String? + + public var awsCredentialIdentityResolver: any AWSClientRuntime.AWSCredentialIdentityResolver + + public var awsRetryMode: AWSClientRuntime.AWSRetryMode + + public var region: Swift.String? + + public var signingRegion: Swift.String? + + public var endpointResolver: EndpointResolver + + 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 httpClientEngine: ClientRuntime.HTTPClient + + public var httpClientConfiguration: ClientRuntime.HttpClientConfiguration + + public var authSchemes: [ClientRuntime.AuthScheme]? + + public var authSchemeResolver: ClientRuntime.AuthSchemeResolver + + internal let logger: ClientRuntime.LogAgent + + private init(_ useFIPS: Swift.Bool?, _ useDualStack: Swift.Bool?, _ appID: Swift.String?, _ awsCredentialIdentityResolver: any AWSClientRuntime.AWSCredentialIdentityResolver, _ awsRetryMode: AWSClientRuntime.AWSRetryMode, _ region: Swift.String?, _ signingRegion: Swift.String?, _ endpointResolver: EndpointResolver, _ telemetryProvider: ClientRuntime.TelemetryProvider, _ retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions, _ clientLogMode: ClientRuntime.ClientLogMode, _ endpoint: Swift.String?, _ idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator, _ httpClientEngine: ClientRuntime.HTTPClient, _ httpClientConfiguration: ClientRuntime.HttpClientConfiguration, _ authSchemes: [ClientRuntime.AuthScheme]?, _ authSchemeResolver: ClientRuntime.AuthSchemeResolver) { + self.useFIPS = useFIPS + self.useDualStack = useDualStack + self.appID = appID + self.awsCredentialIdentityResolver = awsCredentialIdentityResolver + self.awsRetryMode = awsRetryMode + self.region = region + self.signingRegion = signingRegion + self.endpointResolver = endpointResolver + 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.authSchemeResolver = authSchemeResolver + self.logger = telemetryProvider.loggerProvider.getLogger(name: ExampleClient.clientName) + } + + public convenience init(useFIPS: Swift.Bool? = nil, useDualStack: Swift.Bool? = nil, appID: Swift.String? = nil, awsCredentialIdentityResolver: (any AWSClientRuntime.AWSCredentialIdentityResolver)? = nil, awsRetryMode: AWSClientRuntime.AWSRetryMode? = nil, region: Swift.String? = nil, signingRegion: Swift.String? = nil, endpointResolver: EndpointResolver? = nil, telemetryProvider: ClientRuntime.TelemetryProvider? = nil, retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions? = nil, clientLogMode: ClientRuntime.ClientLogMode? = nil, endpoint: Swift.String? = nil, idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator? = nil, httpClientEngine: ClientRuntime.HTTPClient? = nil, httpClientConfiguration: ClientRuntime.HttpClientConfiguration? = nil, authSchemes: [ClientRuntime.AuthScheme]? = nil, authSchemeResolver: ClientRuntime.AuthSchemeResolver? = nil) throws { + self.init(useFIPS, useDualStack, try appID ?? AWSClientConfigDefaultsProvider.appID(), try awsCredentialIdentityResolver ?? AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(awsCredentialIdentityResolver), try awsRetryMode ?? AWSClientConfigDefaultsProvider.retryMode(), region, signingRegion, try endpointResolver ?? DefaultEndpointResolver(), telemetryProvider ?? ClientRuntime.DefaultTelemetry.provider, try retryStrategyOptions ?? AWSClientConfigDefaultsProvider.retryStrategyOptions(), clientLogMode ?? AWSClientConfigDefaultsProvider.clientLogMode, endpoint, idempotencyTokenGenerator ?? AWSClientConfigDefaultsProvider.idempotencyTokenGenerator, httpClientEngine ?? AWSClientConfigDefaultsProvider.httpClientEngine, httpClientConfiguration ?? AWSClientConfigDefaultsProvider.httpClientConfiguration, authSchemes ?? [SigV4AuthScheme()], authSchemeResolver ?? DefaultExampleAuthSchemeResolver()) + } + + public convenience init(useFIPS: Swift.Bool? = nil, useDualStack: Swift.Bool? = nil, appID: Swift.String? = nil, awsCredentialIdentityResolver: (any AWSClientRuntime.AWSCredentialIdentityResolver)? = nil, awsRetryMode: AWSClientRuntime.AWSRetryMode? = nil, region: Swift.String? = nil, signingRegion: Swift.String? = nil, endpointResolver: EndpointResolver? = nil, telemetryProvider: ClientRuntime.TelemetryProvider? = nil, retryStrategyOptions: SmithyRetriesAPI.RetryStrategyOptions? = nil, clientLogMode: ClientRuntime.ClientLogMode? = nil, endpoint: Swift.String? = nil, idempotencyTokenGenerator: ClientRuntime.IdempotencyTokenGenerator? = nil, httpClientEngine: ClientRuntime.HTTPClient? = nil, httpClientConfiguration: ClientRuntime.HttpClientConfiguration? = nil, authSchemes: [ClientRuntime.AuthScheme]? = nil, authSchemeResolver: ClientRuntime.AuthSchemeResolver? = nil) async throws { + self.init(useFIPS, useDualStack, try appID ?? AWSClientConfigDefaultsProvider.appID(), try awsCredentialIdentityResolver ?? AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(awsCredentialIdentityResolver), try awsRetryMode ?? AWSClientConfigDefaultsProvider.retryMode(), try await AWSClientConfigDefaultsProvider.region(region), try await AWSClientConfigDefaultsProvider.region(region), try endpointResolver ?? DefaultEndpointResolver(), telemetryProvider ?? ClientRuntime.DefaultTelemetry.provider, try retryStrategyOptions ?? AWSClientConfigDefaultsProvider.retryStrategyOptions(), clientLogMode ?? AWSClientConfigDefaultsProvider.clientLogMode, endpoint, idempotencyTokenGenerator ?? AWSClientConfigDefaultsProvider.idempotencyTokenGenerator, httpClientEngine ?? AWSClientConfigDefaultsProvider.httpClientEngine, httpClientConfiguration ?? AWSClientConfigDefaultsProvider.httpClientConfiguration, authSchemes ?? [SigV4AuthScheme()], authSchemeResolver ?? DefaultExampleAuthSchemeResolver()) + } + + public convenience required init() async throws { + try await self.init(useFIPS: nil, useDualStack: nil, appID: nil, awsCredentialIdentityResolver: nil, awsRetryMode: nil, region: nil, signingRegion: nil, endpointResolver: nil, telemetryProvider: nil, retryStrategyOptions: nil, clientLogMode: nil, endpoint: nil, idempotencyTokenGenerator: nil, httpClientEngine: nil, httpClientConfiguration: nil, authSchemes: nil, authSchemeResolver: nil) + } + + public convenience init(region: String) throws { + self.init(nil, nil, try AWSClientConfigDefaultsProvider.appID(), try AWSClientConfigDefaultsProvider.awsCredentialIdentityResolver(), try AWSClientConfigDefaultsProvider.retryMode(), region, region, try DefaultEndpointResolver(), ClientRuntime.DefaultTelemetry.provider, try AWSClientConfigDefaultsProvider.retryStrategyOptions(), AWSClientConfigDefaultsProvider.clientLogMode, nil, AWSClientConfigDefaultsProvider.idempotencyTokenGenerator, AWSClientConfigDefaultsProvider.httpClientEngine, AWSClientConfigDefaultsProvider.httpClientConfiguration, [SigV4AuthScheme()], DefaultExampleAuthSchemeResolver()) + } + + public var partitionID: String? { + return "\(ExampleClient.clientName) - \(region ?? "")" + } + } + + public static func builder() -> ClientBuilder { + return ClientBuilder(defaultPlugins: [ + ClientRuntime.DefaultClientPlugin(), + AWSClientRuntime.DefaultAWSClientPlugin(clientName: self.clientName), + DefaultAWSAuthSchemePlugin() + ]) + } +} + +public struct ExampleClientLogHandlerFactory: ClientRuntime.SDKLogHandlerFactory { + public var label = "ExampleClient" + let logLevel: ClientRuntime.SDKLogLevel + public func construct(label: String) -> LogHandler { + var handler = StreamLogHandler.standardOutput(label: label) + handler.logLevel = logLevel.toLoggerType() + return handler + } + public init(logLevel: ClientRuntime.SDKLogLevel) { + self.logLevel = logLevel + } +} +""" contents.shouldContainOnlyOnce(expectedContents) } private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext { diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt index b7ce47bd1eb..c3f72a71934 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/FlexibleChecksumMiddlewareTests.kt @@ -11,67 +11,29 @@ import software.amazon.smithy.aws.traits.protocols.RestJson1Trait class FlexibleChecksumMiddlewareTests { @Test - fun `Test that FlexibleChecksumsRequestMiddleware and FlexibleChecksumsResponseMiddleware are properly generated`() { + fun `Test that FlexibleChecksumsRequestMiddleware is properly generated`() { val context = setupTests("flexible-checksums.smithy", "aws.flex.checks#ChecksumTests") val contents = TestUtils.getFileContents(context.manifest, "/Example/ChecksumTestsClient.swift") contents.shouldSyntacticSanityCheck() val expectedContents = """ -extension ChecksumTestsClient { - /// Performs the `SomeOperation` operation on the `ChecksumTests` service. - /// - /// - /// - Parameter SomeOperationInput : [no documentation found] - /// - /// - Returns: `SomeOperationOutput` : [no documentation found] - public func someOperation(input: SomeOperationInput) async throws -> SomeOperationOutput { - let context = ClientRuntime.HttpContextBuilder() - .withEncoder(value: encoder) - .withDecoder(value: decoder) - .withMethod(value: .post) - .withServiceName(value: serviceName) - .withOperation(value: "someOperation") - .withIdempotencyTokenGenerator(value: config.idempotencyTokenGenerator) - .withLogger(value: config.logger) - .withPartitionID(value: config.partitionID) - .withAuthSchemes(value: config.authSchemes ?? []) - .withAuthSchemeResolver(value: config.authSchemeResolver) - .withUnsignedPayloadTrait(value: false) - .withSocketTimeout(value: config.httpClientConfiguration.socketTimeout) - .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4") - .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4a") - .withRegion(value: config.region) - .build() - var operation = ClientRuntime.OperationStack(id: "someOperation") - operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLPathMiddleware(SomeOperationInput.urlPathProvider(_:))) - operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLHostMiddleware()) - operation.buildStep.intercept(position: .before, middleware: ClientRuntime.ContentMD5Middleware()) - let endpointParams = EndpointParams() - operation.buildStep.intercept(position: .before, middleware: EndpointResolverMiddleware(endpointResolver: config.endpointResolver, endpointParams: endpointParams)) - operation.buildStep.intercept(position: .before, middleware: AWSClientRuntime.UserAgentMiddleware(metadata: AWSClientRuntime.AWSUserAgentMetadata.fromConfig(serviceID: serviceName, version: "1.0.0", config: config))) - operation.buildStep.intercept(position: .before, middleware: ClientRuntime.AuthSchemeMiddleware()) - operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.HeaderMiddleware(SomeOperationInput.headerProvider(_:))) - operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/octet-stream")) - operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.BlobBodyMiddleware(keyPath: \.content)) operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.FlexibleChecksumsRequestMiddleware(checksumAlgorithm: input.checksumAlgorithm?.rawValue)) - operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) - operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) - operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.SignerMiddleware()) - operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware(responseClosure(decoder: decoder), responseErrorClosure(SomeOperationOutputError.self, decoder: decoder))) - operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) - operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.FlexibleChecksumsResponseMiddleware(validationMode: true)) - let result = try await operation.handleMiddleware(context: context, input: input, next: client.getHandler()) - return result +""" + contents.shouldContainOnlyOnce(expectedContents) } -} - """.trimIndent() + @Test + fun `Test that FlexibleChecksumsResponseMiddleware is properly generated`() { + val context = setupTests("flexible-checksums.smithy", "aws.flex.checks#ChecksumTests") + val contents = TestUtils.getFileContents(context.manifest, "/Example/ChecksumTestsClient.swift") + contents.shouldSyntacticSanityCheck() + val expectedContents = """ + operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.FlexibleChecksumsResponseMiddleware(validationMode: true)) +""" contents.shouldContainOnlyOnce(expectedContents) } private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext { - val context = - TestUtils.executeDirectedCodegen(smithyFile, serviceShapeId, RestJson1Trait.ID) - + val context = TestUtils.executeDirectedCodegen(smithyFile, serviceShapeId, RestJson1Trait.ID) val generator = AWSRestJson1ProtocolGenerator() generator.generateProtocolUnitTests(context.ctx) context.ctx.delegator.flushWriters()