Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions swift/example_code/lambda/using-lambda-runtime/Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.10
// swift-tools-version: 6.0
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

Expand All @@ -20,7 +20,7 @@ let package = Package(
dependencies: [
.package(
url: "https://github.com/swift-server/swift-aws-lambda-runtime.git",
from: "1.0.0-alpha"),
from: "2.0.0-beta.1"),
.package(url: "https://github.com/awslabs/aws-sdk-swift.git",
from: "1.0.0"),
],
Expand Down
180 changes: 70 additions & 110 deletions swift/example_code/lambda/using-lambda-runtime/Sources/lambda.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// snippet-start:[lambda.swift.function.imports]
import Foundation
import AWSLambdaRuntime
import AWSS3
@preconcurrency import AWSS3

import protocol AWSClientRuntime.AWSServiceError
import enum Smithy.ByteStream
Expand Down Expand Up @@ -38,125 +38,85 @@ enum S3ExampleLambdaErrors: Error {
/// A required environment variable is missing. The missing variable is
/// specified.
case noEnvironmentVariable(String)
/// The Amazon Simple Storage Service (S3) client couldn't be created.
case noS3Client
}
// snippet-end:[lambda.swift.function.errors]
// snippet-end:[lambda.swift.function.types]

// snippet-start:[lambda.swift.function.handler]
/// A Swift AWS Lambda Runtime `LambdaHandler` lets you both perform needed
/// initialization and handle AWS Lambda requests. There are other handler
/// protocols available for other use cases.
@main
struct S3ExampleLambda: LambdaHandler {
let s3Client: S3Client?

// snippet-start:[lambda.swift.function.handler.init]
/// Initialize the AWS Lambda runtime.
///
/// ^ The logger is a standard Swift logger. You can control the verbosity
/// by setting the `LOG_LEVEL` environment variable.
init(context: LambdaInitializationContext) async throws {
// Display the `LOG_LEVEL` configuration for this process.
context.logger.info(
"Log Level env var : \(ProcessInfo.processInfo.environment["LOG_LEVEL"] ?? "info" )"
)

// Initialize the Amazon S3 client. This single client is used for every
// request.
let currentRegion = ProcessInfo.processInfo.environment["AWS_REGION"] ?? "us-east-1"
self.s3Client = try? S3Client(region: currentRegion)
}
// snippet-end:[lambda.swift.function.handler.init]

// snippet-start:[lambda.swift.function.handler.putobject]
/// Write the specified text into a given Amazon S3 bucket. The object's
/// name is based on the current time.
///
/// - Parameters:
/// - s3Client: The `S3Client` to use when sending the object to the
/// bucket.
/// - bucketName: The name of the Amazon S3 bucket to put the object
/// into.
/// - body: The string to write into the new object.
///
/// - Returns: A string indicating the name of the file created in the AWS
/// S3 bucket.
private func putObject(client: S3Client,
bucketName: String,
body: String) async throws -> String {
// Generate an almost certainly unique object name based on the current
// timestamp.
let objectName = "\(Int(Date().timeIntervalSince1970*1_000_000)).txt"

// Create a Smithy `ByteStream` that represents the string to write into
// the bucket.
let inputStream = Smithy.ByteStream.data(body.data(using: .utf8))

// Store the text into an object in the Amazon S3 bucket.
let putObjectRequest = PutObjectInput(
let currentRegion = ProcessInfo.processInfo.environment["AWS_REGION"] ?? "us-east-1"
let s3Client = try S3Client(region: currentRegion)

// snippet-start:[lambda.swift.function.putobject]
/// Create a new object on Amazon S3 whose name is based on the current
/// timestamp, containing the text specified.
///
/// - Parameters:
/// - body: The text to store in the new S3 object.
/// - bucketName: The name of the Amazon S3 bucket to put the new object
/// into.
///
/// - Throws: Errors from `PutObject`.
///
/// - Returns: The name of the new Amazon S3 object that contains the
/// specified body text.
func putObject(body: String, bucketName: String) async throws -> String {
// Generate an almost certainly unique object name based on the current
// timestamp.

let objectName = "\(Int(Date().timeIntervalSince1970*1_000_000)).txt"

// Create a Smithy `ByteStream` that represents the string to write into
// the bucket.

let inputStream = Smithy.ByteStream.data(body.data(using: .utf8))

// Store the text into an object in the Amazon S3 bucket.

_ = try await s3Client.putObject(
input: PutObjectInput(
body: inputStream,
bucket: bucketName,
key: objectName
)
let _ = try await client.putObject(input: putObjectRequest)
)

// Return the name of the file

return objectName
}
// snippet-end:[lambda.swift.function.putobject]

// snippet-start:[lambda.swift.function.runtime]
let runtime = LambdaRuntime {
(event: Request, context: LambdaContext) async throws -> Response in

// Return the name of the file.
return objectName
var responseMessage: String

// Get the name of the bucket to write the new object into from the
// environment variable `BUCKET_NAME`.
guard let bucketName = ProcessInfo.processInfo.environment["BUCKET_NAME"] else {
context.logger.error("Set the environment variable BUCKET_NAME to the name of the S3 bucket to write files to.")
throw S3ExampleLambdaErrors.noEnvironmentVariable("BUCKET_NAME")
}
// snippet-end:[lambda.swift.function.handler.putobject]

// snippet-start:[lambda.swift.function.handler.handle]
/// The Lambda function's entry point. Called by the Lambda runtime.
///
/// - Parameters:
/// - event: The `Request` describing the request made by the
/// client.
/// - context: A `LambdaContext` describing the context in
/// which the lambda function is running.
///
/// - Returns: A `Response` object that will be encoded to JSON and sent
/// to the client by the Lambda runtime.
func handle(_ event: Request, context: LambdaContext) async throws -> Response {
// Get the bucket name from the environment.
guard let bucketName = ProcessInfo.processInfo.environment["BUCKET_NAME"] else {
throw S3ExampleLambdaErrors.noEnvironmentVariable("BUCKET_NAME")
}

// Make sure the `S3Client` is valid.
guard let s3Client else {
throw S3ExampleLambdaErrors.noS3Client
}

// Call the `putObject` function to store the object on Amazon S3.
var responseMessage: String
do {
let filename = try await putObject(
client: s3Client,
bucketName: bucketName,
body: event.body)

// Generate the response text.
responseMessage = "The Lambda function has successfully stored your data in S3 with name \(filename)'"

// Send the success notification to the logger.
context.logger.info("Data successfully stored in S3.")
} catch let error as AWSServiceError {
// Generate the error message.
responseMessage = "The Lambda function encountered an error and your data was not saved. Root cause: \(error.errorCode ?? "") - \(error.message ?? "")"

// Send the error message to the logger.
context.logger.error("Failed to upload data to Amazon S3.")
}

// Return the response message. The AWS Lambda runtime will send it to the
// client.
return Response(
req_id: context.requestID,
body: responseMessage)

do {
let filename = try await putObject(body: event.body, bucketName: bucketName)

// Generate the response text and update the log.
responseMessage = "The Lambda function has successfully stored your data in S3 with name '\(filename)'"
context.logger.info("Data successfully stored in S3.")
} catch let error as AWSServiceError {
// Generate the error message and update the log.
responseMessage = "The Lambda function encountered an error and your data was not saved. Root cause: \(error.errorCode ?? "") - \(error.message ?? "")"
context.logger.error("Failed to upload data to Amazon S3.")
}
// snippet-end:[lambda.swift.function.handler.handle]

return Response(req_id: context.requestID, body: responseMessage)
}
// snippet-end:[lambda.swift.function.handler]
// snippet-end:[lambda.swift.function.runtime]

// Start up the runtime.

// snippet-start:[lambda.swift.function.start]
try await runtime.run()
// snippet-end:[lambda.swift.function.start]
// snippet-end:[lambda.swift.function.complete]
2 changes: 0 additions & 2 deletions swift/example_code/lambda/using-lambda-runtime/test.sh
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
#!/bin/bash
echo "No automated tests available."
Loading