-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
102 lines (84 loc) · 2.37 KB
/
index.js
File metadata and controls
102 lines (84 loc) · 2.37 KB
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
const crypto = require("crypto");
const _ = {
get: require("lodash.get"),
merge: require("lodash.merge")
};
const AWS = require("aws-sdk");
const { DataSource } = require("apollo-datasource");
const { InMemoryLRUCache } = require("apollo-server-caching");
const bunyan = require("bunyan");
const DEFAULT_TTL = 5;
const logger = bunyan.createLogger({
name: "AWSLambdaDataSource",
level: _.get(process.env, "LOG_LEVEL", "INFO")
});
class AWSLambdaDataSource extends DataSource {
constructor(awsOptions = {}, invokeOptions) {
super();
this.context;
this.cache;
this.lambda = new AWS.Lambda(awsOptions);
this.invokeOptions = invokeOptions;
}
initialize(config) {
this.context = config.context;
this.cache = config.cache || new InMemoryLRUCache();
}
createCacheKey(params) {
logger.debug(`createCacheKey got params: ${JSON.stringify(params)}`);
const {
ClientContext = null,
FunctionName,
InvocationType = "RequestResponse",
Payload = null,
Qualifier = null
} = params;
logger.debug(Payload, "hashing payload");
const hashedPayload = crypto
.createHash("md5")
.update(Payload)
.digest("base64");
const key = [
`ClientContext:${ClientContext}`,
`FunctionName:${FunctionName}`,
`InvocationType:${InvocationType}`,
`Qualifier:${Qualifier}`,
`Payload:${hashedPayload}`
].join("_");
logger.debug(`raw cache key = "${key}"`);
return crypto
.createHash("sha1")
.update(key)
.digest("base64");
}
invoke(event, ttl = DEFAULT_TTL) {
const params = _.merge(
{
Payload: event
},
this.invokeOptions
);
logger.debug(params, "invoke params");
const cacheKey = this.createCacheKey(params);
return this.cache.get(cacheKey).then(entry => {
if (entry) {
logger.debug(`found in cache: ${cacheKey}`);
return Promise.resolve(JSON.parse(entry));
}
return this.lambda
.invoke(params)
.on("success", response => {
if (ttl === 0) {
logger.debug({ key: cacheKey }, "will not cache");
return;
}
logger.debug({ key: cacheKey, ttl }, "will cache");
this.cache.set(cacheKey, JSON.stringify(response.data), { ttl });
})
.promise();
});
}
}
module.exports = {
AWSLambdaDataSource
};