Skip to content

Commit 5c9e694

Browse files
committed
Update Lambda runtime for Swift example
1 parent 7f3e8cd commit 5c9e694

File tree

3 files changed

+75
-114
lines changed

3 files changed

+75
-114
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version: 5.10
1+
// swift-tools-version: 6.0
22
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
// SPDX-License-Identifier: Apache-2.0
44

@@ -20,7 +20,7 @@ let package = Package(
2020
dependencies: [
2121
.package(
2222
url: "https://github.com/swift-server/swift-aws-lambda-runtime.git",
23-
from: "1.0.0-alpha"),
23+
from: "2.0.0-beta.1"),
2424
.package(url: "https://github.com/awslabs/aws-sdk-swift.git",
2525
from: "1.0.0"),
2626
],

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

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

99
import protocol AWSClientRuntime.AWSServiceError
1010
import enum Smithy.ByteStream
1111
// snippet-end:[lambda.swift.function.imports]
12+
1213
// snippet-start:[lambda.swift.function.types]
1314
// snippet-start:[lambda.swift.function.struct.request]
1415
/// Represents the contents of the requests being received from the client.
@@ -19,6 +20,7 @@ struct Request: Decodable, Sendable {
1920
let body: String
2021
}
2122
// snippet-end:[lambda.swift.function.struct.request]
23+
2224
// snippet-start:[lambda.swift.function.struct.response]
2325
/// The contents of the response sent back to the client. This must be
2426
/// `Encodable`.
@@ -29,131 +31,92 @@ struct Response: Encodable, Sendable {
2931
let body: String
3032
}
3133
// snippet-end:[lambda.swift.function.struct.response]
34+
3235
// snippet-start:[lambda.swift.function.errors]
3336
/// The errors that the Lambda function can return.
3437
enum S3ExampleLambdaErrors: Error {
3538
/// A required environment variable is missing. The missing variable is
3639
/// specified.
3740
case noEnvironmentVariable(String)
38-
/// The Amazon Simple Storage Service (S3) client couldn't be created.
39-
case noS3Client
4041
}
4142
// snippet-end:[lambda.swift.function.errors]
4243
// snippet-end:[lambda.swift.function.types]
4344

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-
)
45+
let currentRegion = ProcessInfo.processInfo.environment["AWS_REGION"] ?? "us-east-1"
46+
let s3Client = try S3Client(region: currentRegion)
6247

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(
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.
73+
74+
_ = try await s3Client.putObject(
75+
input: PutObjectInput(
9676
body: inputStream,
9777
bucket: bucketName,
9878
key: objectName
9979
)
100-
let _ = try await client.putObject(input: putObjectRequest)
80+
)
81+
82+
// Return the name of the file
10183

102-
// Return the name of the file.
103-
return objectName
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")
10499
}
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)
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.")
155111
}
156-
// snippet-end:[lambda.swift.function.handler.handle]
112+
113+
return Response(req_id: context.requestID, body: responseMessage)
157114
}
158-
// snippet-end:[lambda.swift.function.handler]
159-
// snippet-end:[lambda.swift.function.complete]
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]
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +0,0 @@
1-
#!/bin/bash
2-
echo "No automated tests available."

0 commit comments

Comments
 (0)