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:
Fabian Fett
2020-03-24 16:01:40 -07:00
committed by GitHub
parent a9606fc636
commit 643dd91375
4 changed files with 219 additions and 0 deletions
+6
View File
@@ -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
}
}
+77
View File
@@ -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
}
}
+88
View File
@@ -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")
}
}