mirror of
https://github.com/swift-server/swift-aws-lambda-runtime.git
synced 2026-06-02 07:27:33 +00:00
Added S3 Event (#45)
motivation: support S3 Events changes: - Created `AWSLambdaEvents` target - Added S3 Event as first event - Use propertyWrapper for customers Encoding/Decoding
This commit is contained in:
@@ -4,8 +4,12 @@ import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "swift-aws-lambda-runtime",
|
||||
platforms: [
|
||||
.macOS(.v10_13),
|
||||
],
|
||||
products: [
|
||||
.library(name: "AWSLambdaRuntime", targets: ["AWSLambdaRuntime"]),
|
||||
.library(name: "AWSLambdaEvents", targets: ["AWSLambdaEvents"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/apple/swift-nio.git", from: "2.8.0"),
|
||||
@@ -20,6 +24,8 @@ let package = Package(
|
||||
.product(name: "NIOFoundationCompat", package: "swift-nio"),
|
||||
]),
|
||||
.testTarget(name: "AWSLambdaRuntimeTests", dependencies: ["AWSLambdaRuntime"]),
|
||||
.target(name: "AWSLambdaEvents", dependencies: []),
|
||||
.testTarget(name: "AWSLambdaEventsTests", dependencies: ["AWSLambdaEvents"]),
|
||||
// samples
|
||||
.target(name: "StringSample", dependencies: ["AWSLambdaRuntime"]),
|
||||
.target(name: "CodableSample", dependencies: ["AWSLambdaRuntime"]),
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 struct Foundation.Date
|
||||
import class Foundation.ISO8601DateFormatter
|
||||
|
||||
@propertyWrapper
|
||||
public struct ISO8601WithFractionalSecondsCoding: Decodable {
|
||||
public let wrappedValue: Date
|
||||
|
||||
public init(wrappedValue: Date) {
|
||||
self.wrappedValue = wrappedValue
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
let dateString = try container.decode(String.self)
|
||||
guard let date = Self.dateFormatter.date(from: dateString) else {
|
||||
throw DecodingError.dataCorruptedError(in: container, debugDescription:
|
||||
"Expected date to be in iso8601 date format with fractional seconds, but `\(dateString) does not forfill format`")
|
||||
}
|
||||
self.wrappedValue = date
|
||||
}
|
||||
|
||||
private static let dateFormatter: ISO8601DateFormatter = Self.createDateFormatter()
|
||||
private static func createDateFormatter() -> ISO8601DateFormatter {
|
||||
let formatter = ISO8601DateFormatter()
|
||||
formatter.formatOptions = [
|
||||
.withInternetDateTime,
|
||||
.withDashSeparatorInDate,
|
||||
.withColonSeparatorInTime,
|
||||
.withColonSeparatorInTimeZone,
|
||||
.withFractionalSeconds,
|
||||
]
|
||||
return formatter
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 struct Foundation.Date
|
||||
|
||||
// https://github.com/aws/aws-lambda-go/blob/master/events/s3.go
|
||||
public enum S3 {
|
||||
public struct Event: Decodable {
|
||||
public struct Record: Decodable {
|
||||
public let eventVersion: String
|
||||
public let eventSource: String
|
||||
public let awsRegion: String
|
||||
|
||||
@ISO8601WithFractionalSecondsCoding
|
||||
public var eventTime: Date
|
||||
public let eventName: String
|
||||
public let userIdentity: UserIdentity
|
||||
public let requestParameters: RequestParameters
|
||||
public let responseElements: [String: String]
|
||||
public let s3: Entity
|
||||
}
|
||||
|
||||
public let records: [Record]
|
||||
|
||||
public enum CodingKeys: String, CodingKey {
|
||||
case records = "Records"
|
||||
}
|
||||
}
|
||||
|
||||
public struct RequestParameters: Codable, Equatable {
|
||||
public let sourceIPAddress: String
|
||||
}
|
||||
|
||||
public struct UserIdentity: Codable, Equatable {
|
||||
public let principalId: String
|
||||
}
|
||||
|
||||
public struct Entity: Codable {
|
||||
public let configurationId: String
|
||||
public let schemaVersion: String
|
||||
public let bucket: Bucket
|
||||
public let object: Object
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case configurationId
|
||||
case schemaVersion = "s3SchemaVersion"
|
||||
case bucket
|
||||
case object
|
||||
}
|
||||
}
|
||||
|
||||
public struct Bucket: Codable {
|
||||
public let name: String
|
||||
public let ownerIdentity: UserIdentity
|
||||
public let arn: String
|
||||
}
|
||||
|
||||
public struct Object: Codable {
|
||||
public let key: String
|
||||
public let size: UInt64
|
||||
public let urlDecodedKey: String?
|
||||
public let versionId: String?
|
||||
public let eTag: String
|
||||
public let sequencer: String
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@testable import AWSLambdaEvents
|
||||
import XCTest
|
||||
|
||||
class S3Tests: XCTestCase {
|
||||
static let eventPayload = """
|
||||
{
|
||||
"Records": [
|
||||
{
|
||||
"eventVersion":"2.1",
|
||||
"eventSource":"aws:s3",
|
||||
"awsRegion":"eu-central-1",
|
||||
"eventTime":"2020-01-13T09:25:40.621Z",
|
||||
"eventName":"ObjectCreated:Put",
|
||||
"userIdentity":{
|
||||
"principalId":"AWS:AAAAAAAJ2MQ4YFQZ7AULJ"
|
||||
},
|
||||
"requestParameters":{
|
||||
"sourceIPAddress":"123.123.123.123"
|
||||
},
|
||||
"responseElements":{
|
||||
"x-amz-request-id":"01AFA1430E18C358",
|
||||
"x-amz-id-2":"JsbNw6sHGFwgzguQjbYcew//bfAeZITyTYLfjuu1U4QYqCq5CPlSyYLtvWQS+gw0RxcroItGwm8="
|
||||
},
|
||||
"s3":{
|
||||
"s3SchemaVersion":"1.0",
|
||||
"configurationId":"98b55bc4-3c0c-4007-b727-c6b77a259dde",
|
||||
"bucket":{
|
||||
"name":"eventsources",
|
||||
"ownerIdentity":{
|
||||
"principalId":"AAAAAAAAAAAAAA"
|
||||
},
|
||||
"arn":"arn:aws:s3:::eventsources"
|
||||
},
|
||||
"object":{
|
||||
"key":"Hi.md",
|
||||
"size":2880,
|
||||
"eTag":"91a7f2c3ae81bcc6afef83979b463f0e",
|
||||
"sequencer":"005E1C37948E783A6E"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
"""
|
||||
|
||||
func testSimpleEventFromJSON() {
|
||||
let data = S3Tests.eventPayload.data(using: .utf8)!
|
||||
var event: S3.Event?
|
||||
XCTAssertNoThrow(event = try JSONDecoder().decode(S3.Event.self, from: data))
|
||||
|
||||
guard let record = event?.records.first else {
|
||||
XCTFail("Expected to have one record")
|
||||
return
|
||||
}
|
||||
|
||||
XCTAssertEqual(record.eventVersion, "2.1")
|
||||
XCTAssertEqual(record.eventSource, "aws:s3")
|
||||
XCTAssertEqual(record.awsRegion, "eu-central-1")
|
||||
XCTAssertEqual(record.eventName, "ObjectCreated:Put")
|
||||
XCTAssertEqual(record.eventTime, Date(timeIntervalSince1970: 1_578_907_540.621))
|
||||
XCTAssertEqual(record.userIdentity, S3.UserIdentity(principalId: "AWS:AAAAAAAJ2MQ4YFQZ7AULJ"))
|
||||
XCTAssertEqual(record.requestParameters, S3.RequestParameters(sourceIPAddress: "123.123.123.123"))
|
||||
XCTAssertEqual(record.responseElements.count, 2)
|
||||
XCTAssertEqual(record.s3.schemaVersion, "1.0")
|
||||
XCTAssertEqual(record.s3.configurationId, "98b55bc4-3c0c-4007-b727-c6b77a259dde")
|
||||
XCTAssertEqual(record.s3.bucket.name, "eventsources")
|
||||
XCTAssertEqual(record.s3.bucket.ownerIdentity, S3.UserIdentity(principalId: "AAAAAAAAAAAAAA"))
|
||||
XCTAssertEqual(record.s3.bucket.arn, "arn:aws:s3:::eventsources")
|
||||
XCTAssertEqual(record.s3.object.key, "Hi.md")
|
||||
XCTAssertEqual(record.s3.object.size, 2880)
|
||||
XCTAssertEqual(record.s3.object.eTag, "91a7f2c3ae81bcc6afef83979b463f0e")
|
||||
XCTAssertEqual(record.s3.object.sequencer, "005E1C37948E783A6E")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user