Skip to content

Commit

Permalink
Merge 4d00e1c into 71c5d39
Browse files Browse the repository at this point in the history
  • Loading branch information
danonorato committed Sep 12, 2018
2 parents 71c5d39 + 4d00e1c commit b57b1ea
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 1 deletion.
1 change: 1 addition & 0 deletions localstack/ext/java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
<include>com.amazonaws:aws-java-sdk-core</include>
<include>com.amazonaws:aws-java-sdk-kinesis</include>
<include>com.amazonaws:aws-java-sdk-lambda</include>
<include>com.amazonaws:aws-java-sdk-s3</include>
<include>com.amazonaws:aws-lambda-java-events</include>
<include>com.amazonaws:aws-lambda-java-core</include>
<include>commons-*:*</include>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cloud.localstack;

import cloud.localstack.lambda.DDBEventParser;
import cloud.localstack.lambda.S3EventParser;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
Expand Down Expand Up @@ -91,8 +92,12 @@ public static void main(String[] args) throws Exception {

inputObject = DDBEventParser.parse(records);

} else if (records.stream().anyMatch(record -> record.containsKey("s3"))) {

inputObject = S3EventParser.parse(records);

}
//TODO: Support other events (S3, SQS...)
//TODO: Support other events (SQS...)
}

Context ctx = new LambdaContext();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package cloud.localstack.lambda;
import static cloud.localstack.LambdaExecutor.get;
import com.amazonaws.services.lambda.runtime.events.S3Event;
import com.amazonaws.services.s3.event.S3EventNotification;
import org.joda.time.DateTime;

import java.util.*;


public class S3EventParser {

public static S3Event parse(List<Map<String, Object>> records) {

// parse out items to construct the S3EventNotification
Map<String, Object> record = records.get(0);
Map<String, Object> rp = (Map<String, Object>) get(record, "requestParameters");
String sip = (String) get(rp,"sourceIPAddress");

Map<String, Object> re = (Map<String, Object>) get(record, "responseElements");
String xAmzld2 = (String) get(re,"x-amz-id-2");
String xAmzRequestId = (String) get(re,"x-amz-request-id");

Map<String, Object> s3 = (Map<String, Object>) get(record, "s3");
Map<String, Object> bk = (Map<String, Object>) get(s3, "bucket");
Map<String, Object> oi = (Map<String, Object>) get(bk, "ownerIdentity");
String bucketPrincipalId = (String) get(oi, "principalId");
String bucketName = (String) get(bk,"name");
String arn = (String) get(bk,"arn");
String s3SchemaVersion = (String) get(s3, "s3SchemaVersion");

Map<String, Object> obj = (Map<String, Object>) get(s3, "object");
String key = (String) get(obj,"key");
Long size = ((Number) get(obj,"size")).longValue();
String eTag = (String) get(obj,"eTag");
String versionId = (String) get(obj,"versionId");
String sequencer = (String) get(obj,"sequencer");
String configurationId = (String) get(s3,"configurationId");

String awsRegion = (String) get(record, "awsRegion");
String eventName = (String) get(record, "eventName");
String eventSource = (String) get(record, "eventSource");
String eventTime = (String) get(record, "eventTime");
String eventVersion = (String) get(record, "eventVersion");

Map<String, Object> ui = (Map<String, Object>) get(record, "userIdentity");
String principalId = (String) get(ui,"principalId");

// build up a S3Event to be passed to the Lambda
List s3Records = new LinkedList<>();

// bucket and S3ObjectEntity needed for S3Entity constructor
S3EventNotification.UserIdentityEntity bucketUserIdentityEntity = new S3EventNotification.UserIdentityEntity(bucketPrincipalId);
S3EventNotification.S3BucketEntity bucket = new S3EventNotification.S3BucketEntity(
bucketName,
bucketUserIdentityEntity,
arn);

S3EventNotification.S3ObjectEntity s3ObjectEntity = new S3EventNotification.S3ObjectEntity(
key,
size,
eTag,
versionId,
sequencer);

// S3Entity
S3EventNotification.S3Entity s3Entity = new S3EventNotification.S3Entity(
configurationId,
bucket,
s3ObjectEntity,
s3SchemaVersion);

// build S3EventNotificationRecord
S3EventNotification.RequestParametersEntity requestParameters = new S3EventNotification.RequestParametersEntity(sip);
S3EventNotification.ResponseElementsEntity responseEntity = new S3EventNotification.ResponseElementsEntity(xAmzld2, xAmzRequestId);
S3EventNotification.UserIdentityEntity eventNotifyUserIdentityEntity = new S3EventNotification.UserIdentityEntity(principalId);
S3EventNotification.S3EventNotificationRecord s3record = new S3EventNotification.S3EventNotificationRecord(
awsRegion,
eventName,
eventSource,
eventTime,
eventVersion,
requestParameters,
responseEntity,
s3Entity,
eventNotifyUserIdentityEntity);

// add the record to records list
s3Records.add(0, s3record);

// finally hydrate S3Event
return new S3Event(s3Records);

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package cloud.localstack;

import cloud.localstack.lambda.S3EventParser;
import com.amazonaws.services.lambda.runtime.events.S3Event;
import com.amazonaws.services.s3.event.S3EventNotification;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assert;
import org.junit.Test;

import java.util.List;
import java.util.Map;

import static cloud.localstack.LambdaExecutor.get;
import static cloud.localstack.LambdaExecutor.readFile;

public class S3EventMappingTest {

static String fileName = "src/test/resources/S3EventLambda.json";

@Test
public void testParseS3Event() throws Exception {
String fileContent = readFile(fileName);

ObjectMapper reader = new ObjectMapper();
@SuppressWarnings("deprecation")
Map<String,Object> map = reader.reader(Map.class).readValue(fileContent);
List<Map<String,Object>> records = (List<Map<String, Object>>) get(map, "Records");

S3Event s3Event = S3EventParser.parse(records);
S3EventNotification.S3EventNotificationRecord record = s3Event.getRecords().get(0);

Assert.assertTrue("eventVersion match", record.getEventVersion().contains("2.0"));
Assert.assertTrue("eventTime match", record.getEventTime().toString().equals("2018-08-23T21:41:36.511Z"));
Assert.assertTrue("sourceIPAddress match", record.getRequestParameters().getSourceIPAddress().equals("127.0.0.1"));

Assert.assertTrue("s3 configurationId match", record.getS3().getConfigurationId().equals("testConfigRule"));
Assert.assertTrue("s3 object versionId match", record.getS3().getObject().getVersionId().equals("096fKKXTRTtl3on89fVO.nfljtsv6qko"));
Assert.assertTrue("s3 object eTag match", record.getS3().getObject().geteTag().equals("d41d8cd98f00b204e9800998ecf8427e"));
Assert.assertTrue("s3 object key match", record.getS3().getObject().getKey().equals("key/file.txt"));
Assert.assertTrue("s3 object sequencer match", record.getS3().getObject().getSequencer().equals("0055AED6DCD90281E5"));
Assert.assertTrue("s3 object size match", record.getS3().getObject().getSizeAsLong().equals(1024L));
Assert.assertTrue("s3 ownerEntity principalId match", record.getS3().getBucket().getOwnerIdentity().getPrincipalId().equals("A3NL1KOZZKExample"));
Assert.assertTrue("s3 bucket name match", record.getS3().getBucket().getName().equals("bucket-name"));
Assert.assertTrue("s3 bucket arn match", record.getS3().getBucket().getArn().equals("arn:aws:s3:::bucket-name"));
Assert.assertTrue("s3 schemaVersion match", record.getS3().getS3SchemaVersion().equals("1.0"));

Assert.assertTrue("responseElements x-amz-id-2 match", record.getResponseElements().getxAmzId2().equals("eftixk72aD6Ap51TnqcoF8eFidJG9Z/2"));
Assert.assertTrue("responseElements x-amz-request-id match", record.getResponseElements().getxAmzRequestId().equals("8a0c0d15"));
Assert.assertTrue("awsRegion", record.getAwsRegion().equals("us-east-1"));
Assert.assertTrue("eventName", record.getEventName().equals("ObjectCreated:Put"));
Assert.assertTrue("userIdentity principalId", record.getUserIdentity().getPrincipalId().equals("AIDAJDPLRKLG7UEXAMPLE"));
Assert.assertTrue("eventSource match", record.getEventSource().equals("aws:s3"));

}

}

39 changes: 39 additions & 0 deletions localstack/ext/java/src/test/resources/S3EventLambda.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"Records": [
{
"eventVersion": "2.0",
"eventTime": "2018-08-23T21:41:36.511Z",
"requestParameters": {
"sourceIPAddress": "127.0.0.1"
},
"s3": {
"configurationId": "testConfigRule",
"object": {
"versionId": "096fKKXTRTtl3on89fVO.nfljtsv6qko",
"eTag": "d41d8cd98f00b204e9800998ecf8427e",
"key": "key/file.txt",
"sequencer": "0055AED6DCD90281E5",
"size": 1024
},
"bucket": {
"ownerIdentity": {
"principalId": "A3NL1KOZZKExample"
},
"name": "bucket-name",
"arn": "arn:aws:s3:::bucket-name"
},
"s3SchemaVersion": "1.0"
},
"responseElements": {
"x-amz-id-2": "eftixk72aD6Ap51TnqcoF8eFidJG9Z/2",
"x-amz-request-id": "8a0c0d15"
},
"awsRegion": "us-east-1",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "AIDAJDPLRKLG7UEXAMPLE"
},
"eventSource": "aws:s3"
}
]
}

0 comments on commit b57b1ea

Please sign in to comment.