Skip to content

Commit 9bdcdbb

Browse files
authored
Swift: Lambda Undo changes incorrectly applied (#7603)
* Undo changes incorrectly applied * Add missing tag
1 parent 9f35f67 commit 9bdcdbb

File tree

1 file changed

+110
-73
lines changed
  • swift/example_code/lambda/using-lambda-runtime/Sources

1 file changed

+110
-73
lines changed

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

Lines changed: 110 additions & 73 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]
122-
// snippet-end:[lambda.swift.function.complete]
158+
// snippet-end:[lambda.swift.function.handler]
159+
// snippet-end:[lambda.swift.function.complete]

0 commit comments

Comments
 (0)