Skip to content

Commit f3abaa4

Browse files
authored
Restore lambda.swift to previous state
Undo changes made to the Swift lambda runtime example by mistake. This file should have been part of another PR.
1 parent ed8b1c4 commit f3abaa4

File tree

1 file changed

+109
-72
lines changed
  • swift/example_code/lambda/using-lambda-runtime/Sources

1 file changed

+109
-72
lines changed

swift/example_code/lambda/using-lambda-runtime/Sources/lambda.swift

Lines changed: 109 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
// snippet-start:[lambda.swift.function.imports]
55
import Foundation
66
import AWSLambdaRuntime
7-
@preconcurrency import AWSS3
7+
import AWSS3
88

99
import protocol AWSClientRuntime.AWSServiceError
1010
import enum Smithy.ByteStream
1111
// snippet-end:[lambda.swift.function.imports]
12-
1312
// snippet-start:[lambda.swift.function.types]
1413
// snippet-start:[lambda.swift.function.struct.request]
1514
/// Represents the contents of the requests being received from the client.
@@ -20,7 +19,6 @@ struct Request: Decodable, Sendable {
2019
let body: String
2120
}
2221
// snippet-end:[lambda.swift.function.struct.request]
23-
2422
// snippet-start:[lambda.swift.function.struct.response]
2523
/// The contents of the response sent back to the client. This must be
2624
/// `Encodable`.
@@ -31,92 +29,131 @@ struct Response: Encodable, Sendable {
3129
let body: String
3230
}
3331
// snippet-end:[lambda.swift.function.struct.response]
34-
3532
// snippet-start:[lambda.swift.function.errors]
3633
/// The errors that the Lambda function can return.
3734
enum S3ExampleLambdaErrors: Error {
3835
/// A required environment variable is missing. The missing variable is
3936
/// specified.
4037
case noEnvironmentVariable(String)
38+
/// The Amazon Simple Storage Service (S3) client couldn't be created.
39+
case noS3Client
4140
}
4241
// snippet-end:[lambda.swift.function.errors]
4342
// snippet-end:[lambda.swift.function.types]
4443

45-
let currentRegion = ProcessInfo.processInfo.environment["AWS_REGION"] ?? "us-east-1"
46-
let s3Client = try S3Client(region: currentRegion)
47-
48-
// snippet-start:[lambda.swift.function.putobject]
49-
/// Create a new object on Amazon S3 whose name is based on the current
50-
/// timestamp, containing the text specified.
51-
///
52-
/// - Parameters:
53-
/// - body: The text to store in the new S3 object.
54-
/// - bucketName: The name of the Amazon S3 bucket to put the new object
55-
/// into.
56-
///
57-
/// - Throws: Errors from `PutObject`.
58-
///
59-
/// - Returns: The name of the new Amazon S3 object that contains the
60-
/// specified body text.
61-
func putObject(body: String, bucketName: String) async throws -> String {
62-
// Generate an almost certainly unique object name based on the current
63-
// timestamp.
64-
65-
let objectName = "\(Int(Date().timeIntervalSince1970*1_000_000)).txt"
66-
67-
// Create a Smithy `ByteStream` that represents the string to write into
68-
// the bucket.
69-
70-
let inputStream = Smithy.ByteStream.data(body.data(using: .utf8))
71-
72-
// Store the text into an object in the Amazon S3 bucket.
44+
// snippet-start:[lambda.swift.function.handler]
45+
/// A Swift AWS Lambda Runtime `LambdaHandler` lets you both perform needed
46+
/// initialization and handle AWS Lambda requests. There are other handler
47+
/// protocols available for other use cases.
48+
@main
49+
struct S3ExampleLambda: LambdaHandler {
50+
let s3Client: S3Client?
51+
52+
// snippet-start:[lambda.swift.function.handler.init]
53+
/// Initialize the AWS Lambda runtime.
54+
///
55+
/// ^ The logger is a standard Swift logger. You can control the verbosity
56+
/// by setting the `LOG_LEVEL` environment variable.
57+
init(context: LambdaInitializationContext) async throws {
58+
// Display the `LOG_LEVEL` configuration for this process.
59+
context.logger.info(
60+
"Log Level env var : \(ProcessInfo.processInfo.environment["LOG_LEVEL"] ?? "info" )"
61+
)
7362

74-
_ = try await s3Client.putObject(
75-
input: PutObjectInput(
63+
// Initialize the Amazon S3 client. This single client is used for every
64+
// request.
65+
let currentRegion = ProcessInfo.processInfo.environment["AWS_REGION"] ?? "us-east-1"
66+
self.s3Client = try? S3Client(region: currentRegion)
67+
}
68+
// snippet-end:[lambda.swift.function.handler.init]
69+
70+
// snippet-start:[lambda.swift.function.handler.putobject]
71+
/// Write the specified text into a given Amazon S3 bucket. The object's
72+
/// name is based on the current time.
73+
///
74+
/// - Parameters:
75+
/// - s3Client: The `S3Client` to use when sending the object to the
76+
/// bucket.
77+
/// - bucketName: The name of the Amazon S3 bucket to put the object
78+
/// into.
79+
/// - body: The string to write into the new object.
80+
///
81+
/// - Returns: A string indicating the name of the file created in the AWS
82+
/// S3 bucket.
83+
private func putObject(client: S3Client,
84+
bucketName: String,
85+
body: String) async throws -> String {
86+
// Generate an almost certainly unique object name based on the current
87+
// timestamp.
88+
let objectName = "\(Int(Date().timeIntervalSince1970*1_000_000)).txt"
89+
90+
// Create a Smithy `ByteStream` that represents the string to write into
91+
// the bucket.
92+
let inputStream = Smithy.ByteStream.data(body.data(using: .utf8))
93+
94+
// Store the text into an object in the Amazon S3 bucket.
95+
let putObjectRequest = PutObjectInput(
7696
body: inputStream,
7797
bucket: bucketName,
7898
key: objectName
7999
)
80-
)
81-
82-
// Return the name of the file
100+
let _ = try await client.putObject(input: putObjectRequest)
83101

84-
return objectName
85-
}
86-
// snippet-end:[lambda.swift.function.putobject]
87-
88-
// snippet-start:[lambda.swift.function.runtime]
89-
let runtime = LambdaRuntime {
90-
(event: Request, context: LambdaContext) async throws -> Response in
91-
92-
var responseMessage: String
93-
94-
// Get the name of the bucket to write the new object into from the
95-
// environment variable `BUCKET_NAME`.
96-
guard let bucketName = ProcessInfo.processInfo.environment["BUCKET_NAME"] else {
97-
context.logger.error("Set the environment variable BUCKET_NAME to the name of the S3 bucket to write files to.")
98-
throw S3ExampleLambdaErrors.noEnvironmentVariable("BUCKET_NAME")
102+
// Return the name of the file.
103+
return objectName
99104
}
100-
101-
do {
102-
let filename = try await putObject(body: event.body, bucketName: bucketName)
103-
104-
// Generate the response text and update the log.
105-
responseMessage = "The Lambda function has successfully stored your data in S3 with name '\(filename)'"
106-
context.logger.info("Data successfully stored in S3.")
107-
} catch let error as AWSServiceError {
108-
// Generate the error message and update the log.
109-
responseMessage = "The Lambda function encountered an error and your data was not saved. Root cause: \(error.errorCode ?? "") - \(error.message ?? "")"
110-
context.logger.error("Failed to upload data to Amazon S3.")
105+
// snippet-end:[lambda.swift.function.handler.putobject]
106+
107+
// snippet-start:[lambda.swift.function.handler.handle]
108+
/// The Lambda function's entry point. Called by the Lambda runtime.
109+
///
110+
/// - Parameters:
111+
/// - event: The `Request` describing the request made by the
112+
/// client.
113+
/// - context: A `LambdaContext` describing the context in
114+
/// which the lambda function is running.
115+
///
116+
/// - Returns: A `Response` object that will be encoded to JSON and sent
117+
/// to the client by the Lambda runtime.
118+
func handle(_ event: Request, context: LambdaContext) async throws -> Response {
119+
// Get the bucket name from the environment.
120+
guard let bucketName = ProcessInfo.processInfo.environment["BUCKET_NAME"] else {
121+
throw S3ExampleLambdaErrors.noEnvironmentVariable("BUCKET_NAME")
122+
}
123+
124+
// Make sure the `S3Client` is valid.
125+
guard let s3Client else {
126+
throw S3ExampleLambdaErrors.noS3Client
127+
}
128+
129+
// Call the `putObject` function to store the object on Amazon S3.
130+
var responseMessage: String
131+
do {
132+
let filename = try await putObject(
133+
client: s3Client,
134+
bucketName: bucketName,
135+
body: event.body)
136+
137+
// Generate the response text.
138+
responseMessage = "The Lambda function has successfully stored your data in S3 with name \(filename)'"
139+
140+
// Send the success notification to the logger.
141+
context.logger.info("Data successfully stored in S3.")
142+
} catch let error as AWSServiceError {
143+
// Generate the error message.
144+
responseMessage = "The Lambda function encountered an error and your data was not saved. Root cause: \(error.errorCode ?? "") - \(error.message ?? "")"
145+
146+
// Send the error message to the logger.
147+
context.logger.error("Failed to upload data to Amazon S3.")
148+
}
149+
150+
// Return the response message. The AWS Lambda runtime will send it to the
151+
// client.
152+
return Response(
153+
req_id: context.requestID,
154+
body: responseMessage)
111155
}
112-
113-
return Response(req_id: context.requestID, body: responseMessage)
156+
// snippet-end:[lambda.swift.function.handler.handle]
114157
}
115-
// snippet-end:[lambda.swift.function.runtime]
116-
117-
// Start up the runtime.
118-
119-
// snippet-start:[lambda.swift.function.start]
120-
try await runtime.run()
121-
// snippet-end:[lambda.swift.function.start]
158+
// snippet-end:[lambda.swift.function.handler]
122159
// snippet-end:[lambda.swift.function.complete]

0 commit comments

Comments
 (0)