Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding event for SES #176

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.amazonaws.services.lambda.runtime.events;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.joda.time.DateTime;

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

/**
* Represent an event received from SES when it receives an incoming message.
*
* See <a href="https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-action-lambda.html">documentation</a>.
*/
@Data
@AllArgsConstructor
@Builder(setterPrefix = "with")
@NoArgsConstructor
public class SESEvent {

private List<Record> records;

@Data
@AllArgsConstructor
@Builder(setterPrefix = "with")
@NoArgsConstructor
public static class Record {
private String eventSource;
private String eventVersion;
private Ses ses;
}

@Data
@AllArgsConstructor
@Builder(setterPrefix = "with")
@NoArgsConstructor
public static class Ses {
private Mail mail;
private Receipt receipt;
}

@Data
@AllArgsConstructor
@Builder(setterPrefix = "with")
@NoArgsConstructor
public static class Mail {
private DateTime timestamp;
private String source;
private String messageId;
private String[] destination;
private boolean headersTruncated;
private List<Header> headers;
private CommonHeaders commonHeaders;
}

@Data
@AllArgsConstructor
@Builder(setterPrefix = "with")
@NoArgsConstructor
public static class Header {
private String name;
private String value;
}

@Data
@AllArgsConstructor
@Builder(setterPrefix = "with")
@NoArgsConstructor
public static class CommonHeaders {
private String returnPath;
private String[] from;
private String date;
private String[] to;
private String messageId;
private String subject;
}

@Data
@AllArgsConstructor
@Builder(setterPrefix = "with")
@NoArgsConstructor
public static class Receipt {
private DateTime timestamp;
private long processingTimeMillis;
private String[] recipients;
private Action action;
private Verdict spamVerdict;
private Verdict virusVerdict;
private Verdict spfVerdict;
private Verdict dkimVerdict;
private Verdict dmarcVerdict;
}

@Data
@AllArgsConstructor
@Builder(setterPrefix = "with")
@NoArgsConstructor
public static class Action {
private String type;
private String functionArn;
private String invocationType;
}

@Data
@AllArgsConstructor
@Builder(setterPrefix = "with")
@NoArgsConstructor
public static class Verdict {
private String status;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,7 @@

package com.amazonaws.services.lambda.runtime.serialization.events;

import com.amazonaws.services.lambda.runtime.serialization.events.mixins.CloudFormationCustomResourceEventMixin;
import com.amazonaws.services.lambda.runtime.serialization.events.mixins.CloudFrontEventMixin;
import com.amazonaws.services.lambda.runtime.serialization.events.mixins.CloudWatchLogsEventMixin;
import com.amazonaws.services.lambda.runtime.serialization.events.mixins.CodeCommitEventMixin;
import com.amazonaws.services.lambda.runtime.serialization.events.mixins.ConnectEventMixin;
import com.amazonaws.services.lambda.runtime.serialization.events.mixins.DynamodbEventMixin;
import com.amazonaws.services.lambda.runtime.serialization.events.mixins.KinesisEventMixin;
import com.amazonaws.services.lambda.runtime.serialization.events.mixins.SNSEventMixin;
import com.amazonaws.services.lambda.runtime.serialization.events.mixins.SQSEventMixin;
import com.amazonaws.services.lambda.runtime.serialization.events.mixins.ScheduledEventMixin;
import com.amazonaws.services.lambda.runtime.serialization.events.mixins.SecretsManagerRotationEventMixin;
import com.amazonaws.services.lambda.runtime.serialization.events.mixins.*;
import com.amazonaws.services.lambda.runtime.serialization.factories.JacksonFactory;
import com.amazonaws.services.lambda.runtime.serialization.PojoSerializer;
import com.amazonaws.services.lambda.runtime.serialization.util.ReflectUtil;
Expand Down Expand Up @@ -73,6 +63,7 @@ public class LambdaEventSerializers {
"com.amazonaws.services.s3.event.S3EventNotification",
"com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification",
"com.amazonaws.services.lambda.runtime.events.S3Event",
"com.amazonaws.services.lambda.runtime.events.SESEvent",
"com.amazonaws.services.lambda.runtime.events.SNSEvent",
"com.amazonaws.services.lambda.runtime.events.SQSEvent")
.collect(Collectors.toList());
Expand Down Expand Up @@ -136,6 +127,8 @@ public class LambdaEventSerializers {
ScheduledEventMixin.class),
new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SecretsManagerRotationEvent",
SecretsManagerRotationEventMixin.class),
new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SESEvent",
SESEventMixin.class),
new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SNSEvent",
SNSEventMixin.class),
new SimpleEntry<>("com.amazonaws.services.lambda.runtime.events.SNSEvent$SNSRecord",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.amazonaws.services.lambda.runtime.serialization.events.mixins;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

public abstract class SESEventMixin {

// needed because Jackson expects "records" instead of "Records"
@JsonProperty("Records") abstract List<?> getRecords();
@JsonProperty("Records") abstract void setRecords(List<?> records);
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ public static ScheduledEvent loadScheduledEvent(String filename) {
return loadEvent(filename, ScheduledEvent.class);
}

public static SESEvent loadSESEvent(String filename) {
return loadEvent(filename, SESEvent.class);
}

public static SNSEvent loadSNSEvent(String filename) {
return loadEvent(filename, SNSEvent.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,4 +300,13 @@ public void testLoadSecretsManagerRotationEvent() {
.returns("arn:aws:secretsmanager:eu-central-1:123456789012:secret:/powertools/secretparam-xBPaJ5", from(SecretsManagerRotationEvent::getSecretId))
.returns("CreateSecret", from(SecretsManagerRotationEvent::getStep));
}

@Test
public void testLoadSESEvent() {
SESEvent event = EventLoader.loadSESEvent("ses_event.json");
assertThat(event).isNotNull();
assertThat(event.getRecords()).hasSize(1);
assertThat(event.getRecords().get(0).getSes().getMail().getDestination()[0]).isEqualTo("recipient@example.com");
assertThat(event.getRecords().get(0).getSes().getMail().getHeaders()).hasSize(29);
}
}
136 changes: 136 additions & 0 deletions aws-lambda-java-tests/src/test/resources/ses_event.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
{
"Records": [{
"eventSource": "aws:ses",
"eventVersion": "1.0",
"ses": {
"mail": {
"timestamp": "2019-08-05T21:30:02.028Z",
"source": "prvs=144d0cba7=sender@example.com",
"messageId": "EXAMPLE7c191be45-e9aedb9a-02f9-4d12-a87d-dd0099a07f8a-000000",
"destination": ["recipient@example.com"],
"headersTruncated": false,
"headers": [{
"name": "Return-Path",
"value": "<prvs=144d0cba7=sender@example.com>"
}, {
"name": "Received",
"value": "from smtp.example.com [203.0.113.0]) by inbound-smtp.us-east-1.amazonaws.com with SMTP id bsvpsoklfhu7u50iur7h0kk9a2ou0r7iexample for recipient@example.com;Mon, 05 Aug 2019 21:30:02 +0000 (UTC)"
}, {
"name": "X-SES-Spam-Verdict",
"value": "PASS"
}, {
"name": "X-SES-Virus-Verdict",
"value": "PASS"
}, {
"name": "Received-SPF",
"value": "pass (spfCheck: domain of example.com designates 203.0.113.0 as permitted sender) client-ip=203.0.113.0; envelope-from=prvs=144d0cba42=sender@example.com; helo=smtp.example.com;"
}, {
"name": "Authentication-Results",
"value": "amazonses.com; spf=pass (spfCheck: domain of example.com designates 203.0.113.0as permitted sender) client-ip=203.0.113.0; envelope-from=prvs=144d0cba42=sender@example.com; helo=smtp.example.com; dkim=pass header.i=@example.com; dmarc=none header.from=example.com;"
}, {
"name": "X-SES-RECEIPT",
"value": "AEFBQUFBQUFBQUFHbFo0VU81VzVuYmRDNm51nhTVWpabDh6J4V2l5cG5PSHFtNzlBeUk90example"
}, {
"name": "X-SES-DKIM-SIGNATURE",
"value": "a=rsa-sha256; q=dns/txt; b=Cm1emU30VcD6example=; c=relaxed/simple; s=6gbrjpgwjs5zn6fwqknexample; d=amazonses.com; t=1567719002; v=1; bh=DSofsjAoUvyZj6YsBDP5enpRO1otGb7Nes0Qexample=; h=From:To:Cc:Bcc:Subject:Date:Message-ID:MIME-Version:Content-Type:X-SES-RECEIPT;"
}, {
"name": "DKIM-Signature",
"value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; i=@example.com; q=dns/txt; s=example12345; t=1567719001; x=1599255001; h=from:to:subject:date:message-id:references:in-reply-to:mime-version; bh=sjAoUvyZj6YsBDP5enpRO1otGb7s0Qexample=; b=EQw2D4RLOW2IHE9OgfEA4WXp+AENJtaD2+63wmd5J+d+t/xoaiKUGClOS7WhpyOmlipryOz+iOhxUv350xJIHjLTi9Jsnlw76mRK8o4770TaUz620joCVN21n4cxsrRZpv+1kS0EcAxaF30pmwlni+XT4emsVxn7zO0I8example=;"
}, {
"name": "Received",
"value": "from mail.example.com (mail.example.com [203.0.113.0]) by email-inbound-relay-1d-9ec21598.us-east-1.example.com (Postfix) with ESMTPS id 57F83A2042 for <recipient@example.com>; Mon, 5 Aug 2019 21:29:58 +0000 (UTC)"
}, {
"name": "From",
"value": "\"Doe, John\" <sender@example.com>"
}, {
"name": "To",
"value": "\"recipient@example.com\" <recipient@example.com>"
}, {
"name": "Subject",
"value": "This is a test"
}, {
"name": "Thread-Topic",
"value": "This is a test"
}, {
"name": "Thread-Index",
"value": "AQHVZDAaQ58yKI8q7kaAjkhC5stGexample"
}, {
"name": "Date",
"value": "Mon, 5 Aug 2019 21:29:57 +0000"
}, {
"name": "Message-ID",
"value": "<F8098FDD-49A3-442D-9935-F6112example@example.com>"
}, {
"name": "References",
"value": "<1FCED16B-F6B0-4506-A6F0-594DFexample@example.com>"
}, {
"name": "In-Reply-To",
"value": "<1FCED16B-F6B0-4506-A6F0-594DFexample@example.com>"
}, {
"name": "Accept-Language",
"value": "en-US"
}, {
"name": "Content-Language",
"value": "en-US"
}, {
"name": "X-MS-Has-Attach",
"value": ""
}, {
"name": "X-MS-TNEF-Correlator",
"value": ""
}, {
"name": "x-ms-exchange-messagesentrepresentingtype",
"value": "1"
}, {
"name": "x-ms-exchange-transport-fromentityheader",
"value": "Hosted"
}, {
"name": "x-originating-ip",
"value": "[203.0.113.0]"
}, {
"name": "Content-Type",
"value": "multipart/alternative; boundary=\"_000_F8098FDD49A344F6112B195BDAexamplecom_\""
}, {
"name": "MIME-Version",
"value": "1.0"
}, {
"name": "Precedence",
"value": "Bulk"
}],
"commonHeaders": {
"returnPath": "prvs=144d0cba7=sender@example.com",
"from": ["\"Doe, John\" <sender@example.com>"],
"date": "Mon, 5 Aug 2019 21:29:57 +0000",
"to": ["\"recipient@example.com\" <recipient@example.com>"],
"messageId": "<F8098FDD-49A3-442D-9935-F6112B195BDA@example.com>",
"subject": "This is a test"
}
},
"receipt": {
"timestamp": "2019-08-05T21:30:02.028Z",
"processingTimeMillis": 1205,
"recipients": ["recipient@example.com"],
"spamVerdict": {
"status": "PASS"
},
"virusVerdict": {
"status": "PASS"
},
"spfVerdict": {
"status": "PASS"
},
"dkimVerdict": {
"status": "PASS"
},
"dmarcVerdict": {
"status": "GRAY"
},
"action": {
"type": "Lambda",
"functionArn": "arn:aws:lambda:us-east-1:123456789012:function:IncomingEmail",
"invocationType": "Event"
}
}
}
}]
}