Skip to content

Commit 643dd91

Browse files
authored
Added S3 Event (#45)
motivation: support S3 Events changes: - Created `AWSLambdaEvents` target - Added S3 Event as first event - Use propertyWrapper for customers Encoding/Decoding
1 parent a9606fc commit 643dd91

File tree

4 files changed

+219
-0
lines changed

4 files changed

+219
-0
lines changed

Package.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ import PackageDescription
44

55
let package = Package(
66
name: "swift-aws-lambda-runtime",
7+
platforms: [
8+
.macOS(.v10_13),
9+
],
710
products: [
811
.library(name: "AWSLambdaRuntime", targets: ["AWSLambdaRuntime"]),
12+
.library(name: "AWSLambdaEvents", targets: ["AWSLambdaEvents"]),
913
],
1014
dependencies: [
1115
.package(url: "https://github.com/apple/swift-nio.git", from: "2.8.0"),
@@ -20,6 +24,8 @@ let package = Package(
2024
.product(name: "NIOFoundationCompat", package: "swift-nio"),
2125
]),
2226
.testTarget(name: "AWSLambdaRuntimeTests", dependencies: ["AWSLambdaRuntime"]),
27+
.target(name: "AWSLambdaEvents", dependencies: []),
28+
.testTarget(name: "AWSLambdaEventsTests", dependencies: ["AWSLambdaEvents"]),
2329
// samples
2430
.target(name: "StringSample", dependencies: ["AWSLambdaRuntime"]),
2531
.target(name: "CodableSample", dependencies: ["AWSLambdaRuntime"]),
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftAWSLambdaRuntime open source project
4+
//
5+
// Copyright (c) 2017-2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import struct Foundation.Date
16+
import class Foundation.ISO8601DateFormatter
17+
18+
@propertyWrapper
19+
public struct ISO8601WithFractionalSecondsCoding: Decodable {
20+
public let wrappedValue: Date
21+
22+
public init(wrappedValue: Date) {
23+
self.wrappedValue = wrappedValue
24+
}
25+
26+
public init(from decoder: Decoder) throws {
27+
let container = try decoder.singleValueContainer()
28+
let dateString = try container.decode(String.self)
29+
guard let date = Self.dateFormatter.date(from: dateString) else {
30+
throw DecodingError.dataCorruptedError(in: container, debugDescription:
31+
"Expected date to be in iso8601 date format with fractional seconds, but `\(dateString) does not forfill format`")
32+
}
33+
self.wrappedValue = date
34+
}
35+
36+
private static let dateFormatter: ISO8601DateFormatter = Self.createDateFormatter()
37+
private static func createDateFormatter() -> ISO8601DateFormatter {
38+
let formatter = ISO8601DateFormatter()
39+
formatter.formatOptions = [
40+
.withInternetDateTime,
41+
.withDashSeparatorInDate,
42+
.withColonSeparatorInTime,
43+
.withColonSeparatorInTimeZone,
44+
.withFractionalSeconds,
45+
]
46+
return formatter
47+
}
48+
}

Sources/AWSLambdaEvents/S3.swift

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftAWSLambdaRuntime open source project
4+
//
5+
// Copyright (c) 2017-2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import struct Foundation.Date
16+
17+
// https://github.com/aws/aws-lambda-go/blob/master/events/s3.go
18+
public enum S3 {
19+
public struct Event: Decodable {
20+
public struct Record: Decodable {
21+
public let eventVersion: String
22+
public let eventSource: String
23+
public let awsRegion: String
24+
25+
@ISO8601WithFractionalSecondsCoding
26+
public var eventTime: Date
27+
public let eventName: String
28+
public let userIdentity: UserIdentity
29+
public let requestParameters: RequestParameters
30+
public let responseElements: [String: String]
31+
public let s3: Entity
32+
}
33+
34+
public let records: [Record]
35+
36+
public enum CodingKeys: String, CodingKey {
37+
case records = "Records"
38+
}
39+
}
40+
41+
public struct RequestParameters: Codable, Equatable {
42+
public let sourceIPAddress: String
43+
}
44+
45+
public struct UserIdentity: Codable, Equatable {
46+
public let principalId: String
47+
}
48+
49+
public struct Entity: Codable {
50+
public let configurationId: String
51+
public let schemaVersion: String
52+
public let bucket: Bucket
53+
public let object: Object
54+
55+
enum CodingKeys: String, CodingKey {
56+
case configurationId
57+
case schemaVersion = "s3SchemaVersion"
58+
case bucket
59+
case object
60+
}
61+
}
62+
63+
public struct Bucket: Codable {
64+
public let name: String
65+
public let ownerIdentity: UserIdentity
66+
public let arn: String
67+
}
68+
69+
public struct Object: Codable {
70+
public let key: String
71+
public let size: UInt64
72+
public let urlDecodedKey: String?
73+
public let versionId: String?
74+
public let eTag: String
75+
public let sequencer: String
76+
}
77+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftAWSLambdaRuntime open source project
4+
//
5+
// Copyright (c) 2017-2020 Apple Inc. and the SwiftAWSLambdaRuntime project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
@testable import AWSLambdaEvents
16+
import XCTest
17+
18+
class S3Tests: XCTestCase {
19+
static let eventPayload = """
20+
{
21+
"Records": [
22+
{
23+
"eventVersion":"2.1",
24+
"eventSource":"aws:s3",
25+
"awsRegion":"eu-central-1",
26+
"eventTime":"2020-01-13T09:25:40.621Z",
27+
"eventName":"ObjectCreated:Put",
28+
"userIdentity":{
29+
"principalId":"AWS:AAAAAAAJ2MQ4YFQZ7AULJ"
30+
},
31+
"requestParameters":{
32+
"sourceIPAddress":"123.123.123.123"
33+
},
34+
"responseElements":{
35+
"x-amz-request-id":"01AFA1430E18C358",
36+
"x-amz-id-2":"JsbNw6sHGFwgzguQjbYcew//bfAeZITyTYLfjuu1U4QYqCq5CPlSyYLtvWQS+gw0RxcroItGwm8="
37+
},
38+
"s3":{
39+
"s3SchemaVersion":"1.0",
40+
"configurationId":"98b55bc4-3c0c-4007-b727-c6b77a259dde",
41+
"bucket":{
42+
"name":"eventsources",
43+
"ownerIdentity":{
44+
"principalId":"AAAAAAAAAAAAAA"
45+
},
46+
"arn":"arn:aws:s3:::eventsources"
47+
},
48+
"object":{
49+
"key":"Hi.md",
50+
"size":2880,
51+
"eTag":"91a7f2c3ae81bcc6afef83979b463f0e",
52+
"sequencer":"005E1C37948E783A6E"
53+
}
54+
}
55+
}
56+
]
57+
}
58+
"""
59+
60+
func testSimpleEventFromJSON() {
61+
let data = S3Tests.eventPayload.data(using: .utf8)!
62+
var event: S3.Event?
63+
XCTAssertNoThrow(event = try JSONDecoder().decode(S3.Event.self, from: data))
64+
65+
guard let record = event?.records.first else {
66+
XCTFail("Expected to have one record")
67+
return
68+
}
69+
70+
XCTAssertEqual(record.eventVersion, "2.1")
71+
XCTAssertEqual(record.eventSource, "aws:s3")
72+
XCTAssertEqual(record.awsRegion, "eu-central-1")
73+
XCTAssertEqual(record.eventName, "ObjectCreated:Put")
74+
XCTAssertEqual(record.eventTime, Date(timeIntervalSince1970: 1_578_907_540.621))
75+
XCTAssertEqual(record.userIdentity, S3.UserIdentity(principalId: "AWS:AAAAAAAJ2MQ4YFQZ7AULJ"))
76+
XCTAssertEqual(record.requestParameters, S3.RequestParameters(sourceIPAddress: "123.123.123.123"))
77+
XCTAssertEqual(record.responseElements.count, 2)
78+
XCTAssertEqual(record.s3.schemaVersion, "1.0")
79+
XCTAssertEqual(record.s3.configurationId, "98b55bc4-3c0c-4007-b727-c6b77a259dde")
80+
XCTAssertEqual(record.s3.bucket.name, "eventsources")
81+
XCTAssertEqual(record.s3.bucket.ownerIdentity, S3.UserIdentity(principalId: "AAAAAAAAAAAAAA"))
82+
XCTAssertEqual(record.s3.bucket.arn, "arn:aws:s3:::eventsources")
83+
XCTAssertEqual(record.s3.object.key, "Hi.md")
84+
XCTAssertEqual(record.s3.object.size, 2880)
85+
XCTAssertEqual(record.s3.object.eTag, "91a7f2c3ae81bcc6afef83979b463f0e")
86+
XCTAssertEqual(record.s3.object.sequencer, "005E1C37948E783A6E")
87+
}
88+
}

0 commit comments

Comments
 (0)