Skip to content

Commit

Permalink
Merge pull request #354 from shagoon/s3event
Browse files Browse the repository at this point in the history
Add S3Event
  • Loading branch information
armanbilge authored Jun 6, 2023
2 parents 3065e42 + 4a2ac19 commit ba6df30
Show file tree
Hide file tree
Showing 2 changed files with 250 additions and 0 deletions.
145 changes: 145 additions & 0 deletions lambda/shared/src/main/scala/feral/lambda/events/S3Event.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* Copyright 2021 Typelevel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package feral.lambda.events

import io.circe.Decoder

import java.time.Instant

// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/aws-lambda/trigger/s3.d.ts

final case class S3Event(records: List[S3EventRecord])

object S3Event {
implicit val decoder: Decoder[S3Event] = Decoder.forProduct1("Records")(S3Event.apply)
}

final case class S3EventRecord(
eventVersion: String,
eventSource: String,
awsRegion: String,
eventTime: Instant,
eventName: String,
userIdentity: S3UserIdentity,
requestParameters: S3RequestParameters,
responseElements: S3ResponseElements,
s3: S3,
glacierEventData: Option[S3EventRecordGlacierEventData])

object S3EventRecord {

implicit val decoder: Decoder[S3EventRecord] =
Decoder.forProduct10(
"eventVersion",
"eventSource",
"awsRegion",
"eventTime",
"eventName",
"userIdentity",
"requestParameters",
"responseElements",
"s3",
"glacierEventData"
)(S3EventRecord.apply)

}

final case class S3UserIdentity(principalId: String)

object S3UserIdentity {

implicit val decoder: Decoder[S3UserIdentity] =
Decoder.forProduct1("principalId")(S3UserIdentity.apply)

}

final case class S3RequestParameters(sourceIPAddress: String)

object S3RequestParameters {

implicit val decoder: Decoder[S3RequestParameters] =
Decoder.forProduct1("sourceIPAddress")(S3RequestParameters.apply)

}

final case class S3ResponseElements(`x-amz-request-id`: String, `x-amz-id-2`: String)

object S3ResponseElements {

implicit val decoder: Decoder[S3ResponseElements] =
Decoder.forProduct2("x-amz-request-id", "x-amz-id-2")(S3ResponseElements.apply)

}

final case class S3(
s3SchemaVersion: String,
configurationId: String,
bucket: S3Bucket,
`object`: S3Object)

object S3 {

implicit val decoder: Decoder[S3] =
Decoder.forProduct4("s3SchemaVersion", "configurationId", "bucket", "object")(S3.apply)

}

final case class S3Bucket(name: String, ownerIdentity: S3UserIdentity, arn: String)

object S3Bucket {

implicit val decoder: Decoder[S3Bucket] =
Decoder.forProduct3("name", "ownerIdentity", "arn")(S3Bucket.apply)

}

final case class S3Object(
key: String,
size: Long,
eTag: String,
versionId: Option[String],
sequencer: String)

object S3Object {

implicit val decoder: Decoder[S3Object] =
Decoder.forProduct5("key", "size", "eTag", "versionId", "sequencer")(S3Object.apply)

}

final case class S3EventRecordGlacierEventData(
restoreEventData: S3EventRecordGlacierRestoreEventData)

object S3EventRecordGlacierEventData {

implicit val decoder: Decoder[S3EventRecordGlacierEventData] =
Decoder.forProduct1("restoreEventData")(S3EventRecordGlacierEventData.apply)

}

final case class S3EventRecordGlacierRestoreEventData(
lifecycleRestorationExpiryTime: Instant,
lifecycleRestoreStorageClass: String)

object S3EventRecordGlacierRestoreEventData {

implicit val decoder: Decoder[S3EventRecordGlacierRestoreEventData] =
Decoder.forProduct2("lifecycleRestorationExpiryTime", "lifecycleRestoreStorageClass")(
S3EventRecordGlacierRestoreEventData.apply
)

}
105 changes: 105 additions & 0 deletions lambda/shared/src/test/scala/feral/lambda/events/S3EventSuite.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2021 Typelevel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package feral.lambda.events

import io.circe.literal._
import munit.FunSuite

import java.time.Instant

class S3EventSuite extends FunSuite {

test("decoder") {
assertEquals(event.as[S3Event].toTry.get, result)
}

def event = json"""
{
"Records":[
{
"eventVersion":"2.1",
"eventSource":"aws:s3",
"awsRegion":"us-west-2",
"eventTime":"1970-01-01T00:00:00.000Z",
"eventName":"ObjectCreated:Put",
"userIdentity":{
"principalId":"AIDAJDPLRKLG7UEXAMPLE"
},
"requestParameters":{
"sourceIPAddress":"127.0.0.1"
},
"responseElements":{
"x-amz-request-id":"C3D13FE58DE4C810",
"x-amz-id-2":"FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"
},
"s3":{
"s3SchemaVersion":"1.0",
"configurationId":"testConfigRule",
"bucket":{
"name":"mybucket",
"ownerIdentity":{
"principalId":"A3NL1KOZZKExample"
},
"arn":"arn:aws:s3:::mybucket"
},
"object":{
"key":"HappyFace.jpg",
"size":1024,
"eTag":"d41d8cd98f00b204e9800998ecf8427e",
"versionId":"096fKKXTRTtl3on89fVO.nfljtsv6qko",
"sequencer":"0055AED6DCD90281E5"
}
}
}
]
}
"""

def result = S3Event(records = List(
S3EventRecord(
eventVersion = "2.1",
eventSource = "aws:s3",
awsRegion = "us-west-2",
eventTime = Instant.ofEpochSecond(0),
eventName = "ObjectCreated:Put",
userIdentity = S3UserIdentity("AIDAJDPLRKLG7UEXAMPLE"),
requestParameters = S3RequestParameters("127.0.0.1"),
responseElements = S3ResponseElements(
"C3D13FE58DE4C810",
"FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"
),
s3 = S3(
s3SchemaVersion = "1.0",
configurationId = "testConfigRule": String,
bucket = S3Bucket(
name = "mybucket",
ownerIdentity = S3UserIdentity("A3NL1KOZZKExample"),
arn = "arn:aws:s3:::mybucket"
),
`object` = S3Object(
key = "HappyFace.jpg",
size = 1024L,
eTag = "d41d8cd98f00b204e9800998ecf8427e",
versionId = Option("096fKKXTRTtl3on89fVO.nfljtsv6qko"),
sequencer = "0055AED6DCD90281E5"
)
),
glacierEventData = None
)
))

}

0 comments on commit ba6df30

Please sign in to comment.