/
handle-request.js
109 lines (89 loc) · 3.17 KB
/
handle-request.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
const AWS = require("aws-sdk"); // eslint-disable-line import/no-extraneous-dependencies
const moment = require("moment");
const { parseContext } = require("./lib/context");
const { publishToSns } = require("./lib/sns");
const buildTopicArns = ({
accountId,
region,
}, {
completeSnsTopic,
failedSnsTopic,
}) => ({
snsFailureTopicArn: `arn:aws:sns:${region}:${accountId}:${failedSnsTopic}`,
snsCompleteTopicArn: `arn:aws:sns:${region}:${accountId}:${completeSnsTopic}`,
});
const dynamoTableName = () => `${process.env.service || "checkless"}_lastResult`;
const buildKey = (name, region) => `${name}_${region}`;
const getStateHistoryValues = (success, previousResult) => {
if (!previousResult || previousResult.success !== success) {
return {
lastStateChange: moment().format(),
checksInState: 1,
};
}
const { lastStateChange, checksInState } = previousResult;
return {
lastStateChange,
checksInState: checksInState + 1,
};
};
const buildDynamoRecord = ({ success, name, region }, previousResult) => ({
key: `${name}_${region}`,
success,
...getStateHistoryValues(success, previousResult),
});
const storeResultToDynamo = async (homeRegion, item) => {
const dynamodb = new AWS.DynamoDB.DocumentClient({ region: homeRegion });
return dynamodb.put({
TableName: dynamoTableName(),
Item: item,
}).promise();
};
const getLastResultFromDynamo = async (homeRegion, { name, region }) => {
const dynamodb = new AWS.DynamoDB.DocumentClient({ region: homeRegion });
const record = await dynamodb.get({
TableName: dynamoTableName(),
Key: buildKey(name, region),
}).promise();
return record.Item;
};
module.exports.handleRequest = async (event, context, callback) => {
const result = JSON.parse(event.Records[0].Sns.Message);
const parsedContext = parseContext(context);
const homeRegion = parsedContext.region;
const previousResult = process.env.storeResult
? await getLastResultFromDynamo(homeRegion, result)
: undefined;
const {
snsFailureTopicArn,
snsCompleteTopicArn,
} = buildTopicArns(parsedContext, process.env);
const topicsToSendTo = [
{
topicArn: snsCompleteTopicArn,
title: `SITE RESULT: ${result.url}`,
message: result,
},
...(result.success ? [] : [
{
topicArn: snsFailureTopicArn,
title: `SITE FAIL: ${result.url}`,
message: result,
},
]),
];
console.log(`Handling request for ${result.url} (${result.location}), success: ${result.success}, sendingToTopics: ${topicsToSendTo.map(({ topicArn }) => topicArn).join(", ")}`);
try {
await Promise.all(topicsToSendTo.map(({
topicArn,
title,
message,
}) => publishToSns(topicArn, title, message)));
} catch (error) {
console.error(`Error sending SNS: ${error.message}`);
}
if (process.env.storeResult) {
await storeResultToDynamo(homeRegion, buildDynamoRecord(result, previousResult));
}
return callback();
};