diff --git a/Sources/AWSLambdaRuntimeCore/ControlPlaneRequest.swift b/Sources/AWSLambdaRuntimeCore/ControlPlaneRequest.swift new file mode 100644 index 00000000..48da5237 --- /dev/null +++ b/Sources/AWSLambdaRuntimeCore/ControlPlaneRequest.swift @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftAWSLambdaRuntime open source project +// +// Copyright (c) 2017-2021 Apple Inc. and the SwiftAWSLambdaRuntime project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import NIOCore +import NIOHTTP1 + +enum ControlPlaneRequest: Hashable { + case next + case invocationResponse(String, ByteBuffer?) + case invocationError(String, ErrorResponse) + case initializationError(ErrorResponse) +} + +enum ControlPlaneResponse: Hashable { + case next(Invocation, ByteBuffer) + case accepted + case error(ErrorResponse) +} + +struct Invocation: Hashable { + let requestID: String + let deadlineInMillisSinceEpoch: Int64 + let invokedFunctionARN: String + let traceID: String + let clientContext: String? + let cognitoIdentity: String? + + init(headers: HTTPHeaders) throws { + guard let requestID = headers.first(name: AmazonHeaders.requestID), !requestID.isEmpty else { + throw Lambda.RuntimeError.invocationMissingHeader(AmazonHeaders.requestID) + } + + guard let deadline = headers.first(name: AmazonHeaders.deadline), + let unixTimeInMilliseconds = Int64(deadline) + else { + throw Lambda.RuntimeError.invocationMissingHeader(AmazonHeaders.deadline) + } + + guard let invokedFunctionARN = headers.first(name: AmazonHeaders.invokedFunctionARN) else { + throw Lambda.RuntimeError.invocationMissingHeader(AmazonHeaders.invokedFunctionARN) + } + + guard let traceID = headers.first(name: AmazonHeaders.traceID) else { + throw Lambda.RuntimeError.invocationMissingHeader(AmazonHeaders.traceID) + } + + self.requestID = requestID + self.deadlineInMillisSinceEpoch = unixTimeInMilliseconds + self.invokedFunctionARN = invokedFunctionARN + self.traceID = traceID + self.clientContext = headers["Lambda-Runtime-Client-Context"].first + self.cognitoIdentity = headers["Lambda-Runtime-Cognito-Identity"].first + } +} + +struct ErrorResponse: Hashable, Codable { + var errorType: String + var errorMessage: String +} + +extension ErrorResponse { + internal func toJSONBytes() -> [UInt8] { + var bytes = [UInt8]() + bytes.append(UInt8(ascii: "{")) + bytes.append(contentsOf: #""errorType":"#.utf8) + self.errorType.encodeAsJSONString(into: &bytes) + bytes.append(contentsOf: #","errorMessage":"#.utf8) + self.errorMessage.encodeAsJSONString(into: &bytes) + bytes.append(UInt8(ascii: "}")) + return bytes + } +} diff --git a/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift b/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift index 8497bf44..c2404b4b 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRunner.swift @@ -103,7 +103,7 @@ extension Lambda { } extension LambdaContext { - init(logger: Logger, eventLoop: EventLoop, allocator: ByteBufferAllocator, invocation: Lambda.Invocation) { + init(logger: Logger, eventLoop: EventLoop, allocator: ByteBufferAllocator, invocation: Invocation) { self.init(requestID: invocation.requestID, traceID: invocation.traceID, invokedFunctionARN: invocation.invokedFunctionARN, diff --git a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift index f60925d6..7303ef1c 100644 --- a/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift +++ b/Sources/AWSLambdaRuntimeCore/LambdaRuntimeClient.swift @@ -137,62 +137,6 @@ extension Lambda { } } -internal struct ErrorResponse: Codable { - var errorType: String - var errorMessage: String -} - -extension ErrorResponse { - internal func toJSONBytes() -> [UInt8] { - var bytes = [UInt8]() - bytes.append(UInt8(ascii: "{")) - bytes.append(contentsOf: #""errorType":"#.utf8) - self.errorType.encodeAsJSONString(into: &bytes) - bytes.append(contentsOf: #","errorMessage":"#.utf8) - self.errorMessage.encodeAsJSONString(into: &bytes) - bytes.append(UInt8(ascii: "}")) - return bytes - } -} - -extension Lambda { - internal struct Invocation { - let requestID: String - let deadlineInMillisSinceEpoch: Int64 - let invokedFunctionARN: String - let traceID: String - let clientContext: String? - let cognitoIdentity: String? - - init(headers: HTTPHeaders) throws { - guard let requestID = headers.first(name: AmazonHeaders.requestID), !requestID.isEmpty else { - throw RuntimeError.invocationMissingHeader(AmazonHeaders.requestID) - } - - guard let deadline = headers.first(name: AmazonHeaders.deadline), - let unixTimeInMilliseconds = Int64(deadline) - else { - throw RuntimeError.invocationMissingHeader(AmazonHeaders.deadline) - } - - guard let invokedFunctionARN = headers.first(name: AmazonHeaders.invokedFunctionARN) else { - throw RuntimeError.invocationMissingHeader(AmazonHeaders.invokedFunctionARN) - } - - guard let traceID = headers.first(name: AmazonHeaders.traceID) else { - throw RuntimeError.invocationMissingHeader(AmazonHeaders.traceID) - } - - self.requestID = requestID - self.deadlineInMillisSinceEpoch = unixTimeInMilliseconds - self.invokedFunctionARN = invokedFunctionARN - self.traceID = traceID - self.clientContext = headers["Lambda-Runtime-Client-Context"].first - self.cognitoIdentity = headers["Lambda-Runtime-Cognito-Identity"].first - } - } -} - extension Lambda.RuntimeClient { internal static let defaultHeaders = HTTPHeaders([("user-agent", "Swift-Lambda/Unknown")]) diff --git a/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTest.swift b/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTest.swift index 76bab980..551cc014 100644 --- a/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTest.swift +++ b/Tests/AWSLambdaRuntimeCoreTests/LambdaRuntimeClientTest.swift @@ -260,8 +260,8 @@ class LambdaRuntimeClientTest: XCTestCase { (AmazonHeaders.invokedFunctionARN, "arn:aws:lambda:us-east-1:123456789012:function:custom-runtime"), (AmazonHeaders.traceID, "Root=\(AmazonHeaders.generateXRayTraceID());Sampled=1"), ]) - var inv: Lambda.Invocation? - XCTAssertNoThrow(inv = try Lambda.Invocation(headers: header)) + var inv: Invocation? + XCTAssertNoThrow(inv = try Invocation(headers: header)) guard let invocation = inv else { return } let result = client.reportResults(logger: logger, invocation: invocation, result: Result.failure(TestError("boom"))) @@ -300,8 +300,8 @@ class LambdaRuntimeClientTest: XCTestCase { (AmazonHeaders.invokedFunctionARN, "arn:aws:lambda:us-east-1:123456789012:function:custom-runtime"), (AmazonHeaders.traceID, "Root=\(AmazonHeaders.generateXRayTraceID());Sampled=1"), ]) - var inv: Lambda.Invocation? - XCTAssertNoThrow(inv = try Lambda.Invocation(headers: header)) + var inv: Invocation? + XCTAssertNoThrow(inv = try Invocation(headers: header)) guard let invocation = inv else { return } let result = client.reportResults(logger: logger, invocation: invocation, result: Result.success(nil))