Skip to content

Commit 6e4963a

Browse files
committed
Initial code for the exercise.
1 parent 662d212 commit 6e4963a

File tree

5 files changed

+390
-0
lines changed

5 files changed

+390
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package lambda;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
import com.amazonaws.regions.Region;
7+
import com.amazonaws.regions.Regions;
8+
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
9+
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
10+
import com.amazonaws.services.dynamodbv2.model.AttributeValueUpdate;
11+
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
12+
import com.amazonaws.services.dynamodbv2.model.PutItemResult;
13+
import com.amazonaws.services.dynamodbv2.model.UpdateItemRequest;
14+
import com.amazonaws.services.dynamodbv2.model.UpdateItemResult;
15+
import com.amazonaws.services.lambda.runtime.Context;
16+
import com.amazonaws.services.lambda.runtime.RequestHandler;
17+
18+
/**
19+
*
20+
* @author markusklems
21+
*
22+
*/
23+
public class LambdaApprovalFunctionHandler implements
24+
RequestHandler<Object, Object> {
25+
26+
private static AmazonDynamoDBClient dynamoDB;
27+
28+
@Override
29+
public Object handleRequest(Object input, Context context) {
30+
context.getLogger().log("input: " + input);
31+
if (input.toString().equals("{}") || input.toString().equals("")) {
32+
context.getLogger().log("input is empty: abort");
33+
return "{\"status\":\"error\",\"message\":\"input at lambda function is empty\"}";
34+
}
35+
36+
dynamoDB = new AmazonDynamoDBClient().withRegion(Region
37+
.getRegion(Regions.EU_WEST_1));
38+
39+
HashMap<String, String> mapInput = (HashMap<String, String>) input;
40+
Map<String, AttributeValue> employeeKey = new HashMap<String, AttributeValue>();
41+
String employeeId = mapInput.get("employee_id");
42+
context.getLogger().log("employee_id: " + employeeId);
43+
employeeKey.put("employee_id", new AttributeValue().withS(employeeId));
44+
Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<String, AttributeValueUpdate>();
45+
attributeUpdates.put("approval", new AttributeValueUpdate()
46+
.withValue(new AttributeValue().withS("approved")));
47+
UpdateItemRequest updateItemRequest = new UpdateItemRequest()
48+
.withKey(employeeKey).withAttributeUpdates(attributeUpdates)
49+
.withTableName("lambda-reimbursment");
50+
UpdateItemResult updateItemResult = dynamoDB
51+
.updateItem(updateItemRequest);
52+
context.getLogger().log("Result: " + updateItemResult);
53+
54+
return "{'status':'done'}";
55+
}
56+
57+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package lambda;
2+
3+
import java.util.Map.Entry;
4+
5+
import com.amazonaws.regions.Region;
6+
import com.amazonaws.regions.Regions;
7+
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
8+
import com.amazonaws.services.dynamodbv2.model.StreamRecord;
9+
import com.amazonaws.services.lambda.runtime.Context;
10+
import com.amazonaws.services.lambda.runtime.RequestHandler;
11+
import com.amazonaws.services.lambda.runtime.events.DynamodbEvent;
12+
import com.amazonaws.services.lambda.runtime.events.DynamodbEvent.DynamodbStreamRecord;
13+
import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClient;
14+
import com.amazonaws.services.simpleemail.model.Body;
15+
import com.amazonaws.services.simpleemail.model.Content;
16+
import com.amazonaws.services.simpleemail.model.Destination;
17+
import com.amazonaws.services.simpleemail.model.Message;
18+
import com.amazonaws.services.simpleemail.model.SendEmailRequest;
19+
20+
public class LambdaSendMailFunctionHandler implements
21+
RequestHandler<DynamodbEvent, Object> {
22+
23+
static final String BODY = "This email was sent through Amazon SES by using the AWS SDK for Java.";
24+
static final String SUBJECT = "Amazon SES test (AWS SDK for Java)";
25+
26+
@Override
27+
public Object handleRequest(DynamodbEvent input, Context context) {
28+
String employeeId = "";
29+
String employeeName = "";
30+
String expenseType = "";
31+
Double amount = 0.0;
32+
33+
for (DynamodbStreamRecord r : input.getRecords()) {
34+
// context.getLogger().log("Event id: "+r.getEventID());
35+
// context.getLogger().log("Event name: "+r.getEventName());
36+
// context.getLogger().log("Event source: "+r.getEventSource());
37+
StreamRecord sr = r.getDynamodb();
38+
for (Entry<String, AttributeValue> entry : sr.getNewImage()
39+
.entrySet()) {
40+
String k = entry.getKey();
41+
AttributeValue v = entry.getValue();
42+
switch (k) {
43+
case "employee_id":
44+
employeeId = v.getS();
45+
break;
46+
case "employee_name":
47+
employeeName = v.getS();
48+
break;
49+
case "expense_type":
50+
expenseType = v.getS();
51+
break;
52+
case "amount":
53+
amount = Double.valueOf(entry.getValue().getN());
54+
break;
55+
default:
56+
context.getLogger().log("Key " + k + " is unknown.");
57+
}
58+
}
59+
}
60+
61+
context.getLogger().log(
62+
"ENTRY: " + employeeId + " | " + employeeName + " | "
63+
+ expenseType + " | " + amount);
64+
65+
String from = "klems@tu-berlin.de"; // TODO Replace with your "From" address.
66+
// This address must be verified.
67+
String to = "klems@tu-berlin.de"; // TODO Replace with a "To" address. If you
68+
// have not yet requested production
69+
// access, this address must be
70+
// verified.
71+
String subject = String.format("Expense reimbursment request by %s",
72+
employeeName);
73+
// TODO Replace with your own approval URL
74+
String approvalUrl = String
75+
.format("https://.......execute-api.eu-west-1.amazonaws.com/test/reimbursment?id=%s",
76+
employeeId);
77+
String body = String
78+
.format("Hello boss,\n\nplease approve my expense reimbursment:\n%s\n\nExpense type: %s\nAmount: %s EUR\n\nThanks!\n%s\nEmployee ID: %s ",
79+
approvalUrl, expenseType, amount, employeeName,
80+
employeeId);
81+
sendMail(from, to, subject, body);
82+
context.getLogger().log("Email sent from " + from + " to " + to);
83+
84+
return null;
85+
}
86+
87+
private void sendMail(final String from, final String to,
88+
final String subjectStr, final String bodyStr) {
89+
// Construct an object to contain the recipient address.
90+
Destination destination = new Destination()
91+
.withToAddresses(new String[] { to });
92+
93+
// Create the subject and body of the message.
94+
Content subject = new Content().withData(subjectStr);
95+
Content textBody = new Content().withData(bodyStr);
96+
Body body = new Body().withText(textBody);
97+
98+
// Create a message with the specified subject and body.
99+
Message message = new Message().withSubject(subject).withBody(body);
100+
101+
// TODO Assemble the email.
102+
103+
// TODO Send the email.
104+
105+
}
106+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package lambda;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
import com.amazonaws.regions.Region;
7+
import com.amazonaws.regions.Regions;
8+
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
9+
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
10+
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
11+
import com.amazonaws.services.dynamodbv2.model.PutItemResult;
12+
import com.amazonaws.services.lambda.runtime.Context;
13+
import com.amazonaws.services.lambda.runtime.RequestHandler;
14+
15+
/**
16+
*
17+
* @author markusklems
18+
*
19+
*/
20+
public class LambdaFormFunctionHandler implements
21+
RequestHandler<Object, Object> {
22+
23+
private static AmazonDynamoDBClient dynamoDB;
24+
25+
/**
26+
* Example object:
27+
*
28+
* {"employee_id":"1", "employee_name":"John Doh", "expense_type":"travel",
29+
* "amount": "2565.75" }
30+
*/
31+
@Override
32+
public Object handleRequest(Object input, Context context) {
33+
dynamoDB = new AmazonDynamoDBClient().withRegion(Region
34+
.getRegion(Regions.EU_WEST_1));
35+
// TODO
36+
// Parse the input object into a DynamoDB item, e.g., by using the newItem helper method
37+
// Create a PutItemRequest and send the request at the DynamoDB table with name 'lambda-reimbursment'
38+
39+
return "{'status':'done'}";
40+
}
41+
42+
/**
43+
* Helper method.
44+
*
45+
* @param employee_id
46+
* @param employee_name
47+
* @param expense_type
48+
* @param amount
49+
* @return DynamoDB item
50+
*/
51+
private static Map<String, AttributeValue> newItem(String employee_id,
52+
String employee_name, String expense_type, String amount) {
53+
Map<String, AttributeValue> item = new HashMap<String, AttributeValue>();
54+
item.put("employee_id", new AttributeValue((String) employee_id));
55+
item.put("employee_name", new AttributeValue((String) employee_name));
56+
item.put("expense_type", new AttributeValue((String) expense_type));
57+
item.put("amount", new AttributeValue().withN(amount));
58+
return item;
59+
}
60+
61+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package lambda;
2+
3+
import java.io.IOException;
4+
import java.util.HashMap;
5+
6+
import org.junit.BeforeClass;
7+
import org.junit.Test;
8+
9+
import com.amazonaws.services.lambda.runtime.Context;
10+
11+
/**
12+
* A simple test harness for locally invoking your Lambda function handler.
13+
*/
14+
public class LambdaFormFunctionHandlerTest {
15+
16+
private static Object input;
17+
18+
@BeforeClass
19+
public static void createInput() throws IOException {
20+
// TODO: set up your sample input object here.
21+
HashMap<String, String> hashMap = new HashMap<String, String>();
22+
hashMap.put("employee_id", "99");
23+
hashMap.put("employee_name", "Jimmy");
24+
hashMap.put("expense_type", "travel");
25+
hashMap.put("amount", "465.98");
26+
input = hashMap ;
27+
}
28+
29+
private Context createContext() {
30+
TestContext ctx = new TestContext();
31+
32+
// TODO: customize your context here if needed.
33+
ctx.setFunctionName("LambdaForm");
34+
35+
return ctx;
36+
}
37+
38+
@Test
39+
public void testLambdaFormFunctionHandler() {
40+
LambdaFormFunctionHandler handler = new LambdaFormFunctionHandler();
41+
Context ctx = createContext();
42+
43+
Object output = handler.handleRequest(input, ctx);
44+
45+
// TODO: validate output here if needed.
46+
if (output != null) {
47+
System.out.println(output.toString());
48+
}
49+
}
50+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package lambda;
2+
3+
import com.amazonaws.services.lambda.runtime.ClientContext;
4+
import com.amazonaws.services.lambda.runtime.CognitoIdentity;
5+
import com.amazonaws.services.lambda.runtime.Context;
6+
import com.amazonaws.services.lambda.runtime.LambdaLogger;
7+
8+
/**
9+
* A simple mock implementation of the {@code Context} interface. Default
10+
* values are stubbed out, and setters are provided so you can customize
11+
* the context before passing it to your function.
12+
*/
13+
public class TestContext implements Context {
14+
15+
private String awsRequestId = "EXAMPLE";
16+
private ClientContext clientContext;
17+
private String functionName = "EXAMPLE";
18+
private CognitoIdentity identity;
19+
private String logGroupName = "EXAMPLE";
20+
private String logStreamName = "EXAMPLE";
21+
private LambdaLogger logger = new TestLogger();
22+
private int memoryLimitInMB = 128;
23+
private int remainingTimeInMillis = 15000;
24+
25+
@Override
26+
public String getAwsRequestId() {
27+
return awsRequestId;
28+
}
29+
30+
public void setAwsRequestId(String value) {
31+
awsRequestId = value;
32+
}
33+
34+
@Override
35+
public ClientContext getClientContext() {
36+
return clientContext;
37+
}
38+
39+
public void setClientContext(ClientContext value) {
40+
clientContext = value;
41+
}
42+
43+
@Override
44+
public String getFunctionName() {
45+
return functionName;
46+
}
47+
48+
public void setFunctionName(String value) {
49+
functionName = value;
50+
}
51+
52+
@Override
53+
public CognitoIdentity getIdentity() {
54+
return identity;
55+
}
56+
57+
public void setIdentity(CognitoIdentity value) {
58+
identity = value;
59+
}
60+
61+
@Override
62+
public String getLogGroupName() {
63+
return logGroupName;
64+
}
65+
66+
public void setLogGroupName(String value) {
67+
logGroupName = value;
68+
}
69+
70+
@Override
71+
public String getLogStreamName() {
72+
return logStreamName;
73+
}
74+
75+
public void setLogStreamName(String value) {
76+
logStreamName = value;
77+
}
78+
79+
@Override
80+
public LambdaLogger getLogger() {
81+
return logger;
82+
}
83+
84+
public void setLogger(LambdaLogger value) {
85+
logger = value;
86+
}
87+
88+
@Override
89+
public int getMemoryLimitInMB() {
90+
return memoryLimitInMB;
91+
}
92+
93+
public void setMemoryLimitInMB(int value) {
94+
memoryLimitInMB = value;
95+
}
96+
97+
@Override
98+
public int getRemainingTimeInMillis() {
99+
return remainingTimeInMillis;
100+
}
101+
102+
public void setRemainingTimeInMillis(int value) {
103+
remainingTimeInMillis = value;
104+
}
105+
106+
/**
107+
* A simple {@code LambdaLogger} that prints everything to stderr.
108+
*/
109+
private static class TestLogger implements LambdaLogger {
110+
111+
@Override
112+
public void log(String message) {
113+
System.err.println(message);
114+
}
115+
}
116+
}

0 commit comments

Comments
 (0)