forked from swift-server/swift-aws-lambda-runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLambdaContext.swift
197 lines (164 loc) · 7.37 KB
/
LambdaContext.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2017-2020 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 BaggageContext
import Dispatch
import Logging
import NIO
// MARK: - InitializationContext
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 {
/// `Logger` to log with
///
/// - note: The `LogLevel` can be configured using the `LOG_LEVEL` environment variable.
public let logger: Logger
/// The `EventLoop` the Lambda is executed on. Use this to schedule work with.
///
/// - note: The `EventLoop` is shared with the Lambda runtime engine and should be handled with extra care.
/// Most importantly the `EventLoop` must never be blocked.
public let eventLoop: EventLoop
/// `ByteBufferAllocator` to allocate `ByteBuffer`
public let allocator: ByteBufferAllocator
internal init(logger: Logger, eventLoop: EventLoop, allocator: ByteBufferAllocator) {
self.eventLoop = eventLoop
self.logger = logger
self.allocator = allocator
}
}
}
// MARK: - Context
extension Lambda {
/// Lambda runtime context.
/// The Lambda runtime generates and passes the `Context` to the Lambda handler as an argument.
public final class Context: BaggageContext.Context, CustomDebugStringConvertible {
/// Contains contextual metadata such as request and trace identifiers, along with other information which may
/// be carried throughout asynchronous and cross-node boundaries (e.g. through HTTPClient calls).
public let baggage: Baggage
/// The request ID, which identifies the request that triggered the function invocation.
public var requestID: String {
self.baggage.lambdaRequestID
}
/// The AWS X-Ray tracing header.
public var traceID: String {
self.baggage.lambdaTraceID
}
/// The ARN of the Lambda function, version, or alias that's specified in the invocation.
public let invokedFunctionARN: String
/// The timestamp that the function times out
public let deadline: DispatchWallTime
/// For invocations from the AWS Mobile SDK, data about the Amazon Cognito identity provider.
public let cognitoIdentity: String?
/// For invocations from the AWS Mobile SDK, data about the client application and device.
public let clientContext: String?
/// `Logger` to log with, it is automatically populated with `baggage` information (such as `traceID` and `requestID`).
///
/// - note: The `LogLevel` can be configured using the `LOG_LEVEL` environment variable.
public var logger: Logger {
self._logger.with(self.baggage)
}
private var _logger: Logger
/// The `EventLoop` the Lambda is executed on. Use this to schedule work with.
/// This is useful when implementing the `EventLoopLambdaHandler` protocol.
///
/// - note: The `EventLoop` is shared with the Lambda runtime engine and should be handled with extra care.
/// Most importantly the `EventLoop` must never be blocked.
public let eventLoop: EventLoop
/// `ByteBufferAllocator` to allocate `ByteBuffer`
/// This is useful when implementing `EventLoopLambdaHandler`
public let allocator: ByteBufferAllocator
internal init(requestID: String,
traceID: String,
invokedFunctionARN: String,
deadline: DispatchWallTime,
cognitoIdentity: String? = nil,
clientContext: String? = nil,
logger: Logger,
eventLoop: EventLoop,
allocator: ByteBufferAllocator) {
var baggage = Baggage.background
baggage.lambdaRequestID = requestID
baggage.lambdaTraceID = traceID
self.baggage = baggage
self.invokedFunctionARN = invokedFunctionARN
self.cognitoIdentity = cognitoIdentity
self.clientContext = clientContext
self.deadline = deadline
// utility
self.eventLoop = eventLoop
self.allocator = allocator
self._logger = logger
}
public func getRemainingTime() -> TimeAmount {
let deadline = self.deadline.millisSinceEpoch
let now = DispatchWallTime.now().millisSinceEpoch
let remaining = deadline - now
return .milliseconds(remaining)
}
public var debugDescription: String {
"\(Self.self)(requestID: \(self.requestID), traceID: \(self.traceID), invokedFunctionARN: \(self.invokedFunctionARN), cognitoIdentity: \(self.cognitoIdentity ?? "nil"), clientContext: \(self.clientContext ?? "nil"), deadline: \(self.deadline))"
}
}
}
// MARK: - ShutdownContext
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 {
/// `Logger` to log with
///
/// - note: The `LogLevel` can be configured using the `LOG_LEVEL` environment variable.
public let logger: Logger
/// The `EventLoop` the Lambda is executed on. Use this to schedule work with.
///
/// - note: The `EventLoop` is shared with the Lambda runtime engine and should be handled with extra care.
/// Most importantly the `EventLoop` must never be blocked.
public let eventLoop: EventLoop
internal init(logger: Logger, eventLoop: EventLoop) {
self.eventLoop = eventLoop
self.logger = logger
}
}
}
// MARK: - Baggage Items
extension Baggage {
// MARK: - Baggage: RequestID
enum LambdaRequestIDKey: Key {
typealias Value = String
static var name: String? { AmazonHeaders.requestID }
}
/// The request ID, which identifies the request that triggered the function invocation.
public internal(set) var lambdaRequestID: String {
get {
self[LambdaRequestIDKey.self]! // !-safe, the runtime guarantees to always set an identifier, even in testing
}
set {
self[LambdaRequestIDKey.self] = newValue
}
}
// MARK: - Baggage: TraceID
enum LambdaTraceIDKey: Key {
typealias Value = String
static var name: String? { AmazonHeaders.traceID }
}
/// The AWS X-Ray tracing header.
public internal(set) var lambdaTraceID: String {
get {
self[LambdaTraceIDKey.self]! // !-safe, the runtime guarantees to always set an identifier, even in testing
}
set {
self[LambdaTraceIDKey.self] = newValue
}
}
}