@natlibfi/melinda-rest-api-commons 2.1.3-alpha.1 → 2.2.0-alpha.10
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/README.md +20 -17
- package/dist/constants.js +20 -7
- package/dist/constants.js.map +1 -1
- package/dist/helpers/conversion.js +18 -8
- package/dist/helpers/conversion.js.map +1 -1
- package/dist/helpers/conversion.spec.js +18 -7
- package/dist/helpers/conversion.spec.js.map +1 -1
- package/dist/index.js +29 -1
- package/dist/index.js.map +1 -1
- package/dist/mongo.js +281 -58
- package/dist/mongo.js.map +1 -1
- package/dist/utils.js +132 -0
- package/dist/utils.js.map +1 -1
- package/package.json +10 -11
package/README.md
CHANGED
|
@@ -10,27 +10,30 @@ Shared modules for microservices of Melinda rest api import system
|
|
|
10
10
|
|
|
11
11
|
#### QueueItemState flow for bulk jobs (multiple records, no validations):
|
|
12
12
|
|
|
13
|
-
|microservice | states
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
|
19
|
-
|any | any -> ERROR if errored
|
|
13
|
+
| microservice | states |
|
|
14
|
+
|--------------|--------------------------------------------------------|
|
|
15
|
+
| `http` | -> VALIDATOR.UPLOADING -> VALIDATOR.PENDING_QUEUING -> |
|
|
16
|
+
| `validator` | VALIDATOR.QUEUING_IN_PROGRESS -> IMPORTER.IN_QUEUE -> |
|
|
17
|
+
| `importer` | IMPORTER.IMPORTING -> IMPORT_JOB_STATEs* -> DONE |
|
|
18
|
+
| | |
|
|
19
|
+
| any | any -> ERROR if errored |
|
|
20
20
|
|
|
21
|
+
*IMPORT_JOB_STATEs: EMPTY or IN_QUEUE, PROCESSING -> final: DONE, ERROR, ABORT
|
|
21
22
|
|
|
22
23
|
#### QueueItemState flow for prio jobs (single record):
|
|
23
24
|
|
|
24
|
-
|microservice | states
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
|
33
|
-
| any
|
|
25
|
+
| microservice | states |
|
|
26
|
+
|--------------|------------------------------------------------------------|
|
|
27
|
+
| `http` | -> VALIDATOR.PENDING_VALIDATION -> |
|
|
28
|
+
| `validator` | VALIDATOR.VALIDATING -> IMPORTER.IN_QUEUE -> |
|
|
29
|
+
| `importer` | IMPORTER.IMPORTING -> IMPORT_JOB_STATEs* -> DONE |
|
|
30
|
+
| | |
|
|
31
|
+
| `http` | any -> ABORT if job has stayed in an active state too long |
|
|
32
|
+
| `validator` | VALIDATOR.VALIDATING -> DONE for noop (no-operation) jobs |
|
|
33
|
+
| | |
|
|
34
|
+
| any | any -> ERROR if errored |
|
|
35
|
+
|
|
36
|
+
*IMPORT_JOB_STATEs: EMPTY or IN_QUEUE, PROCESSING -> final: DONE, ERROR, ABORT
|
|
34
37
|
|
|
35
38
|
### CHUNK_SIZE
|
|
36
39
|
Chunck size to execution time ratio (From file to queue: ~450 records in 15sec)
|
package/dist/constants.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.QUEUE_ITEM_STATE = exports.OPERATIONS = exports.IMPORT_JOB_STATE = exports.CONVERSION_FORMATS = exports.CHUNK_SIZE = void 0;
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
*
|
|
@@ -38,8 +38,9 @@ const QUEUE_ITEM_STATE = {
|
|
|
38
38
|
PENDING_QUEUING: 'PENDING_QUEUING',
|
|
39
39
|
PENDING_VALIDATION: 'PENDING_VALIDATION',
|
|
40
40
|
QUEUING_IN_PROGRESS: 'QUEUING_IN_PROGRESS',
|
|
41
|
+
UPLOADING: 'UPLOADING',
|
|
41
42
|
VALIDATING: 'VALIDATING',
|
|
42
|
-
|
|
43
|
+
WAITING_FOR_RECORDS: 'WAITING_FOR_RECORDS'
|
|
43
44
|
},
|
|
44
45
|
IMPORTER: {
|
|
45
46
|
IMPORTING: 'IMPORTING',
|
|
@@ -51,6 +52,17 @@ const QUEUE_ITEM_STATE = {
|
|
|
51
52
|
ABORT: 'ABORT'
|
|
52
53
|
};
|
|
53
54
|
exports.QUEUE_ITEM_STATE = QUEUE_ITEM_STATE;
|
|
55
|
+
const IMPORT_JOB_STATE = {
|
|
56
|
+
EMPTY: 'EMPTY',
|
|
57
|
+
QUEUING: 'QUEUING',
|
|
58
|
+
IN_QUEUE: 'IN_QUEUE',
|
|
59
|
+
IMPORTING: 'IMPORTING',
|
|
60
|
+
PROCESSING: 'PROCESSING',
|
|
61
|
+
DONE: 'DONE',
|
|
62
|
+
ERROR: 'ERROR',
|
|
63
|
+
ABORT: 'ABORT'
|
|
64
|
+
};
|
|
65
|
+
exports.IMPORT_JOB_STATE = IMPORT_JOB_STATE;
|
|
54
66
|
const OPERATIONS = {
|
|
55
67
|
CREATE: 'CREATE',
|
|
56
68
|
UPDATE: 'UPDATE'
|
|
@@ -58,10 +70,11 @@ const OPERATIONS = {
|
|
|
58
70
|
exports.OPERATIONS = OPERATIONS;
|
|
59
71
|
const CHUNK_SIZE = 100;
|
|
60
72
|
exports.CHUNK_SIZE = CHUNK_SIZE;
|
|
61
|
-
const
|
|
62
|
-
MARCXML:
|
|
63
|
-
ISO2709:
|
|
64
|
-
JSON:
|
|
73
|
+
const CONVERSION_FORMATS = {
|
|
74
|
+
MARCXML: 'MARCXML',
|
|
75
|
+
ISO2709: 'ISO2709',
|
|
76
|
+
JSON: 'JSON',
|
|
77
|
+
ALEPHSEQ: 'ALEPHSEQ'
|
|
65
78
|
};
|
|
66
|
-
exports.
|
|
79
|
+
exports.CONVERSION_FORMATS = CONVERSION_FORMATS;
|
|
67
80
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.js"],"names":["QUEUE_ITEM_STATE","VALIDATOR","PENDING_QUEUING","PENDING_VALIDATION","QUEUING_IN_PROGRESS","VALIDATING","
|
|
1
|
+
{"version":3,"sources":["../src/constants.js"],"names":["QUEUE_ITEM_STATE","VALIDATOR","PENDING_QUEUING","PENDING_VALIDATION","QUEUING_IN_PROGRESS","UPLOADING","VALIDATING","WAITING_FOR_RECORDS","IMPORTER","IMPORTING","IN_PROCESS","IN_QUEUE","DONE","ERROR","ABORT","IMPORT_JOB_STATE","EMPTY","QUEUING","PROCESSING","OPERATIONS","CREATE","UPDATE","CHUNK_SIZE","CONVERSION_FORMATS","MARCXML","ISO2709","JSON","ALEPHSEQ"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEO,MAAMA,gBAAgB,GAAG;AAC9BC,EAAAA,SAAS,EAAE;AACTC,IAAAA,eAAe,EAAE,iBADR;AAETC,IAAAA,kBAAkB,EAAE,oBAFX;AAGTC,IAAAA,mBAAmB,EAAE,qBAHZ;AAITC,IAAAA,SAAS,EAAE,WAJF;AAKTC,IAAAA,UAAU,EAAE,YALH;AAMTC,IAAAA,mBAAmB,EAAE;AANZ,GADmB;AAS9BC,EAAAA,QAAQ,EAAE;AACRC,IAAAA,SAAS,EAAE,WADH;AAERC,IAAAA,UAAU,EAAE,YAFJ;AAGRC,IAAAA,QAAQ,EAAE;AAHF,GAToB;AAc9BC,EAAAA,IAAI,EAAE,MAdwB;AAe9BC,EAAAA,KAAK,EAAE,OAfuB;AAgB9BC,EAAAA,KAAK,EAAE;AAhBuB,CAAzB;;AAmBA,MAAMC,gBAAgB,GAAG;AAC9BC,EAAAA,KAAK,EAAE,OADuB;AAE9BC,EAAAA,OAAO,EAAE,SAFqB;AAG9BN,EAAAA,QAAQ,EAAE,UAHoB;AAI9BF,EAAAA,SAAS,EAAE,WAJmB;AAK9BS,EAAAA,UAAU,EAAE,YALkB;AAM9BN,EAAAA,IAAI,EAAE,MANwB;AAO9BC,EAAAA,KAAK,EAAE,OAPuB;AAQ9BC,EAAAA,KAAK,EAAE;AARuB,CAAzB;;AAWA,MAAMK,UAAU,GAAG;AACxBC,EAAAA,MAAM,EAAE,QADgB;AAExBC,EAAAA,MAAM,EAAE;AAFgB,CAAnB;;AAKA,MAAMC,UAAU,GAAG,GAAnB;;AAEA,MAAMC,kBAAkB,GAAG;AAChCC,EAAAA,OAAO,EAAE,SADuB;AAEhCC,EAAAA,OAAO,EAAE,SAFuB;AAGhCC,EAAAA,IAAI,EAAE,MAH0B;AAIhCC,EAAAA,QAAQ,EAAE;AAJsB,CAA3B","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\n// QueueItemState flows: see README.md\n\nexport const QUEUE_ITEM_STATE = {\n VALIDATOR: {\n PENDING_QUEUING: 'PENDING_QUEUING',\n PENDING_VALIDATION: 'PENDING_VALIDATION',\n QUEUING_IN_PROGRESS: 'QUEUING_IN_PROGRESS',\n UPLOADING: 'UPLOADING',\n VALIDATING: 'VALIDATING',\n WAITING_FOR_RECORDS: 'WAITING_FOR_RECORDS'\n },\n IMPORTER: {\n IMPORTING: 'IMPORTING',\n IN_PROCESS: 'IN_PROCESS',\n IN_QUEUE: 'IN_QUEUE'\n },\n DONE: 'DONE',\n ERROR: 'ERROR',\n ABORT: 'ABORT'\n};\n\nexport const IMPORT_JOB_STATE = {\n EMPTY: 'EMPTY',\n QUEUING: 'QUEUING',\n IN_QUEUE: 'IN_QUEUE',\n IMPORTING: 'IMPORTING',\n PROCESSING: 'PROCESSING',\n DONE: 'DONE',\n ERROR: 'ERROR',\n ABORT: 'ABORT'\n};\n\nexport const OPERATIONS = {\n CREATE: 'CREATE',\n UPDATE: 'UPDATE'\n};\n\nexport const CHUNK_SIZE = 100;\n\nexport const CONVERSION_FORMATS = {\n MARCXML: 'MARCXML',\n ISO2709: 'ISO2709',\n JSON: 'JSON',\n ALEPHSEQ: 'ALEPHSEQ'\n};\n"],"file":"constants.js"}
|
|
@@ -51,24 +51,28 @@ function _default() {
|
|
|
51
51
|
return {
|
|
52
52
|
serialize,
|
|
53
53
|
unserialize
|
|
54
|
-
};
|
|
54
|
+
}; // This uses format as a number form contants CONVERSION_FORMATS
|
|
55
55
|
|
|
56
56
|
function serialize(record, format) {
|
|
57
57
|
logger.verbose(`Serializing record to ${format}`);
|
|
58
58
|
|
|
59
59
|
try {
|
|
60
|
-
if (format === _constants.
|
|
60
|
+
if (format === _constants.CONVERSION_FORMATS.MARCXML) {
|
|
61
61
|
return _marcRecordSerializers.MARCXML.to(record);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
if (format === _constants.
|
|
64
|
+
if (format === _constants.CONVERSION_FORMATS.ISO2709) {
|
|
65
65
|
return _marcRecordSerializers.ISO2709.to(record);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
if (format === _constants.
|
|
68
|
+
if (format === _constants.CONVERSION_FORMATS.JSON) {
|
|
69
69
|
return _marcRecordSerializers.Json.to(record);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
if (format === _constants.CONVERSION_FORMATS.ALEPHSEQ) {
|
|
73
|
+
return _marcRecordSerializers.AlephSequential.to(record);
|
|
74
|
+
}
|
|
75
|
+
|
|
72
76
|
throw new _melindaCommons.Error(_httpStatus.default.UNSUPPORTED_MEDIA_TYPE);
|
|
73
77
|
} catch (err) {
|
|
74
78
|
(0, _utils.logError)(err);
|
|
@@ -80,7 +84,8 @@ function _default() {
|
|
|
80
84
|
|
|
81
85
|
throw new _melindaCommons.Error(_httpStatus.default.BAD_REQUEST, 'Error while serializing record');
|
|
82
86
|
}
|
|
83
|
-
}
|
|
87
|
+
} // eslint-disable-next-line max-statements
|
|
88
|
+
|
|
84
89
|
|
|
85
90
|
function unserialize(data, format, validationOptions = {
|
|
86
91
|
subfieldValues: false
|
|
@@ -91,21 +96,26 @@ function _default() {
|
|
|
91
96
|
logger.silly(`Data: ${JSON.stringify(data)}`);
|
|
92
97
|
|
|
93
98
|
try {
|
|
94
|
-
if (format === _constants.
|
|
99
|
+
if (format === _constants.CONVERSION_FORMATS.MARCXML) {
|
|
95
100
|
logger.silly('Unserialize format marcxml');
|
|
96
101
|
return _marcRecordSerializers.MARCXML.from(data, validationOptions);
|
|
97
102
|
}
|
|
98
103
|
|
|
99
|
-
if (format === _constants.
|
|
104
|
+
if (format === _constants.CONVERSION_FORMATS.ISO2709) {
|
|
100
105
|
logger.silly('Unserialize format iso2709');
|
|
101
106
|
return _marcRecordSerializers.ISO2709.from(data, validationOptions);
|
|
102
107
|
}
|
|
103
108
|
|
|
104
|
-
if (format === _constants.
|
|
109
|
+
if (format === _constants.CONVERSION_FORMATS.JSON) {
|
|
105
110
|
logger.silly('Unserialize format json');
|
|
106
111
|
return _marcRecordSerializers.Json.from(data, validationOptions);
|
|
107
112
|
}
|
|
108
113
|
|
|
114
|
+
if (format === _constants.CONVERSION_FORMATS.ALEPHSEQ) {
|
|
115
|
+
logger.silly('Unserialize format aleph sequential');
|
|
116
|
+
return _marcRecordSerializers.AlephSequential.from(data, validationOptions);
|
|
117
|
+
}
|
|
118
|
+
|
|
109
119
|
throw new _melindaCommons.Error(_httpStatus.default.UNSUPPORTED_MEDIA_TYPE);
|
|
110
120
|
} catch (err) {
|
|
111
121
|
(0, _utils.logError)(err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/helpers/conversion.js"],"names":["logger","serialize","unserialize","record","format","verbose","
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/conversion.js"],"names":["logger","serialize","unserialize","record","format","verbose","CONVERSION_FORMATS","MARCXML","to","ISO2709","JSON","Json","ALEPHSEQ","AlephSequential","ConversionError","httpStatus","UNSUPPORTED_MEDIA_TYPE","err","BAD_REQUEST","data","validationOptions","subfieldValues","silly","debug","stringify","from"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport httpStatus from 'http-status';\nimport {MARCXML, ISO2709, Json, AlephSequential} from '@natlibfi/marc-record-serializers';\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport {Error as ConversionError} from '@natlibfi/melinda-commons';\nimport {CONVERSION_FORMATS} from '../constants';\nimport {logError} from '../utils';\n\nexport default function () {\n const logger = createLogger();\n\n return {serialize, unserialize};\n\n // This uses format as a number form contants CONVERSION_FORMATS\n function serialize(record, format) {\n logger.verbose(`Serializing record to ${format}`);\n try {\n if (format === CONVERSION_FORMATS.MARCXML) {\n return MARCXML.to(record);\n }\n\n if (format === CONVERSION_FORMATS.ISO2709) {\n return ISO2709.to(record);\n }\n\n if (format === CONVERSION_FORMATS.JSON) {\n return Json.to(record);\n }\n\n if (format === CONVERSION_FORMATS.ALEPHSEQ) {\n return AlephSequential.to(record);\n }\n\n throw new ConversionError(httpStatus.UNSUPPORTED_MEDIA_TYPE);\n } catch (err) {\n logError(err);\n if (err instanceof ConversionError) { // eslint-disable-line functional/no-conditional-statement\n throw err;\n }\n throw new ConversionError(httpStatus.BAD_REQUEST, 'Error while serializing record');\n }\n }\n\n // eslint-disable-next-line max-statements\n function unserialize(data, format, validationOptions = {subfieldValues: false}) {\n logger.verbose(`Unserializing record from ${format}`);\n logger.silly(`Format: ${format}`);\n logger.debug(`Validation options: ${JSON.stringify(validationOptions)}`);\n logger.silly(`Data: ${JSON.stringify(data)}`);\n try {\n if (format === CONVERSION_FORMATS.MARCXML) {\n logger.silly('Unserialize format marcxml');\n return MARCXML.from(data, validationOptions);\n }\n\n if (format === CONVERSION_FORMATS.ISO2709) {\n logger.silly('Unserialize format iso2709');\n return ISO2709.from(data, validationOptions);\n }\n\n if (format === CONVERSION_FORMATS.JSON) {\n logger.silly('Unserialize format json');\n return Json.from(data, validationOptions);\n }\n\n if (format === CONVERSION_FORMATS.ALEPHSEQ) {\n logger.silly('Unserialize format aleph sequential');\n return AlephSequential.from(data, validationOptions);\n }\n\n throw new ConversionError(httpStatus.UNSUPPORTED_MEDIA_TYPE);\n } catch (err) {\n logError(err);\n if (err instanceof ConversionError) { // eslint-disable-line functional/no-conditional-statement\n throw err;\n }\n throw new ConversionError(httpStatus.BAD_REQUEST, 'Error while unserializing record');\n }\n }\n}\n"],"file":"conversion.js"}
|
|
@@ -62,6 +62,9 @@ describe('services/conversion', () => {
|
|
|
62
62
|
const json = getFixture({
|
|
63
63
|
components: ['json1']
|
|
64
64
|
});
|
|
65
|
+
const alephSeq = getFixture({
|
|
66
|
+
components: ['aleph_sequential']
|
|
67
|
+
});
|
|
65
68
|
describe('factory', () => {
|
|
66
69
|
it('Should create the expected object', () => {
|
|
67
70
|
const service = (0, _conversion.default)();
|
|
@@ -73,37 +76,45 @@ describe('services/conversion', () => {
|
|
|
73
76
|
(0, _chai.expect)(conversionService.serialize).to.throw();
|
|
74
77
|
});
|
|
75
78
|
it('Should serialize to MARCXML', () => {
|
|
76
|
-
const data = conversionService.serialize(marcRecord, _constants.
|
|
79
|
+
const data = conversionService.serialize(marcRecord, _constants.CONVERSION_FORMATS.MARCXML);
|
|
77
80
|
(0, _chai.expect)(data).to.equal(marcXml);
|
|
78
81
|
});
|
|
79
82
|
it('Should serialize to ISO2709', () => {
|
|
80
|
-
const data = conversionService.serialize(marcRecord, _constants.
|
|
83
|
+
const data = conversionService.serialize(marcRecord, _constants.CONVERSION_FORMATS.ISO2709);
|
|
81
84
|
(0, _chai.expect)(data).to.equal(iso2709);
|
|
82
85
|
});
|
|
83
86
|
it('Should serialize to JSON', () => {
|
|
84
|
-
const data = conversionService.serialize(marcRecord, _constants.
|
|
87
|
+
const data = conversionService.serialize(marcRecord, _constants.CONVERSION_FORMATS.JSON);
|
|
85
88
|
(0, _chai.expect)(data).to.equal(json);
|
|
86
89
|
});
|
|
90
|
+
it('Should serialize to aleph sequential', () => {
|
|
91
|
+
const data = conversionService.serialize(marcRecord, _constants.CONVERSION_FORMATS.ALEPHSEQ);
|
|
92
|
+
(0, _chai.expect)(data).to.equal(alephSeq);
|
|
93
|
+
});
|
|
87
94
|
});
|
|
88
95
|
describe('#unserialize', () => {
|
|
89
96
|
it('Should throw because of unsupported format', () => {
|
|
90
97
|
(0, _chai.expect)(conversionService.unserialize).to.throw();
|
|
91
98
|
});
|
|
92
99
|
it('Should unserialize from MARCXML', async () => {
|
|
93
|
-
const record = await conversionService.unserialize(marcXml, _constants.
|
|
100
|
+
const record = await conversionService.unserialize(marcXml, _constants.CONVERSION_FORMATS.MARCXML);
|
|
94
101
|
(0, _chai.expect)(record.equalsTo(marcRecord)).to.equal(true);
|
|
95
102
|
});
|
|
96
103
|
it('Should unserialize from ISO2709', () => {
|
|
97
|
-
const record = conversionService.unserialize(iso2709, _constants.
|
|
104
|
+
const record = conversionService.unserialize(iso2709, _constants.CONVERSION_FORMATS.ISO2709);
|
|
98
105
|
(0, _chai.expect)(record.equalsTo(marcRecord)).to.equal(true);
|
|
99
106
|
});
|
|
100
107
|
it('Should unserialize from JSON', () => {
|
|
101
|
-
const record = conversionService.unserialize(json, _constants.
|
|
108
|
+
const record = conversionService.unserialize(json, _constants.CONVERSION_FORMATS.JSON);
|
|
109
|
+
(0, _chai.expect)(record.equalsTo(marcRecord)).to.equal(true);
|
|
110
|
+
});
|
|
111
|
+
it('Should unserialize from Aleph sequential', () => {
|
|
112
|
+
const record = conversionService.unserialize(alephSeq, _constants.CONVERSION_FORMATS.ALEPHSEQ);
|
|
102
113
|
(0, _chai.expect)(record.equalsTo(marcRecord)).to.equal(true);
|
|
103
114
|
});
|
|
104
115
|
it('Should throw because the record could not be unserialized', () => {
|
|
105
116
|
(0, _chai.expect)(() => {
|
|
106
|
-
conversionService.unserialize('', _constants.
|
|
117
|
+
conversionService.unserialize('', _constants.CONVERSION_FORMATS.JSON);
|
|
107
118
|
}).to.throw(_melindaCommons.Error);
|
|
108
119
|
});
|
|
109
120
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/helpers/conversion.spec.js"],"names":["describe","getFixture","root","__dirname","conversionService","marcRecord","MarcRecord","JSON","parse","components","subfieldValues","marcXml","iso2709","json","it","service","to","be","an","and","respondTo","serialize","throw","data","
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/conversion.spec.js"],"names":["describe","getFixture","root","__dirname","conversionService","marcRecord","MarcRecord","JSON","parse","components","subfieldValues","marcXml","iso2709","json","alephSeq","it","service","to","be","an","and","respondTo","serialize","throw","data","CONVERSION_FORMATS","MARCXML","equal","ISO2709","ALEPHSEQ","unserialize","record","equalsTo","ConversionError"],"mappings":";;AA4BA;;AACA;;AACA;;AACA;;AACA;;AACA;;;;AAjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASAA,QAAQ,CAAC,qBAAD,EAAwB,MAAM;AACpC,QAAM;AAACC,IAAAA;AAAD,MAAe,qBAAe;AAACC,IAAAA,IAAI,EAAE,CACzCC,SADyC,EAEzC,IAFyC,EAGzC,IAHyC,EAIzC,eAJyC,EAKzC,YALyC;AAAP,GAAf,CAArB;AAOA,QAAMC,iBAAiB,GAAG,0BAA1B;AAEA,QAAMC,UAAU,GAAG,IAAIC,sBAAJ,CAAeC,IAAI,CAACC,KAAL,CAAWP,UAAU,CAAC;AAACQ,IAAAA,UAAU,EAAE,CAAC,OAAD;AAAb,GAAD,CAArB,CAAf,EAAgE;AAACC,IAAAA,cAAc,EAAE;AAAjB,GAAhE,CAAnB;AACA,QAAMC,OAAO,GAAGV,UAAU,CAAC;AAACQ,IAAAA,UAAU,EAAE,CAAC,UAAD;AAAb,GAAD,CAA1B;AACA,QAAMG,OAAO,GAAGX,UAAU,CAAC;AAACQ,IAAAA,UAAU,EAAE,CAAC,WAAD;AAAb,GAAD,CAA1B;AACA,QAAMI,IAAI,GAAGZ,UAAU,CAAC;AAACQ,IAAAA,UAAU,EAAE,CAAC,OAAD;AAAb,GAAD,CAAvB;AACA,QAAMK,QAAQ,GAAGb,UAAU,CAAC;AAACQ,IAAAA,UAAU,EAAE,CAAC,kBAAD;AAAb,GAAD,CAA3B;AAGAT,EAAAA,QAAQ,CAAC,SAAD,EAAY,MAAM;AACxBe,IAAAA,EAAE,CAAC,mCAAD,EAAsC,MAAM;AAC5C,YAAMC,OAAO,GAAG,0BAAhB;AACA,wBAAOA,OAAP,EAAgBC,EAAhB,CAAmBC,EAAnB,CAAsBC,EAAtB,CAAyB,QAAzB,EAAmCC,GAAnC,CACGC,SADH,CACa,WADb,EAEGA,SAFH,CAEa,aAFb;AAGD,KALC,CAAF;AAMD,GAPO,CAAR;AASArB,EAAAA,QAAQ,CAAC,YAAD,EAAe,MAAM;AAC3Be,IAAAA,EAAE,CAAC,4CAAD,EAA+C,MAAM;AACrD,wBAAOX,iBAAiB,CAACkB,SAAzB,EAAoCL,EAApC,CAAuCM,KAAvC;AACD,KAFC,CAAF;AAIAR,IAAAA,EAAE,CAAC,6BAAD,EAAgC,MAAM;AACtC,YAAMS,IAAI,GAAGpB,iBAAiB,CAACkB,SAAlB,CAA4BjB,UAA5B,EAAwCoB,8BAAmBC,OAA3D,CAAb;AACA,wBAAOF,IAAP,EAAaP,EAAb,CAAgBU,KAAhB,CAAsBhB,OAAtB;AACD,KAHC,CAAF;AAKAI,IAAAA,EAAE,CAAC,6BAAD,EAAgC,MAAM;AACtC,YAAMS,IAAI,GAAGpB,iBAAiB,CAACkB,SAAlB,CAA4BjB,UAA5B,EAAwCoB,8BAAmBG,OAA3D,CAAb;AACA,wBAAOJ,IAAP,EAAaP,EAAb,CAAgBU,KAAhB,CAAsBf,OAAtB;AACD,KAHC,CAAF;AAKAG,IAAAA,EAAE,CAAC,0BAAD,EAA6B,MAAM;AACnC,YAAMS,IAAI,GAAGpB,iBAAiB,CAACkB,SAAlB,CAA4BjB,UAA5B,EAAwCoB,8BAAmBlB,IAA3D,CAAb;AACA,wBAAOiB,IAAP,EAAaP,EAAb,CAAgBU,KAAhB,CAAsBd,IAAtB;AACD,KAHC,CAAF;AAKAE,IAAAA,EAAE,CAAC,sCAAD,EAAyC,MAAM;AAC/C,YAAMS,IAAI,GAAGpB,iBAAiB,CAACkB,SAAlB,CAA4BjB,UAA5B,EAAwCoB,8BAAmBI,QAA3D,CAAb;AACA,wBAAOL,IAAP,EAAaP,EAAb,CAAgBU,KAAhB,CAAsBb,QAAtB;AACD,KAHC,CAAF;AAKD,GAzBO,CAAR;AA2BAd,EAAAA,QAAQ,CAAC,cAAD,EAAiB,MAAM;AAC7Be,IAAAA,EAAE,CAAC,4CAAD,EAA+C,MAAM;AACrD,wBAAOX,iBAAiB,CAAC0B,WAAzB,EAAsCb,EAAtC,CAAyCM,KAAzC;AACD,KAFC,CAAF;AAIAR,IAAAA,EAAE,CAAC,iCAAD,EAAoC,YAAY;AAChD,YAAMgB,MAAM,GAAG,MAAM3B,iBAAiB,CAAC0B,WAAlB,CAA8BnB,OAA9B,EAAuCc,8BAAmBC,OAA1D,CAArB;AACA,wBAAOK,MAAM,CAACC,QAAP,CAAgB3B,UAAhB,CAAP,EAAoCY,EAApC,CAAuCU,KAAvC,CAA6C,IAA7C;AACD,KAHC,CAAF;AAKAZ,IAAAA,EAAE,CAAC,iCAAD,EAAoC,MAAM;AAC1C,YAAMgB,MAAM,GAAG3B,iBAAiB,CAAC0B,WAAlB,CAA8BlB,OAA9B,EAAuCa,8BAAmBG,OAA1D,CAAf;AACA,wBAAOG,MAAM,CAACC,QAAP,CAAgB3B,UAAhB,CAAP,EAAoCY,EAApC,CAAuCU,KAAvC,CAA6C,IAA7C;AACD,KAHC,CAAF;AAKAZ,IAAAA,EAAE,CAAC,8BAAD,EAAiC,MAAM;AACvC,YAAMgB,MAAM,GAAG3B,iBAAiB,CAAC0B,WAAlB,CAA8BjB,IAA9B,EAAoCY,8BAAmBlB,IAAvD,CAAf;AACA,wBAAOwB,MAAM,CAACC,QAAP,CAAgB3B,UAAhB,CAAP,EAAoCY,EAApC,CAAuCU,KAAvC,CAA6C,IAA7C;AACD,KAHC,CAAF;AAKAZ,IAAAA,EAAE,CAAC,0CAAD,EAA6C,MAAM;AACnD,YAAMgB,MAAM,GAAG3B,iBAAiB,CAAC0B,WAAlB,CAA8BhB,QAA9B,EAAwCW,8BAAmBI,QAA3D,CAAf;AACA,wBAAOE,MAAM,CAACC,QAAP,CAAgB3B,UAAhB,CAAP,EAAoCY,EAApC,CAAuCU,KAAvC,CAA6C,IAA7C;AACD,KAHC,CAAF;AAMAZ,IAAAA,EAAE,CAAC,2DAAD,EAA8D,MAAM;AACpE,wBAAO,MAAM;AACXX,QAAAA,iBAAiB,CAAC0B,WAAlB,CAA8B,EAA9B,EAAkCL,8BAAmBlB,IAArD;AACD,OAFD,EAEGU,EAFH,CAEMM,KAFN,CAEYU,qBAFZ;AAGD,KAJC,CAAF;AAKD,GA/BO,CAAR;AAgCD,CArFO,CAAR","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport {expect} from 'chai';\nimport fixtureFactory from '@natlibfi/fixura';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport {Error as ConversionError} from '@natlibfi/melinda-commons';\nimport createConversionService from './conversion';\nimport {CONVERSION_FORMATS} from '../constants';\n\ndescribe('services/conversion', () => {\n const {getFixture} = fixtureFactory({root: [\n __dirname,\n '..',\n '..',\n 'test-fixtures',\n 'conversion'\n ]});\n const conversionService = createConversionService();\n\n const marcRecord = new MarcRecord(JSON.parse(getFixture({components: ['json1']})), {subfieldValues: false});\n const marcXml = getFixture({components: ['marcxml1']});\n const iso2709 = getFixture({components: ['iso2709_1']});\n const json = getFixture({components: ['json1']});\n const alephSeq = getFixture({components: ['aleph_sequential']});\n\n\n describe('factory', () => {\n it('Should create the expected object', () => {\n const service = createConversionService();\n expect(service).to.be.an('object').and\n .respondTo('serialize')\n .respondTo('unserialize');\n });\n });\n\n describe('#serialize', () => {\n it('Should throw because of unsupported format', () => {\n expect(conversionService.serialize).to.throw();\n });\n\n it('Should serialize to MARCXML', () => {\n const data = conversionService.serialize(marcRecord, CONVERSION_FORMATS.MARCXML);\n expect(data).to.equal(marcXml);\n });\n\n it('Should serialize to ISO2709', () => {\n const data = conversionService.serialize(marcRecord, CONVERSION_FORMATS.ISO2709);\n expect(data).to.equal(iso2709);\n });\n\n it('Should serialize to JSON', () => {\n const data = conversionService.serialize(marcRecord, CONVERSION_FORMATS.JSON);\n expect(data).to.equal(json);\n });\n\n it('Should serialize to aleph sequential', () => {\n const data = conversionService.serialize(marcRecord, CONVERSION_FORMATS.ALEPHSEQ);\n expect(data).to.equal(alephSeq);\n });\n\n });\n\n describe('#unserialize', () => {\n it('Should throw because of unsupported format', () => {\n expect(conversionService.unserialize).to.throw();\n });\n\n it('Should unserialize from MARCXML', async () => {\n const record = await conversionService.unserialize(marcXml, CONVERSION_FORMATS.MARCXML);\n expect(record.equalsTo(marcRecord)).to.equal(true);\n });\n\n it('Should unserialize from ISO2709', () => {\n const record = conversionService.unserialize(iso2709, CONVERSION_FORMATS.ISO2709);\n expect(record.equalsTo(marcRecord)).to.equal(true);\n });\n\n it('Should unserialize from JSON', () => {\n const record = conversionService.unserialize(json, CONVERSION_FORMATS.JSON);\n expect(record.equalsTo(marcRecord)).to.equal(true);\n });\n\n it('Should unserialize from Aleph sequential', () => {\n const record = conversionService.unserialize(alephSeq, CONVERSION_FORMATS.ALEPHSEQ);\n expect(record.equalsTo(marcRecord)).to.equal(true);\n });\n\n\n it('Should throw because the record could not be unserialized', () => {\n expect(() => {\n conversionService.unserialize('', CONVERSION_FORMATS.JSON);\n }).to.throw(ConversionError);\n });\n });\n});\n"],"file":"conversion.spec.js"}
|
package/dist/index.js
CHANGED
|
@@ -9,8 +9,18 @@ var _exportNames = {
|
|
|
9
9
|
conversions: true,
|
|
10
10
|
validations: true,
|
|
11
11
|
format: true,
|
|
12
|
-
logError: true
|
|
12
|
+
logError: true,
|
|
13
|
+
createImportJobState: true,
|
|
14
|
+
createImportJobStateForQuery: true,
|
|
15
|
+
createRecordResponseItem: true,
|
|
16
|
+
addRecordResponseItem: true
|
|
13
17
|
};
|
|
18
|
+
Object.defineProperty(exports, "addRecordResponseItem", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _utils.addRecordResponseItem;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
14
24
|
Object.defineProperty(exports, "amqpFactory", {
|
|
15
25
|
enumerable: true,
|
|
16
26
|
get: function () {
|
|
@@ -23,6 +33,24 @@ Object.defineProperty(exports, "conversions", {
|
|
|
23
33
|
return _conversion.default;
|
|
24
34
|
}
|
|
25
35
|
});
|
|
36
|
+
Object.defineProperty(exports, "createImportJobState", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _utils.createImportJobState;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "createImportJobStateForQuery", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _utils.createImportJobStateForQuery;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "createRecordResponseItem", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _utils.createRecordResponseItem;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
26
54
|
exports.format = void 0;
|
|
27
55
|
Object.defineProperty(exports, "logError", {
|
|
28
56
|
enumerable: true,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA;;AACA;;AACA;;AACA;;AACA;;;;AACA;;AAGA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport mongoFactory from './mongo';\nimport amqpFactory from './amqp';\nimport conversions from './helpers/conversion';\nimport validations from './helpers/validation';\nimport * as format from './helpers/format';\nimport {logError, createImportJobState, createImportJobStateForQuery, createRecordResponseItem, addRecordResponseItem} from './utils';\n\nexport {mongoFactory, amqpFactory, conversions, validations, format, logError, createImportJobState, createImportJobStateForQuery, createRecordResponseItem, addRecordResponseItem};\nexport * from './constants';\n"],"file":"index.js"}
|
package/dist/mongo.js
CHANGED
|
@@ -57,6 +57,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
57
57
|
"cataloger":"xxx0000",
|
|
58
58
|
"oCatalogerIn":"xxx0000"
|
|
59
59
|
"operation":"UPDATE",
|
|
60
|
+
"operations":["UPDATE", "CREATE"]
|
|
60
61
|
"contentType":"application/json",
|
|
61
62
|
"recordLoadParams": {
|
|
62
63
|
"pActiveLibrary": "XXX00",
|
|
@@ -66,6 +67,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
66
67
|
"pOldNew": "NEW"
|
|
67
68
|
},
|
|
68
69
|
"queueItemState":"PENDING_QUEUING",
|
|
70
|
+
"importJobState": {
|
|
71
|
+
"CREATE": "EMPTY",
|
|
72
|
+
"UPDATE": "EMPTY"
|
|
73
|
+
},
|
|
69
74
|
"creationTime":"2020-01-01T00:00:00.000Z",
|
|
70
75
|
"modificationTime":"2020-01-01T00:00:01.000Z",
|
|
71
76
|
"handledIds": []
|
|
@@ -86,6 +91,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
86
91
|
createPrio,
|
|
87
92
|
createBulk,
|
|
88
93
|
checkAndSetState,
|
|
94
|
+
checkAndSetImportJobState,
|
|
89
95
|
query,
|
|
90
96
|
queryById,
|
|
91
97
|
remove,
|
|
@@ -94,8 +100,11 @@ async function _default(MONGO_URI, collection) {
|
|
|
94
100
|
getOne,
|
|
95
101
|
getStream,
|
|
96
102
|
setState,
|
|
103
|
+
setImportJobState,
|
|
97
104
|
pushIds,
|
|
98
|
-
pushMessages
|
|
105
|
+
pushMessages,
|
|
106
|
+
setOperation,
|
|
107
|
+
setOperations
|
|
99
108
|
};
|
|
100
109
|
|
|
101
110
|
async function createPrio({
|
|
@@ -103,22 +112,24 @@ async function _default(MONGO_URI, collection) {
|
|
|
103
112
|
cataloger,
|
|
104
113
|
oCatalogerIn,
|
|
105
114
|
operation,
|
|
106
|
-
|
|
107
|
-
unique = undefined,
|
|
108
|
-
prio = true
|
|
115
|
+
operationSettings
|
|
109
116
|
}) {
|
|
110
117
|
const time = (0, _moment.default)().toDate();
|
|
111
118
|
const newQueueItem = {
|
|
112
119
|
correlationId,
|
|
113
120
|
cataloger,
|
|
114
121
|
operation,
|
|
122
|
+
operations: [operation],
|
|
115
123
|
oCatalogerIn,
|
|
116
124
|
operationSettings: {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
prio
|
|
125
|
+
prio: true,
|
|
126
|
+
...operationSettings
|
|
120
127
|
},
|
|
121
128
|
queueItemState: _constants.QUEUE_ITEM_STATE.VALIDATOR.PENDING_VALIDATION,
|
|
129
|
+
importJobState: {
|
|
130
|
+
CREATE: _constants.IMPORT_JOB_STATE.EMPTY,
|
|
131
|
+
UPDATE: _constants.IMPORT_JOB_STATE.EMPTY
|
|
132
|
+
},
|
|
122
133
|
creationTime: time,
|
|
123
134
|
modificationTime: time,
|
|
124
135
|
handledIds: [],
|
|
@@ -140,7 +151,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
140
151
|
}
|
|
141
152
|
}
|
|
142
153
|
|
|
143
|
-
function createBulk({
|
|
154
|
+
async function createBulk({
|
|
144
155
|
correlationId,
|
|
145
156
|
cataloger,
|
|
146
157
|
oCatalogerIn,
|
|
@@ -148,7 +159,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
148
159
|
contentType,
|
|
149
160
|
recordLoadParams,
|
|
150
161
|
stream,
|
|
151
|
-
|
|
162
|
+
operationSettings
|
|
152
163
|
}) {
|
|
153
164
|
const time = (0, _moment.default)().toDate();
|
|
154
165
|
const newQueueItem = {
|
|
@@ -156,45 +167,75 @@ async function _default(MONGO_URI, collection) {
|
|
|
156
167
|
cataloger,
|
|
157
168
|
oCatalogerIn,
|
|
158
169
|
operation,
|
|
170
|
+
operations: [operation],
|
|
159
171
|
operationSettings: {
|
|
160
|
-
prio
|
|
172
|
+
prio: false,
|
|
173
|
+
...operationSettings
|
|
161
174
|
},
|
|
162
175
|
contentType,
|
|
163
176
|
recordLoadParams,
|
|
164
|
-
queueItemState: _constants.QUEUE_ITEM_STATE.VALIDATOR.UPLOADING,
|
|
177
|
+
queueItemState: stream ? _constants.QUEUE_ITEM_STATE.VALIDATOR.UPLOADING : _constants.QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS,
|
|
178
|
+
importJobState: {
|
|
179
|
+
CREATE: _constants.IMPORT_JOB_STATE.EMPTY,
|
|
180
|
+
UPDATE: _constants.IMPORT_JOB_STATE.EMPTY
|
|
181
|
+
},
|
|
165
182
|
creationTime: time,
|
|
166
183
|
modificationTime: time,
|
|
167
184
|
handledIds: [],
|
|
168
185
|
rejectedIds: []
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
186
|
+
}; // eslint-disable-next-line functional/no-conditional-statement
|
|
187
|
+
|
|
188
|
+
if (stream) {
|
|
189
|
+
try {
|
|
190
|
+
// No await here, promises later
|
|
191
|
+
db.collection(collection).insertOne(newQueueItem);
|
|
192
|
+
logger.info(`New BULK queue item for ${operation} ${correlationId} has been made in ${collection}!`);
|
|
193
|
+
return new Promise((resolve, reject) => {
|
|
194
|
+
const outputStream = gridFSBucket.openUploadStream(correlationId);
|
|
195
|
+
stream.on('error', reject).on('data', chunk => outputStream.write(chunk)).on('end', () => outputStream.end(undefined, undefined, () => {
|
|
196
|
+
resolve(correlationId);
|
|
197
|
+
}));
|
|
198
|
+
});
|
|
199
|
+
} catch (error) {
|
|
200
|
+
(0, _utils.logError)(error);
|
|
201
|
+
throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR);
|
|
202
|
+
}
|
|
178
203
|
}
|
|
179
204
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
205
|
+
logger.debug(`No stream`); // eslint-disable-next-line functional/no-conditional-statement
|
|
206
|
+
|
|
207
|
+
if (!stream) {
|
|
208
|
+
try {
|
|
209
|
+
const result = await db.collection(collection).insertOne(newQueueItem);
|
|
210
|
+
|
|
211
|
+
if (result.acknowledged) {
|
|
212
|
+
logger.info(`New noStream BULK queue item for ${operation} ${correlationId} has been made in ${collection}`);
|
|
213
|
+
return {
|
|
214
|
+
correlationId,
|
|
215
|
+
queueItemState: _constants.QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
(0, _utils.logError)(error);
|
|
222
|
+
throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
186
225
|
} // Check state that the queueItem has not waited too long and set state
|
|
187
226
|
|
|
188
227
|
|
|
189
228
|
async function checkAndSetState({
|
|
190
229
|
correlationId,
|
|
191
230
|
state,
|
|
192
|
-
errorMessage =
|
|
193
|
-
errorStatus =
|
|
231
|
+
errorMessage = undefined,
|
|
232
|
+
errorStatus = undefined
|
|
194
233
|
}) {
|
|
195
234
|
// checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR
|
|
196
235
|
// otherwise it sets queueItem to state ABORT (408, 'Timeout')
|
|
197
|
-
const timeOut = await checkTimeOut(
|
|
236
|
+
const timeOut = await checkTimeOut({
|
|
237
|
+
correlationId
|
|
238
|
+
});
|
|
198
239
|
|
|
199
240
|
if (timeOut) {
|
|
200
241
|
return setState({
|
|
@@ -205,6 +246,36 @@ async function _default(MONGO_URI, collection) {
|
|
|
205
246
|
});
|
|
206
247
|
}
|
|
207
248
|
|
|
249
|
+
return false;
|
|
250
|
+
} // Check state that the queueItem has not waited too long and set state
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
async function checkAndSetImportJobState({
|
|
254
|
+
correlationId,
|
|
255
|
+
operation,
|
|
256
|
+
importJobState,
|
|
257
|
+
errorMessage = '',
|
|
258
|
+
errorStatus = ''
|
|
259
|
+
}) {
|
|
260
|
+
// checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR
|
|
261
|
+
// otherwise it sets queueItem to state ABORT (408, 'Timeout')
|
|
262
|
+
logger.debug(`${correlationId}, ${importJobState}, ${operation}`);
|
|
263
|
+
const timeOut = await checkTimeOut({
|
|
264
|
+
correlationId,
|
|
265
|
+
operation,
|
|
266
|
+
importJobState
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
if (timeOut) {
|
|
270
|
+
return setImportJobState({
|
|
271
|
+
correlationId,
|
|
272
|
+
operation,
|
|
273
|
+
importJobState,
|
|
274
|
+
errorMessage,
|
|
275
|
+
errorStatus
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
208
279
|
return false;
|
|
209
280
|
}
|
|
210
281
|
|
|
@@ -218,16 +289,23 @@ async function _default(MONGO_URI, collection) {
|
|
|
218
289
|
return result;
|
|
219
290
|
}
|
|
220
291
|
|
|
221
|
-
async function queryById(
|
|
292
|
+
async function queryById({
|
|
293
|
+
correlationId,
|
|
294
|
+
checkModTime = false
|
|
295
|
+
}) {
|
|
222
296
|
const result = await db.collection(collection).findOne({
|
|
223
297
|
correlationId
|
|
224
298
|
});
|
|
225
299
|
|
|
226
300
|
if (checkModTime) {
|
|
227
|
-
const timeOut = await checkTimeOut(
|
|
301
|
+
const timeOut = await checkTimeOut({
|
|
302
|
+
correlationId
|
|
303
|
+
});
|
|
228
304
|
|
|
229
305
|
if (timeOut) {
|
|
230
|
-
return queryById(
|
|
306
|
+
return queryById({
|
|
307
|
+
correlationId
|
|
308
|
+
});
|
|
231
309
|
}
|
|
232
310
|
|
|
233
311
|
return result;
|
|
@@ -240,15 +318,18 @@ async function _default(MONGO_URI, collection) {
|
|
|
240
318
|
// If the state is already ABORT or ERROR return false
|
|
241
319
|
|
|
242
320
|
|
|
243
|
-
async function checkTimeOut(
|
|
321
|
+
async function checkTimeOut({
|
|
322
|
+
correlationId
|
|
323
|
+
}) {
|
|
244
324
|
const {
|
|
245
325
|
modificationTime,
|
|
246
|
-
queueitemState: oldState
|
|
326
|
+
queueitemState: oldState,
|
|
327
|
+
importJobState
|
|
247
328
|
} = await db.collection(collection).findOne({
|
|
248
329
|
correlationId
|
|
249
|
-
});
|
|
330
|
+
}); // should we check for DONE too?
|
|
250
331
|
|
|
251
|
-
if ([_constants.QUEUE_ITEM_STATE.ABORT, _constants.QUEUE_ITEM_STATE.ERROR].includes(oldState)) {
|
|
332
|
+
if ([_constants.QUEUE_ITEM_STATE.ABORT, _constants.QUEUE_ITEM_STATE.ERROR, _constants.QUEUE_ITEM_STATE.DONE].includes(oldState)) {
|
|
252
333
|
logger.silly(`${correlationId} has already state: ${oldState}`);
|
|
253
334
|
return false;
|
|
254
335
|
}
|
|
@@ -257,6 +338,26 @@ async function _default(MONGO_URI, collection) {
|
|
|
257
338
|
logger.silly(`timeOut @ ${timeoutTime}`);
|
|
258
339
|
|
|
259
340
|
if (timeoutTime.isBefore()) {
|
|
341
|
+
const finalImportJobStates = [_constants.IMPORT_JOB_STATE.ABORT, _constants.IMPORT_JOB_STATE.DONE, _constants.IMPORT_JOB_STATE.EMPTY, _constants.IMPORT_JOB_STATE.ERROR];
|
|
342
|
+
|
|
343
|
+
if (!finalImportJobStates.includes(importJobState.CREATE)) {
|
|
344
|
+
// eslint-disable-line
|
|
345
|
+
await setImportJobState({
|
|
346
|
+
correlationId,
|
|
347
|
+
operation: 'CREATE',
|
|
348
|
+
importJobState: _constants.IMPORT_JOB_STATE.ABORT
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (!finalImportJobStates.includes(importJobState.UPDATE)) {
|
|
353
|
+
// eslint-disable-line
|
|
354
|
+
await setImportJobState({
|
|
355
|
+
correlationId,
|
|
356
|
+
operation: 'UPDATE',
|
|
357
|
+
importJobState: _constants.IMPORT_JOB_STATE.ABORT
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
|
|
260
361
|
await setState({
|
|
261
362
|
correlationId,
|
|
262
363
|
state: _constants.QUEUE_ITEM_STATE.ABORT,
|
|
@@ -336,30 +437,43 @@ async function _default(MONGO_URI, collection) {
|
|
|
336
437
|
}
|
|
337
438
|
|
|
338
439
|
return true;
|
|
339
|
-
}
|
|
440
|
+
} // eslint-disable-next-line max-statements
|
|
441
|
+
|
|
340
442
|
|
|
341
443
|
function getOne({
|
|
342
|
-
|
|
343
|
-
|
|
444
|
+
queueItemState,
|
|
445
|
+
importJobState = undefined
|
|
344
446
|
}) {
|
|
345
|
-
|
|
447
|
+
logger.silly(`queueItemState: ${queueItemState}, importJobState: ${JSON.stringify(importJobState)}`);
|
|
448
|
+
const cleanQueueItemState = queueItemState ? {
|
|
346
449
|
queueItemState: (0, _mongoSanitize.default)(queueItemState)
|
|
347
|
-
};
|
|
450
|
+
} : undefined;
|
|
348
451
|
|
|
349
452
|
try {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
453
|
+
// Just queueItemState
|
|
454
|
+
if (queueItemState && importJobState === undefined) {
|
|
455
|
+
logger.silly(`Checking DB ${collection} for just ${JSON.stringify(cleanQueueItemState.queueItemState)}`);
|
|
456
|
+
return db.collection(collection).findOne({ ...cleanQueueItemState
|
|
457
|
+
});
|
|
458
|
+
} // importJobState
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
if (importJobState && queueItemState === undefined) {
|
|
462
|
+
logger.silly(`Checking DB ${collection} for ${JSON.stringify(importJobState)}`);
|
|
463
|
+
return db.collection(collection).findOne({ ...importJobState
|
|
464
|
+
});
|
|
465
|
+
} // importJobState and queueItemState
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
if (importJobState && queueItemState) {
|
|
469
|
+
logger.silly(`Checking DB ${collection} for ${queueItemState} and ${JSON.stringify(importJobState)}`);
|
|
470
|
+
return db.collection(collection).findOne({ ...cleanQueueItemState,
|
|
471
|
+
...importJobState
|
|
353
472
|
});
|
|
354
473
|
}
|
|
355
474
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
};
|
|
359
|
-
logger.silly(`Checking DB ${collection} for ${clean.queueItemState} + ${clean2.operation}`);
|
|
360
|
-
return db.collection(collection).findOne({ ...clean,
|
|
361
|
-
...clean2
|
|
362
|
-
});
|
|
475
|
+
logger.debug(`getOne not working!`);
|
|
476
|
+
throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, 'Missing parameters, cannot get queueItem');
|
|
363
477
|
} catch (error) {
|
|
364
478
|
(0, _utils.logError)(error);
|
|
365
479
|
}
|
|
@@ -428,20 +542,128 @@ async function _default(MONGO_URI, collection) {
|
|
|
428
542
|
function setState({
|
|
429
543
|
correlationId,
|
|
430
544
|
state,
|
|
431
|
-
errorMessage =
|
|
432
|
-
errorStatus =
|
|
545
|
+
errorMessage = undefined,
|
|
546
|
+
errorStatus = undefined
|
|
433
547
|
}) {
|
|
434
|
-
const errorString = errorMessage || errorStatus ? `, Error message: '${errorMessage}', Error status: '${errorStatus}'` : '';
|
|
548
|
+
const errorString = errorMessage || errorStatus ? `, Error message: '${errorMessage || ''}', Error status: '${errorStatus || ''}'` : '';
|
|
435
549
|
logger.info(`Setting queue-item state ${state} for ${correlationId}${errorString} to ${collection}`);
|
|
550
|
+
const stateInQueueItemStates = Object.values(_constants.QUEUE_ITEM_STATE).indexOf(state) > -1;
|
|
551
|
+
const stateInQueueItemStatesValidator = Object.values(_constants.QUEUE_ITEM_STATE.VALIDATOR).indexOf(state) > -1;
|
|
552
|
+
const stateInQueueItemStatesImporter = Object.values(_constants.QUEUE_ITEM_STATE.IMPORTER).indexOf(state) > -1;
|
|
553
|
+
|
|
554
|
+
if (!stateInQueueItemStates && !stateInQueueItemStatesValidator && !stateInQueueItemStatesImporter) {
|
|
555
|
+
throw new _melindaCommons.Error(_httpStatus.default.BAD_REQUEST, 'Trying to set invalid state');
|
|
556
|
+
}
|
|
557
|
+
|
|
436
558
|
const clean = (0, _mongoSanitize.default)(correlationId);
|
|
559
|
+
const updateValues = {
|
|
560
|
+
queueItemState: state,
|
|
561
|
+
modificationTime: (0, _moment.default)().toDate(),
|
|
562
|
+
errorMessage,
|
|
563
|
+
errorStatus
|
|
564
|
+
}; // Do not update value that are undefined
|
|
565
|
+
// eslint-disable-next-line functional/immutable-data
|
|
566
|
+
|
|
567
|
+
Object.keys(updateValues).forEach(key => updateValues[key] === undefined && delete updateValues[key]);
|
|
437
568
|
return db.collection(collection).findOneAndUpdate({
|
|
438
569
|
correlationId: clean
|
|
570
|
+
}, {
|
|
571
|
+
$set: updateValues
|
|
572
|
+
}, {
|
|
573
|
+
projection: {
|
|
574
|
+
_id: 0
|
|
575
|
+
},
|
|
576
|
+
returnNewDocument: true
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
function setImportJobState({
|
|
581
|
+
correlationId,
|
|
582
|
+
operation,
|
|
583
|
+
importJobState
|
|
584
|
+
}) {
|
|
585
|
+
// should this also get importJobState as previously created object? {}
|
|
586
|
+
logger.info(`Setting queue-item importJobState: {${operation}: ${importJobState}} for ${correlationId}`);
|
|
587
|
+
const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
|
|
588
|
+
const cleanImportJobState = (0, _mongoSanitize.default)(importJobState);
|
|
589
|
+
|
|
590
|
+
if (!(operation in _constants.OPERATIONS)) {
|
|
591
|
+
throw new _melindaCommons.Error('400', 'Invalid operation for import job state');
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
if (!(cleanImportJobState in _constants.IMPORT_JOB_STATE)) {
|
|
595
|
+
throw new _melindaCommons.Error('400', 'Invalid import job state');
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
const newJobState = operation === _constants.OPERATIONS.CREATE ? {
|
|
599
|
+
'importJobState.CREATE': cleanImportJobState
|
|
600
|
+
} : {
|
|
601
|
+
'importJobState.UPDATE': cleanImportJobState
|
|
602
|
+
};
|
|
603
|
+
return db.collection(collection).findOneAndUpdate({
|
|
604
|
+
correlationId: cleanCorrelationId
|
|
605
|
+
}, {
|
|
606
|
+
$set: { ...newJobState,
|
|
607
|
+
modificationTime: (0, _moment.default)().toDate()
|
|
608
|
+
}
|
|
609
|
+
}, {
|
|
610
|
+
projection: {
|
|
611
|
+
_id: 0
|
|
612
|
+
},
|
|
613
|
+
returnNewDocument: true
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
async function setOperation({
|
|
618
|
+
correlationId,
|
|
619
|
+
operation
|
|
620
|
+
}) {
|
|
621
|
+
const newOperation = operation;
|
|
622
|
+
const {
|
|
623
|
+
operation: oldOperation
|
|
624
|
+
} = await db.collection(collection).findOne({
|
|
625
|
+
correlationId
|
|
626
|
+
});
|
|
627
|
+
logger.info(`Setting queue-item operation from ${oldOperation} to ${newOperation} for ${correlationId} to ${collection}`);
|
|
628
|
+
const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
|
|
629
|
+
const cleanNewOperation = (0, _mongoSanitize.default)(newOperation);
|
|
630
|
+
const result = await db.collection(collection).findOneAndUpdate({
|
|
631
|
+
correlationId: cleanCorrelationId
|
|
439
632
|
}, {
|
|
440
633
|
$set: {
|
|
441
|
-
|
|
442
|
-
modificationTime: (0, _moment.default)().toDate()
|
|
443
|
-
|
|
444
|
-
|
|
634
|
+
operation: cleanNewOperation,
|
|
635
|
+
modificationTime: (0, _moment.default)().toDate()
|
|
636
|
+
}
|
|
637
|
+
}, {
|
|
638
|
+
projection: {
|
|
639
|
+
_id: 0
|
|
640
|
+
},
|
|
641
|
+
returnNewDocument: true
|
|
642
|
+
});
|
|
643
|
+
return result.ok; // logger.debug(JSON.stringify(result));
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
async function setOperations({
|
|
647
|
+
correlationId,
|
|
648
|
+
addOperation,
|
|
649
|
+
removeOperation = undefined
|
|
650
|
+
}) {
|
|
651
|
+
const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId); //logger.info(`Setting queue-item operation from ${JSON.stringify(oldOperations)} by adding ${addOperation} and removing ${removeOperation} for ${correlationId} to ${collection}`);
|
|
652
|
+
|
|
653
|
+
const queueItem = await db.collection(collection).findOne({
|
|
654
|
+
correlationId: cleanCorrelationId
|
|
655
|
+
});
|
|
656
|
+
logger.debug(`We fould a queueItem: ${JSON.stringify(queueItem)}`);
|
|
657
|
+
const oldOperations = queueItem.operations;
|
|
658
|
+
logger.info(`Setting queue-item operation from ${JSON.stringify(oldOperations)} by adding ${addOperation} and removing ${removeOperation} for ${correlationId} to ${collection}`);
|
|
659
|
+
const operationsAfterRemove = oldOperations.filter(operation => operation !== removeOperation);
|
|
660
|
+
const operationsAfterRemoveAndAdd = [addOperation, ...operationsAfterRemove];
|
|
661
|
+
const result = await db.collection(collection).findOneAndUpdate({
|
|
662
|
+
correlationId: cleanCorrelationId
|
|
663
|
+
}, {
|
|
664
|
+
$set: {
|
|
665
|
+
operations: operationsAfterRemoveAndAdd,
|
|
666
|
+
modificationTime: (0, _moment.default)().toDate()
|
|
445
667
|
}
|
|
446
668
|
}, {
|
|
447
669
|
projection: {
|
|
@@ -449,6 +671,7 @@ async function _default(MONGO_URI, collection) {
|
|
|
449
671
|
},
|
|
450
672
|
returnNewDocument: true
|
|
451
673
|
});
|
|
674
|
+
return result.ok; // logger.debug(JSON.stringify(result));
|
|
452
675
|
}
|
|
453
676
|
}
|
|
454
677
|
//# sourceMappingURL=mongo.js.map
|
package/dist/mongo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mongo.js"],"names":["MONGO_URI","collection","logger","client","MongoClient","connect","useNewUrlParser","useUnifiedTopology","db","gridFSBucket","GridFSBucket","bucketName","createPrio","createBulk","checkAndSetState","query","queryById","remove","readContent","removeContent","getOne","getStream","setState","pushIds","pushMessages","correlationId","cataloger","oCatalogerIn","operation","noop","undefined","unique","prio","time","toDate","newQueueItem","operationSettings","queueItemState","QUEUE_ITEM_STATE","VALIDATOR","PENDING_VALIDATION","creationTime","modificationTime","handledIds","rejectedIds","result","insertOne","acknowledged","info","ApiError","httpStatus","INTERNAL_SERVER_ERROR","error","contentType","recordLoadParams","stream","UPLOADING","Promise","resolve","reject","outputStream","openUploadStream","on","chunk","write","end","state","errorMessage","errorStatus","timeOut","checkTimeOut","params","find","projection","_id","toArray","debug","length","checkModTime","findOne","queueitemState","oldState","ABORT","ERROR","includes","silly","timeoutTime","add","isBefore","REQUEST_TIMEOUT","JSON","stringify","clean","noContent","deleteOne","err","MongoDriverError","message","indexOf","readStream","openDownloadStreamByName","NOT_FOUND","delete","clean2","verbose","updateOne","$set","$push","$each","messages","messageField","cleanMessageField","errorString","findOneAndUpdate","returnNewDocument"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport {MongoClient, GridFSBucket, MongoDriverError} from 'mongodb';\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport {Error as ApiError} from '@natlibfi/melinda-commons';\nimport {QUEUE_ITEM_STATE} from './constants';\nimport {logError} from './utils.js';\nimport moment from 'moment';\nimport httpStatus from 'http-status';\nimport sanitize from 'mongo-sanitize';\n\n/* QueueItem:\n{\n \"correlationId\":\"FOO\",\n \"cataloger\":\"xxx0000\",\n \"oCatalogerIn\":\"xxx0000\"\n \"operation\":\"UPDATE\",\n \"contentType\":\"application/json\",\n \"recordLoadParams\": {\n \"pActiveLibrary\": \"XXX00\",\n \"pInputFile\": \"filename.seq\",\n \"pRejectFile\": \"filename.rej\",\n \"pLogFile\": \"filename.syslog\",\n \"pOldNew\": \"NEW\"\n },\n \"queueItemState\":\"PENDING_QUEUING\",\n \"creationTime\":\"2020-01-01T00:00:00.000Z\",\n \"modificationTime\":\"2020-01-01T00:00:01.000Z\",\n \"handledIds\": []\n}\n*/\n\nexport default async function (MONGO_URI, collection) {\n const logger = createLogger();\n\n // Connect to mongo (MONGO)\n const client = await MongoClient.connect(MONGO_URI, {useNewUrlParser: true, useUnifiedTopology: true});\n const db = client.db('rest-api');\n const gridFSBucket = new GridFSBucket(db, {bucketName: collection});\n\n return {createPrio, createBulk, checkAndSetState, query, queryById, remove, readContent, removeContent, getOne, getStream, setState, pushIds, pushMessages};\n\n async function createPrio({correlationId, cataloger, oCatalogerIn, operation, noop = undefined, unique = undefined, prio = true}) {\n const time = moment().toDate();\n const newQueueItem = {\n correlationId,\n cataloger,\n operation,\n oCatalogerIn,\n operationSettings: {unique, noop, prio},\n queueItemState: QUEUE_ITEM_STATE.VALIDATOR.PENDING_VALIDATION,\n creationTime: time,\n modificationTime: time,\n handledIds: [],\n rejectedIds: []\n };\n try {\n const result = await db.collection(collection).insertOne(newQueueItem);\n if (result.acknowledged) {\n logger.info(`New PRIO queue item for ${operation} ${correlationId} has been made in ${collection}`);\n return;\n }\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n } catch (error) {\n logError(error);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n }\n }\n\n function createBulk({correlationId, cataloger, oCatalogerIn, operation, contentType, recordLoadParams, stream, prio = false}) {\n const time = moment().toDate();\n const newQueueItem = {\n correlationId,\n cataloger,\n oCatalogerIn,\n operation,\n operationSettings: {prio},\n contentType,\n recordLoadParams,\n queueItemState: QUEUE_ITEM_STATE.VALIDATOR.UPLOADING,\n creationTime: time,\n modificationTime: time,\n handledIds: [],\n rejectedIds: []\n };\n try {\n // No await here, promises later\n db.collection(collection).insertOne(newQueueItem);\n logger.info(`New BULK queue item for ${operation} ${correlationId} has been made in ${collection}!`);\n } catch (error) {\n logError(error);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n }\n\n return new Promise((resolve, reject) => {\n const outputStream = gridFSBucket.openUploadStream(correlationId);\n\n stream\n .on('error', reject)\n .on('data', chunk => outputStream.write(chunk))\n .on('end', () => outputStream.end(undefined, undefined, () => {\n resolve(correlationId);\n }));\n });\n }\n\n // Check state that the queueItem has not waited too long and set state\n async function checkAndSetState({correlationId, state, errorMessage = '', errorStatus = ''}) {\n // checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR\n // otherwise it sets queueItem to state ABORT (408, 'Timeout')\n const timeOut = await checkTimeOut(correlationId);\n if (timeOut) {\n return setState({correlationId, state, errorMessage, errorStatus});\n }\n return false;\n }\n\n async function query(params) {\n const result = await db.collection(collection).find(params, {projection: {_id: 0}})\n .toArray();\n logger.debug(`Query result: ${result.length > 0 ? 'Found!' : 'Not found!'}`);\n return result;\n }\n\n async function queryById(correlationId, checkModTime) {\n const result = await db.collection(collection).findOne({correlationId});\n if (checkModTime) {\n const timeOut = await checkTimeOut(correlationId);\n if (timeOut) {\n return queryById(correlationId);\n }\n return result;\n }\n\n return result;\n }\n\n // Check that if the item has waited too long\n // If the last modification time for the queueItem is older than 1 minute\n // set state to ABORT and return false, otherwise return true\n // If the state is already ABORT or ERROR return false\n\n async function checkTimeOut(correlationId) {\n const {modificationTime, queueitemState: oldState} = await db.collection(collection).findOne({correlationId});\n\n if ([QUEUE_ITEM_STATE.ABORT, QUEUE_ITEM_STATE.ERROR].includes(oldState)) {\n logger.silly(`${correlationId} has already state: ${oldState}`);\n return false;\n }\n\n const timeoutTime = moment(modificationTime).add(1, 'm');\n logger.silly(`timeOut @ ${timeoutTime}`);\n\n if (timeoutTime.isBefore()) {\n await setState({correlationId, state: QUEUE_ITEM_STATE.ABORT, errorStatus: httpStatus.REQUEST_TIMEOUT, errorMessage: `Timeout in ${oldState}`});\n return false;\n }\n\n return true;\n }\n\n async function remove(params) {\n logger.silly(`${JSON.stringify(params)}`);\n logger.info(`Removing from Mongo (${collection}) id: ${params.correlationId}`);\n const clean = sanitize(params.correlationId);\n logger.silly(`mongo/remove: clean: ${JSON.stringify(clean)}`);\n\n try {\n //const metadataResult = await getFileMetadata({filename: clean});\n //logger.debug(`mongo/remove: metadataResult: ${JSON.stringify(metadataResult)}`);\n const noContent = await removeContent(params);\n if (noContent) {\n await db.collection(collection).deleteOne({correlationId: clean});\n return true;\n }\n } catch (err) {\n if (err instanceof MongoDriverError) {\n if (err.message.indexOf('File not found for id') !== -1) {\n logger.silly(`mongo/remove: File not found, removing queueItem ${JSON.stringify(clean)} from ${collection}`);\n await db.collection(collection).deleteOne({correlationId: clean});\n return true;\n }\n logger.error(err.message);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, err.message);\n }\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, err.message);\n }\n }\n\n async function readContent(correlationId) {\n logger.info(`Reading content from mongo for id: ${correlationId} in ${collection}`);\n const clean = sanitize(correlationId);\n const result = await db.collection(collection).findOne({correlationId: clean}); // njsscan-ignore: node_nosqli_injection\n\n if (result) {\n return {\n contentType: result.contentType,\n readStream: gridFSBucket.openDownloadStreamByName(clean)\n };\n }\n\n throw new ApiError(httpStatus.NOT_FOUND);\n }\n\n async function removeContent(params) {\n logger.info(`Removing content from mongo for id: ${params.correlationId} in ${collection}`);\n const clean = sanitize(params.correlationId);\n\n const result = await db.collection(collection).findOne({correlationId: clean}); // njsscan-ignore: node_nosqli_injection\n logger.silly(`mongo/removeContent: result ${JSON.stringify(result)}`);\n\n if (result) {\n await gridFSBucket.delete(clean);\n return true;\n }\n\n return true;\n }\n\n function getOne({operation, queueItemState}) {\n const clean = {queueItemState: sanitize(queueItemState)};\n try {\n if (operation === undefined) {\n logger.silly(`Checking DB ${collection} for ${JSON.stringify(clean.queueItemState)}`);\n return db.collection(collection).findOne({...clean});\n }\n\n const clean2 = {operation: sanitize(operation)};\n logger.silly(`Checking DB ${collection} for ${clean.queueItemState} + ${clean2.operation}`);\n return db.collection(collection).findOne({...clean, ...clean2});\n } catch (error) {\n logError(error);\n }\n }\n\n function getStream(correlationId) {\n logger.info(`Forming stream from mongo for ${correlationId} in ${collection}`);\n const clean = sanitize(correlationId);\n try {\n // Return content stream\n return gridFSBucket.openDownloadStreamByName(clean);\n } catch (error) {\n logError(error);\n }\n }\n\n async function pushIds({correlationId, handledIds, rejectedIds}) {\n logger.verbose(`Push ids (${handledIds.length}) and rejectedIds (${rejectedIds.length}) ${correlationId} to ${collection}`);\n logger.debug(`ids (${handledIds.length}): ${JSON.stringify(handledIds)}, rejectedIds ${rejectedIds.length}: ${JSON.stringify(rejectedIds)}`);\n const clean = sanitize(correlationId);\n await db.collection(collection).updateOne({\n correlationId: clean\n }, {\n $set: {\n modificationTime: moment().toDate()\n },\n $push: {\n handledIds: {$each: handledIds},\n rejectedIds: {$each: rejectedIds}\n }\n });\n }\n\n async function pushMessages({correlationId, messages, messageField = 'messages'}) {\n logger.verbose(`Push messages (${messages.length}) to ${messageField} ${correlationId} to ${collection}`);\n logger.silly(`Messages (${messages.length}): ${JSON.stringify(messages)}}`);\n const clean = sanitize(correlationId);\n const cleanMessageField = sanitize(messageField);\n await db.collection(collection).updateOne({\n correlationId: clean\n }, {\n $set: {\n modificationTime: moment().toDate()\n },\n $push: {\n [cleanMessageField]: {$each: messages}\n }\n });\n }\n\n function setState({correlationId, state, errorMessage = '', errorStatus = ''}) {\n const errorString = errorMessage || errorStatus ? `, Error message: '${errorMessage}', Error status: '${errorStatus}'` : '';\n logger.info(`Setting queue-item state ${state} for ${correlationId}${errorString} to ${collection}`);\n const clean = sanitize(correlationId);\n return db.collection(collection).findOneAndUpdate({\n correlationId: clean\n }, {\n $set: {\n queueItemState: state,\n modificationTime: moment().toDate(),\n errorMessage,\n errorStatus\n }\n }, {projection: {_id: 0}, returnNewDocument: true});\n }\n}\n"],"file":"mongo.js"}
|
|
1
|
+
{"version":3,"sources":["../src/mongo.js"],"names":["MONGO_URI","collection","logger","client","MongoClient","connect","useNewUrlParser","useUnifiedTopology","db","gridFSBucket","GridFSBucket","bucketName","createPrio","createBulk","checkAndSetState","checkAndSetImportJobState","query","queryById","remove","readContent","removeContent","getOne","getStream","setState","setImportJobState","pushIds","pushMessages","setOperation","setOperations","correlationId","cataloger","oCatalogerIn","operation","operationSettings","time","toDate","newQueueItem","operations","prio","queueItemState","QUEUE_ITEM_STATE","VALIDATOR","PENDING_VALIDATION","importJobState","CREATE","IMPORT_JOB_STATE","EMPTY","UPDATE","creationTime","modificationTime","handledIds","rejectedIds","result","insertOne","acknowledged","info","ApiError","httpStatus","INTERNAL_SERVER_ERROR","error","contentType","recordLoadParams","stream","UPLOADING","WAITING_FOR_RECORDS","Promise","resolve","reject","outputStream","openUploadStream","on","chunk","write","end","undefined","debug","state","errorMessage","errorStatus","timeOut","checkTimeOut","params","find","projection","_id","toArray","length","checkModTime","findOne","queueitemState","oldState","ABORT","ERROR","DONE","includes","silly","timeoutTime","add","isBefore","finalImportJobStates","REQUEST_TIMEOUT","JSON","stringify","clean","noContent","deleteOne","err","MongoDriverError","message","indexOf","readStream","openDownloadStreamByName","NOT_FOUND","delete","cleanQueueItemState","verbose","updateOne","$set","$push","$each","messages","messageField","cleanMessageField","errorString","stateInQueueItemStates","Object","values","stateInQueueItemStatesValidator","stateInQueueItemStatesImporter","IMPORTER","BAD_REQUEST","updateValues","keys","forEach","key","findOneAndUpdate","returnNewDocument","cleanCorrelationId","cleanImportJobState","OPERATIONS","newJobState","newOperation","oldOperation","cleanNewOperation","ok","addOperation","removeOperation","queueItem","oldOperations","operationsAfterRemove","filter","operationsAfterRemoveAndAdd"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport {MongoClient, GridFSBucket, MongoDriverError} from 'mongodb';\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport {Error as ApiError} from '@natlibfi/melinda-commons';\nimport {QUEUE_ITEM_STATE, IMPORT_JOB_STATE, OPERATIONS} from './constants';\nimport {logError} from './utils.js';\nimport moment from 'moment';\nimport httpStatus from 'http-status';\nimport sanitize from 'mongo-sanitize';\n\n/* QueueItem:\n{\n \"correlationId\":\"FOO\",\n \"cataloger\":\"xxx0000\",\n \"oCatalogerIn\":\"xxx0000\"\n \"operation\":\"UPDATE\",\n \"operations\":[\"UPDATE\", \"CREATE\"]\n \"contentType\":\"application/json\",\n \"recordLoadParams\": {\n \"pActiveLibrary\": \"XXX00\",\n \"pInputFile\": \"filename.seq\",\n \"pRejectFile\": \"filename.rej\",\n \"pLogFile\": \"filename.syslog\",\n \"pOldNew\": \"NEW\"\n },\n \"queueItemState\":\"PENDING_QUEUING\",\n \"importJobState\": {\n \"CREATE\": \"EMPTY\",\n \"UPDATE\": \"EMPTY\"\n },\n \"creationTime\":\"2020-01-01T00:00:00.000Z\",\n \"modificationTime\":\"2020-01-01T00:00:01.000Z\",\n \"handledIds\": []\n}\n*/\n\nexport default async function (MONGO_URI, collection) {\n const logger = createLogger();\n\n // Connect to mongo (MONGO)\n const client = await MongoClient.connect(MONGO_URI, {useNewUrlParser: true, useUnifiedTopology: true});\n const db = client.db('rest-api');\n const gridFSBucket = new GridFSBucket(db, {bucketName: collection});\n\n return {createPrio, createBulk, checkAndSetState, checkAndSetImportJobState, query, queryById, remove, readContent, removeContent, getOne, getStream, setState, setImportJobState, pushIds, pushMessages, setOperation, setOperations};\n\n async function createPrio({correlationId, cataloger, oCatalogerIn, operation, operationSettings}) {\n const time = moment().toDate();\n const newQueueItem = {\n correlationId,\n cataloger,\n operation,\n operations: [operation],\n oCatalogerIn,\n operationSettings: {\n prio: true,\n ...operationSettings\n },\n queueItemState: QUEUE_ITEM_STATE.VALIDATOR.PENDING_VALIDATION,\n importJobState: {\n CREATE: IMPORT_JOB_STATE.EMPTY,\n UPDATE: IMPORT_JOB_STATE.EMPTY\n },\n creationTime: time,\n modificationTime: time,\n handledIds: [],\n rejectedIds: []\n };\n try {\n const result = await db.collection(collection).insertOne(newQueueItem);\n if (result.acknowledged) {\n logger.info(`New PRIO queue item for ${operation} ${correlationId} has been made in ${collection}`);\n return;\n }\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n } catch (error) {\n logError(error);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n }\n }\n\n async function createBulk({correlationId, cataloger, oCatalogerIn, operation, contentType, recordLoadParams, stream, operationSettings}) {\n const time = moment().toDate();\n const newQueueItem = {\n correlationId,\n cataloger,\n oCatalogerIn,\n operation,\n operations: [operation],\n operationSettings: {\n prio: false,\n ...operationSettings\n },\n contentType,\n recordLoadParams,\n queueItemState: stream ? QUEUE_ITEM_STATE.VALIDATOR.UPLOADING : QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS,\n importJobState: {\n CREATE: IMPORT_JOB_STATE.EMPTY,\n UPDATE: IMPORT_JOB_STATE.EMPTY\n },\n creationTime: time,\n modificationTime: time,\n handledIds: [],\n rejectedIds: []\n };\n\n // eslint-disable-next-line functional/no-conditional-statement\n if (stream) {\n try {\n // No await here, promises later\n db.collection(collection).insertOne(newQueueItem);\n logger.info(`New BULK queue item for ${operation} ${correlationId} has been made in ${collection}!`);\n return new Promise((resolve, reject) => {\n const outputStream = gridFSBucket.openUploadStream(correlationId);\n\n stream\n .on('error', reject)\n .on('data', chunk => outputStream.write(chunk))\n .on('end', () => outputStream.end(undefined, undefined, () => {\n resolve(correlationId);\n }));\n });\n } catch (error) {\n logError(error);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n }\n }\n\n logger.debug(`No stream`);\n // eslint-disable-next-line functional/no-conditional-statement\n if (!stream) {\n try {\n const result = await db.collection(collection).insertOne(newQueueItem);\n if (result.acknowledged) {\n logger.info(`New noStream BULK queue item for ${operation} ${correlationId} has been made in ${collection}`);\n return {correlationId, queueItemState: QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS};\n }\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n } catch (error) {\n logError(error);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n }\n }\n }\n\n // Check state that the queueItem has not waited too long and set state\n async function checkAndSetState({correlationId, state, errorMessage = undefined, errorStatus = undefined}) {\n // checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR\n // otherwise it sets queueItem to state ABORT (408, 'Timeout')\n const timeOut = await checkTimeOut({correlationId});\n if (timeOut) {\n return setState({correlationId, state, errorMessage, errorStatus});\n }\n return false;\n }\n\n // Check state that the queueItem has not waited too long and set state\n async function checkAndSetImportJobState({correlationId, operation, importJobState, errorMessage = '', errorStatus = ''}) {\n // checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR\n // otherwise it sets queueItem to state ABORT (408, 'Timeout')\n logger.debug(`${correlationId}, ${importJobState}, ${operation}`);\n const timeOut = await checkTimeOut({correlationId, operation, importJobState});\n if (timeOut) {\n return setImportJobState({correlationId, operation, importJobState, errorMessage, errorStatus});\n }\n return false;\n }\n\n async function query(params) {\n const result = await db.collection(collection).find(params, {projection: {_id: 0}})\n .toArray();\n logger.debug(`Query result: ${result.length > 0 ? 'Found!' : 'Not found!'}`);\n return result;\n }\n\n async function queryById({correlationId, checkModTime = false}) {\n const result = await db.collection(collection).findOne({correlationId});\n if (checkModTime) {\n const timeOut = await checkTimeOut({correlationId});\n if (timeOut) {\n return queryById({correlationId});\n }\n return result;\n }\n\n return result;\n }\n\n // Check that if the item has waited too long\n // If the last modification time for the queueItem is older than 1 minute\n // set state to ABORT and return false, otherwise return true\n // If the state is already ABORT or ERROR return false\n\n async function checkTimeOut({correlationId}) {\n const {modificationTime, queueitemState: oldState, importJobState} = await db.collection(collection).findOne({correlationId});\n\n // should we check for DONE too?\n if ([QUEUE_ITEM_STATE.ABORT, QUEUE_ITEM_STATE.ERROR, QUEUE_ITEM_STATE.DONE].includes(oldState)) {\n logger.silly(`${correlationId} has already state: ${oldState}`);\n return false;\n }\n\n const timeoutTime = moment(modificationTime).add(1, 'm');\n logger.silly(`timeOut @ ${timeoutTime}`);\n\n if (timeoutTime.isBefore()) {\n const finalImportJobStates = [IMPORT_JOB_STATE.ABORT, IMPORT_JOB_STATE.DONE, IMPORT_JOB_STATE.EMPTY, IMPORT_JOB_STATE.ERROR];\n if (!finalImportJobStates.includes(importJobState.CREATE)) { // eslint-disable-line\n await setImportJobState({correlationId, operation: 'CREATE', importJobState: IMPORT_JOB_STATE.ABORT});\n }\n\n if (!finalImportJobStates.includes(importJobState.UPDATE)) { // eslint-disable-line\n await setImportJobState({correlationId, operation: 'UPDATE', importJobState: IMPORT_JOB_STATE.ABORT});\n }\n\n await setState({correlationId, state: QUEUE_ITEM_STATE.ABORT, errorStatus: httpStatus.REQUEST_TIMEOUT, errorMessage: `Timeout in ${oldState}`});\n\n return false;\n }\n\n return true;\n }\n\n async function remove(params) {\n logger.silly(`${JSON.stringify(params)}`);\n logger.info(`Removing from Mongo (${collection}) id: ${params.correlationId}`);\n const clean = sanitize(params.correlationId);\n logger.silly(`mongo/remove: clean: ${JSON.stringify(clean)}`);\n\n try {\n //const metadataResult = await getFileMetadata({filename: clean});\n //logger.debug(`mongo/remove: metadataResult: ${JSON.stringify(metadataResult)}`);\n const noContent = await removeContent(params);\n if (noContent) {\n await db.collection(collection).deleteOne({correlationId: clean});\n return true;\n }\n } catch (err) {\n if (err instanceof MongoDriverError) {\n if (err.message.indexOf('File not found for id') !== -1) {\n logger.silly(`mongo/remove: File not found, removing queueItem ${JSON.stringify(clean)} from ${collection}`);\n await db.collection(collection).deleteOne({correlationId: clean});\n return true;\n }\n logger.error(err.message);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, err.message);\n }\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, err.message);\n }\n }\n\n async function readContent(correlationId) {\n logger.info(`Reading content from mongo for id: ${correlationId} in ${collection}`);\n const clean = sanitize(correlationId);\n const result = await db.collection(collection).findOne({correlationId: clean}); // njsscan-ignore: node_nosqli_injection\n\n if (result) {\n return {\n contentType: result.contentType,\n readStream: gridFSBucket.openDownloadStreamByName(clean)\n };\n }\n\n throw new ApiError(httpStatus.NOT_FOUND);\n }\n\n async function removeContent(params) {\n logger.info(`Removing content from mongo for id: ${params.correlationId} in ${collection}`);\n const clean = sanitize(params.correlationId);\n\n const result = await db.collection(collection).findOne({correlationId: clean}); // njsscan-ignore: node_nosqli_injection\n logger.silly(`mongo/removeContent: result ${JSON.stringify(result)}`);\n\n if (result) {\n await gridFSBucket.delete(clean);\n return true;\n }\n\n return true;\n }\n\n // eslint-disable-next-line max-statements\n function getOne({queueItemState, importJobState = undefined}) {\n\n logger.silly(`queueItemState: ${queueItemState}, importJobState: ${JSON.stringify(importJobState)}`);\n const cleanQueueItemState = queueItemState ? {queueItemState: sanitize(queueItemState)} : undefined;\n\n try {\n\n // Just queueItemState\n if (queueItemState && importJobState === undefined) {\n logger.silly(`Checking DB ${collection} for just ${JSON.stringify(cleanQueueItemState.queueItemState)}`);\n return db.collection(collection).findOne({...cleanQueueItemState});\n }\n\n // importJobState\n if (importJobState && queueItemState === undefined) {\n logger.silly(`Checking DB ${collection} for ${JSON.stringify(importJobState)}`);\n return db.collection(collection).findOne({...importJobState});\n }\n\n // importJobState and queueItemState\n if (importJobState && queueItemState) {\n logger.silly(`Checking DB ${collection} for ${queueItemState} and ${JSON.stringify(importJobState)}`);\n return db.collection(collection).findOne({...cleanQueueItemState, ...importJobState});\n }\n\n logger.debug(`getOne not working!`);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, 'Missing parameters, cannot get queueItem');\n\n } catch (error) {\n logError(error);\n }\n }\n\n function getStream(correlationId) {\n logger.info(`Forming stream from mongo for ${correlationId} in ${collection}`);\n const clean = sanitize(correlationId);\n try {\n // Return content stream\n return gridFSBucket.openDownloadStreamByName(clean);\n } catch (error) {\n logError(error);\n }\n }\n\n async function pushIds({correlationId, handledIds, rejectedIds}) {\n logger.verbose(`Push ids (${handledIds.length}) and rejectedIds (${rejectedIds.length}) ${correlationId} to ${collection}`);\n logger.debug(`ids (${handledIds.length}): ${JSON.stringify(handledIds)}, rejectedIds ${rejectedIds.length}: ${JSON.stringify(rejectedIds)}`);\n const clean = sanitize(correlationId);\n await db.collection(collection).updateOne({\n correlationId: clean\n }, {\n $set: {\n modificationTime: moment().toDate()\n },\n $push: {\n handledIds: {$each: handledIds},\n rejectedIds: {$each: rejectedIds}\n }\n });\n }\n\n async function pushMessages({correlationId, messages, messageField = 'messages'}) {\n logger.verbose(`Push messages (${messages.length}) to ${messageField} ${correlationId} to ${collection}`);\n logger.silly(`Messages (${messages.length}): ${JSON.stringify(messages)}}`);\n const clean = sanitize(correlationId);\n const cleanMessageField = sanitize(messageField);\n await db.collection(collection).updateOne({\n correlationId: clean\n }, {\n $set: {\n modificationTime: moment().toDate()\n },\n $push: {\n [cleanMessageField]: {$each: messages}\n }\n });\n }\n\n function setState({correlationId, state, errorMessage = undefined, errorStatus = undefined}) {\n const errorString = errorMessage || errorStatus ? `, Error message: '${errorMessage || ''}', Error status: '${errorStatus || ''}'` : '';\n logger.info(`Setting queue-item state ${state} for ${correlationId}${errorString} to ${collection}`);\n\n const stateInQueueItemStates = Object.values(QUEUE_ITEM_STATE).indexOf(state) > -1;\n const stateInQueueItemStatesValidator = Object.values(QUEUE_ITEM_STATE.VALIDATOR).indexOf(state) > -1;\n const stateInQueueItemStatesImporter = Object.values(QUEUE_ITEM_STATE.IMPORTER).indexOf(state) > -1;\n if (!stateInQueueItemStates && !stateInQueueItemStatesValidator && !stateInQueueItemStatesImporter) {\n throw new ApiError(httpStatus.BAD_REQUEST, 'Trying to set invalid state');\n }\n\n const clean = sanitize(correlationId);\n const updateValues = {\n queueItemState: state,\n modificationTime: moment().toDate(),\n errorMessage,\n errorStatus\n };\n\n // Do not update value that are undefined\n // eslint-disable-next-line functional/immutable-data\n Object.keys(updateValues).forEach(key => updateValues[key] === undefined && delete updateValues[key]);\n\n return db.collection(collection)\n .findOneAndUpdate(\n {correlationId: clean},\n {$set: updateValues},\n {projection: {_id: 0}, returnNewDocument: true}\n );\n }\n\n function setImportJobState({correlationId, operation, importJobState}) {\n\n // should this also get importJobState as previously created object? {}\n logger.info(`Setting queue-item importJobState: {${operation}: ${importJobState}} for ${correlationId}`);\n const cleanCorrelationId = sanitize(correlationId);\n const cleanImportJobState = sanitize(importJobState);\n\n if (!(operation in OPERATIONS)) {\n throw new ApiError('400', 'Invalid operation for import job state');\n }\n\n if (!(cleanImportJobState in IMPORT_JOB_STATE)) {\n throw new ApiError('400', 'Invalid import job state');\n }\n\n const newJobState = operation === OPERATIONS.CREATE ? {'importJobState.CREATE': cleanImportJobState} : {'importJobState.UPDATE': cleanImportJobState};\n return db.collection(collection).findOneAndUpdate({\n correlationId: cleanCorrelationId\n }, {\n $set: {\n ...newJobState,\n modificationTime: moment().toDate()\n }\n }, {projection: {_id: 0}, returnNewDocument: true});\n }\n\n async function setOperation({correlationId, operation}) {\n const newOperation = operation;\n const {operation: oldOperation} = await db.collection(collection).findOne({correlationId});\n logger.info(`Setting queue-item operation from ${oldOperation} to ${newOperation} for ${correlationId} to ${collection}`);\n const cleanCorrelationId = sanitize(correlationId);\n const cleanNewOperation = sanitize(newOperation);\n\n const result = await db.collection(collection).findOneAndUpdate({\n correlationId: cleanCorrelationId\n }, {\n $set: {\n operation: cleanNewOperation,\n modificationTime: moment().toDate()\n }\n }, {projection: {_id: 0}, returnNewDocument: true});\n\n return result.ok;\n // logger.debug(JSON.stringify(result));\n }\n\n async function setOperations({correlationId, addOperation, removeOperation = undefined}) {\n const cleanCorrelationId = sanitize(correlationId);\n\n //logger.info(`Setting queue-item operation from ${JSON.stringify(oldOperations)} by adding ${addOperation} and removing ${removeOperation} for ${correlationId} to ${collection}`);\n\n const queueItem = await db.collection(collection).findOne({correlationId: cleanCorrelationId});\n logger.debug(`We fould a queueItem: ${JSON.stringify(queueItem)}`);\n\n const oldOperations = queueItem.operations;\n\n logger.info(`Setting queue-item operation from ${JSON.stringify(oldOperations)} by adding ${addOperation} and removing ${removeOperation} for ${correlationId} to ${collection}`);\n\n const operationsAfterRemove = oldOperations.filter(operation => operation !== removeOperation);\n const operationsAfterRemoveAndAdd = [addOperation, ...operationsAfterRemove];\n\n const result = await db.collection(collection).findOneAndUpdate({\n correlationId: cleanCorrelationId\n }, {\n $set: {\n operations: operationsAfterRemoveAndAdd,\n modificationTime: moment().toDate()\n }\n }, {projection: {_id: 0}, returnNewDocument: true});\n\n return result.ok;\n // logger.debug(JSON.stringify(result));\n }\n}\n"],"file":"mongo.js"}
|
package/dist/utils.js
CHANGED
|
@@ -3,12 +3,21 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.addRecordResponseItem = addRecordResponseItem;
|
|
7
|
+
exports.createImportJobState = createImportJobState;
|
|
8
|
+
exports.createRecordResponseItem = createRecordResponseItem;
|
|
6
9
|
exports.logError = logError;
|
|
7
10
|
|
|
8
11
|
var _melindaBackendCommons = require("@natlibfi/melinda-backend-commons");
|
|
9
12
|
|
|
10
13
|
var _melindaCommons = require("@natlibfi/melinda-commons");
|
|
11
14
|
|
|
15
|
+
var _constants = require("./constants");
|
|
16
|
+
|
|
17
|
+
var _httpStatus = _interopRequireDefault(require("http-status"));
|
|
18
|
+
|
|
19
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
20
|
+
|
|
12
21
|
/**
|
|
13
22
|
*
|
|
14
23
|
* @licstart The following is the entire license notice for the JavaScript code in this file.
|
|
@@ -51,4 +60,127 @@ function logError(err) {
|
|
|
51
60
|
|
|
52
61
|
logger.error(err.stack === undefined ? err : err.stack);
|
|
53
62
|
}
|
|
63
|
+
|
|
64
|
+
function createImportJobState(operation, state, queryImportJobState = false) {
|
|
65
|
+
if (!(state in _constants.IMPORT_JOB_STATE)) {
|
|
66
|
+
throw new Error('Invalid IMPORT_JOB_STATE');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!(operation in _constants.OPERATIONS)) {
|
|
70
|
+
throw new Error('Invalid operation');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (queryImportJobState) {
|
|
74
|
+
const importJobStateWithOperation = `importJobState.${operation}`;
|
|
75
|
+
const importJobStateForQuery = {
|
|
76
|
+
[importJobStateWithOperation]: state
|
|
77
|
+
};
|
|
78
|
+
return importJobStateForQuery;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
[operation]: state
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function createRecordResponseItem({
|
|
87
|
+
responsePayload,
|
|
88
|
+
responseStatus,
|
|
89
|
+
recordMetadata,
|
|
90
|
+
id
|
|
91
|
+
}) {
|
|
92
|
+
const recordResponseStatusAndMessage = getRecordResponseStatusAndMessage(responseStatus, responsePayload);
|
|
93
|
+
const recordResponseItem = {
|
|
94
|
+
melindaId: id || '000000000',
|
|
95
|
+
recordMetadata: responsePayload.recordMetadata || recordMetadata || undefined,
|
|
96
|
+
...recordResponseStatusAndMessage
|
|
97
|
+
};
|
|
98
|
+
return recordResponseItem;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getRecordResponseStatusAndMessage(responseStatus, responsePayload) {
|
|
102
|
+
logger.debug(`Response status: ${responseStatus} responsePayload: ${JSON.stringify(responsePayload)}`);
|
|
103
|
+
const responseStatusName = _httpStatus.default[`${responseStatus}_NAME`];
|
|
104
|
+
logger.debug(`Response status name: ${responseStatusName}`);
|
|
105
|
+
const message = getMessageFromResponsePayload(responsePayload);
|
|
106
|
+
logger.debug(`Response message: ${message}`); // Non-http statuses
|
|
107
|
+
|
|
108
|
+
if (['UPDATED', 'CREATED', 'INVALID', 'ERROR'].includes(responseStatus)) {
|
|
109
|
+
return {
|
|
110
|
+
status: responseStatus,
|
|
111
|
+
message
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (['UNKNOWN'].includes(responseStatus)) {
|
|
116
|
+
const possibleIds = responsePayload.ids || [];
|
|
117
|
+
return {
|
|
118
|
+
status: responseStatus,
|
|
119
|
+
message,
|
|
120
|
+
possibleIds
|
|
121
|
+
};
|
|
122
|
+
} // Duplicates and other CONFLICT statuses
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
if ([_httpStatus.default.CONFLICT, 'CONFLICT'].includes(responseStatus)) {
|
|
126
|
+
if (/^Duplicates in database/u.test(message)) {
|
|
127
|
+
const duplicateIds = responsePayload.ids || [];
|
|
128
|
+
return {
|
|
129
|
+
status: 'DUPLICATE',
|
|
130
|
+
message,
|
|
131
|
+
duplicateIds
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
status: 'CONFLICT',
|
|
137
|
+
message
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if ([_httpStatus.default.UNPROCESSABLE_ENTITY, 'UNPROCESSABLE_ENTITY'].includes(responseStatus)) {
|
|
142
|
+
return {
|
|
143
|
+
status: 'UNPROCESSABLE_ENTITY',
|
|
144
|
+
message
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if ([_httpStatus.default.NOT_FOUND, 'NOT_FOUND'].includes(responseStatus)) {
|
|
149
|
+
return {
|
|
150
|
+
status: 'NOT_FOUND',
|
|
151
|
+
message
|
|
152
|
+
};
|
|
153
|
+
} // Otherwise
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
status: 'ERROR',
|
|
158
|
+
message
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function getMessageFromResponsePayload(responsePayload) {
|
|
163
|
+
if (responsePayload.message) {
|
|
164
|
+
return responsePayload.message;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (typeof responsePayload === 'string' || responsePayload instanceof String) {
|
|
168
|
+
return responsePayload;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return '';
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function addRecordResponseItem({
|
|
175
|
+
recordResponseItem,
|
|
176
|
+
correlationId,
|
|
177
|
+
mongoOperator
|
|
178
|
+
}) {
|
|
179
|
+
await mongoOperator.pushMessages({
|
|
180
|
+
correlationId,
|
|
181
|
+
messages: [recordResponseItem],
|
|
182
|
+
messageField: 'records'
|
|
183
|
+
});
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
54
186
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.js"],"names":["logger","logError","err","ApiError","error","JSON","stringify","stack","undefined"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/utils.js"],"names":["logger","logError","err","ApiError","error","JSON","stringify","stack","undefined","createImportJobState","operation","state","queryImportJobState","IMPORT_JOB_STATE","Error","OPERATIONS","importJobStateWithOperation","importJobStateForQuery","createRecordResponseItem","responsePayload","responseStatus","recordMetadata","id","recordResponseStatusAndMessage","getRecordResponseStatusAndMessage","recordResponseItem","melindaId","debug","responseStatusName","httpStatus","message","getMessageFromResponsePayload","includes","status","possibleIds","ids","CONFLICT","test","duplicateIds","UNPROCESSABLE_ENTITY","NOT_FOUND","String","addRecordResponseItem","correlationId","mongoOperator","pushMessages","messages","messageField"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport {Error as ApiError} from '@natlibfi/melinda-commons';\nimport {IMPORT_JOB_STATE, OPERATIONS} from './constants';\nimport httpStatus from 'http-status';\n\nconst logger = createLogger();\n\nexport function logError(err) {\n if (err instanceof ApiError) {\n logger.error(JSON.stringify(err));\n return;\n }\n\n if (err === 'SIGINT') {\n logger.error(err);\n return;\n }\n\n logger.error(err.stack === undefined ? err : err.stack);\n}\n\nexport function createImportJobState(operation, state, queryImportJobState = false) {\n if (!(state in IMPORT_JOB_STATE)) {\n throw new Error('Invalid IMPORT_JOB_STATE');\n }\n\n if (!(operation in OPERATIONS)) {\n throw new Error('Invalid operation');\n }\n\n if (queryImportJobState) {\n const importJobStateWithOperation = `importJobState.${operation}`;\n const importJobStateForQuery = {[importJobStateWithOperation]: state};\n\n return importJobStateForQuery;\n }\n\n return {[operation]: state};\n}\n\nexport function createRecordResponseItem({responsePayload, responseStatus, recordMetadata, id}) {\n const recordResponseStatusAndMessage = getRecordResponseStatusAndMessage(responseStatus, responsePayload);\n const recordResponseItem = {\n melindaId: id || '000000000',\n recordMetadata: responsePayload.recordMetadata || recordMetadata || undefined,\n ...recordResponseStatusAndMessage\n };\n return recordResponseItem;\n}\n\nfunction getRecordResponseStatusAndMessage(responseStatus, responsePayload) {\n\n logger.debug(`Response status: ${responseStatus} responsePayload: ${JSON.stringify(responsePayload)}`);\n const responseStatusName = httpStatus[`${responseStatus}_NAME`];\n logger.debug(`Response status name: ${responseStatusName}`);\n\n const message = getMessageFromResponsePayload(responsePayload);\n\n logger.debug(`Response message: ${message}`);\n\n // Non-http statuses\n if (['UPDATED', 'CREATED', 'INVALID', 'ERROR'].includes(responseStatus)) {\n return {status: responseStatus, message};\n }\n\n if (['UNKNOWN'].includes(responseStatus)) {\n const possibleIds = responsePayload.ids || [];\n return {status: responseStatus, message, possibleIds};\n }\n\n // Duplicates and other CONFLICT statuses\n if ([httpStatus.CONFLICT, 'CONFLICT'].includes(responseStatus)) {\n if ((/^Duplicates in database/u).test(message)) {\n const duplicateIds = responsePayload.ids || [];\n return {status: 'DUPLICATE', message, duplicateIds};\n }\n return {status: 'CONFLICT', message};\n }\n\n if ([httpStatus.UNPROCESSABLE_ENTITY, 'UNPROCESSABLE_ENTITY'].includes(responseStatus)) {\n return {status: 'UNPROCESSABLE_ENTITY', message};\n }\n\n if ([httpStatus.NOT_FOUND, 'NOT_FOUND'].includes(responseStatus)) {\n return {status: 'NOT_FOUND', message};\n }\n\n // Otherwise\n return {status: 'ERROR', message};\n}\n\nfunction getMessageFromResponsePayload(responsePayload) {\n if (responsePayload.message) {\n return responsePayload.message;\n }\n if (typeof responsePayload === 'string' || responsePayload instanceof String) {\n return responsePayload;\n }\n return '';\n}\n\nexport async function addRecordResponseItem({recordResponseItem, correlationId, mongoOperator}) {\n await mongoOperator.pushMessages({correlationId, messages: [recordResponseItem], messageField: 'records'});\n return true;\n}\n\n"],"file":"utils.js"}
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"url": "git@github.com:natlibfi/melinda-rest-api-commons.git"
|
|
15
15
|
},
|
|
16
16
|
"license": "AGPL-3.0+",
|
|
17
|
-
"version": "2.
|
|
17
|
+
"version": "2.2.0-alpha.10",
|
|
18
18
|
"main": "./dist/index.js",
|
|
19
19
|
"engines": {
|
|
20
20
|
"node": ">=14"
|
|
@@ -33,34 +33,33 @@
|
|
|
33
33
|
"build": "babel src --source-maps --copy-files --delete-dir-on-start --out-dir=dist"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@natlibfi/fixura": "^2.2.1",
|
|
37
36
|
"@natlibfi/marc-record": "^7.0.0",
|
|
38
37
|
"@natlibfi/marc-record-serializers": "^8.1.0",
|
|
39
38
|
"@natlibfi/marc-record-validate": "^7.0.1",
|
|
40
|
-
"@natlibfi/marc-record-validators-melinda": "^9.0.
|
|
39
|
+
"@natlibfi/marc-record-validators-melinda": "^9.0.4",
|
|
41
40
|
"@natlibfi/melinda-backend-commons": "^2.0.5",
|
|
42
41
|
"@natlibfi/melinda-commons": "^12.0.3",
|
|
43
42
|
"amqplib": ">=0.8.0 <1.0.0",
|
|
44
43
|
"http-status": "^1.5.0",
|
|
45
|
-
"moment": "^2.29.
|
|
44
|
+
"moment": "^2.29.2",
|
|
46
45
|
"mongo-sanitize": "^1.1.0",
|
|
47
|
-
"mongodb": "^4.
|
|
46
|
+
"mongodb": "^4.5.0"
|
|
48
47
|
},
|
|
49
48
|
"devDependencies": {
|
|
50
|
-
"@babel/cli": "^7.
|
|
51
|
-
"@babel/core": "^7.
|
|
49
|
+
"@babel/cli": "^7.17.6",
|
|
50
|
+
"@babel/core": "^7.17.8",
|
|
51
|
+
"@babel/eslint-parser": "^7.17.0",
|
|
52
52
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
53
53
|
"@babel/preset-env": "^7.16.11",
|
|
54
54
|
"@natlibfi/eslint-config-melinda-backend": "^2.0.0",
|
|
55
|
-
"@
|
|
55
|
+
"@natlibfi/fixura": "^2.2.1",
|
|
56
56
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
57
57
|
"babel-plugin-istanbul": "^6.1.1",
|
|
58
58
|
"babel-plugin-rewire": "^1.2.0",
|
|
59
59
|
"chai": "^4.3.6",
|
|
60
60
|
"cross-env": "^7.0.3",
|
|
61
|
-
"eslint": "^8.
|
|
62
|
-
"
|
|
63
|
-
"mocha": "^9.2.0",
|
|
61
|
+
"eslint": "^8.12.0",
|
|
62
|
+
"mocha": "^9.2.2",
|
|
64
63
|
"nodemon": "^2.0.15",
|
|
65
64
|
"nyc": "^15.1.0"
|
|
66
65
|
},
|