From b70db6f8428fed2e13ef8820b822c3210c476384 Mon Sep 17 00:00:00 2001 From: mufumade Date: Sat, 13 Mar 2021 12:31:29 +0100 Subject: [PATCH 01/14] Changed the S3.Event object size field to an optional due to the missing field on a s3:ObjectRemoved:* event Added one additional test to check propper json decoding --- Sources/AWSLambdaEvents/S3.swift | 2 +- Tests/AWSLambdaEventsTests/S3Tests.swift | 75 +++++++++++++++++++++++- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/Sources/AWSLambdaEvents/S3.swift b/Sources/AWSLambdaEvents/S3.swift index 0e7add28..f3729fa6 100644 --- a/Sources/AWSLambdaEvents/S3.swift +++ b/Sources/AWSLambdaEvents/S3.swift @@ -69,7 +69,7 @@ public enum S3 { public struct Object: Codable { public let key: String - public let size: UInt64 + public let size: UInt64? // A S3 ObjectRemoved:* event does not contain the object size public let urlDecodedKey: String? public let versionId: String? public let eTag: String diff --git a/Tests/AWSLambdaEventsTests/S3Tests.swift b/Tests/AWSLambdaEventsTests/S3Tests.swift index f1655208..39127d96 100644 --- a/Tests/AWSLambdaEventsTests/S3Tests.swift +++ b/Tests/AWSLambdaEventsTests/S3Tests.swift @@ -16,7 +16,7 @@ import XCTest class S3Tests: XCTestCase { - static let eventBody = """ + static let eventBodyObjectCreated = """ { "Records": [ { @@ -56,9 +56,50 @@ class S3Tests: XCTestCase { ] } """ + + // A S3 ObjectRemoved:* event does not contain the object size + static let eventBodyObjectRemoved = """ + { + "Records": [ + { + "eventVersion":"2.1", + "eventSource":"aws:s3", + "awsRegion":"eu-central-1", + "eventTime":"2020-01-13T09:25:40.621Z", + "eventName":"ObjectRemoved:DeleteMarkerCreated", + "userIdentity":{ + "principalId":"AWS:AAAAAAAJ2MQ4YFQZ7AULJ" + }, + "requestParameters":{ + "sourceIPAddress":"123.123.123.123" + }, + "responseElements":{ + "x-amz-request-id":"01AFA1430E18C358", + "x-amz-id-2":"JsbNw6sHGFwgzguQjbYcew//bfAeZITyTYLfjuu1U4QYqCq5CPlSyYLtvWQS+gw0RxcroItGwm8=" + }, + "s3":{ + "s3SchemaVersion":"1.0", + "configurationId":"98b55bc4-3c0c-4007-b727-c6b77a259dde", + "bucket":{ + "name":"eventsources", + "ownerIdentity":{ + "principalId":"AAAAAAAAAAAAAA" + }, + "arn":"arn:aws:s3:::eventsources" + }, + "object":{ + "key":"Hi.md", + "eTag":"91a7f2c3ae81bcc6afef83979b463f0e", + "sequencer":"005E1C37948E783A6E" + } + } + } + ] + } + """ - func testSimpleEventFromJSON() { - let data = S3Tests.eventBody.data(using: .utf8)! + func testObjectCreatedEvent() { + let data = S3Tests.eventBodyObjectCreated.data(using: .utf8)! var event: S3.Event? XCTAssertNoThrow(event = try JSONDecoder().decode(S3.Event.self, from: data)) @@ -85,4 +126,32 @@ class S3Tests: XCTestCase { XCTAssertEqual(record.s3.object.eTag, "91a7f2c3ae81bcc6afef83979b463f0e") XCTAssertEqual(record.s3.object.sequencer, "005E1C37948E783A6E") } + + func testObjectRemovedEvent() { + let data = S3Tests.eventBodyObjectRemoved.data(using: .utf8)! + var event: S3.Event? + XCTAssertNoThrow(event = try JSONDecoder().decode(S3.Event.self, from: data)) + + guard let record = event?.records.first else { + XCTFail("Expected to have one record") + return + } + + XCTAssertEqual(record.eventVersion, "2.1") + XCTAssertEqual(record.eventSource, "aws:s3") + XCTAssertEqual(record.awsRegion, .eu_central_1) + XCTAssertEqual(record.eventName, "ObjectRemoved:DeleteMarkerCreated") + XCTAssertEqual(record.eventTime, Date(timeIntervalSince1970: 1_578_907_540.621)) + XCTAssertEqual(record.userIdentity, S3.UserIdentity(principalId: "AWS:AAAAAAAJ2MQ4YFQZ7AULJ")) + XCTAssertEqual(record.requestParameters, S3.RequestParameters(sourceIPAddress: "123.123.123.123")) + XCTAssertEqual(record.responseElements.count, 2) + XCTAssertEqual(record.s3.schemaVersion, "1.0") + XCTAssertEqual(record.s3.configurationId, "98b55bc4-3c0c-4007-b727-c6b77a259dde") + XCTAssertEqual(record.s3.bucket.name, "eventsources") + XCTAssertEqual(record.s3.bucket.ownerIdentity, S3.UserIdentity(principalId: "AAAAAAAAAAAAAA")) + XCTAssertEqual(record.s3.bucket.arn, "arn:aws:s3:::eventsources") + XCTAssertEqual(record.s3.object.key, "Hi.md") + XCTAssertEqual(record.s3.object.eTag, "91a7f2c3ae81bcc6afef83979b463f0e") + XCTAssertEqual(record.s3.object.sequencer, "005E1C37948E783A6E") + } } From db21f9bfe7f2ddb96728264cd51d0994ef32aee5 Mon Sep 17 00:00:00 2001 From: ML <44809298+mufumade@users.noreply.github.com> Date: Sat, 13 Mar 2021 15:25:59 +0100 Subject: [PATCH 02/14] Update Sources/AWSLambdaEvents/S3.swift Co-authored-by: Fabian Fett --- Sources/AWSLambdaEvents/S3.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sources/AWSLambdaEvents/S3.swift b/Sources/AWSLambdaEvents/S3.swift index f3729fa6..8fc4855a 100644 --- a/Sources/AWSLambdaEvents/S3.swift +++ b/Sources/AWSLambdaEvents/S3.swift @@ -69,7 +69,10 @@ public enum S3 { public struct Object: Codable { public let key: String - public let size: UInt64? // A S3 ObjectRemoved:* event does not contain the object size + /// The object's size in bytes. + /// + /// Note: This property is available for all event types except "ObjectRemoved:*" + public let size: UInt64? public let urlDecodedKey: String? public let versionId: String? public let eTag: String From 1198d0c25926760d00cb16c89564032c4f5af137 Mon Sep 17 00:00:00 2001 From: ML <44809298+mufumade@users.noreply.github.com> Date: Sat, 13 Mar 2021 15:26:09 +0100 Subject: [PATCH 03/14] Update Tests/AWSLambdaEventsTests/S3Tests.swift Co-authored-by: Fabian Fett --- Tests/AWSLambdaEventsTests/S3Tests.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/AWSLambdaEventsTests/S3Tests.swift b/Tests/AWSLambdaEventsTests/S3Tests.swift index 39127d96..58ea6622 100644 --- a/Tests/AWSLambdaEventsTests/S3Tests.swift +++ b/Tests/AWSLambdaEventsTests/S3Tests.swift @@ -151,6 +151,7 @@ class S3Tests: XCTestCase { XCTAssertEqual(record.s3.bucket.ownerIdentity, S3.UserIdentity(principalId: "AAAAAAAAAAAAAA")) XCTAssertEqual(record.s3.bucket.arn, "arn:aws:s3:::eventsources") XCTAssertEqual(record.s3.object.key, "Hi.md") + XCTAssertNil(record.s3.object.size) XCTAssertEqual(record.s3.object.eTag, "91a7f2c3ae81bcc6afef83979b463f0e") XCTAssertEqual(record.s3.object.sequencer, "005E1C37948E783A6E") } From 9704f7daa541843444474bd0b75d7b3ff90c33be Mon Sep 17 00:00:00 2001 From: mufumade Date: Sun, 14 Mar 2021 15:52:41 +0100 Subject: [PATCH 04/14] swiftformat changes --- .../Sources/CurrencyExchange/main.swift | 20 ++++++++------ Sources/AWSLambdaEvents/APIGateway+V2.swift | 12 ++++----- Sources/AWSLambdaEvents/APIGateway.swift | 4 +-- Sources/AWSLambdaEvents/DynamoDB.swift | 25 +++++++++-------- Sources/AWSLambdaEvents/Utils/Base64.swift | 3 ++- Sources/AWSLambdaEvents/Utils/HTTP.swift | 2 +- Sources/AWSLambdaRuntime/Lambda+Codable.swift | 18 ++++++------- .../Lambda+LocalServer.swift | 2 +- .../AWSLambdaRuntimeCore/Lambda+String.swift | 10 +++---- .../LambdaConfiguration.swift | 2 +- .../AWSLambdaRuntimeCore/LambdaContext.swift | 15 ++++++----- .../LambdaLifecycle.swift | 4 +-- .../AWSLambdaRuntimeCore/LambdaRunner.swift | 2 +- .../LambdaRuntimeClient.swift | 15 ++++++----- Sources/AWSLambdaRuntimeCore/Utils.swift | 2 +- Sources/AWSLambdaTesting/Lambda+Testing.swift | 27 ++++++++++--------- Tests/AWSLambdaEventsTests/S3Tests.swift | 4 +-- .../LambdaLifecycleTest.swift | 2 +- .../MockLambdaServer.swift | 4 +-- 19 files changed, 93 insertions(+), 80 deletions(-) diff --git a/Examples/LambdaFunctions/Sources/CurrencyExchange/main.swift b/Examples/LambdaFunctions/Sources/CurrencyExchange/main.swift index 22c30563..2815447f 100644 --- a/Examples/LambdaFunctions/Sources/CurrencyExchange/main.swift +++ b/Examples/LambdaFunctions/Sources/CurrencyExchange/main.swift @@ -104,7 +104,8 @@ struct ExchangeRatesCalculator { monthIndex: Array.Index, currencies: [String], state: [Date: ExchangeRates], - callback: @escaping ((Result<[Date: ExchangeRates], Swift.Error>) -> Void)) { + callback: @escaping ((Result<[Date: ExchangeRates], Swift.Error>) -> Void)) + { if monthIndex == months.count { return callback(.success(state)) } @@ -145,16 +146,18 @@ struct ExchangeRatesCalculator { dateFormatter.dateFormat = "dd/MMM/yy" let interval: DateInterval? if let period = try document.nodes(forXPath: "/exchangeRateMonthList/@Period").first?.stringValue, - period.count == 26 { + period.count == 26 + { // "01/Sep/2018 to 30/Sep/2018" let startString = period[period.startIndex ..< period.index(period.startIndex, offsetBy: 11)] let to = period[startString.endIndex ..< period.index(startString.endIndex, offsetBy: 4)] let endString = period[to.endIndex ..< period.index(to.endIndex, offsetBy: 11)] if let startDate = dateFormatter.date(from: String(startString)), - let startDay = calendar.dateInterval(of: .day, for: startDate), - to == " to ", - let endDate = dateFormatter.date(from: String(endString)), - let endDay = calendar.dateInterval(of: .day, for: endDate) { + let startDay = calendar.dateInterval(of: .day, for: startDate), + to == " to ", + let endDate = dateFormatter.date(from: String(endString)), + let endDay = calendar.dateInterval(of: .day, for: endDate) + { interval = DateInterval(start: startDay.start, end: endDay.end) } else { interval = nil @@ -166,8 +169,9 @@ struct ExchangeRatesCalculator { let ratesByCurrencyCode: [String: Decimal?] = Dictionary(uniqueKeysWithValues: try currencyCodes.map { let xpathCurrency = $0.replacingOccurrences(of: "'", with: "'") if let rateString = try document.nodes(forXPath: "/exchangeRateMonthList/exchangeRate/currencyCode[text()='\(xpathCurrency)']/../rateNew/text()").first?.stringValue, - // We must parse the decimal data using the UK locale, not the system one. - let rate = Decimal(string: rateString, locale: self.locale) { + // We must parse the decimal data using the UK locale, not the system one. + let rate = Decimal(string: rateString, locale: self.locale) + { return ($0, rate) } else { return ($0, nil) diff --git a/Sources/AWSLambdaEvents/APIGateway+V2.swift b/Sources/AWSLambdaEvents/APIGateway+V2.swift index 1f4f0e22..3667fcf8 100644 --- a/Sources/AWSLambdaEvents/APIGateway+V2.swift +++ b/Sources/AWSLambdaEvents/APIGateway+V2.swift @@ -12,13 +12,13 @@ // //===----------------------------------------------------------------------===// -extension APIGateway { - public struct V2 {} +public extension APIGateway { + struct V2 {} } -extension APIGateway.V2 { +public extension APIGateway.V2 { /// APIGateway.V2.Request contains data coming from the new HTTP API Gateway - public struct Request: Codable { + struct Request: Codable { /// Context contains the information to identify the AWS account and resources invoking the Lambda function. public struct Context: Codable { public struct HTTP: Codable { @@ -91,8 +91,8 @@ extension APIGateway.V2 { } } -extension APIGateway.V2 { - public struct Response: Codable { +public extension APIGateway.V2 { + struct Response: Codable { public var statusCode: HTTPResponseStatus public var headers: HTTPHeaders? public var body: String? diff --git a/Sources/AWSLambdaEvents/APIGateway.swift b/Sources/AWSLambdaEvents/APIGateway.swift index a944cef2..5af53de5 100644 --- a/Sources/AWSLambdaEvents/APIGateway.swift +++ b/Sources/AWSLambdaEvents/APIGateway.swift @@ -68,8 +68,8 @@ public enum APIGateway { // MARK: - Response - -extension APIGateway { - public struct Response: Codable { +public extension APIGateway { + struct Response: Codable { public var statusCode: HTTPResponseStatus public var headers: HTTPHeaders? public var multiValueHeaders: HTTPMultiValueHeaders? diff --git a/Sources/AWSLambdaEvents/DynamoDB.swift b/Sources/AWSLambdaEvents/DynamoDB.swift index ebc9f645..a12e6cc3 100644 --- a/Sources/AWSLambdaEvents/DynamoDB.swift +++ b/Sources/AWSLambdaEvents/DynamoDB.swift @@ -15,7 +15,7 @@ import struct Foundation.Date // https://docs.aws.amazon.com/lambda/latest/dg/with-ddb.html -public struct DynamoDB { +public enum DynamoDB { public struct Event: Decodable { public let records: [EventRecord] @@ -188,8 +188,8 @@ extension DynamoDB.StreamRecord: Decodable { // MARK: - AttributeValue - -extension DynamoDB { - public enum AttributeValue { +public extension DynamoDB { + enum AttributeValue { case boolean(Bool) case binary([UInt8]) case binarySet([[UInt8]]) @@ -341,7 +341,8 @@ extension DynamoDB { } @usableFromInline func container(keyedBy type: Key.Type) throws -> - KeyedDecodingContainer where Key: CodingKey { + KeyedDecodingContainer where Key: CodingKey + { guard case .map(let dictionary) = self.value else { throw DecodingError.typeMismatch([String: AttributeValue].self, DecodingError.Context( codingPath: self.codingPath, @@ -510,8 +511,9 @@ extension DynamoDB { } func nestedContainer(keyedBy type: NestedKey.Type, forKey key: K) throws - -> KeyedDecodingContainer where NestedKey: CodingKey { - return try self.decoderForKey(key).container(keyedBy: type) + -> KeyedDecodingContainer where NestedKey: CodingKey + { + try self.decoderForKey(key).container(keyedBy: type) } func nestedUnkeyedContainer(forKey key: K) throws -> UnkeyedDecodingContainer { @@ -677,7 +679,7 @@ extension DynamoDB { } func decode(_: T.Type) throws -> T where T: Decodable { - return try T(from: self.impl) + try T(from: self.impl) } @inline(__always) private func createTypeMismatchError(type: Any.Type, value: AttributeValue) -> DecodingError { @@ -849,8 +851,9 @@ extension DynamoDB { } mutating func nestedContainer(keyedBy type: NestedKey.Type) throws - -> KeyedDecodingContainer where NestedKey: CodingKey { - return try self.impl.container(keyedBy: type) + -> KeyedDecodingContainer where NestedKey: CodingKey + { + try self.impl.container(keyedBy: type) } mutating func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { @@ -914,8 +917,8 @@ extension DynamoDB { } } -extension DynamoDB.AttributeValue { - fileprivate var debugDataTypeDescription: String { +private extension DynamoDB.AttributeValue { + var debugDataTypeDescription: String { switch self { case .list: return "a list" diff --git a/Sources/AWSLambdaEvents/Utils/Base64.swift b/Sources/AWSLambdaEvents/Utils/Base64.swift index 310a6aa5..04cbb5c3 100644 --- a/Sources/AWSLambdaEvents/Utils/Base64.swift +++ b/Sources/AWSLambdaEvents/Utils/Base64.swift @@ -37,7 +37,8 @@ extension Base64 { @inlinable static func decode(encoded: Buffer, options: DecodingOptions = []) - throws -> [UInt8] where Buffer.Element == UInt8 { + throws -> [UInt8] where Buffer.Element == UInt8 + { let alphabet = options.contains(.base64UrlAlphabet) ? Base64.decodeBase64Url : Base64.decodeBase64 diff --git a/Sources/AWSLambdaEvents/Utils/HTTP.swift b/Sources/AWSLambdaEvents/Utils/HTTP.swift index 9e0d8f2d..2ca7357b 100644 --- a/Sources/AWSLambdaEvents/Utils/HTTP.swift +++ b/Sources/AWSLambdaEvents/Utils/HTTP.swift @@ -157,7 +157,7 @@ extension HTTPResponseStatus: Codable { } extension String { - internal var isValidHTTPToken: Bool { + var isValidHTTPToken: Bool { self.utf8.allSatisfy { (char) -> Bool in switch char { case UInt8(ascii: "a") ... UInt8(ascii: "z"), diff --git a/Sources/AWSLambdaRuntime/Lambda+Codable.swift b/Sources/AWSLambdaRuntime/Lambda+Codable.swift index 495e5a69..b007fdc2 100644 --- a/Sources/AWSLambdaRuntime/Lambda+Codable.swift +++ b/Sources/AWSLambdaRuntime/Lambda+Codable.swift @@ -20,9 +20,9 @@ import NIO import NIOFoundationCompat /// Extension to the `Lambda` companion to enable execution of Lambdas that take and return `Codable` events. -extension Lambda { +public extension Lambda { /// An asynchronous Lambda Closure that takes a `In: Decodable` and returns a `Result` via a completion handler. - public typealias CodableClosure = (Lambda.Context, In, @escaping (Result) -> Void) -> Void + typealias CodableClosure = (Lambda.Context, In, @escaping (Result) -> Void) -> Void /// Run a Lambda defined by implementing the `CodableClosure` function. /// @@ -30,12 +30,12 @@ extension Lambda { /// - closure: `CodableClosure` based Lambda. /// /// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine. - public static func run(_ closure: @escaping CodableClosure) { + static func run(_ closure: @escaping CodableClosure) { self.run(CodableClosureWrapper(closure)) } /// An asynchronous Lambda Closure that takes a `In: Decodable` and returns a `Result` via a completion handler. - public typealias CodableVoidClosure = (Lambda.Context, In, @escaping (Result) -> Void) -> Void + typealias CodableVoidClosure = (Lambda.Context, In, @escaping (Result) -> Void) -> Void /// Run a Lambda defined by implementing the `CodableVoidClosure` function. /// @@ -43,7 +43,7 @@ extension Lambda { /// - closure: `CodableVoidClosure` based Lambda. /// /// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine. - public static func run(_ closure: @escaping CodableVoidClosure) { + static func run(_ closure: @escaping CodableVoidClosure) { self.run(CodableVoidClosureWrapper(closure)) } } @@ -132,16 +132,16 @@ extension JSONEncoder: LambdaCodableEncoder { } } -extension JSONEncoder { +public extension JSONEncoder { /// Convenience method to allow encoding json directly into a `String`. It can be used to encode a payload into an `APIGateway.V2.Response`'s body. - public func encodeAsString(_ value: T) throws -> String { + func encodeAsString(_ value: T) throws -> String { try String(decoding: self.encode(value), as: Unicode.UTF8.self) } } -extension JSONDecoder { +public extension JSONDecoder { /// Convenience method to allow decoding json directly from a `String`. It can be used to decode a payload from an `APIGateway.V2.Request`'s body. - public func decode(_ type: T.Type, from string: String) throws -> T { + func decode(_ type: T.Type, from string: String) throws -> T { try self.decode(type, from: Data(string.utf8)) } } diff --git a/Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift b/Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift index 48cea94e..9f77a278 100644 --- a/Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift +++ b/Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift @@ -35,7 +35,7 @@ extension Lambda { /// - body: Code to run within the context of the mock server. Typically this would be a Lambda.run function call. /// /// - note: This API is designed stricly for local testing and is behind a DEBUG flag - internal static func withLocalServer(invocationEndpoint: String? = nil, _ body: @escaping () -> Value) throws -> Value { + static func withLocalServer(invocationEndpoint: String? = nil, _ body: @escaping () -> Value) throws -> Value { let server = LocalLambda.Server(invocationEndpoint: invocationEndpoint) try server.start().wait() defer { try! server.stop() } diff --git a/Sources/AWSLambdaRuntimeCore/Lambda+String.swift b/Sources/AWSLambdaRuntimeCore/Lambda+String.swift index 9d37356a..cfbe9efd 100644 --- a/Sources/AWSLambdaRuntimeCore/Lambda+String.swift +++ b/Sources/AWSLambdaRuntimeCore/Lambda+String.swift @@ -14,9 +14,9 @@ import NIO /// Extension to the `Lambda` companion to enable execution of Lambdas that take and return `String` events. -extension Lambda { +public extension Lambda { /// An asynchronous Lambda Closure that takes a `String` and returns a `Result` via a completion handler. - public typealias StringClosure = (Lambda.Context, String, @escaping (Result) -> Void) -> Void + typealias StringClosure = (Lambda.Context, String, @escaping (Result) -> Void) -> Void /// Run a Lambda defined by implementing the `StringClosure` function. /// @@ -24,14 +24,14 @@ extension Lambda { /// - closure: `StringClosure` based Lambda. /// /// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine. - public static func run(_ closure: @escaping StringClosure) { + static func run(_ closure: @escaping StringClosure) { if case .failure(let error) = self.run(closure: closure) { fatalError("\(error)") } } /// An asynchronous Lambda Closure that takes a `String` and returns a `Result` via a completion handler. - public typealias StringVoidClosure = (Lambda.Context, String, @escaping (Result) -> Void) -> Void + typealias StringVoidClosure = (Lambda.Context, String, @escaping (Result) -> Void) -> Void /// Run a Lambda defined by implementing the `StringVoidClosure` function. /// @@ -39,7 +39,7 @@ extension Lambda { /// - closure: `StringVoidClosure` based Lambda. /// /// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine. - public static func run(_ closure: @escaping StringVoidClosure) { + static func run(_ closure: @escaping StringVoidClosure) { if case .failure(let error) = self.run(closure: closure) { fatalError("\(error)") } diff --git a/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift b/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift index 9b9ec8fb..20b6986e 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift @@ -17,7 +17,7 @@ import Logging import NIO extension Lambda { - internal struct Configuration: CustomStringConvertible { + struct Configuration: CustomStringConvertible { let general: General let lifecycle: Lifecycle let runtimeEngine: RuntimeEngine diff --git a/Sources/AWSLambdaRuntimeCore/LambdaContext.swift b/Sources/AWSLambdaRuntimeCore/LambdaContext.swift index ab30dd7b..39475188 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaContext.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaContext.swift @@ -18,10 +18,10 @@ import NIO // MARK: - InitializationContext -extension Lambda { +public extension Lambda { /// Lambda runtime initialization context. /// The Lambda runtime generates and passes the `InitializationContext` to the Lambda factory as an argument. - public final class InitializationContext { + final class InitializationContext { /// `Logger` to log with /// /// - note: The `LogLevel` can be configured using the `LOG_LEVEL` environment variable. @@ -46,10 +46,10 @@ extension Lambda { // MARK: - Context -extension Lambda { +public extension Lambda { /// Lambda runtime context. /// The Lambda runtime generates and passes the `Context` to the Lambda handler as an argument. - public final class Context: CustomDebugStringConvertible { + final class Context: CustomDebugStringConvertible { /// The request ID, which identifies the request that triggered the function invocation. public let requestID: String @@ -92,7 +92,8 @@ extension Lambda { clientContext: String? = nil, logger: Logger, eventLoop: EventLoop, - allocator: ByteBufferAllocator) { + allocator: ByteBufferAllocator) + { self.requestID = requestID self.traceID = traceID self.invokedFunctionARN = invokedFunctionARN @@ -125,10 +126,10 @@ extension Lambda { // MARK: - ShutdownContext -extension Lambda { +public extension Lambda { /// Lambda runtime shutdown context. /// The Lambda runtime generates and passes the `ShutdownContext` to the Lambda handler as an argument. - public final class ShutdownContext { + final class ShutdownContext { /// `Logger` to log with /// /// - note: The `LogLevel` can be configured using the `LOG_LEVEL` environment variable. diff --git a/Sources/AWSLambdaRuntimeCore/LambdaLifecycle.swift b/Sources/AWSLambdaRuntimeCore/LambdaLifecycle.swift index ec609901..422505b7 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaLifecycle.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaLifecycle.swift @@ -16,11 +16,11 @@ import Logging import NIO import NIOConcurrencyHelpers -extension Lambda { +public extension Lambda { /// `Lifecycle` manages the Lambda process lifecycle. /// /// - note: It is intended to be used within a single `EventLoop`. For this reason this class is not thread safe. - public final class Lifecycle { + final class Lifecycle { private let eventLoop: EventLoop private let shutdownPromise: EventLoopPromise private let logger: Logger diff --git a/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift b/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift index 96bae6ed..0ffe0d4f 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift @@ -18,7 +18,7 @@ import NIO extension Lambda { /// LambdaRunner manages the Lambda runtime workflow, or business logic. - internal final class Runner { + final class Runner { private let runtimeClient: RuntimeClient private let eventLoop: EventLoop private let allocator: ByteBufferAllocator diff --git a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift index 5e9e6aea..591978bc 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift @@ -22,7 +22,7 @@ import NIOHTTP1 /// * /runtime/invocation/error /// * /runtime/init/error extension Lambda { - internal struct RuntimeClient { + struct RuntimeClient { private let eventLoop: EventLoop private let allocator = ByteBufferAllocator() private let httpClient: HTTPClient @@ -146,9 +146,9 @@ internal extension ErrorResponse { func toJSONBytes() -> [UInt8] { var bytes = [UInt8]() bytes.append(UInt8(ascii: "{")) - bytes.append(contentsOf: #""errorType":"# .utf8) + bytes.append(contentsOf: #""errorType":"#.utf8) self.errorType.encodeAsJSONString(into: &bytes) - bytes.append(contentsOf: #","errorMessage":"# .utf8) + bytes.append(contentsOf: #","errorMessage":"#.utf8) self.errorMessage.encodeAsJSONString(into: &bytes) bytes.append(UInt8(ascii: "}")) return bytes @@ -156,7 +156,7 @@ internal extension ErrorResponse { } extension Lambda { - internal struct Invocation { + struct Invocation { let requestID: String let deadlineInMillisSinceEpoch: Int64 let invokedFunctionARN: String @@ -170,7 +170,8 @@ extension Lambda { } guard let deadline = headers.first(name: AmazonHeaders.deadline), - let unixTimeInMilliseconds = Int64(deadline) else { + let unixTimeInMilliseconds = Int64(deadline) + else { throw RuntimeError.invocationMissingHeader(AmazonHeaders.deadline) } @@ -193,10 +194,10 @@ extension Lambda { } extension Lambda.RuntimeClient { - internal static let defaultHeaders = HTTPHeaders([("user-agent", "Swift-Lambda/Unknown")]) + static let defaultHeaders = HTTPHeaders([("user-agent", "Swift-Lambda/Unknown")]) /// These headers must be sent along an invocation or initialization error report - internal static let errorHeaders = HTTPHeaders([ + static let errorHeaders = HTTPHeaders([ ("user-agent", "Swift-Lambda/Unknown"), ("lambda-runtime-function-error-type", "Unhandled"), ]) diff --git a/Sources/AWSLambdaRuntimeCore/Utils.swift b/Sources/AWSLambdaRuntimeCore/Utils.swift index 5e7ffa6e..fbf03487 100644 --- a/Sources/AWSLambdaRuntimeCore/Utils.swift +++ b/Sources/AWSLambdaRuntimeCore/Utils.swift @@ -117,7 +117,7 @@ extension AmazonHeaders { /// # References /// - [Generating trace IDs](https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html#xray-api-traceids) /// - [Tracing header](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader) - internal static func generateXRayTraceID() -> String { + static func generateXRayTraceID() -> String { // The version number, that is, 1. let version: UInt = 1 // The time of the original request, in Unix epoch time, in 8 hexadecimal digits. diff --git a/Sources/AWSLambdaTesting/Lambda+Testing.swift b/Sources/AWSLambdaTesting/Lambda+Testing.swift index 981ca736..9040eca4 100644 --- a/Sources/AWSLambdaTesting/Lambda+Testing.swift +++ b/Sources/AWSLambdaTesting/Lambda+Testing.swift @@ -40,8 +40,8 @@ import Dispatch import Logging import NIO -extension Lambda { - public struct TestConfig { +public extension Lambda { + struct TestConfig { public var requestID: String public var traceID: String public var invokedFunctionARN: String @@ -50,7 +50,8 @@ extension Lambda { public init(requestID: String = "\(DispatchTime.now().uptimeNanoseconds)", traceID: String = "Root=\(DispatchTime.now().uptimeNanoseconds);Parent=\(DispatchTime.now().uptimeNanoseconds);Sampled=1", invokedFunctionARN: String = "arn:aws:lambda:us-west-1:\(DispatchTime.now().uptimeNanoseconds):function:custom-runtime", - timeout: DispatchTimeInterval = .seconds(5)) { + timeout: DispatchTimeInterval = .seconds(5)) + { self.requestID = requestID self.traceID = traceID self.invokedFunctionARN = invokedFunctionARN @@ -58,19 +59,21 @@ extension Lambda { } } - public static func test(_ closure: @escaping Lambda.StringClosure, - with event: String, - using config: TestConfig = .init()) throws -> String { + static func test(_ closure: @escaping Lambda.StringClosure, + with event: String, + using config: TestConfig = .init()) throws -> String + { try Self.test(StringClosureWrapper(closure), with: event, using: config) } - public static func test(_ closure: @escaping Lambda.StringVoidClosure, - with event: String, - using config: TestConfig = .init()) throws { + static func test(_ closure: @escaping Lambda.StringVoidClosure, + with event: String, + using config: TestConfig = .init()) throws + { _ = try Self.test(StringVoidClosureWrapper(closure), with: event, using: config) } - public static func test( + static func test( _ closure: @escaping Lambda.CodableClosure, with event: In, using config: TestConfig = .init() @@ -78,7 +81,7 @@ extension Lambda { try Self.test(CodableClosureWrapper(closure), with: event, using: config) } - public static func test( + static func test( _ closure: @escaping Lambda.CodableVoidClosure, with event: In, using config: TestConfig = .init() @@ -86,7 +89,7 @@ extension Lambda { _ = try Self.test(CodableVoidClosureWrapper(closure), with: event, using: config) } - public static func test( + static func test( _ handler: Handler, with event: In, using config: TestConfig = .init() diff --git a/Tests/AWSLambdaEventsTests/S3Tests.swift b/Tests/AWSLambdaEventsTests/S3Tests.swift index 39127d96..fd07c4a9 100644 --- a/Tests/AWSLambdaEventsTests/S3Tests.swift +++ b/Tests/AWSLambdaEventsTests/S3Tests.swift @@ -56,7 +56,7 @@ class S3Tests: XCTestCase { ] } """ - + // A S3 ObjectRemoved:* event does not contain the object size static let eventBodyObjectRemoved = """ { @@ -126,7 +126,7 @@ class S3Tests: XCTestCase { XCTAssertEqual(record.s3.object.eTag, "91a7f2c3ae81bcc6afef83979b463f0e") XCTAssertEqual(record.s3.object.sequencer, "005E1C37948E783A6E") } - + func testObjectRemovedEvent() { let data = S3Tests.eventBodyObjectRemoved.data(using: .utf8)! var event: S3.Event? diff --git a/Tests/AWSLambdaRuntimeCoreTests/LambdaLifecycleTest.swift b/Tests/AWSLambdaRuntimeCoreTests/LambdaLifecycleTest.swift index a485530d..14e32235 100644 --- a/Tests/AWSLambdaRuntimeCoreTests/LambdaLifecycleTest.swift +++ b/Tests/AWSLambdaRuntimeCoreTests/LambdaLifecycleTest.swift @@ -72,7 +72,7 @@ class LambdaLifecycleTest: XCTestCase { var count = 0 let handler = CallbackLambdaHandler({ XCTFail("Should not be reached"); return $0.eventLoop.makeSucceededFuture($1) }) { context in count += 1 - return context.eventLoop.makeSucceededFuture(Void()) + return context.eventLoop.makeSucceededFuture(()) } let eventLoop = eventLoopGroup.next() diff --git a/Tests/AWSLambdaRuntimeCoreTests/MockLambdaServer.swift b/Tests/AWSLambdaRuntimeCoreTests/MockLambdaServer.swift index 9708ccc1..14ddcdd6 100644 --- a/Tests/AWSLambdaRuntimeCoreTests/MockLambdaServer.swift +++ b/Tests/AWSLambdaRuntimeCoreTests/MockLambdaServer.swift @@ -162,8 +162,8 @@ internal final class HTTPHandler: ChannelInboundHandler { } } else if request.head.uri.hasSuffix(Consts.postErrorURLSuffix) { guard let requestId = request.head.uri.split(separator: "/").dropFirst(3).first, - let json = requestBody, - let error = ErrorResponse.fromJson(json) + let json = requestBody, + let error = ErrorResponse.fromJson(json) else { return self.writeResponse(context: context, status: .badRequest) } From 0da8bc4074bad0e16fefb9a5a7625f5a494dbd8d Mon Sep 17 00:00:00 2001 From: mufumade Date: Sun, 14 Mar 2021 16:10:53 +0100 Subject: [PATCH 05/14] swiftformat changes --- Sources/AWSLambdaEvents/S3.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AWSLambdaEvents/S3.swift b/Sources/AWSLambdaEvents/S3.swift index 8fc4855a..d90de568 100644 --- a/Sources/AWSLambdaEvents/S3.swift +++ b/Sources/AWSLambdaEvents/S3.swift @@ -69,7 +69,7 @@ public enum S3 { public struct Object: Codable { public let key: String - /// The object's size in bytes. + /// The object's size in bytes. /// /// Note: This property is available for all event types except "ObjectRemoved:*" public let size: UInt64? From 2c7e127c866a567ab317656eda4abdff9233d124 Mon Sep 17 00:00:00 2001 From: ML <44809298+mufumade@users.noreply.github.com> Date: Thu, 15 Apr 2021 12:43:30 +0200 Subject: [PATCH 06/14] Update Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift Co-authored-by: Fabian Fett --- Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift index c32ce396..05451b83 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift @@ -197,7 +197,7 @@ extension Lambda.RuntimeClient { static let defaultHeaders = HTTPHeaders([("user-agent", "Swift-Lambda/Unknown")]) /// These headers must be sent along an invocation or initialization error report - static let errorHeaders = HTTPHeaders([ + internal static let errorHeaders = HTTPHeaders([ ("user-agent", "Swift-Lambda/Unknown"), ("lambda-runtime-function-error-type", "Unhandled"), ]) From 3e2d491a6d74b434d85cfa8f72a2c32e9e0790c3 Mon Sep 17 00:00:00 2001 From: ML <44809298+mufumade@users.noreply.github.com> Date: Thu, 15 Apr 2021 12:43:51 +0200 Subject: [PATCH 07/14] Update Sources/AWSLambdaRuntimeCore/Utils.swift Co-authored-by: Fabian Fett --- Sources/AWSLambdaRuntimeCore/Utils.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AWSLambdaRuntimeCore/Utils.swift b/Sources/AWSLambdaRuntimeCore/Utils.swift index 97243f5d..8d2132cb 100644 --- a/Sources/AWSLambdaRuntimeCore/Utils.swift +++ b/Sources/AWSLambdaRuntimeCore/Utils.swift @@ -117,7 +117,7 @@ extension AmazonHeaders { /// # References /// - [Generating trace IDs](https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html#xray-api-traceids) /// - [Tracing header](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader) - static func generateXRayTraceID() -> String { + internal static func generateXRayTraceID() -> String { // The version number, that is, 1. let version: UInt = 1 // The time of the original request, in Unix epoch time, in 8 hexadecimal digits. From 37b431f61289796544e26d372fea5a28226da780 Mon Sep 17 00:00:00 2001 From: ML <44809298+mufumade@users.noreply.github.com> Date: Thu, 15 Apr 2021 12:44:04 +0200 Subject: [PATCH 08/14] Update Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift Co-authored-by: Fabian Fett --- Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift index 05451b83..f50d1e48 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift @@ -156,7 +156,7 @@ extension ErrorResponse { } extension Lambda { - struct Invocation { + internal struct Invocation { let requestID: String let deadlineInMillisSinceEpoch: Int64 let invokedFunctionARN: String From 9d82c82329dcd448960c8f5aa4ec6fe656b0cf42 Mon Sep 17 00:00:00 2001 From: ML <44809298+mufumade@users.noreply.github.com> Date: Thu, 15 Apr 2021 12:44:14 +0200 Subject: [PATCH 09/14] Update Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift Co-authored-by: Fabian Fett --- Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift index f50d1e48..3d75cb6b 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift @@ -194,7 +194,7 @@ extension Lambda { } extension Lambda.RuntimeClient { - static let defaultHeaders = HTTPHeaders([("user-agent", "Swift-Lambda/Unknown")]) + internal static let defaultHeaders = HTTPHeaders([("user-agent", "Swift-Lambda/Unknown")]) /// These headers must be sent along an invocation or initialization error report internal static let errorHeaders = HTTPHeaders([ From 43882f67e01c917a17b3924af7cdc146ff65fa05 Mon Sep 17 00:00:00 2001 From: ML <44809298+mufumade@users.noreply.github.com> Date: Thu, 15 Apr 2021 12:44:21 +0200 Subject: [PATCH 10/14] Update Sources/AWSLambdaRuntimeCore/LambdaRunner.swift Co-authored-by: Fabian Fett --- Sources/AWSLambdaRuntimeCore/LambdaRunner.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift b/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift index 95967676..ec5e9898 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift @@ -18,7 +18,7 @@ import NIO extension Lambda { /// LambdaRunner manages the Lambda runtime workflow, or business logic. - final class Runner { + internal final class Runner { private let runtimeClient: RuntimeClient private let eventLoop: EventLoop private let allocator: ByteBufferAllocator From 0458ef51ba0177bf178e50d38040bdf15b15eedf Mon Sep 17 00:00:00 2001 From: ML <44809298+mufumade@users.noreply.github.com> Date: Thu, 15 Apr 2021 12:44:29 +0200 Subject: [PATCH 11/14] Update Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift Co-authored-by: Fabian Fett --- Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift b/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift index 20b6986e..9b9ec8fb 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift @@ -17,7 +17,7 @@ import Logging import NIO extension Lambda { - struct Configuration: CustomStringConvertible { + internal struct Configuration: CustomStringConvertible { let general: General let lifecycle: Lifecycle let runtimeEngine: RuntimeEngine From 528a2a07d422e7bfe60d7234a7d3800f53509031 Mon Sep 17 00:00:00 2001 From: ML <44809298+mufumade@users.noreply.github.com> Date: Thu, 15 Apr 2021 12:44:36 +0200 Subject: [PATCH 12/14] Update Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift Co-authored-by: Fabian Fett --- Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift b/Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift index 9f77a278..48cea94e 100644 --- a/Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift +++ b/Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift @@ -35,7 +35,7 @@ extension Lambda { /// - body: Code to run within the context of the mock server. Typically this would be a Lambda.run function call. /// /// - note: This API is designed stricly for local testing and is behind a DEBUG flag - static func withLocalServer(invocationEndpoint: String? = nil, _ body: @escaping () -> Value) throws -> Value { + internal static func withLocalServer(invocationEndpoint: String? = nil, _ body: @escaping () -> Value) throws -> Value { let server = LocalLambda.Server(invocationEndpoint: invocationEndpoint) try server.start().wait() defer { try! server.stop() } From 05333230eacbbfa5b536ae6646a3bd445e769842 Mon Sep 17 00:00:00 2001 From: ML <44809298+mufumade@users.noreply.github.com> Date: Thu, 15 Apr 2021 12:44:43 +0200 Subject: [PATCH 13/14] Update Sources/AWSLambdaEvents/Utils/HTTP.swift Co-authored-by: Fabian Fett --- Sources/AWSLambdaEvents/Utils/HTTP.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AWSLambdaEvents/Utils/HTTP.swift b/Sources/AWSLambdaEvents/Utils/HTTP.swift index 2ca7357b..9e0d8f2d 100644 --- a/Sources/AWSLambdaEvents/Utils/HTTP.swift +++ b/Sources/AWSLambdaEvents/Utils/HTTP.swift @@ -157,7 +157,7 @@ extension HTTPResponseStatus: Codable { } extension String { - var isValidHTTPToken: Bool { + internal var isValidHTTPToken: Bool { self.utf8.allSatisfy { (char) -> Bool in switch char { case UInt8(ascii: "a") ... UInt8(ascii: "z"), From 0a676c273146da992e81d6dfa7901d1d51a9e0fa Mon Sep 17 00:00:00 2001 From: Fabian Fett Date: Thu, 15 Apr 2021 18:49:17 +0200 Subject: [PATCH 14/14] Update Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift --- Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift index 3d75cb6b..9b9546c4 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift @@ -22,7 +22,7 @@ import NIOHTTP1 /// * /runtime/invocation/error /// * /runtime/init/error extension Lambda { - struct RuntimeClient { + internal struct RuntimeClient { private let eventLoop: EventLoop private let allocator = ByteBufferAllocator() private let httpClient: HTTPClient