@natlibfi/melinda-rest-api-commons 4.2.3-alpha.1 → 4.2.4-alpha.11
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/.github/workflows/melinda-node-tests.yml +1 -1
- package/dist/amqp.js +2 -2
- package/dist/amqp.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mongo.js +158 -80
- package/dist/mongo.js.map +1 -1
- package/dist/mongoLog.js +1 -4
- package/dist/mongoLog.js.map +1 -1
- package/package.json +26 -24
- package/{dist → tests}/amqp.health.spec.js +17 -10
- package/tests/amqp.tests.spec.js +301 -0
- package/tests/helpers/conversion.spec.js +95 -0
- package/tests/helpers/fix.spec.js +41 -0
- package/tests/helpers/validation.spec.js +58 -0
- package/tests/mongo-add-blob-size.spec.js +100 -0
- package/tests/mongo-check-and-check-state.spec.js +112 -0
- package/tests/mongo-check-and-set-import-job-state.spec.js +112 -0
- package/tests/mongo-check-timeout.spec.js +111 -0
- package/tests/mongo-create-bulk.spec.js +100 -0
- package/tests/mongo-create-prio.spec.js +98 -0
- package/tests/mongo-get-one.spec.js +103 -0
- package/tests/mongo-get-stream.spec.js +120 -0
- package/tests/mongo-push-ids.spec.js +101 -0
- package/tests/mongo-push-messages.spec.js +99 -0
- package/tests/mongo-query-by-id.spec.js +112 -0
- package/tests/mongo-query.spec.js +108 -0
- package/tests/mongo-read-content.spec.js +123 -0
- package/tests/mongo-remove.spec.js +115 -0
- package/tests/mongo-set-blob-size.spec.js +99 -0
- package/tests/mongo-set-import-job-state.spec.js +102 -0
- package/tests/mongo-set-operation.spec.js +102 -0
- package/tests/mongo-set-operations.spec.js +101 -0
- package/tests/mongo-set-state.spec.js +102 -0
- package/{dist → tests}/mongoLog.spec.js +22 -22
- package/tests/testUtils.js +94 -0
- package/dist/amqp.health.spec.js.map +0 -1
- package/dist/amqp.tests.spec.js +0 -310
- package/dist/amqp.tests.spec.js.map +0 -1
- package/dist/helpers/conversion.spec.js +0 -88
- package/dist/helpers/conversion.spec.js.map +0 -1
- package/dist/helpers/fix.spec.js +0 -46
- package/dist/helpers/fix.spec.js.map +0 -1
- package/dist/helpers/validation.spec.js +0 -47
- package/dist/helpers/validation.spec.js.map +0 -1
- package/dist/mongo.spec.js.draft +0 -54
- package/dist/mongoLog.spec.js.map +0 -1
package/dist/mongo.js
CHANGED
|
@@ -13,6 +13,7 @@ var _utils = require("./utils.js");
|
|
|
13
13
|
var _moment = _interopRequireDefault(require("moment"));
|
|
14
14
|
var _httpStatus = _interopRequireDefault(require("http-status"));
|
|
15
15
|
var _mongoSanitize = _interopRequireDefault(require("mongo-sanitize"));
|
|
16
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
16
17
|
/* eslint-disable max-lines */
|
|
17
18
|
|
|
18
19
|
//import isDeepStrictEqual from 'util';
|
|
@@ -46,25 +47,28 @@ var _mongoSanitize = _interopRequireDefault(require("mongo-sanitize"));
|
|
|
46
47
|
}
|
|
47
48
|
*/
|
|
48
49
|
|
|
49
|
-
async function _default(MONGO_URI, collection) {
|
|
50
|
+
async function _default(MONGO_URI, collection, db = 'rest-api') {
|
|
50
51
|
const logger = (0, _melindaBackendCommons.createLogger)();
|
|
52
|
+
const debug = (0, _debug.default)('@natlibfi/melinda-rest-api-commons/mongo');
|
|
53
|
+
const debugDev = debug.extend(':dev');
|
|
51
54
|
|
|
52
55
|
// Connect to mongo (MONGO)
|
|
53
|
-
const client = await _mongodb.MongoClient.connect(MONGO_URI
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
});
|
|
57
|
-
const db = client.db('rest-api');
|
|
58
|
-
const gridFSBucket = new _mongodb.GridFSBucket(db, {
|
|
56
|
+
const client = await _mongodb.MongoClient.connect(MONGO_URI);
|
|
57
|
+
const dbConnection = client.db(db);
|
|
58
|
+
const gridFSBucket = new _mongodb.GridFSBucket(dbConnection, {
|
|
59
59
|
bucketName: collection
|
|
60
60
|
});
|
|
61
|
+
const operator = dbConnection.collection(collection);
|
|
62
|
+
debugDev(`mongo: ${MONGO_URI}, db: ${db}, collection: ${collection}`);
|
|
61
63
|
return {
|
|
62
64
|
createPrio,
|
|
63
65
|
createBulk,
|
|
64
66
|
checkAndSetState,
|
|
65
67
|
checkAndSetImportJobState,
|
|
66
68
|
query,
|
|
69
|
+
createProjection,
|
|
67
70
|
queryById,
|
|
71
|
+
checkTimeOut,
|
|
68
72
|
remove,
|
|
69
73
|
readContent,
|
|
70
74
|
removeContent,
|
|
@@ -86,6 +90,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
86
90
|
operation,
|
|
87
91
|
operationSettings
|
|
88
92
|
}) {
|
|
93
|
+
debugDev('createPrio');
|
|
89
94
|
const time = (0, _moment.default)().toDate();
|
|
90
95
|
const newQueueItem = {
|
|
91
96
|
correlationId,
|
|
@@ -111,13 +116,17 @@ async function _default(MONGO_URI, collection) {
|
|
|
111
116
|
modificationTime: time
|
|
112
117
|
};
|
|
113
118
|
try {
|
|
114
|
-
|
|
119
|
+
debugDev(`Inserting: ${JSON.stringify(newQueueItem)} to ${collection}}`);
|
|
120
|
+
const result = await operator.insertOne(newQueueItem);
|
|
121
|
+
debugDev(JSON.stringify(result));
|
|
115
122
|
if (result.acknowledged) {
|
|
116
123
|
logger.info(`New PRIO queue item for ${operation} ${correlationId} has been made in ${collection}`);
|
|
117
124
|
return;
|
|
118
125
|
}
|
|
126
|
+
// TEST-COVERAGE: this error is not (currently) tested
|
|
119
127
|
throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR);
|
|
120
128
|
} catch (error) {
|
|
129
|
+
// TEST-COVERAGE: this error is not (currently) tested
|
|
121
130
|
const errorMessage = error.payload || error.message || '';
|
|
122
131
|
(0, _utils.logError)(error);
|
|
123
132
|
throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, `Mongo errored: ${errorMessage}`);
|
|
@@ -164,16 +173,17 @@ async function _default(MONGO_URI, collection) {
|
|
|
164
173
|
|
|
165
174
|
// eslint-disable-next-line functional/no-conditional-statements
|
|
166
175
|
if (stream) {
|
|
176
|
+
debug(`Creating streamBulk`);
|
|
167
177
|
try {
|
|
168
|
-
|
|
169
|
-
db.collection(collection).insertOne(newQueueItem);
|
|
170
|
-
logger.info(`New BULK queue item for ${operation} ${correlationId} has been made in ${collection}!`);
|
|
171
|
-
return new Promise((resolve, reject) => {
|
|
178
|
+
await new Promise((resolve, reject) => {
|
|
172
179
|
const outputStream = gridFSBucket.openUploadStream(correlationId);
|
|
173
180
|
stream.on('error', reject).on('data', chunk => outputStream.write(chunk)).on('end', () => outputStream.end(undefined, undefined, () => {
|
|
174
181
|
resolve(correlationId);
|
|
175
182
|
}));
|
|
176
183
|
});
|
|
184
|
+
logger.info(`New BULK queue item for ${operation} ${correlationId} has been made in ${collection}!`);
|
|
185
|
+
debug(`New BULK queue item for ${operation} ${correlationId} has been made in ${collection}!`);
|
|
186
|
+
return operator.insertOne(newQueueItem);
|
|
177
187
|
} catch (error) {
|
|
178
188
|
const errorMessage = error.payload || error.message || '';
|
|
179
189
|
(0, _utils.logError)(error);
|
|
@@ -181,19 +191,23 @@ async function _default(MONGO_URI, collection) {
|
|
|
181
191
|
}
|
|
182
192
|
}
|
|
183
193
|
logger.debug(`No stream`);
|
|
194
|
+
debug(`Creating noStreamBulk`);
|
|
184
195
|
// eslint-disable-next-line functional/no-conditional-statements
|
|
185
196
|
if (!stream) {
|
|
186
197
|
try {
|
|
187
|
-
const result = await
|
|
198
|
+
const result = await operator.insertOne(newQueueItem);
|
|
188
199
|
if (result.acknowledged) {
|
|
189
200
|
logger.info(`New noStream BULK queue item for ${operation} ${correlationId} has been made in ${collection}`);
|
|
201
|
+
debug(`New noStream BULK queue item for ${operation} ${correlationId} has been made in ${collection}`);
|
|
190
202
|
return {
|
|
191
203
|
correlationId,
|
|
192
204
|
queueItemState: _constants.QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS
|
|
193
205
|
};
|
|
194
206
|
}
|
|
207
|
+
// TEST-COVERAGE: this error is not (currently) tested
|
|
195
208
|
throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR);
|
|
196
209
|
} catch (error) {
|
|
210
|
+
// TEST-COVERAGE: this error is not (currently) tested
|
|
197
211
|
const errorMessage = error.payload || error.message || '';
|
|
198
212
|
(0, _utils.logError)(error);
|
|
199
213
|
throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, `Mongo errored: ${errorMessage}`);
|
|
@@ -202,14 +216,15 @@ async function _default(MONGO_URI, collection) {
|
|
|
202
216
|
}
|
|
203
217
|
|
|
204
218
|
// Check state that the queueItem has not waited too long and set state
|
|
219
|
+
// Optionally set also queueItems errorStatus & errorMessage
|
|
205
220
|
async function checkAndSetState({
|
|
206
221
|
correlationId,
|
|
207
222
|
state,
|
|
208
223
|
errorMessage = undefined,
|
|
209
224
|
errorStatus = undefined
|
|
210
225
|
}) {
|
|
211
|
-
// checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR
|
|
212
|
-
// otherwise it sets queueItem to state ABORT (408, 'Timeout')
|
|
226
|
+
// checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR/DONE
|
|
227
|
+
// otherwise it sets queueItem and importJobStates to state ABORT and add errorStatus and errorMessage (408, 'Timeout')
|
|
213
228
|
const timeOut = await checkTimeOut({
|
|
214
229
|
correlationId
|
|
215
230
|
});
|
|
@@ -224,16 +239,15 @@ async function _default(MONGO_URI, collection) {
|
|
|
224
239
|
return false;
|
|
225
240
|
}
|
|
226
241
|
|
|
227
|
-
// Check state that the queueItem has not waited too long and set
|
|
242
|
+
// Check state that the queueItem has not waited too long and set importJobState
|
|
243
|
+
// Note: checkAndSetImportJobState cannot be used to set queueItems errorStatus & errorMessage (expect in case of a TimeOut)
|
|
228
244
|
async function checkAndSetImportJobState({
|
|
229
245
|
correlationId,
|
|
230
246
|
operation,
|
|
231
|
-
importJobState
|
|
232
|
-
errorMessage = '',
|
|
233
|
-
errorStatus = ''
|
|
247
|
+
importJobState
|
|
234
248
|
}) {
|
|
235
|
-
// checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR
|
|
236
|
-
// otherwise it sets queueItem to state ABORT (408, 'Timeout')
|
|
249
|
+
// checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR/DONE
|
|
250
|
+
// otherwise it sets queueItem and importJobStates to state ABORT and errorStatue and errorMessage (408, 'Timeout')
|
|
237
251
|
logger.debug(`${correlationId}, ${importJobState}, ${operation}`);
|
|
238
252
|
const timeOut = await checkTimeOut({
|
|
239
253
|
correlationId,
|
|
@@ -244,25 +258,25 @@ async function _default(MONGO_URI, collection) {
|
|
|
244
258
|
return setImportJobState({
|
|
245
259
|
correlationId,
|
|
246
260
|
operation,
|
|
247
|
-
importJobState
|
|
248
|
-
errorMessage,
|
|
249
|
-
errorStatus
|
|
261
|
+
importJobState
|
|
250
262
|
});
|
|
251
263
|
}
|
|
252
264
|
return false;
|
|
253
265
|
}
|
|
254
266
|
async function query(params, showParams = {}) {
|
|
255
267
|
logger.debug(`Querying: ${JSON.stringify(params)}, ${JSON.stringify(showParams)}`);
|
|
268
|
+
debug(`Querying: ${JSON.stringify(params)}, ${JSON.stringify(showParams)}`);
|
|
256
269
|
const {
|
|
257
270
|
limit = 1000,
|
|
258
271
|
skip = 0,
|
|
259
272
|
...rest
|
|
260
273
|
} = params;
|
|
261
|
-
const result = await
|
|
274
|
+
const result = await operator.find(rest, {
|
|
262
275
|
projection: createProjection(showParams)
|
|
263
276
|
}).limit(parseInt(limit, 10)).skip(parseInt(skip, 10)).toArray();
|
|
264
277
|
logger.debug(`Query result: ${result.length > 0 ? 'Found!' : 'Not found!'}`);
|
|
265
278
|
logger.silly(`${JSON.stringify(result)}`);
|
|
279
|
+
debug(`${JSON.stringify(result)}`);
|
|
266
280
|
return result;
|
|
267
281
|
}
|
|
268
282
|
|
|
@@ -272,6 +286,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
272
286
|
|
|
273
287
|
function createProjection(showParams = {}) {
|
|
274
288
|
logger.silly(`Creating projection for query: ${JSON.stringify(showParams)}`);
|
|
289
|
+
debug(`Creating projection for query: ${JSON.stringify(showParams)}`);
|
|
275
290
|
const {
|
|
276
291
|
showAll = 0,
|
|
277
292
|
showOperations = 0,
|
|
@@ -279,8 +294,21 @@ async function _default(MONGO_URI, collection) {
|
|
|
279
294
|
showRecordLoadParams = 0,
|
|
280
295
|
showImportJobState = 0
|
|
281
296
|
} = showParams;
|
|
297
|
+
const combinedShowParams = {
|
|
298
|
+
showAll,
|
|
299
|
+
showOperations,
|
|
300
|
+
showOperationSettings,
|
|
301
|
+
showRecordLoadParams,
|
|
302
|
+
showImportJobState
|
|
303
|
+
};
|
|
282
304
|
logger.debug(`showAll: ${showAll}, showOperations: ${showOperations}, showOperationSettings: ${showOperationSettings}, showRecordLoadParams: ${showRecordLoadParams}, showImportJobState: ${showImportJobState}`);
|
|
283
|
-
|
|
305
|
+
debug(`showAll: ${showAll}, showOperations: ${showOperations}, showOperationSettings: ${showOperationSettings}, showRecordLoadParams: ${showRecordLoadParams}, showImportJobState: ${showImportJobState}`);
|
|
306
|
+
debug(`${JSON.stringify(combinedShowParams)}`);
|
|
307
|
+
|
|
308
|
+
// NOTE: parseBoolean parses any non-empty, non-"false" string as true!
|
|
309
|
+
if ((0, _melindaCommons.parseBoolean)(showAll)) {
|
|
310
|
+
//if (showAll === true || showAll === '1' || showAll === 1) {
|
|
311
|
+
debug(`ShowAll: ${showAll}`);
|
|
284
312
|
return {
|
|
285
313
|
_id: 0
|
|
286
314
|
};
|
|
@@ -291,52 +319,61 @@ async function _default(MONGO_URI, collection) {
|
|
|
291
319
|
'showRecordLoadParams': 'recordLoadParams',
|
|
292
320
|
'showImportJobState': 'importJobState'
|
|
293
321
|
};
|
|
294
|
-
const result = Object.keys(
|
|
322
|
+
const result = Object.keys(combinedShowParams)
|
|
323
|
+
//.filter(param => param !== 'showAll' && combinedShowParams[param] !== true && combinedShowParams[param] !== 1 && combinedShowParams[param] !== '1')
|
|
324
|
+
.filter(param => param !== 'showAll' && !(0, _melindaCommons.parseBoolean)(combinedShowParams[param])).filter(param => showParamToField[param]).map(param => showParamToField[param]);
|
|
295
325
|
logger.silly(`We want to exclude from projection: ${JSON.stringify(result)}`);
|
|
326
|
+
debug(`We want to exclude from projection: ${JSON.stringify(result)}`);
|
|
296
327
|
const excludeObject = Object.fromEntries(result.map(param => [param, 0]));
|
|
297
328
|
logger.silly(`We want to exclude from projection: ${JSON.stringify(excludeObject)}`);
|
|
329
|
+
debug(`We want to exclude from projection: ${JSON.stringify(excludeObject)}`);
|
|
298
330
|
return {
|
|
299
331
|
_id: 0,
|
|
300
332
|
...excludeObject
|
|
301
333
|
};
|
|
302
334
|
}
|
|
335
|
+
|
|
336
|
+
// Note: edited in v4.2.4 to return queueItem *after* possible timout has aborted it
|
|
337
|
+
// Note: previous versions returned queueItem *before* its state/queueItemState is timeOuted
|
|
303
338
|
async function queryById({
|
|
304
339
|
correlationId,
|
|
305
340
|
checkModTime = false
|
|
306
341
|
}) {
|
|
307
|
-
const result = await db.collection(collection).findOne({
|
|
308
|
-
correlationId
|
|
309
|
-
});
|
|
310
342
|
if (checkModTime) {
|
|
311
|
-
|
|
343
|
+
debug(`queryById checkModTime: ${checkModTime}`);
|
|
344
|
+
await checkTimeOut({
|
|
345
|
+
correlationId
|
|
346
|
+
});
|
|
347
|
+
return queryById({
|
|
312
348
|
correlationId
|
|
313
349
|
});
|
|
314
|
-
if (timeOut) {
|
|
315
|
-
return queryById({
|
|
316
|
-
correlationId
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
return result;
|
|
320
350
|
}
|
|
351
|
+
const result = await operator.findOne({
|
|
352
|
+
correlationId
|
|
353
|
+
}, {
|
|
354
|
+
projection: {
|
|
355
|
+
_id: 0
|
|
356
|
+
}
|
|
357
|
+
});
|
|
321
358
|
return result;
|
|
322
359
|
}
|
|
323
360
|
|
|
324
361
|
// Check that if the item has waited too long
|
|
325
362
|
// If the last modification time for the queueItem is older than 1 minute
|
|
326
363
|
// set state to ABORT and return false, otherwise return true
|
|
327
|
-
// If the state is already ABORT or ERROR return false
|
|
364
|
+
// If the state is already ABORT or ERROR or DONE return false
|
|
328
365
|
|
|
329
366
|
async function checkTimeOut({
|
|
330
367
|
correlationId
|
|
331
368
|
}) {
|
|
332
369
|
const {
|
|
333
370
|
modificationTime,
|
|
334
|
-
|
|
371
|
+
queueItemState: oldState,
|
|
335
372
|
importJobState
|
|
336
|
-
} = await
|
|
373
|
+
} = await operator.findOne({
|
|
337
374
|
correlationId
|
|
338
375
|
});
|
|
339
|
-
|
|
376
|
+
//debug(`${modificationTime} - oldState: ${oldState}`);
|
|
340
377
|
// should we check for DONE too?
|
|
341
378
|
if ([_constants.QUEUE_ITEM_STATE.ABORT, _constants.QUEUE_ITEM_STATE.ERROR, _constants.QUEUE_ITEM_STATE.DONE].includes(oldState)) {
|
|
342
379
|
logger.silly(`${correlationId} has already state: ${oldState}`);
|
|
@@ -380,26 +417,38 @@ async function _default(MONGO_URI, collection) {
|
|
|
380
417
|
}
|
|
381
418
|
return true;
|
|
382
419
|
}
|
|
420
|
+
|
|
421
|
+
// eslint-disable-next-line max-statements
|
|
383
422
|
async function remove(params) {
|
|
384
423
|
logger.silly(`${JSON.stringify(params)}`);
|
|
385
424
|
logger.info(`Removing from Mongo (${collection}) id: ${params.correlationId}`);
|
|
425
|
+
debug(`${JSON.stringify(params)}`);
|
|
426
|
+
debug(`Removing from Mongo (${collection}) id: ${params.correlationId}`);
|
|
386
427
|
const clean = (0, _mongoSanitize.default)(params.correlationId);
|
|
387
428
|
logger.silly(`mongo/remove: clean: ${JSON.stringify(clean)}`);
|
|
429
|
+
debug(`mongo/remove: clean: ${JSON.stringify(clean)}`);
|
|
388
430
|
try {
|
|
389
431
|
//const metadataResult = await getFileMetadata({filename: clean});
|
|
390
432
|
//logger.debug(`mongo/remove: metadataResult: ${JSON.stringify(metadataResult)}`);
|
|
391
|
-
const noContent = await removeContent(
|
|
433
|
+
const noContent = await removeContent({
|
|
434
|
+
correlationId: params.correlationId
|
|
435
|
+
});
|
|
436
|
+
debug(`noContent (removeContent result): ${JSON.stringify(noContent)}`);
|
|
392
437
|
if (noContent) {
|
|
393
|
-
await
|
|
438
|
+
const deleteResult = await operator.deleteOne({
|
|
394
439
|
correlationId: clean
|
|
395
440
|
});
|
|
441
|
+
debug(`deleteResult: ${JSON.stringify(deleteResult)}`);
|
|
396
442
|
return true;
|
|
397
443
|
}
|
|
398
444
|
} catch (err) {
|
|
445
|
+
// TEST-COVERAGE: this error is not (currently) tested
|
|
399
446
|
if (err instanceof _mongodb.MongoDriverError) {
|
|
447
|
+
debug(err);
|
|
400
448
|
if (err.message.indexOf('File not found for id') !== -1) {
|
|
401
449
|
logger.silly(`mongo/remove: File not found, removing queueItem ${JSON.stringify(clean)} from ${collection}`);
|
|
402
|
-
|
|
450
|
+
debug(`mongo/remove: File not found, removing queueItem ${JSON.stringify(clean)} from ${collection}`);
|
|
451
|
+
await operator.deleteOne({
|
|
403
452
|
correlationId: clean
|
|
404
453
|
});
|
|
405
454
|
return true;
|
|
@@ -412,11 +461,13 @@ async function _default(MONGO_URI, collection) {
|
|
|
412
461
|
}
|
|
413
462
|
async function readContent(correlationId) {
|
|
414
463
|
logger.info(`Reading content from mongo for id: ${correlationId} in ${collection}`);
|
|
464
|
+
debug(`Reading content from mongo for id: ${correlationId} in ${collection}`);
|
|
415
465
|
const clean = (0, _mongoSanitize.default)(correlationId);
|
|
416
|
-
|
|
466
|
+
debug(clean);
|
|
467
|
+
const result = await operator.findOne({
|
|
417
468
|
correlationId: clean
|
|
418
469
|
}); // njsscan-ignore: node_nosqli_injection
|
|
419
|
-
|
|
470
|
+
debug(result);
|
|
420
471
|
if (result) {
|
|
421
472
|
const {
|
|
422
473
|
operationSettings
|
|
@@ -428,6 +479,8 @@ async function _default(MONGO_URI, collection) {
|
|
|
428
479
|
};
|
|
429
480
|
}
|
|
430
481
|
logger.debug(`OperationSettings for ${correlationId}: ${JSON.stringify(operationSettings)}`);
|
|
482
|
+
debug(`OperationSettings for ${correlationId}: ${JSON.stringify(operationSettings)}`);
|
|
483
|
+
debug(`Content is only available for streamBulk jobs. ${correlationId} is not a streamBulk job.`);
|
|
431
484
|
throw new _melindaCommons.Error(_httpStatus.default.BAD_REQUEST, {
|
|
432
485
|
message: `Content is only available for streamBulk jobs. ${correlationId} is not a streamBulk job.`
|
|
433
486
|
});
|
|
@@ -438,51 +491,64 @@ async function _default(MONGO_URI, collection) {
|
|
|
438
491
|
}
|
|
439
492
|
async function removeContent(params) {
|
|
440
493
|
logger.info(`Removing content from mongo for id: ${params.correlationId} in ${collection}`);
|
|
494
|
+
debug(`Removing content from mongo for id: ${params.correlationId} in ${collection}`);
|
|
441
495
|
const clean = (0, _mongoSanitize.default)(params.correlationId);
|
|
442
|
-
const result = await
|
|
443
|
-
|
|
444
|
-
});
|
|
445
|
-
|
|
446
|
-
if (result) {
|
|
447
|
-
|
|
496
|
+
const result = await gridFSBucket.find({
|
|
497
|
+
filename: clean
|
|
498
|
+
}).toArray();
|
|
499
|
+
debug(`mongo/removeContent: find bucket result ${JSON.stringify(result)}`);
|
|
500
|
+
if (result.length > 0) {
|
|
501
|
+
// Note: we assume and handle just one file for filename!
|
|
502
|
+
const [firstBucketResult] = result;
|
|
503
|
+
const fileId = firstBucketResult._id;
|
|
504
|
+
await gridFSBucket.delete(fileId);
|
|
448
505
|
return true;
|
|
449
506
|
}
|
|
507
|
+
logger.debug(`No files for ${params.correlationId} to delete`);
|
|
450
508
|
return true;
|
|
451
509
|
}
|
|
452
|
-
|
|
453
|
-
// eslint-disable-next-line max-statements
|
|
454
510
|
function getOne({
|
|
455
511
|
queueItemState,
|
|
456
512
|
importJobState = undefined
|
|
457
513
|
}) {
|
|
514
|
+
//params example: "queueItemState": "IMPORTER.IN_QUEUE", "importJobState":{"importJobState.UPDATE": "IN_QUEUE"}
|
|
458
515
|
logger.silly(`queueItemState: ${queueItemState}, importJobState: ${JSON.stringify(importJobState)}`);
|
|
516
|
+
//debug(`queueItemState: ${queueItemState}, importJobState: ${JSON.stringify(importJobState)}`);
|
|
459
517
|
const cleanQueueItemState = queueItemState ? {
|
|
460
518
|
queueItemState: (0, _mongoSanitize.default)(queueItemState)
|
|
461
519
|
} : undefined;
|
|
520
|
+
const options = {
|
|
521
|
+
projection: {
|
|
522
|
+
_id: 0
|
|
523
|
+
}
|
|
524
|
+
};
|
|
462
525
|
try {
|
|
463
526
|
// Just queueItemState
|
|
464
527
|
if (queueItemState && importJobState === undefined) {
|
|
465
528
|
logger.silly(`Checking DB ${collection} for just ${JSON.stringify(cleanQueueItemState.queueItemState)}`);
|
|
466
|
-
|
|
529
|
+
//debug(`Checking DB ${collection} for just ${JSON.stringify(cleanQueueItemState.queueItemState)}`);
|
|
530
|
+
return operator.findOne({
|
|
467
531
|
...cleanQueueItemState
|
|
468
|
-
});
|
|
532
|
+
}, options);
|
|
469
533
|
}
|
|
470
534
|
|
|
471
535
|
// importJobState
|
|
472
536
|
if (importJobState && queueItemState === undefined) {
|
|
473
537
|
logger.silly(`Checking DB ${collection} for ${JSON.stringify(importJobState)}`);
|
|
474
|
-
|
|
538
|
+
//debug(`Checking DB ${collection} for ${JSON.stringify(importJobState)}`);
|
|
539
|
+
return operator.findOne({
|
|
475
540
|
...importJobState
|
|
476
|
-
});
|
|
541
|
+
}, options);
|
|
477
542
|
}
|
|
478
543
|
|
|
479
544
|
// importJobState and queueItemState
|
|
480
545
|
if (importJobState && queueItemState) {
|
|
481
546
|
logger.silly(`Checking DB ${collection} for ${queueItemState} and ${JSON.stringify(importJobState)}`);
|
|
482
|
-
|
|
547
|
+
//debug(`Checking DB ${collection} for ${queueItemState} and ${JSON.stringify(importJobState)}`);
|
|
548
|
+
return operator.findOne({
|
|
483
549
|
...cleanQueueItemState,
|
|
484
550
|
...importJobState
|
|
485
|
-
});
|
|
551
|
+
}, options);
|
|
486
552
|
}
|
|
487
553
|
logger.debug(`getOne not working!`);
|
|
488
554
|
throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, 'Missing parameters, cannot get queueItem');
|
|
@@ -499,6 +565,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
499
565
|
// Return content stream
|
|
500
566
|
return gridFSBucket.openDownloadStreamByName(clean);
|
|
501
567
|
} catch (error) {
|
|
568
|
+
// TEST-COVERAGE: this error is not (currently) tested
|
|
502
569
|
const errorMessage = error.payload || error.message || '';
|
|
503
570
|
(0, _utils.logError)(error);
|
|
504
571
|
throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, `Mongo errored: ${errorMessage}`);
|
|
@@ -512,7 +579,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
512
579
|
logger.verbose(`Push ids (${handledIds.length}) and rejectedIds (${rejectedIds.length}) ${correlationId} to ${collection}`);
|
|
513
580
|
logger.debug(`ids (${handledIds.length}): ${JSON.stringify(handledIds)}, rejectedIds ${rejectedIds.length}: ${JSON.stringify(rejectedIds)}`);
|
|
514
581
|
const clean = (0, _mongoSanitize.default)(correlationId);
|
|
515
|
-
await
|
|
582
|
+
await operator.updateOne({
|
|
516
583
|
correlationId: clean
|
|
517
584
|
}, {
|
|
518
585
|
$set: {
|
|
@@ -537,7 +604,8 @@ async function _default(MONGO_URI, collection) {
|
|
|
537
604
|
logger.silly(`Messages (${messages.length}): ${JSON.stringify(messages)}}`);
|
|
538
605
|
const clean = (0, _mongoSanitize.default)(correlationId);
|
|
539
606
|
const cleanMessageField = (0, _mongoSanitize.default)(messageField);
|
|
540
|
-
|
|
607
|
+
debug(`${messageField} -> ${cleanMessageField}`);
|
|
608
|
+
await operator.updateOne({
|
|
541
609
|
correlationId: clean
|
|
542
610
|
}, {
|
|
543
611
|
$set: {
|
|
@@ -562,6 +630,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
562
630
|
const stateInQueueItemStatesValidator = Object.values(_constants.QUEUE_ITEM_STATE.VALIDATOR).indexOf(state) > -1;
|
|
563
631
|
const stateInQueueItemStatesImporter = Object.values(_constants.QUEUE_ITEM_STATE.IMPORTER).indexOf(state) > -1;
|
|
564
632
|
if (!stateInQueueItemStates && !stateInQueueItemStatesValidator && !stateInQueueItemStatesImporter) {
|
|
633
|
+
debug(`Trying to set invalid state ${state}`);
|
|
565
634
|
throw new _melindaCommons.Error(_httpStatus.default.BAD_REQUEST, 'Trying to set invalid state');
|
|
566
635
|
}
|
|
567
636
|
const clean = (0, _mongoSanitize.default)(correlationId);
|
|
@@ -575,7 +644,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
575
644
|
// Do not update value that are undefined
|
|
576
645
|
// eslint-disable-next-line functional/immutable-data
|
|
577
646
|
Object.keys(updateValues).forEach(key => updateValues[key] === undefined && delete updateValues[key]);
|
|
578
|
-
return
|
|
647
|
+
return operator.findOneAndUpdate({
|
|
579
648
|
correlationId: clean
|
|
580
649
|
}, {
|
|
581
650
|
$set: updateValues
|
|
@@ -583,7 +652,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
583
652
|
projection: {
|
|
584
653
|
_id: 0
|
|
585
654
|
},
|
|
586
|
-
|
|
655
|
+
returnDocument: 'after'
|
|
587
656
|
});
|
|
588
657
|
}
|
|
589
658
|
function setImportJobState({
|
|
@@ -593,13 +662,16 @@ async function _default(MONGO_URI, collection) {
|
|
|
593
662
|
}) {
|
|
594
663
|
// should this also get importJobState as previously created object? {}
|
|
595
664
|
logger.info(`Setting queue-item importJobState: {${operation}: ${importJobState}} for ${correlationId}`);
|
|
665
|
+
debug(`Setting queue-item importJobState: {${operation}: ${importJobState}} for ${correlationId}`);
|
|
596
666
|
const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
|
|
597
667
|
const cleanImportJobState = (0, _mongoSanitize.default)(importJobState);
|
|
598
668
|
if (!(operation in _constants.OPERATIONS)) {
|
|
599
|
-
|
|
669
|
+
debug(`Error: ${operation} is not in ${JSON.stringify(_constants.OPERATIONS)}`);
|
|
670
|
+
throw new _melindaCommons.Error(_httpStatus.default.BAD_REQUEST, 'Invalid operation for import job state');
|
|
600
671
|
}
|
|
601
672
|
if (!(cleanImportJobState in _constants.IMPORT_JOB_STATE)) {
|
|
602
|
-
|
|
673
|
+
debug(`Error: ${cleanImportJobState} is not in ${JSON.stringify(_constants.IMPORT_JOB_STATE)}`);
|
|
674
|
+
throw new _melindaCommons.Error(_httpStatus.default.BAD_REQUEST, 'Invalid import job state');
|
|
603
675
|
}
|
|
604
676
|
const newJobState = getNewJobState(operation, cleanImportJobState);
|
|
605
677
|
function getNewJobState(operation, cleanImportJobState) {
|
|
@@ -618,9 +690,11 @@ async function _default(MONGO_URI, collection) {
|
|
|
618
690
|
'importJobState.FIX': cleanImportJobState
|
|
619
691
|
};
|
|
620
692
|
}
|
|
693
|
+
// istanbul ignore next
|
|
694
|
+
// Ignoring for coverage - we error this already
|
|
621
695
|
throw new _melindaCommons.Error('400', 'Invalid operation for import job state');
|
|
622
696
|
}
|
|
623
|
-
return
|
|
697
|
+
return operator.findOneAndUpdate({
|
|
624
698
|
correlationId: cleanCorrelationId
|
|
625
699
|
}, {
|
|
626
700
|
$set: {
|
|
@@ -631,7 +705,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
631
705
|
projection: {
|
|
632
706
|
_id: 0
|
|
633
707
|
},
|
|
634
|
-
|
|
708
|
+
returnDocument: 'after'
|
|
635
709
|
});
|
|
636
710
|
}
|
|
637
711
|
async function setOperation({
|
|
@@ -641,13 +715,13 @@ async function _default(MONGO_URI, collection) {
|
|
|
641
715
|
const newOperation = operation;
|
|
642
716
|
const {
|
|
643
717
|
operation: oldOperation
|
|
644
|
-
} = await
|
|
718
|
+
} = await operator.findOne({
|
|
645
719
|
correlationId
|
|
646
720
|
});
|
|
647
721
|
logger.info(`Setting queue-item operation from ${oldOperation} to ${newOperation} for ${correlationId} to ${collection}`);
|
|
648
722
|
const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
|
|
649
723
|
const cleanNewOperation = (0, _mongoSanitize.default)(newOperation);
|
|
650
|
-
const result = await
|
|
724
|
+
const result = await operator.findOneAndUpdate({
|
|
651
725
|
correlationId: cleanCorrelationId
|
|
652
726
|
}, {
|
|
653
727
|
$set: {
|
|
@@ -658,9 +732,10 @@ async function _default(MONGO_URI, collection) {
|
|
|
658
732
|
projection: {
|
|
659
733
|
_id: 0
|
|
660
734
|
},
|
|
661
|
-
|
|
735
|
+
returnDocument: 'after'
|
|
662
736
|
});
|
|
663
|
-
|
|
737
|
+
debugDev(`${JSON.stringify(result)}`);
|
|
738
|
+
return result.ok || result;
|
|
664
739
|
// logger.debug(JSON.stringify(result));
|
|
665
740
|
}
|
|
666
741
|
async function setOperations({
|
|
@@ -669,7 +744,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
669
744
|
removeOperation = undefined
|
|
670
745
|
}) {
|
|
671
746
|
const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
|
|
672
|
-
const queueItem = await
|
|
747
|
+
const queueItem = await operator.findOne({
|
|
673
748
|
correlationId: cleanCorrelationId
|
|
674
749
|
});
|
|
675
750
|
logger.silly(`We found a queueItem: ${JSON.stringify(queueItem)}`);
|
|
@@ -679,7 +754,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
679
754
|
const operationsAfterRemoveAndAdd = operationsAfterRemove.includes(addOperation) ? operationsAfterRemove : [...operationsAfterRemove, addOperation];
|
|
680
755
|
logger.silly(`operationsAfterRemove: ${operationsAfterRemove}`);
|
|
681
756
|
logger.silly(`operationAfterRemoveAndAdd: ${operationsAfterRemoveAndAdd}`);
|
|
682
|
-
const result = await
|
|
757
|
+
const result = await operator.findOneAndUpdate({
|
|
683
758
|
correlationId: cleanCorrelationId
|
|
684
759
|
}, {
|
|
685
760
|
$set: {
|
|
@@ -690,16 +765,17 @@ async function _default(MONGO_URI, collection) {
|
|
|
690
765
|
projection: {
|
|
691
766
|
_id: 0
|
|
692
767
|
},
|
|
693
|
-
|
|
768
|
+
returnDocument: 'after'
|
|
694
769
|
});
|
|
695
|
-
|
|
770
|
+
debugDev(`${JSON.stringify(result)}`);
|
|
771
|
+
return result.ok || result;
|
|
696
772
|
// logger.debug(JSON.stringify(result));
|
|
697
773
|
}
|
|
698
774
|
async function addBlobSize({
|
|
699
775
|
correlationId
|
|
700
776
|
}) {
|
|
701
777
|
const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
|
|
702
|
-
const result = await
|
|
778
|
+
const result = await operator.findOneAndUpdate({
|
|
703
779
|
correlationId: cleanCorrelationId,
|
|
704
780
|
queueItemState: _constants.QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS
|
|
705
781
|
}, {
|
|
@@ -713,9 +789,10 @@ async function _default(MONGO_URI, collection) {
|
|
|
713
789
|
projection: {
|
|
714
790
|
_id: 0
|
|
715
791
|
},
|
|
716
|
-
|
|
792
|
+
returnDocument: 'after'
|
|
717
793
|
});
|
|
718
794
|
logger.verbose(`AddBlobSizeResult in mongo: ${JSON.stringify(result)}`);
|
|
795
|
+
debugDev(`${JSON.stringify(result)}`);
|
|
719
796
|
return result;
|
|
720
797
|
}
|
|
721
798
|
async function setBlobSize({
|
|
@@ -724,7 +801,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
724
801
|
}) {
|
|
725
802
|
const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
|
|
726
803
|
const cleanBlobSize = (0, _mongoSanitize.default)(blobSize);
|
|
727
|
-
const result = await
|
|
804
|
+
const result = await operator.findOneAndUpdate({
|
|
728
805
|
correlationId: cleanCorrelationId
|
|
729
806
|
}, {
|
|
730
807
|
$set: {
|
|
@@ -735,9 +812,10 @@ async function _default(MONGO_URI, collection) {
|
|
|
735
812
|
projection: {
|
|
736
813
|
_id: 0
|
|
737
814
|
},
|
|
738
|
-
|
|
815
|
+
returnDocument: 'after'
|
|
739
816
|
});
|
|
740
817
|
logger.verbose(`SetBlobSizeResult in mongo: ${JSON.stringify(result)}`);
|
|
818
|
+
debugDev(`${JSON.stringify(result)}`);
|
|
741
819
|
return result;
|
|
742
820
|
}
|
|
743
821
|
}
|