@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.
Files changed (47) hide show
  1. package/.github/workflows/melinda-node-tests.yml +1 -1
  2. package/dist/amqp.js +2 -2
  3. package/dist/amqp.js.map +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/mongo.js +158 -80
  7. package/dist/mongo.js.map +1 -1
  8. package/dist/mongoLog.js +1 -4
  9. package/dist/mongoLog.js.map +1 -1
  10. package/package.json +26 -24
  11. package/{dist → tests}/amqp.health.spec.js +17 -10
  12. package/tests/amqp.tests.spec.js +301 -0
  13. package/tests/helpers/conversion.spec.js +95 -0
  14. package/tests/helpers/fix.spec.js +41 -0
  15. package/tests/helpers/validation.spec.js +58 -0
  16. package/tests/mongo-add-blob-size.spec.js +100 -0
  17. package/tests/mongo-check-and-check-state.spec.js +112 -0
  18. package/tests/mongo-check-and-set-import-job-state.spec.js +112 -0
  19. package/tests/mongo-check-timeout.spec.js +111 -0
  20. package/tests/mongo-create-bulk.spec.js +100 -0
  21. package/tests/mongo-create-prio.spec.js +98 -0
  22. package/tests/mongo-get-one.spec.js +103 -0
  23. package/tests/mongo-get-stream.spec.js +120 -0
  24. package/tests/mongo-push-ids.spec.js +101 -0
  25. package/tests/mongo-push-messages.spec.js +99 -0
  26. package/tests/mongo-query-by-id.spec.js +112 -0
  27. package/tests/mongo-query.spec.js +108 -0
  28. package/tests/mongo-read-content.spec.js +123 -0
  29. package/tests/mongo-remove.spec.js +115 -0
  30. package/tests/mongo-set-blob-size.spec.js +99 -0
  31. package/tests/mongo-set-import-job-state.spec.js +102 -0
  32. package/tests/mongo-set-operation.spec.js +102 -0
  33. package/tests/mongo-set-operations.spec.js +101 -0
  34. package/tests/mongo-set-state.spec.js +102 -0
  35. package/{dist → tests}/mongoLog.spec.js +22 -22
  36. package/tests/testUtils.js +94 -0
  37. package/dist/amqp.health.spec.js.map +0 -1
  38. package/dist/amqp.tests.spec.js +0 -310
  39. package/dist/amqp.tests.spec.js.map +0 -1
  40. package/dist/helpers/conversion.spec.js +0 -88
  41. package/dist/helpers/conversion.spec.js.map +0 -1
  42. package/dist/helpers/fix.spec.js +0 -46
  43. package/dist/helpers/fix.spec.js.map +0 -1
  44. package/dist/helpers/validation.spec.js +0 -47
  45. package/dist/helpers/validation.spec.js.map +0 -1
  46. package/dist/mongo.spec.js.draft +0 -54
  47. 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
- useNewUrlParser: true,
55
- useUnifiedTopology: true
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
- const result = await db.collection(collection).insertOne(newQueueItem);
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
- // No await here, promises later
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 db.collection(collection).insertOne(newQueueItem);
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 state
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 db.collection(collection).find(rest, {
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
- if (showAll) {
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(showParams).filter(param => param !== 'showAll' && showParams[param] !== true && showParams[param] !== 1).filter(param => showParamToField[param]).map(param => showParamToField[param]);
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
- const timeOut = await checkTimeOut({
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
- queueitemState: oldState,
371
+ queueItemState: oldState,
335
372
  importJobState
336
- } = await db.collection(collection).findOne({
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(params);
433
+ const noContent = await removeContent({
434
+ correlationId: params.correlationId
435
+ });
436
+ debug(`noContent (removeContent result): ${JSON.stringify(noContent)}`);
392
437
  if (noContent) {
393
- await db.collection(collection).deleteOne({
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
- await db.collection(collection).deleteOne({
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
- const result = await db.collection(collection).findOne({
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 db.collection(collection).findOne({
443
- correlationId: clean
444
- }); // njsscan-ignore: node_nosqli_injection
445
- logger.silly(`mongo/removeContent: result ${JSON.stringify(result)}`);
446
- if (result) {
447
- await gridFSBucket.delete(clean);
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
- return db.collection(collection).findOne({
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
- return db.collection(collection).findOne({
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
- return db.collection(collection).findOne({
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 db.collection(collection).updateOne({
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
- await db.collection(collection).updateOne({
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 db.collection(collection).findOneAndUpdate({
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
- returnNewDocument: true
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
- throw new _melindaCommons.Error('400', 'Invalid operation for import job state');
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
- throw new _melindaCommons.Error('400', 'Invalid import job state');
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 db.collection(collection).findOneAndUpdate({
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
- returnNewDocument: true
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 db.collection(collection).findOne({
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 db.collection(collection).findOneAndUpdate({
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
- returnNewDocument: true
735
+ returnDocument: 'after'
662
736
  });
663
- return result.ok;
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 db.collection(collection).findOne({
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 db.collection(collection).findOneAndUpdate({
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
- returnNewDocument: true
768
+ returnDocument: 'after'
694
769
  });
695
- return result.ok;
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 db.collection(collection).findOneAndUpdate({
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
- returnNewDocument: true
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 db.collection(collection).findOneAndUpdate({
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
- returnNewDocument: true
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
  }