@comicrelief/lambda-wrapper 1.10.0 → 1.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.yml +7 -4
- package/.github/workflows/main.yml +5 -10
- package/README.md +2 -0
- package/dist/Config/Dependencies.js +0 -7
- package/dist/DependencyInjection/DependencyAware.class.js +2 -9
- package/dist/DependencyInjection/DependencyInjection.class.js +9 -29
- package/dist/Model/CloudEvent.model.js +12 -30
- package/dist/Model/Model.model.js +1 -7
- package/dist/Model/Response.model.js +11 -26
- package/dist/Model/SQS/MarketingPreference.model.js +55 -112
- package/dist/Model/SQS/Message.model.js +7 -19
- package/dist/Model/Status.model.js +5 -16
- package/dist/Service/BaseConfig.service.js +20 -41
- package/dist/Service/HTTP.service.js +5 -18
- package/dist/Service/Logger.service.js +19 -56
- package/dist/Service/Request.service.js +27 -75
- package/dist/Service/SQS.service.js +23 -79
- package/dist/Service/Timer.service.js +4 -13
- package/dist/Wrapper/LambdaTermination.js +0 -5
- package/dist/Wrapper/LambdaWrapper.js +17 -38
- package/dist/Wrapper/PromisifiedDelay.js +4 -8
- package/dist/index.js +36 -55
- package/package.json +30 -24
|
@@ -3,28 +3,17 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.default = exports.
|
|
7
|
-
|
|
6
|
+
exports.default = exports.REQUEST_TYPES = exports.HTTP_METHODS_WITH_PAYLOADS = exports.HTTP_METHODS_WITHOUT_PAYLOADS = exports.ERROR_TYPES = void 0;
|
|
8
7
|
var _querystring = _interopRequireDefault(require("querystring"));
|
|
9
|
-
|
|
10
8
|
var _useragent = _interopRequireDefault(require("useragent"));
|
|
11
|
-
|
|
12
9
|
var _validate = _interopRequireDefault(require("validate.js/validate"));
|
|
13
|
-
|
|
14
10
|
var _xml2js = _interopRequireDefault(require("xml2js"));
|
|
15
|
-
|
|
16
11
|
var _Dependencies = require("../Config/Dependencies");
|
|
17
|
-
|
|
18
12
|
var _DependencyAware = _interopRequireDefault(require("../DependencyInjection/DependencyAware.class"));
|
|
19
|
-
|
|
20
13
|
var _Response = _interopRequireDefault(require("../Model/Response.model"));
|
|
21
|
-
|
|
22
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
|
-
|
|
24
15
|
/* eslint-disable class-methods-use-this */
|
|
25
|
-
|
|
26
|
-
/* eslint-disable sonarjs/no-duplicate-string */
|
|
27
|
-
const REQUEST_TYPES = {
|
|
16
|
+
/* eslint-disable sonarjs/no-duplicate-string */const REQUEST_TYPES = {
|
|
28
17
|
DELETE: 'DELETE',
|
|
29
18
|
GET: 'GET',
|
|
30
19
|
HEAD: 'HEAD',
|
|
@@ -36,18 +25,18 @@ const REQUEST_TYPES = {
|
|
|
36
25
|
exports.REQUEST_TYPES = REQUEST_TYPES;
|
|
37
26
|
const HTTP_METHODS_WITHOUT_PAYLOADS = [REQUEST_TYPES.DELETE, REQUEST_TYPES.GET, REQUEST_TYPES.HEAD, REQUEST_TYPES.OPTIONS];
|
|
38
27
|
exports.HTTP_METHODS_WITHOUT_PAYLOADS = HTTP_METHODS_WITHOUT_PAYLOADS;
|
|
39
|
-
const HTTP_METHODS_WITH_PAYLOADS = [REQUEST_TYPES.PATCH, REQUEST_TYPES.POST, REQUEST_TYPES.PUT];
|
|
28
|
+
const HTTP_METHODS_WITH_PAYLOADS = [REQUEST_TYPES.PATCH, REQUEST_TYPES.POST, REQUEST_TYPES.PUT];
|
|
40
29
|
|
|
30
|
+
// Define action specific error types
|
|
41
31
|
exports.HTTP_METHODS_WITH_PAYLOADS = HTTP_METHODS_WITH_PAYLOADS;
|
|
42
32
|
const ERROR_TYPES = {
|
|
43
33
|
VALIDATION_ERROR: new _Response.default({}, 400, 'required fields are missing')
|
|
44
34
|
};
|
|
35
|
+
|
|
45
36
|
/**
|
|
46
37
|
* RequestService class
|
|
47
38
|
*/
|
|
48
|
-
|
|
49
39
|
exports.ERROR_TYPES = ERROR_TYPES;
|
|
50
|
-
|
|
51
40
|
class RequestService extends _DependencyAware.default {
|
|
52
41
|
/**
|
|
53
42
|
* Get a parameter from the request.
|
|
@@ -58,24 +47,23 @@ class RequestService extends _DependencyAware.default {
|
|
|
58
47
|
*/
|
|
59
48
|
get(parameter, ifNull = null, requestType = null) {
|
|
60
49
|
const queryParameters = this.getAll(requestType);
|
|
61
|
-
|
|
62
50
|
if (queryParameters === null) {
|
|
63
51
|
return ifNull;
|
|
64
52
|
}
|
|
65
|
-
|
|
66
53
|
return typeof queryParameters[parameter] !== 'undefined' ? queryParameters[parameter] : ifNull;
|
|
67
54
|
}
|
|
55
|
+
|
|
68
56
|
/**
|
|
69
57
|
* Get all HTTP headers included in the request.
|
|
70
58
|
*
|
|
71
59
|
* @returns {object} An object with a key for each header.
|
|
72
60
|
*/
|
|
73
|
-
|
|
74
|
-
|
|
75
61
|
getAllHeaders() {
|
|
76
|
-
return {
|
|
62
|
+
return {
|
|
63
|
+
...this.getContainer().getEvent().headers
|
|
77
64
|
};
|
|
78
65
|
}
|
|
66
|
+
|
|
79
67
|
/**
|
|
80
68
|
* Get an HTTP header from the request.
|
|
81
69
|
*
|
|
@@ -84,67 +72,57 @@ class RequestService extends _DependencyAware.default {
|
|
|
84
72
|
* @param {string} name The name of the header.
|
|
85
73
|
* @param {string} [whenMissing] Value to return if the header is missing.
|
|
86
74
|
* (default: empty string)
|
|
87
|
-
*
|
|
88
75
|
* @returns {string}
|
|
89
76
|
*/
|
|
90
|
-
|
|
91
|
-
|
|
92
77
|
getHeader(name, whenMissing = '') {
|
|
93
78
|
const headers = this.getAllHeaders();
|
|
94
|
-
|
|
95
79
|
if (!headers) {
|
|
96
80
|
return whenMissing;
|
|
97
81
|
}
|
|
98
|
-
|
|
99
82
|
const lowerName = name.toLowerCase();
|
|
100
83
|
const key = Object.keys(headers).find(k => k.toLowerCase() === lowerName);
|
|
101
84
|
return key && headers[key] || whenMissing;
|
|
102
85
|
}
|
|
86
|
+
|
|
103
87
|
/**
|
|
104
88
|
* Get authorization token
|
|
105
89
|
*
|
|
106
90
|
* @returns {*}
|
|
107
91
|
*/
|
|
108
|
-
|
|
109
|
-
|
|
110
92
|
getAuthorizationToken() {
|
|
111
93
|
const authorization = this.getHeader('Authorization');
|
|
112
|
-
|
|
113
94
|
if (!authorization) {
|
|
114
95
|
return null;
|
|
115
96
|
}
|
|
116
|
-
|
|
117
97
|
const tokenParts = authorization.split(' ');
|
|
118
98
|
const tokenValue = tokenParts[1];
|
|
119
|
-
|
|
120
99
|
if (!(tokenParts[0].toLowerCase() === 'bearer' && tokenValue)) {
|
|
121
100
|
return null;
|
|
122
101
|
}
|
|
123
|
-
|
|
124
102
|
return tokenValue;
|
|
125
103
|
}
|
|
104
|
+
|
|
126
105
|
/**
|
|
127
106
|
* Get a path parameter
|
|
128
107
|
*
|
|
129
108
|
* @param parameter
|
|
130
109
|
* @param ifNull mixed
|
|
131
110
|
*/
|
|
132
|
-
|
|
133
|
-
|
|
134
111
|
getPathParameter(parameter = null, ifNull = {}) {
|
|
135
|
-
const event = this.getContainer().getEvent();
|
|
112
|
+
const event = this.getContainer().getEvent();
|
|
136
113
|
|
|
114
|
+
// If no parameter has been requested, return all path parameters
|
|
137
115
|
if (parameter === null && typeof event.pathParameters === 'object') {
|
|
138
116
|
return event.pathParameters;
|
|
139
|
-
}
|
|
140
|
-
|
|
117
|
+
}
|
|
141
118
|
|
|
119
|
+
// If a specifc parameter has been requested, return the parameter if it exists
|
|
142
120
|
if (typeof parameter === 'string' && typeof event.pathParameters === 'object' && event.pathParameters !== null && typeof event.pathParameters[parameter] !== 'undefined') {
|
|
143
121
|
return event.pathParameters[parameter];
|
|
144
122
|
}
|
|
145
|
-
|
|
146
123
|
return ifNull;
|
|
147
124
|
}
|
|
125
|
+
|
|
148
126
|
/**
|
|
149
127
|
* Get all request parameters
|
|
150
128
|
*
|
|
@@ -152,30 +130,25 @@ class RequestService extends _DependencyAware.default {
|
|
|
152
130
|
* @returns {{}}
|
|
153
131
|
*/
|
|
154
132
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
155
|
-
|
|
156
|
-
|
|
157
133
|
getAll(requestType = null) {
|
|
158
134
|
const event = this.getContainer().getEvent();
|
|
159
|
-
|
|
160
135
|
if (HTTP_METHODS_WITHOUT_PAYLOADS.includes(event.httpMethod) || HTTP_METHODS_WITHOUT_PAYLOADS.includes(requestType)) {
|
|
161
136
|
// get simple parameters
|
|
162
|
-
const params = {
|
|
163
|
-
|
|
164
|
-
|
|
137
|
+
const params = {
|
|
138
|
+
...event.queryStringParameters
|
|
139
|
+
};
|
|
140
|
+
// add array parameters as arrays
|
|
165
141
|
Object.keys(params).filter(key => key.endsWith('[]')).forEach(key => {
|
|
166
142
|
params[key] = event.multiValueQueryStringParameters[key];
|
|
167
143
|
});
|
|
168
144
|
return params;
|
|
169
145
|
}
|
|
170
|
-
|
|
171
146
|
if (HTTP_METHODS_WITH_PAYLOADS.includes(event.httpMethod) || HTTP_METHODS_WITH_PAYLOADS.includes(requestType)) {
|
|
172
147
|
const contentType = this.getHeader('Content-Type');
|
|
173
148
|
let queryParameters = {};
|
|
174
|
-
|
|
175
149
|
if (contentType.includes('application/x-www-form-urlencoded')) {
|
|
176
150
|
queryParameters = _querystring.default.parse(event.body);
|
|
177
151
|
}
|
|
178
|
-
|
|
179
152
|
if (contentType.includes('application/json')) {
|
|
180
153
|
try {
|
|
181
154
|
queryParameters = JSON.parse(event.body);
|
|
@@ -183,55 +156,44 @@ class RequestService extends _DependencyAware.default {
|
|
|
183
156
|
queryParameters = {};
|
|
184
157
|
}
|
|
185
158
|
}
|
|
186
|
-
|
|
187
159
|
if (contentType.includes('text/xml')) {
|
|
188
160
|
_xml2js.default.parseString(event.body, (error, result) => {
|
|
189
161
|
queryParameters = error ? {} : result;
|
|
190
162
|
});
|
|
191
163
|
}
|
|
192
|
-
|
|
193
164
|
if (contentType.includes('multipart/form-data')) {
|
|
194
165
|
queryParameters = this.parseForm(true);
|
|
195
166
|
}
|
|
196
|
-
|
|
197
167
|
return typeof queryParameters !== 'undefined' ? queryParameters : {};
|
|
198
168
|
}
|
|
199
|
-
|
|
200
169
|
return null;
|
|
201
170
|
}
|
|
171
|
+
|
|
202
172
|
/**
|
|
203
173
|
* Fetch the request IP address
|
|
204
174
|
*
|
|
205
175
|
* @returns {*}
|
|
206
176
|
*/
|
|
207
|
-
|
|
208
|
-
|
|
209
177
|
getIp() {
|
|
210
178
|
const event = this.getContainer().getEvent();
|
|
211
|
-
|
|
212
179
|
if (typeof event.requestContext !== 'undefined' && typeof event.requestContext.identity !== 'undefined' && typeof event.requestContext.identity.sourceIp !== 'undefined') {
|
|
213
180
|
return event.requestContext.identity.sourceIp;
|
|
214
181
|
}
|
|
215
|
-
|
|
216
182
|
return null;
|
|
217
183
|
}
|
|
184
|
+
|
|
218
185
|
/**
|
|
219
186
|
* Get user agent
|
|
220
187
|
*
|
|
221
188
|
* @returns {*}
|
|
222
189
|
*/
|
|
223
|
-
|
|
224
|
-
|
|
225
190
|
getUserBrowserAndDevice() {
|
|
226
191
|
const userAgent = this.getHeader('user-agent', null);
|
|
227
|
-
|
|
228
192
|
if (userAgent === null) {
|
|
229
193
|
return null;
|
|
230
194
|
}
|
|
231
|
-
|
|
232
195
|
try {
|
|
233
196
|
const agent = _useragent.default.parse(userAgent);
|
|
234
|
-
|
|
235
197
|
const os = agent.os.toJSON();
|
|
236
198
|
return {
|
|
237
199
|
'browser-type': agent.family,
|
|
@@ -245,19 +207,17 @@ class RequestService extends _DependencyAware.default {
|
|
|
245
207
|
return null;
|
|
246
208
|
}
|
|
247
209
|
}
|
|
210
|
+
|
|
248
211
|
/**
|
|
249
212
|
* Test a request against validation constraints
|
|
250
213
|
*
|
|
251
214
|
* @param constraints
|
|
252
215
|
* @returns {Promise<any>}
|
|
253
216
|
*/
|
|
254
|
-
|
|
255
|
-
|
|
256
217
|
validateAgainstConstraints(constraints) {
|
|
257
218
|
const Logger = this.getContainer().get(_Dependencies.DEFINITIONS.LOGGER);
|
|
258
219
|
return new Promise((resolve, reject) => {
|
|
259
220
|
const validation = (0, _validate.default)(this.getAll(), constraints);
|
|
260
|
-
|
|
261
221
|
if (typeof validation === 'undefined') {
|
|
262
222
|
resolve();
|
|
263
223
|
} else {
|
|
@@ -268,14 +228,13 @@ class RequestService extends _DependencyAware.default {
|
|
|
268
228
|
}
|
|
269
229
|
});
|
|
270
230
|
}
|
|
231
|
+
|
|
271
232
|
/**
|
|
272
233
|
* Fetch the request multipart form
|
|
273
234
|
*
|
|
274
235
|
* @param useBuffer
|
|
275
236
|
* @returns {*}
|
|
276
237
|
*/
|
|
277
|
-
|
|
278
|
-
|
|
279
238
|
parseForm(useBuffer) {
|
|
280
239
|
const event = this.getContainer().getEvent();
|
|
281
240
|
const boundary = this.getBoundary(event);
|
|
@@ -295,23 +254,21 @@ class RequestService extends _DependencyAware.default {
|
|
|
295
254
|
});
|
|
296
255
|
return result;
|
|
297
256
|
}
|
|
257
|
+
|
|
298
258
|
/**
|
|
299
259
|
* Fetch the request AWS event Records
|
|
300
260
|
*
|
|
301
261
|
* @returns {*}
|
|
302
262
|
*/
|
|
303
|
-
|
|
304
|
-
|
|
305
263
|
getAWSRecords() {
|
|
306
264
|
const event = this.getContainer().getEvent();
|
|
307
265
|
const eventRecord = event.Records && event.Records[0];
|
|
308
|
-
|
|
309
266
|
if (typeof event.Records !== 'undefined' && typeof event.Records[0] !== 'undefined' && typeof eventRecord.eventSource !== 'undefined') {
|
|
310
267
|
return eventRecord;
|
|
311
268
|
}
|
|
312
|
-
|
|
313
269
|
return null;
|
|
314
270
|
}
|
|
271
|
+
|
|
315
272
|
/**
|
|
316
273
|
* Gets a value independently from
|
|
317
274
|
* the case of the key
|
|
@@ -319,24 +276,19 @@ class RequestService extends _DependencyAware.default {
|
|
|
319
276
|
* @param object
|
|
320
277
|
* @param key
|
|
321
278
|
*/
|
|
322
|
-
|
|
323
|
-
|
|
324
279
|
getValueIgnoringKeyCase(object, key) {
|
|
325
280
|
const foundKey = Object.keys(object).find(currentKey => currentKey.toLocaleLowerCase() === key.toLowerCase());
|
|
326
281
|
return object[foundKey];
|
|
327
282
|
}
|
|
283
|
+
|
|
328
284
|
/**
|
|
329
285
|
* Returns the content type
|
|
330
286
|
* assoiated with the request
|
|
331
287
|
*
|
|
332
288
|
* @param event
|
|
333
289
|
*/
|
|
334
|
-
|
|
335
|
-
|
|
336
290
|
getBoundary(event) {
|
|
337
291
|
return this.getValueIgnoringKeyCase(event.headers, 'Content-Type').split('=')[1];
|
|
338
292
|
}
|
|
339
|
-
|
|
340
293
|
}
|
|
341
|
-
|
|
342
294
|
exports.default = RequestService;
|
|
@@ -4,31 +4,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.SQS_PUBLISH_FAILURE_MODES = exports.SQS_OFFLINE_MODES = void 0;
|
|
7
|
-
|
|
8
7
|
var _alai = _interopRequireDefault(require("alai"));
|
|
9
|
-
|
|
10
8
|
var _each = _interopRequireDefault(require("async/each"));
|
|
11
|
-
|
|
12
9
|
var _awsSdk = _interopRequireDefault(require("aws-sdk"));
|
|
13
|
-
|
|
14
10
|
var _uuid = require("uuid");
|
|
15
|
-
|
|
16
11
|
var _Dependencies = require("../Config/Dependencies");
|
|
17
|
-
|
|
18
12
|
var _DependencyAware = _interopRequireDefault(require("../DependencyInjection/DependencyAware.class"));
|
|
19
|
-
|
|
20
13
|
var _DependencyInjection = _interopRequireDefault(require("../DependencyInjection/DependencyInjection.class"));
|
|
21
|
-
|
|
22
14
|
var _Message = _interopRequireDefault(require("../Model/SQS/Message.model"));
|
|
23
|
-
|
|
24
15
|
var _Status = _interopRequireWildcard(require("../Model/Status.model"));
|
|
25
|
-
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
29
|
-
|
|
16
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
17
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
30
18
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
31
|
-
|
|
32
19
|
/**
|
|
33
20
|
* Allowed values for `process.env.LAMBDA_WRAPPER_OFFLINE_SQS_MODE`.
|
|
34
21
|
*/
|
|
@@ -39,24 +26,22 @@ const SQS_OFFLINE_MODES = {
|
|
|
39
26
|
* the default.
|
|
40
27
|
*/
|
|
41
28
|
DIRECT: 'direct',
|
|
42
|
-
|
|
43
29
|
/**
|
|
44
30
|
* When running offline, send messages to an offline SQS service defined by
|
|
45
31
|
* `process.env.LAMBDA_WRAPPER_OFFLINE_SQS_HOST`.
|
|
46
32
|
*/
|
|
47
33
|
LOCAL: 'local',
|
|
48
|
-
|
|
49
34
|
/**
|
|
50
35
|
* When running offline, send messages to AWS as normal.
|
|
51
36
|
*/
|
|
52
37
|
AWS: 'aws'
|
|
53
38
|
};
|
|
39
|
+
|
|
54
40
|
/**
|
|
55
41
|
* Defines the preferred behaviour
|
|
56
42
|
* for SQSService.prototype.publish
|
|
57
43
|
* should AWS SQS fail.
|
|
58
44
|
*/
|
|
59
|
-
|
|
60
45
|
exports.SQS_OFFLINE_MODES = SQS_OFFLINE_MODES;
|
|
61
46
|
const SQS_PUBLISH_FAILURE_MODES = {
|
|
62
47
|
/**
|
|
@@ -66,19 +51,17 @@ const SQS_PUBLISH_FAILURE_MODES = {
|
|
|
66
51
|
* and for LambdaWrapper 1.8.2 and above
|
|
67
52
|
*/
|
|
68
53
|
CATCH: 'catch',
|
|
69
|
-
|
|
70
54
|
/**
|
|
71
55
|
* Throws the exception so that the caller
|
|
72
56
|
* can handle it directly.
|
|
73
57
|
*/
|
|
74
58
|
THROW: 'throw'
|
|
75
59
|
};
|
|
60
|
+
|
|
76
61
|
/**
|
|
77
62
|
* SQSService class
|
|
78
63
|
*/
|
|
79
|
-
|
|
80
64
|
exports.SQS_PUBLISH_FAILURE_MODES = SQS_PUBLISH_FAILURE_MODES;
|
|
81
|
-
|
|
82
65
|
class SQSService extends _DependencyAware.default {
|
|
83
66
|
/**
|
|
84
67
|
* SQSService constructor
|
|
@@ -101,12 +84,11 @@ class SQSService extends _DependencyAware.default {
|
|
|
101
84
|
this.queues = {};
|
|
102
85
|
this.$lambda = null;
|
|
103
86
|
this.$sqs = null;
|
|
104
|
-
|
|
105
87
|
if (container.isOffline && !Object.values(SQS_OFFLINE_MODES).includes(offlineMode)) {
|
|
106
88
|
throw new Error(`Invalid LAMBDA_WRAPPER_OFFLINE_SQS_MODE: ${offlineMode}\n` + `Please use one of: ${Object.values(SQS_OFFLINE_MODES).join(', ')}`);
|
|
107
|
-
}
|
|
108
|
-
|
|
89
|
+
}
|
|
109
90
|
|
|
91
|
+
// Add the queues from configuration
|
|
110
92
|
if (queues !== null && Object.keys(queues).length > 0) {
|
|
111
93
|
Object.keys(queues).forEach(queueDefinition => {
|
|
112
94
|
if (container.isOffline && offlineMode === SQS_OFFLINE_MODES.LOCAL) {
|
|
@@ -119,11 +101,10 @@ class SQSService extends _DependencyAware.default {
|
|
|
119
101
|
});
|
|
120
102
|
}
|
|
121
103
|
}
|
|
104
|
+
|
|
122
105
|
/**
|
|
123
106
|
* Returns an SQS client instance
|
|
124
107
|
*/
|
|
125
|
-
|
|
126
|
-
|
|
127
108
|
get sqs() {
|
|
128
109
|
if (!this.$sqs) {
|
|
129
110
|
this.$sqs = new _awsSdk.default.SQS({
|
|
@@ -134,45 +115,41 @@ class SQSService extends _DependencyAware.default {
|
|
|
134
115
|
timeout: 8 * 1000
|
|
135
116
|
},
|
|
136
117
|
maxRetries: 3 // default is 3, we can change that
|
|
137
|
-
|
|
138
118
|
});
|
|
139
119
|
}
|
|
140
120
|
|
|
141
121
|
return this.$sqs;
|
|
142
122
|
}
|
|
123
|
+
|
|
143
124
|
/**
|
|
144
125
|
* Returns a Lambda client instance
|
|
145
126
|
*/
|
|
146
|
-
|
|
147
|
-
|
|
148
127
|
get lambda() {
|
|
149
128
|
if (!this.$lambda) {
|
|
150
129
|
const endpoint = process.env.SERVICE_LAMBDA_URL;
|
|
151
|
-
|
|
152
130
|
if (!endpoint) {
|
|
153
131
|
throw new Error('process.env.SERVICE_LAMBDA_URL must be defined.');
|
|
154
|
-
}
|
|
155
|
-
|
|
132
|
+
}
|
|
156
133
|
|
|
134
|
+
// move to subprocess
|
|
157
135
|
this.$lambda = new _awsSdk.default.Lambda({
|
|
158
136
|
region: process.env.AWS_REGION,
|
|
159
137
|
endpoint
|
|
160
138
|
});
|
|
161
139
|
}
|
|
162
|
-
|
|
163
140
|
return this.$lambda;
|
|
164
141
|
}
|
|
142
|
+
|
|
165
143
|
/**
|
|
166
144
|
* Returns the mode to use for offline SQS.
|
|
167
145
|
*
|
|
168
146
|
* This is configured by `process.env.LAMBDA_WRAPPER_OFFLINE_SQS_MODE`. The
|
|
169
147
|
* default is `SQS_OFFLINE_MODES.LAMBDA`.
|
|
170
148
|
*/
|
|
171
|
-
|
|
172
|
-
|
|
173
149
|
static get offlineMode() {
|
|
174
150
|
return process.env.LAMBDA_WRAPPER_OFFLINE_SQS_MODE || SQS_OFFLINE_MODES.DIRECT;
|
|
175
151
|
}
|
|
152
|
+
|
|
176
153
|
/**
|
|
177
154
|
* Batch delete messages
|
|
178
155
|
*
|
|
@@ -180,8 +157,6 @@ class SQSService extends _DependencyAware.default {
|
|
|
180
157
|
* @param messageModels [SQSMessageModel]
|
|
181
158
|
* @returns {Promise<any>}
|
|
182
159
|
*/
|
|
183
|
-
|
|
184
|
-
|
|
185
160
|
batchDelete(queue, messageModels) {
|
|
186
161
|
const container = this.getContainer();
|
|
187
162
|
const queueUrl = this.queues[queue];
|
|
@@ -190,8 +165,8 @@ class SQSService extends _DependencyAware.default {
|
|
|
190
165
|
const timerId = `sqs-batch-delete-${(0, _uuid.v4)()} - Queue: '${queueUrl}'`;
|
|
191
166
|
return new Promise(resolve => {
|
|
192
167
|
const messagesForDeletion = [];
|
|
193
|
-
Timer.start(timerId);
|
|
194
|
-
|
|
168
|
+
Timer.start(timerId);
|
|
169
|
+
// assuming openFiles is an array of file names
|
|
195
170
|
(0, _each.default)(messageModels, (messageModel, callback) => {
|
|
196
171
|
if (messageModel instanceof _Message.default && messageModel.isForDeletion() === true) {
|
|
197
172
|
messagesForDeletion.push({
|
|
@@ -199,36 +174,31 @@ class SQSService extends _DependencyAware.default {
|
|
|
199
174
|
ReceiptHandle: messageModel.getReceiptHandle()
|
|
200
175
|
});
|
|
201
176
|
}
|
|
202
|
-
|
|
203
177
|
callback();
|
|
204
178
|
}, loopError => {
|
|
205
179
|
if (loopError) {
|
|
206
180
|
Logger.error(loopError);
|
|
207
181
|
resolve();
|
|
208
182
|
}
|
|
209
|
-
|
|
210
183
|
this.sqs.deleteMessageBatch({
|
|
211
184
|
Entries: messagesForDeletion,
|
|
212
185
|
QueueUrl: queueUrl
|
|
213
186
|
}, error => {
|
|
214
187
|
Timer.stop(timerId);
|
|
215
|
-
|
|
216
188
|
if (error) {
|
|
217
189
|
Logger.error(error);
|
|
218
190
|
}
|
|
219
|
-
|
|
220
191
|
resolve();
|
|
221
192
|
});
|
|
222
193
|
});
|
|
223
194
|
});
|
|
224
195
|
}
|
|
196
|
+
|
|
225
197
|
/**
|
|
226
198
|
* Check SQS status
|
|
227
199
|
*
|
|
228
200
|
* @returns {Promise<any>}
|
|
229
201
|
*/
|
|
230
|
-
|
|
231
|
-
|
|
232
202
|
checkStatus() {
|
|
233
203
|
const container = this.getContainer();
|
|
234
204
|
const Logger = container.get(_Dependencies.DEFINITIONS.LOGGER);
|
|
@@ -239,28 +209,24 @@ class SQSService extends _DependencyAware.default {
|
|
|
239
209
|
this.sqs.listQueues({}, (error, data) => {
|
|
240
210
|
Timer.stop(timerId);
|
|
241
211
|
const statusModel = new _Status.default('SQS', _Status.STATUS_TYPES.OK);
|
|
242
|
-
|
|
243
212
|
if (error) {
|
|
244
213
|
Logger.error(error);
|
|
245
214
|
statusModel.setStatus(_Status.STATUS_TYPES.APPLICATION_FAILURE);
|
|
246
215
|
}
|
|
247
|
-
|
|
248
216
|
if (typeof data.QueueUrls === 'undefined' || data.QueueUrls.length === 0) {
|
|
249
217
|
statusModel.setStatus(_Status.STATUS_TYPES.APPLICATION_FAILURE);
|
|
250
218
|
}
|
|
251
|
-
|
|
252
219
|
resolve(statusModel);
|
|
253
220
|
});
|
|
254
221
|
});
|
|
255
222
|
}
|
|
223
|
+
|
|
256
224
|
/**
|
|
257
225
|
* Get number of messages in a queue
|
|
258
226
|
*
|
|
259
227
|
* @param queue
|
|
260
228
|
* @returns {Promise<any>}
|
|
261
229
|
*/
|
|
262
|
-
|
|
263
|
-
|
|
264
230
|
getMessageCount(queue) {
|
|
265
231
|
const container = this.getContainer();
|
|
266
232
|
const queueUrl = this.queues[queue];
|
|
@@ -274,16 +240,15 @@ class SQSService extends _DependencyAware.default {
|
|
|
274
240
|
QueueUrl: queueUrl
|
|
275
241
|
}, (error, data) => {
|
|
276
242
|
Timer.stop(timerId);
|
|
277
|
-
|
|
278
243
|
if (error) {
|
|
279
244
|
Logger.error(error);
|
|
280
245
|
resolve(0);
|
|
281
246
|
}
|
|
282
|
-
|
|
283
247
|
resolve(Number.parseInt(data.Attributes.ApproximateNumberOfMessages, 10));
|
|
284
248
|
});
|
|
285
249
|
});
|
|
286
250
|
}
|
|
251
|
+
|
|
287
252
|
/**
|
|
288
253
|
* Publish to message queue
|
|
289
254
|
*
|
|
@@ -299,13 +264,10 @@ class SQSService extends _DependencyAware.default {
|
|
|
299
264
|
* - `throw`: errors will be thrown, causing promise to reject.
|
|
300
265
|
* @returns {Promise<any>}
|
|
301
266
|
*/
|
|
302
|
-
|
|
303
|
-
|
|
304
267
|
async publish(queue, messageObject, messageGroupId = null, failureMode = SQS_PUBLISH_FAILURE_MODES.CATCH) {
|
|
305
268
|
if (!Object.values(SQS_PUBLISH_FAILURE_MODES).includes(failureMode)) {
|
|
306
269
|
throw new Error(`Invalid value for 'failureMode': ${failureMode}`);
|
|
307
270
|
}
|
|
308
|
-
|
|
309
271
|
const container = this.getContainer();
|
|
310
272
|
const queueUrl = this.queues[queue];
|
|
311
273
|
const Timer = container.get(_Dependencies.DEFINITIONS.TIMER);
|
|
@@ -315,12 +277,10 @@ class SQSService extends _DependencyAware.default {
|
|
|
315
277
|
MessageBody: JSON.stringify(messageObject),
|
|
316
278
|
QueueUrl: queueUrl
|
|
317
279
|
};
|
|
318
|
-
|
|
319
280
|
if (queueUrl.includes('.fifo')) {
|
|
320
281
|
messageParameters.MessageDeduplicationId = (0, _uuid.v4)();
|
|
321
282
|
messageParameters.MessageGroupId = messageGroupId !== null ? messageGroupId : (0, _uuid.v4)();
|
|
322
283
|
}
|
|
323
|
-
|
|
324
284
|
try {
|
|
325
285
|
if (container.isOffline && this.constructor.offlineMode === SQS_OFFLINE_MODES.DIRECT) {
|
|
326
286
|
await this.publishOffline(queue, messageParameters);
|
|
@@ -328,19 +288,15 @@ class SQSService extends _DependencyAware.default {
|
|
|
328
288
|
await this.sqs.sendMessage(messageParameters).promise();
|
|
329
289
|
}
|
|
330
290
|
} catch (error) {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
return null;
|
|
335
|
-
|
|
336
|
-
case SQS_PUBLISH_FAILURE_MODES.THROW:
|
|
337
|
-
default:
|
|
338
|
-
throw error;
|
|
291
|
+
if (failureMode === SQS_PUBLISH_FAILURE_MODES.CATCH) {
|
|
292
|
+
container.get(_Dependencies.DEFINITIONS.LOGGER).error(error);
|
|
293
|
+
return null;
|
|
339
294
|
}
|
|
295
|
+
throw error;
|
|
340
296
|
}
|
|
341
|
-
|
|
342
297
|
return queue;
|
|
343
298
|
}
|
|
299
|
+
|
|
344
300
|
/**
|
|
345
301
|
* Sends a message to a queue consumer running in serverless-offline.
|
|
346
302
|
*
|
|
@@ -351,22 +307,16 @@ class SQSService extends _DependencyAware.default {
|
|
|
351
307
|
* @param queue
|
|
352
308
|
* @param messageParameters
|
|
353
309
|
*/
|
|
354
|
-
|
|
355
|
-
|
|
356
310
|
async publishOffline(queue, messageParameters) {
|
|
357
311
|
const container = this.getContainer();
|
|
358
|
-
|
|
359
312
|
if (!container.isOffline) {
|
|
360
313
|
throw new Error('Can only publishOffline while running serverless offline.');
|
|
361
314
|
}
|
|
362
|
-
|
|
363
315
|
const consumers = container.getConfiguration('QUEUE_CONSUMERS') || {};
|
|
364
316
|
const FunctionName = consumers[queue];
|
|
365
|
-
|
|
366
317
|
if (!FunctionName) {
|
|
367
318
|
throw new Error(`Queue consumer for queue ${queue} was not found. Please configure your application's QUEUE_CONSUMERS.`);
|
|
368
319
|
}
|
|
369
|
-
|
|
370
320
|
const InvocationType = 'RequestResponse';
|
|
371
321
|
const Payload = JSON.stringify({
|
|
372
322
|
Records: [{
|
|
@@ -380,6 +330,7 @@ class SQSService extends _DependencyAware.default {
|
|
|
380
330
|
};
|
|
381
331
|
await this.lambda.invoke(parameters).promise();
|
|
382
332
|
}
|
|
333
|
+
|
|
383
334
|
/**
|
|
384
335
|
* Receive from message queue
|
|
385
336
|
*
|
|
@@ -387,8 +338,6 @@ class SQSService extends _DependencyAware.default {
|
|
|
387
338
|
* @param timeout number
|
|
388
339
|
* @returns {Promise<any>}
|
|
389
340
|
*/
|
|
390
|
-
|
|
391
|
-
|
|
392
341
|
receive(queue, timeout = 15) {
|
|
393
342
|
const container = this.getContainer();
|
|
394
343
|
const queueUrl = this.queues[queue];
|
|
@@ -403,21 +352,16 @@ class SQSService extends _DependencyAware.default {
|
|
|
403
352
|
MaxNumberOfMessages: 10
|
|
404
353
|
}, (error, data) => {
|
|
405
354
|
Timer.stop(timerId);
|
|
406
|
-
|
|
407
355
|
if (error) {
|
|
408
356
|
Logger.error(error);
|
|
409
357
|
return reject(error);
|
|
410
358
|
}
|
|
411
|
-
|
|
412
359
|
if (typeof data.Messages === 'undefined') {
|
|
413
360
|
return resolve([]);
|
|
414
361
|
}
|
|
415
|
-
|
|
416
362
|
return resolve(data.Messages.map(message => new _Message.default(message)));
|
|
417
363
|
});
|
|
418
364
|
});
|
|
419
365
|
}
|
|
420
|
-
|
|
421
366
|
}
|
|
422
|
-
|
|
423
367
|
exports.default = SQSService;
|