-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
148 lines (122 loc) · 4.48 KB
/
index.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
"use strict";
const mongoose = require("mongoose");
const request = require('request-promise');
// DATABASE mongo URI should be set via Lambda env
const uri = process.env.DATABASE;
// scope dbconnection globally
let dbConnection = null;
// lambda entry handler
exports.handler = async function(event, context) {
let time;
const logTime = (msg) => {
if(msg) {
const diff = process.hrtime(time);
console.log(`${msg}: ${diff[0]}.${diff[1].toString().substr(0,2)}s`);
}
time = process.hrtime();
}
context.callbackWaitsForEmptyEventLoop = false;
// if database connection not active, create it in global scope
if (dbConnection == null) {
logTime();
try {
dbConnection = await mongoose.createConnection(uri, {
bufferCommands: false,
bufferMaxEntries: 0,
useNewUrlParser: true,
useCreateIndex: true
});
}
catch(err) {
const response = { "statusCode": 500, "body": err }
context.fail(JSON.stringify(response));
}
// create model and attach to global database connection
const eventSchema = require('./models/event');
dbConnection.model('Event', eventSchema);
logTime('DB Connection Setup');
}
//swap out event for test file when in dev
if(process.env.TESTFILE) {
event = require(process.env.TESTFILE);
}
const query = event.params.querystring;
const site_name = query.s || '';
event = event['body-json'];
if(process.env.LEGACY_WEBHOOK_URI) {
try {
logTime();
let webhookUri = process.env.LEGACY_WEBHOOK_URI + '?s=' + site_name;
console.log('webhookUri', webhookUri);
// pull webhook uri from environment
const options = {
method: 'POST',
uri: webhookUri,
body: event,
json: true
};
await request(options);
logTime('Legacy Webhook Request');
}
catch(err) {
const response = { "statusCode": 500, "body": err }
context.fail(JSON.stringify(response));
}
}
const eventModel = dbConnection.model('Event');
// get event data from gateway passthrough
let eventData = event;
console.log('events received: ',eventData.length);
logTime();
// if event data is a string, parse it
if(typeof eventData == "string") {
eventData = JSON.parse(eventData);
}
// separate unpacked fields and put everything else in eventData embedded data
try {
const handledFields = Object.keys(eventModel.schema.obj);
eventData = eventData.map(event => {
let mappedEvent = { 'site_name': site_name, 'info': {} };
Object.keys(event).forEach(key => {
if (handledFields.indexOf(key) > -1) {
mappedEvent[key] = event[key];
} else {
mappedEvent.info[key] = event[key];
}
});
return mappedEvent;
});
}
catch(err) {
const response = { "statusCode": 500, "body": err }
context.fail(JSON.stringify(response));
}
logTime('Prepare Data');
// initialise return result
const result = { received: eventData.length, dupes: 0, errors: 0 };
logTime();
await new Promise((resolve, reject) => {
// insert records
eventModel.insertMany(eventData, { ordered: false }, (error) => {
// count dupes and non-dupe errors
if(error && error.writeErrors) {
result.dupes = error.writeErrors.filter( error => error.err.code == 11000 ).length;
result.errors = error.writeErrors.length - result.dupes;
}
resolve(true);
});
});
logTime('Database Inserts');
if(result.errors > 0) {
console.error('errorsFoundInData', { allEventData: eventData, insertResult: result });
}
if(result.dupes > 0) {
console.warn('dupesFoundInData', { allEventData: eventData, insertResult: result });
}
const statusCode = result.errors ? 500 : 200
const response = { "statusCode": statusCode, "body": result }
if(statusCode !== 200) {
context.fail(JSON.stringify(response));
}
return response;
};