@natlibfi/melinda-rest-api-commons 4.2.5-alpha.1 → 5.0.0-alpha.1

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 (69) hide show
  1. package/.github/workflows/melinda-node-tests.yml +9 -6
  2. package/dist/conversion.js +70 -0
  3. package/dist/conversion.js.map +7 -0
  4. package/dist/fix-constants.js +63 -0
  5. package/dist/fix-constants.js.map +7 -0
  6. package/dist/fix-handle-tempurns.js +83 -0
  7. package/dist/fix-handle-tempurns.js.map +7 -0
  8. package/dist/fix-strip-f884s.js +160 -0
  9. package/dist/fix-strip-f884s.js.map +7 -0
  10. package/dist/fix-utils.js +39 -0
  11. package/dist/fix-utils.js.map +7 -0
  12. package/dist/fix.js +142 -0
  13. package/dist/fix.js.map +7 -0
  14. package/dist/validation.js +19 -0
  15. package/dist/validation.js.map +7 -0
  16. package/eslint.config.js +53 -0
  17. package/package.json +23 -96
  18. package/tests/{amqp.health.spec.js → amqp.healthtest.js} +2 -2
  19. package/tests/{amqp.tests.spec.js → amqp.tests.localtest.js} +46 -46
  20. package/tests/helpers/{conversion.spec.js → conversion.test.js} +38 -25
  21. package/tests/helpers/{fix.spec.js → fix.test.js} +6 -6
  22. package/tests/helpers/{validation.spec.js → validation.test.js} +12 -9
  23. package/tests/{mongo-add-blob-size.spec.js → mongo-add-blob-size.test.js} +6 -6
  24. package/tests/{mongo-check-and-check-state.spec.js → mongo-check-and-check-state.test.js} +7 -7
  25. package/tests/{mongo-check-and-set-import-job-state.spec.js → mongo-check-and-set-import-job-state.test.js} +7 -7
  26. package/tests/{mongo-check-timeout.spec.js → mongo-check-timeout.test.js} +7 -7
  27. package/tests/{mongo-create-bulk.spec.js → mongo-create-bulk.test.js} +5 -5
  28. package/tests/{mongo-create-prio.spec.js → mongo-create-prio.test.js} +6 -6
  29. package/tests/{mongo-get-one.spec.js → mongo-get-one.test.js} +7 -7
  30. package/tests/{mongo-get-stream.spec.js → mongo-get-stream.test.js} +7 -7
  31. package/tests/{mongo-push-ids.spec.js → mongo-push-ids.test.js} +5 -5
  32. package/tests/{mongo-push-messages.spec.js → mongo-push-messages.test.js} +6 -6
  33. package/tests/{mongo-query-by-id.spec.js → mongo-query-by-id.test.js} +7 -7
  34. package/tests/{mongo-query.spec.js → mongo-query.test.js} +7 -7
  35. package/tests/{mongo-read-content.spec.js → mongo-read-content.test.js} +8 -8
  36. package/tests/{mongo-remove.spec.js → mongo-remove.test.js} +6 -6
  37. package/tests/{mongo-set-blob-size.spec.js → mongo-set-blob-size.test.js} +6 -6
  38. package/tests/{mongo-set-import-job-state.spec.js → mongo-set-import-job-state.test.js} +6 -6
  39. package/tests/{mongo-set-operation.spec.js → mongo-set-operation.test.js} +6 -6
  40. package/tests/{mongo-set-operations.spec.js → mongo-set-operations.test.js} +6 -6
  41. package/tests/{mongo-set-state.spec.js → mongo-set-state.test.js} +7 -7
  42. package/tests/{mongoLog.spec.js → mongoLog.test.js} +10 -11
  43. package/tests/testUtils.js +9 -8
  44. package/dist/amqp.js +0 -326
  45. package/dist/amqp.js.map +0 -1
  46. package/dist/constants.js +0 -60
  47. package/dist/constants.js.map +0 -1
  48. package/dist/helpers/conversion.js +0 -88
  49. package/dist/helpers/conversion.js.map +0 -1
  50. package/dist/helpers/fix-constants.js +0 -70
  51. package/dist/helpers/fix-constants.js.map +0 -1
  52. package/dist/helpers/fix-handle-tempurns.js +0 -133
  53. package/dist/helpers/fix-handle-tempurns.js.map +0 -1
  54. package/dist/helpers/fix-strip-f884s.js +0 -210
  55. package/dist/helpers/fix-strip-f884s.js.map +0 -1
  56. package/dist/helpers/fix-utils.js +0 -54
  57. package/dist/helpers/fix-utils.js.map +0 -1
  58. package/dist/helpers/fix.js +0 -202
  59. package/dist/helpers/fix.js.map +0 -1
  60. package/dist/helpers/validation.js +0 -37
  61. package/dist/helpers/validation.js.map +0 -1
  62. package/dist/index.js +0 -109
  63. package/dist/index.js.map +0 -1
  64. package/dist/mongo.js +0 -822
  65. package/dist/mongo.js.map +0 -1
  66. package/dist/mongoLog.js +0 -409
  67. package/dist/mongoLog.js.map +0 -1
  68. package/dist/utils.js +0 -211
  69. package/dist/utils.js.map +0 -1
package/dist/mongo.js DELETED
@@ -1,822 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
- Object.defineProperty(exports, "__esModule", {
5
- value: true
6
- });
7
- exports.default = _default;
8
- var _mongodb = require("mongodb");
9
- var _melindaBackendCommons = require("@natlibfi/melinda-backend-commons");
10
- var _melindaCommons = require("@natlibfi/melinda-commons");
11
- var _constants = require("./constants");
12
- var _utils = require("./utils.js");
13
- var _moment = _interopRequireDefault(require("moment"));
14
- var _httpStatus = _interopRequireDefault(require("http-status"));
15
- var _mongoSanitize = _interopRequireDefault(require("mongo-sanitize"));
16
- var _debug = _interopRequireDefault(require("debug"));
17
- /* eslint-disable max-lines */
18
-
19
- //import isDeepStrictEqual from 'util';
20
-
21
- /* QueueItem:
22
- {
23
- "correlationId":"FOO",
24
- "cataloger":"xxx0000",
25
- "oCatalogerIn":"xxx0000"
26
- "operation":"UPDATE",
27
- "operations":["UPDATE", "CREATE"]
28
- "contentType":"application/json",
29
- "recordLoadParams": {
30
- "pActiveLibrary": "XXX00",
31
- "pInputFile": "filename.seq",
32
- "pRejectFile": "filename.rej",
33
- "pLogFile": "filename.syslog",
34
- "pOldNew": "NEW"
35
- },
36
- "queueItemState":"PENDING_QUEUING",
37
- "importJobState": {
38
- "CREATE": "EMPTY",
39
- "UPDATE": "EMPTY"
40
- },
41
- blobSize: 1,
42
- records: [],
43
- errorMessage: '',
44
- errorStatus: '',
45
- "creationTime":"2020-01-01T00:00:00.000Z",
46
- "modificationTime":"2020-01-01T00:00:01.000Z",
47
- }
48
- */
49
-
50
- async function _default(MONGO_URI, collection, db = 'rest-api') {
51
- const logger = (0, _melindaBackendCommons.createLogger)();
52
- const debug = (0, _debug.default)('@natlibfi/melinda-rest-api-commons/mongo');
53
- const debugDev = debug.extend(':dev');
54
-
55
- // Connect to mongo (MONGO)
56
- const client = await _mongodb.MongoClient.connect(MONGO_URI);
57
- const dbConnection = client.db(db);
58
- const gridFSBucket = new _mongodb.GridFSBucket(dbConnection, {
59
- bucketName: collection
60
- });
61
- const operator = dbConnection.collection(collection);
62
- debugDev(`mongo: ${MONGO_URI}, db: ${db}, collection: ${collection}`);
63
- return {
64
- createPrio,
65
- createBulk,
66
- checkAndSetState,
67
- checkAndSetImportJobState,
68
- query,
69
- createProjection,
70
- queryById,
71
- checkTimeOut,
72
- remove,
73
- readContent,
74
- removeContent,
75
- getOne,
76
- getStream,
77
- setState,
78
- setImportJobState,
79
- pushIds,
80
- pushMessages,
81
- setOperation,
82
- setOperations,
83
- addBlobSize,
84
- setBlobSize
85
- };
86
- async function createPrio({
87
- correlationId,
88
- cataloger,
89
- oCatalogerIn,
90
- operation,
91
- operationSettings
92
- }) {
93
- debugDev('createPrio');
94
- const time = (0, _moment.default)().toDate();
95
- const newQueueItem = {
96
- correlationId,
97
- cataloger,
98
- operation,
99
- operations: [operation],
100
- oCatalogerIn,
101
- operationSettings: {
102
- prio: true,
103
- ...operationSettings
104
- },
105
- queueItemState: _constants.QUEUE_ITEM_STATE.VALIDATOR.PENDING_VALIDATION,
106
- blobSize: 1,
107
- importJobState: {
108
- CREATE: _constants.IMPORT_JOB_STATE.EMPTY,
109
- UPDATE: _constants.IMPORT_JOB_STATE.EMPTY,
110
- FIX: _constants.IMPORT_JOB_STATE.EMPTY
111
- },
112
- records: [],
113
- errorMessage: '',
114
- errorStatus: '',
115
- creationTime: time,
116
- modificationTime: time
117
- };
118
- try {
119
- debugDev(`Inserting: ${JSON.stringify(newQueueItem)} to ${collection}}`);
120
- const result = await operator.insertOne(newQueueItem);
121
- debugDev(JSON.stringify(result));
122
- if (result.acknowledged) {
123
- logger.info(`New PRIO queue item for ${operation} ${correlationId} has been made in ${collection}`);
124
- return;
125
- }
126
- // TEST-COVERAGE: this error is not (currently) tested
127
- throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR);
128
- } catch (error) {
129
- // TEST-COVERAGE: this error is not (currently) tested
130
- const errorMessage = error.payload || error.message || '';
131
- (0, _utils.logError)(error);
132
- throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, `Mongo errored: ${errorMessage}`);
133
- }
134
- }
135
-
136
- // eslint-disable-next-line max-statements
137
- async function createBulk({
138
- correlationId,
139
- cataloger,
140
- oCatalogerIn,
141
- operation,
142
- contentType,
143
- recordLoadParams,
144
- stream,
145
- operationSettings
146
- }) {
147
- const time = (0, _moment.default)().toDate();
148
- const newQueueItem = {
149
- correlationId,
150
- cataloger,
151
- oCatalogerIn,
152
- operation,
153
- operations: [operation],
154
- operationSettings: {
155
- prio: false,
156
- ...operationSettings
157
- },
158
- contentType,
159
- recordLoadParams,
160
- queueItemState: stream ? _constants.QUEUE_ITEM_STATE.VALIDATOR.UPLOADING : _constants.QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS,
161
- blobSize: 0,
162
- importJobState: {
163
- CREATE: _constants.IMPORT_JOB_STATE.EMPTY,
164
- UPDATE: _constants.IMPORT_JOB_STATE.EMPTY,
165
- FIX: _constants.IMPORT_JOB_STATE.EMPTY
166
- },
167
- records: [],
168
- errorMessage: '',
169
- errorStatus: '',
170
- creationTime: time,
171
- modificationTime: time
172
- };
173
-
174
- // eslint-disable-next-line functional/no-conditional-statements
175
- if (stream) {
176
- debug(`Creating streamBulk`);
177
- try {
178
- await new Promise((resolve, reject) => {
179
- const outputStream = gridFSBucket.openUploadStream(correlationId);
180
- stream.on('error', reject).on('data', chunk => outputStream.write(chunk)).on('end', () => outputStream.end(undefined, undefined, () => {
181
- resolve(correlationId);
182
- }));
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);
187
- } catch (error) {
188
- const errorMessage = error.payload || error.message || '';
189
- (0, _utils.logError)(error);
190
- throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, `Mongo errored: ${errorMessage}`);
191
- }
192
- }
193
- logger.debug(`No stream`);
194
- debug(`Creating noStreamBulk`);
195
- // eslint-disable-next-line functional/no-conditional-statements
196
- if (!stream) {
197
- try {
198
- const result = await operator.insertOne(newQueueItem);
199
- if (result.acknowledged) {
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}`);
202
- return {
203
- correlationId,
204
- queueItemState: _constants.QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS
205
- };
206
- }
207
- // TEST-COVERAGE: this error is not (currently) tested
208
- throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR);
209
- } catch (error) {
210
- // TEST-COVERAGE: this error is not (currently) tested
211
- const errorMessage = error.payload || error.message || '';
212
- (0, _utils.logError)(error);
213
- throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, `Mongo errored: ${errorMessage}`);
214
- }
215
- }
216
- }
217
-
218
- // Check state that the queueItem has not waited too long and set state
219
- // Optionally set also queueItems errorStatus & errorMessage
220
- async function checkAndSetState({
221
- correlationId,
222
- state,
223
- errorMessage = undefined,
224
- errorStatus = undefined
225
- }) {
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')
228
- const timeOut = await checkTimeOut({
229
- correlationId
230
- });
231
- if (timeOut) {
232
- return setState({
233
- correlationId,
234
- state,
235
- errorMessage,
236
- errorStatus
237
- });
238
- }
239
- return false;
240
- }
241
-
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)
244
- async function checkAndSetImportJobState({
245
- correlationId,
246
- operation,
247
- importJobState
248
- }) {
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')
251
- logger.debug(`${correlationId}, ${importJobState}, ${operation}`);
252
- const timeOut = await checkTimeOut({
253
- correlationId,
254
- operation,
255
- importJobState
256
- });
257
- if (timeOut) {
258
- return setImportJobState({
259
- correlationId,
260
- operation,
261
- importJobState
262
- });
263
- }
264
- return false;
265
- }
266
- async function query(params, showParams = {}) {
267
- logger.debug(`Querying: ${JSON.stringify(params)}, ${JSON.stringify(showParams)}`);
268
- debug(`Querying: ${JSON.stringify(params)}, ${JSON.stringify(showParams)}`);
269
- const {
270
- limit = 1000,
271
- skip = 0,
272
- ...rest
273
- } = params;
274
- const result = await operator.find(rest, {
275
- projection: createProjection(showParams)
276
- }).limit(parseInt(limit, 10)).skip(parseInt(skip, 10)).toArray();
277
- logger.debug(`Query result: ${result.length > 0 ? 'Found!' : 'Not found!'}`);
278
- logger.silly(`${JSON.stringify(result)}`);
279
- debug(`${JSON.stringify(result)}`);
280
- return result;
281
- }
282
-
283
- // We default to NOT showing operations, operationSettings, recordLoadParams and importJobState when a queueItem is queried
284
- // These can all be shown with showAll
285
- // Single fields can be shown by showOperation, showOperationSettings, showRecordLoadParams and showImportJobState
286
-
287
- function createProjection(showParams = {}) {
288
- logger.silly(`Creating projection for query: ${JSON.stringify(showParams)}`);
289
- debug(`Creating projection for query: ${JSON.stringify(showParams)}`);
290
- const {
291
- showAll = 0,
292
- showOperations = 0,
293
- showOperationSettings = 0,
294
- showRecordLoadParams = 0,
295
- showImportJobState = 0
296
- } = showParams;
297
- const combinedShowParams = {
298
- showAll,
299
- showOperations,
300
- showOperationSettings,
301
- showRecordLoadParams,
302
- showImportJobState
303
- };
304
- logger.debug(`showAll: ${showAll}, showOperations: ${showOperations}, showOperationSettings: ${showOperationSettings}, showRecordLoadParams: ${showRecordLoadParams}, showImportJobState: ${showImportJobState}`);
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}`);
312
- return {
313
- _id: 0
314
- };
315
- }
316
- const showParamToField = {
317
- 'showOperations': 'operations',
318
- 'showOperationSettings': 'operationSettings',
319
- 'showRecordLoadParams': 'recordLoadParams',
320
- 'showImportJobState': 'importJobState'
321
- };
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]);
325
- logger.silly(`We want to exclude from projection: ${JSON.stringify(result)}`);
326
- debug(`We want to exclude from projection: ${JSON.stringify(result)}`);
327
- const excludeObject = Object.fromEntries(result.map(param => [param, 0]));
328
- logger.silly(`We want to exclude from projection: ${JSON.stringify(excludeObject)}`);
329
- debug(`We want to exclude from projection: ${JSON.stringify(excludeObject)}`);
330
- return {
331
- _id: 0,
332
- ...excludeObject
333
- };
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
338
- async function queryById({
339
- correlationId,
340
- checkModTime = false
341
- }) {
342
- if (checkModTime) {
343
- debug(`queryById checkModTime: ${checkModTime}`);
344
- await checkTimeOut({
345
- correlationId
346
- });
347
- return queryById({
348
- correlationId
349
- });
350
- }
351
- const result = await operator.findOne({
352
- correlationId
353
- }, {
354
- projection: {
355
- _id: 0
356
- }
357
- });
358
- return result;
359
- }
360
-
361
- // Check that if the item has waited too long
362
- // If the last modification time for the queueItem is older than 1 minute
363
- // set state to ABORT and return false, otherwise return true
364
- // If the state is already ABORT or ERROR or DONE return false
365
-
366
- async function checkTimeOut({
367
- correlationId
368
- }) {
369
- const {
370
- modificationTime,
371
- queueItemState: oldState,
372
- importJobState
373
- } = await operator.findOne({
374
- correlationId
375
- });
376
- //debug(`${modificationTime} - oldState: ${oldState}`);
377
- // should we check for DONE too?
378
- if ([_constants.QUEUE_ITEM_STATE.ABORT, _constants.QUEUE_ITEM_STATE.ERROR, _constants.QUEUE_ITEM_STATE.DONE].includes(oldState)) {
379
- logger.silly(`${correlationId} has already state: ${oldState}`);
380
- return false;
381
- }
382
- const timeoutTime = (0, _moment.default)(modificationTime).add(1, 'm');
383
- logger.silly(`${correlationId} timeOut @ ${timeoutTime}`);
384
- if (timeoutTime.isBefore()) {
385
- const finalImportJobStates = [_constants.IMPORT_JOB_STATE.ABORT, _constants.IMPORT_JOB_STATE.DONE, _constants.IMPORT_JOB_STATE.EMPTY, _constants.IMPORT_JOB_STATE.ERROR];
386
- if (!finalImportJobStates.includes(importJobState.CREATE)) {
387
- // eslint-disable-line
388
- await setImportJobState({
389
- correlationId,
390
- operation: 'CREATE',
391
- importJobState: _constants.IMPORT_JOB_STATE.ABORT
392
- });
393
- }
394
- if (!finalImportJobStates.includes(importJobState.UPDATE)) {
395
- // eslint-disable-line
396
- await setImportJobState({
397
- correlationId,
398
- operation: 'UPDATE',
399
- importJobState: _constants.IMPORT_JOB_STATE.ABORT
400
- });
401
- }
402
- if (!finalImportJobStates.includes(importJobState.FIX)) {
403
- // eslint-disable-line
404
- await setImportJobState({
405
- correlationId,
406
- operation: 'FIX',
407
- importJobState: _constants.IMPORT_JOB_STATE.ABORT
408
- });
409
- }
410
- await setState({
411
- correlationId,
412
- state: _constants.QUEUE_ITEM_STATE.ABORT,
413
- errorStatus: _httpStatus.default.REQUEST_TIMEOUT,
414
- errorMessage: `Timeout in ${oldState}`
415
- });
416
- return false;
417
- }
418
- return true;
419
- }
420
-
421
- // eslint-disable-next-line max-statements
422
- async function remove(params) {
423
- logger.silly(`${JSON.stringify(params)}`);
424
- logger.info(`Removing from Mongo (${collection}) id: ${params.correlationId}`);
425
- debug(`${JSON.stringify(params)}`);
426
- debug(`Removing from Mongo (${collection}) id: ${params.correlationId}`);
427
- const clean = (0, _mongoSanitize.default)(params.correlationId);
428
- logger.silly(`mongo/remove: clean: ${JSON.stringify(clean)}`);
429
- debug(`mongo/remove: clean: ${JSON.stringify(clean)}`);
430
- try {
431
- //const metadataResult = await getFileMetadata({filename: clean});
432
- //logger.debug(`mongo/remove: metadataResult: ${JSON.stringify(metadataResult)}`);
433
- const noContent = await removeContent({
434
- correlationId: params.correlationId
435
- });
436
- debug(`noContent (removeContent result): ${JSON.stringify(noContent)}`);
437
- if (noContent) {
438
- const deleteResult = await operator.deleteOne({
439
- correlationId: clean
440
- });
441
- debug(`deleteResult: ${JSON.stringify(deleteResult)}`);
442
- return true;
443
- }
444
- } catch (err) {
445
- // TEST-COVERAGE: this error is not (currently) tested
446
- if (err instanceof _mongodb.MongoDriverError) {
447
- debug(err);
448
- if (err.message.indexOf('File not found for id') !== -1) {
449
- logger.silly(`mongo/remove: File not found, removing queueItem ${JSON.stringify(clean)} from ${collection}`);
450
- debug(`mongo/remove: File not found, removing queueItem ${JSON.stringify(clean)} from ${collection}`);
451
- await operator.deleteOne({
452
- correlationId: clean
453
- });
454
- return true;
455
- }
456
- logger.error(err.message);
457
- throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, err.message);
458
- }
459
- throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, err.message);
460
- }
461
- }
462
- async function readContent(correlationId) {
463
- logger.info(`Reading content from mongo for id: ${correlationId} in ${collection}`);
464
- debug(`Reading content from mongo for id: ${correlationId} in ${collection}`);
465
- const clean = (0, _mongoSanitize.default)(correlationId);
466
- debug(clean);
467
- const result = await operator.findOne({
468
- correlationId: clean
469
- }); // njsscan-ignore: node_nosqli_injection
470
- debug(result);
471
- if (result) {
472
- const {
473
- operationSettings
474
- } = result;
475
- if (operationSettings.prio === false && operationSettings.noStream === false) {
476
- return {
477
- contentType: result.contentType,
478
- readStream: gridFSBucket.openDownloadStreamByName(clean)
479
- };
480
- }
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.`);
484
- throw new _melindaCommons.Error(_httpStatus.default.BAD_REQUEST, {
485
- message: `Content is only available for streamBulk jobs. ${correlationId} is not a streamBulk job.`
486
- });
487
- }
488
- throw new _melindaCommons.Error(_httpStatus.default.NOT_FOUND, {
489
- message: `Job ${correlationId} not found.`
490
- });
491
- }
492
- async function removeContent(params) {
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}`);
495
- const clean = (0, _mongoSanitize.default)(params.correlationId);
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);
505
- return true;
506
- }
507
- logger.debug(`No files for ${params.correlationId} to delete`);
508
- return true;
509
- }
510
- function getOne({
511
- queueItemState,
512
- importJobState = undefined
513
- }) {
514
- //params example: "queueItemState": "IMPORTER.IN_QUEUE", "importJobState":{"importJobState.UPDATE": "IN_QUEUE"}
515
- logger.silly(`queueItemState: ${queueItemState}, importJobState: ${JSON.stringify(importJobState)}`);
516
- //debug(`queueItemState: ${queueItemState}, importJobState: ${JSON.stringify(importJobState)}`);
517
- const cleanQueueItemState = queueItemState ? {
518
- queueItemState: (0, _mongoSanitize.default)(queueItemState)
519
- } : undefined;
520
- const options = {
521
- projection: {
522
- _id: 0
523
- }
524
- };
525
- try {
526
- // Just queueItemState
527
- if (queueItemState && importJobState === undefined) {
528
- logger.silly(`Checking DB ${collection} for just ${JSON.stringify(cleanQueueItemState.queueItemState)}`);
529
- //debug(`Checking DB ${collection} for just ${JSON.stringify(cleanQueueItemState.queueItemState)}`);
530
- return operator.findOne({
531
- ...cleanQueueItemState
532
- }, options);
533
- }
534
-
535
- // importJobState
536
- if (importJobState && queueItemState === undefined) {
537
- logger.silly(`Checking DB ${collection} for ${JSON.stringify(importJobState)}`);
538
- //debug(`Checking DB ${collection} for ${JSON.stringify(importJobState)}`);
539
- return operator.findOne({
540
- ...importJobState
541
- }, options);
542
- }
543
-
544
- // importJobState and queueItemState
545
- if (importJobState && queueItemState) {
546
- logger.silly(`Checking DB ${collection} for ${queueItemState} and ${JSON.stringify(importJobState)}`);
547
- //debug(`Checking DB ${collection} for ${queueItemState} and ${JSON.stringify(importJobState)}`);
548
- return operator.findOne({
549
- ...cleanQueueItemState,
550
- ...importJobState
551
- }, options);
552
- }
553
- logger.debug(`getOne not working!`);
554
- throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, 'Missing parameters, cannot get queueItem');
555
- } catch (error) {
556
- const errorMessage = error.payload || error.message || '';
557
- (0, _utils.logError)(error);
558
- throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, `Mongo errored: ${errorMessage}`);
559
- }
560
- }
561
- function getStream(correlationId) {
562
- logger.info(`Forming stream from mongo for ${correlationId} in ${collection}`);
563
- const clean = (0, _mongoSanitize.default)(correlationId);
564
- try {
565
- // Return content stream
566
- return gridFSBucket.openDownloadStreamByName(clean);
567
- } catch (error) {
568
- // TEST-COVERAGE: this error is not (currently) tested
569
- const errorMessage = error.payload || error.message || '';
570
- (0, _utils.logError)(error);
571
- throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, `Mongo errored: ${errorMessage}`);
572
- }
573
- }
574
- async function pushIds({
575
- correlationId,
576
- handledIds,
577
- rejectedIds
578
- }) {
579
- logger.verbose(`Push ids (${handledIds.length}) and rejectedIds (${rejectedIds.length}) ${correlationId} to ${collection}`);
580
- logger.debug(`ids (${handledIds.length}): ${JSON.stringify(handledIds)}, rejectedIds ${rejectedIds.length}: ${JSON.stringify(rejectedIds)}`);
581
- const clean = (0, _mongoSanitize.default)(correlationId);
582
- await operator.updateOne({
583
- correlationId: clean
584
- }, {
585
- $set: {
586
- modificationTime: (0, _moment.default)().toDate()
587
- },
588
- $push: {
589
- handledIds: {
590
- $each: handledIds
591
- },
592
- rejectedIds: {
593
- $each: rejectedIds
594
- }
595
- }
596
- });
597
- }
598
- async function pushMessages({
599
- correlationId,
600
- messages,
601
- messageField = 'messages'
602
- }) {
603
- logger.verbose(`Push messages (${messages.length}) to ${messageField} ${correlationId} to ${collection}`);
604
- logger.silly(`Messages (${messages.length}): ${JSON.stringify(messages)}}`);
605
- const clean = (0, _mongoSanitize.default)(correlationId);
606
- const cleanMessageField = (0, _mongoSanitize.default)(messageField);
607
- debug(`${messageField} -> ${cleanMessageField}`);
608
- await operator.updateOne({
609
- correlationId: clean
610
- }, {
611
- $set: {
612
- modificationTime: (0, _moment.default)().toDate()
613
- },
614
- $push: {
615
- [cleanMessageField]: {
616
- $each: messages
617
- }
618
- }
619
- });
620
- }
621
- function setState({
622
- correlationId,
623
- state,
624
- errorMessage = undefined,
625
- errorStatus = undefined
626
- }) {
627
- const errorString = errorMessage || errorStatus ? `, Error message: '${JSON.stringify(errorMessage) || ''}', Error status: '${errorStatus || ''}'` : '';
628
- logger.info(`Setting queue-item state ${state} for ${correlationId}${errorString} to ${collection}`);
629
- const stateInQueueItemStates = Object.values(_constants.QUEUE_ITEM_STATE).indexOf(state) > -1;
630
- const stateInQueueItemStatesValidator = Object.values(_constants.QUEUE_ITEM_STATE.VALIDATOR).indexOf(state) > -1;
631
- const stateInQueueItemStatesImporter = Object.values(_constants.QUEUE_ITEM_STATE.IMPORTER).indexOf(state) > -1;
632
- if (!stateInQueueItemStates && !stateInQueueItemStatesValidator && !stateInQueueItemStatesImporter) {
633
- debug(`Trying to set invalid state ${state}`);
634
- throw new _melindaCommons.Error(_httpStatus.default.BAD_REQUEST, 'Trying to set invalid state');
635
- }
636
- const clean = (0, _mongoSanitize.default)(correlationId);
637
- const updateValues = {
638
- queueItemState: state,
639
- modificationTime: (0, _moment.default)().toDate(),
640
- errorMessage,
641
- errorStatus
642
- };
643
-
644
- // Do not update value that are undefined
645
- // eslint-disable-next-line functional/immutable-data
646
- Object.keys(updateValues).forEach(key => updateValues[key] === undefined && delete updateValues[key]);
647
- return operator.findOneAndUpdate({
648
- correlationId: clean
649
- }, {
650
- $set: updateValues
651
- }, {
652
- projection: {
653
- _id: 0
654
- },
655
- returnDocument: 'after'
656
- });
657
- }
658
- function setImportJobState({
659
- correlationId,
660
- operation,
661
- importJobState
662
- }) {
663
- // should this also get importJobState as previously created object? {}
664
- logger.info(`Setting queue-item importJobState: {${operation}: ${importJobState}} for ${correlationId}`);
665
- debug(`Setting queue-item importJobState: {${operation}: ${importJobState}} for ${correlationId}`);
666
- const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
667
- const cleanImportJobState = (0, _mongoSanitize.default)(importJobState);
668
- if (!(operation in _constants.OPERATIONS)) {
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');
671
- }
672
- if (!(cleanImportJobState in _constants.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');
675
- }
676
- const newJobState = getNewJobState(operation, cleanImportJobState);
677
- function getNewJobState(operation, cleanImportJobState) {
678
- if (operation === _constants.OPERATIONS.CREATE) {
679
- return {
680
- 'importJobState.CREATE': cleanImportJobState
681
- };
682
- }
683
- if (operation === _constants.OPERATIONS.UPDATE) {
684
- return {
685
- 'importJobState.UPDATE': cleanImportJobState
686
- };
687
- }
688
- if (operation === _constants.OPERATIONS.FIX) {
689
- return {
690
- 'importJobState.FIX': cleanImportJobState
691
- };
692
- }
693
- // istanbul ignore next
694
- // Ignoring for coverage - we error this already
695
- throw new _melindaCommons.Error('400', 'Invalid operation for import job state');
696
- }
697
- return operator.findOneAndUpdate({
698
- correlationId: cleanCorrelationId
699
- }, {
700
- $set: {
701
- ...newJobState,
702
- modificationTime: (0, _moment.default)().toDate()
703
- }
704
- }, {
705
- projection: {
706
- _id: 0
707
- },
708
- returnDocument: 'after'
709
- });
710
- }
711
- async function setOperation({
712
- correlationId,
713
- operation
714
- }) {
715
- const newOperation = operation;
716
- const {
717
- operation: oldOperation
718
- } = await operator.findOne({
719
- correlationId
720
- });
721
- logger.info(`Setting queue-item operation from ${oldOperation} to ${newOperation} for ${correlationId} to ${collection}`);
722
- const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
723
- const cleanNewOperation = (0, _mongoSanitize.default)(newOperation);
724
- const result = await operator.findOneAndUpdate({
725
- correlationId: cleanCorrelationId
726
- }, {
727
- $set: {
728
- operation: cleanNewOperation,
729
- modificationTime: (0, _moment.default)().toDate()
730
- }
731
- }, {
732
- projection: {
733
- _id: 0
734
- },
735
- returnDocument: 'after'
736
- });
737
- debugDev(`${JSON.stringify(result)}`);
738
- return result.ok || result;
739
- // logger.debug(JSON.stringify(result));
740
- }
741
- async function setOperations({
742
- correlationId,
743
- addOperation,
744
- removeOperation = undefined
745
- }) {
746
- const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
747
- const queueItem = await operator.findOne({
748
- correlationId: cleanCorrelationId
749
- });
750
- logger.silly(`We found a queueItem: ${JSON.stringify(queueItem)}`);
751
- const oldOperations = queueItem.operations;
752
- logger.info(`Setting queue-item operations from ${JSON.stringify(oldOperations)} by adding ${addOperation} and removing ${removeOperation} for ${correlationId} to ${collection}`);
753
- const operationsAfterRemove = oldOperations.filter(operation => operation !== removeOperation);
754
- const operationsAfterRemoveAndAdd = operationsAfterRemove.includes(addOperation) ? operationsAfterRemove : [...operationsAfterRemove, addOperation];
755
- logger.silly(`operationsAfterRemove: ${operationsAfterRemove}`);
756
- logger.silly(`operationAfterRemoveAndAdd: ${operationsAfterRemoveAndAdd}`);
757
- const result = await operator.findOneAndUpdate({
758
- correlationId: cleanCorrelationId
759
- }, {
760
- $set: {
761
- operations: operationsAfterRemoveAndAdd,
762
- modificationTime: (0, _moment.default)().toDate()
763
- }
764
- }, {
765
- projection: {
766
- _id: 0
767
- },
768
- returnDocument: 'after'
769
- });
770
- debugDev(`${JSON.stringify(result)}`);
771
- return result.ok || result;
772
- // logger.debug(JSON.stringify(result));
773
- }
774
- async function addBlobSize({
775
- correlationId
776
- }) {
777
- const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
778
- const result = await operator.findOneAndUpdate({
779
- correlationId: cleanCorrelationId,
780
- queueItemState: _constants.QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS
781
- }, {
782
- $inc: {
783
- blobSize: 1
784
- },
785
- $set: {
786
- modificationTime: (0, _moment.default)().toDate()
787
- }
788
- }, {
789
- projection: {
790
- _id: 0
791
- },
792
- returnDocument: 'after'
793
- });
794
- logger.verbose(`AddBlobSizeResult in mongo: ${JSON.stringify(result)}`);
795
- debugDev(`${JSON.stringify(result)}`);
796
- return result;
797
- }
798
- async function setBlobSize({
799
- correlationId,
800
- blobSize
801
- }) {
802
- const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
803
- const cleanBlobSize = (0, _mongoSanitize.default)(blobSize);
804
- const result = await operator.findOneAndUpdate({
805
- correlationId: cleanCorrelationId
806
- }, {
807
- $set: {
808
- blobSize: cleanBlobSize,
809
- modificationTime: (0, _moment.default)().toDate()
810
- }
811
- }, {
812
- projection: {
813
- _id: 0
814
- },
815
- returnDocument: 'after'
816
- });
817
- logger.verbose(`SetBlobSizeResult in mongo: ${JSON.stringify(result)}`);
818
- debugDev(`${JSON.stringify(result)}`);
819
- return result;
820
- }
821
- }
822
- //# sourceMappingURL=mongo.js.map