@cumulus/es-client 15.0.3 → 16.0.2-alpha.0
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/indexer.js +47 -13
- package/package.json +8 -8
- package/search.js +7 -78
package/indexer.js
CHANGED
|
@@ -127,6 +127,14 @@ function updateAsyncOperation(esClient, id, updates, index = defaultIndexAlias,
|
|
|
127
127
|
return updateExistingRecord(esClient, id, updates, index, type);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
const executionInvalidNullFields = [
|
|
131
|
+
'arn',
|
|
132
|
+
'name',
|
|
133
|
+
'status',
|
|
134
|
+
'updatedAt',
|
|
135
|
+
'createdAt',
|
|
136
|
+
];
|
|
137
|
+
|
|
130
138
|
/**
|
|
131
139
|
* Upsert an execution record in Elasticsearch
|
|
132
140
|
*
|
|
@@ -136,6 +144,8 @@ function updateAsyncOperation(esClient, id, updates, index = defaultIndexAlias,
|
|
|
136
144
|
* @param {string} params.index - Elasticsearch index alias (default defined in search.js)
|
|
137
145
|
* @param {string} params.type - Elasticsearch type (default: execution)
|
|
138
146
|
* @param {string} [params.refresh] - whether to refresh the index on update or not
|
|
147
|
+
* @param {boolean} writeConstraints - boolean toggle restricting if conditionals should
|
|
148
|
+
* be used to determine write eligibility
|
|
139
149
|
* @returns {Promise} elasticsearch update response
|
|
140
150
|
*/
|
|
141
151
|
async function upsertExecution({
|
|
@@ -144,11 +154,42 @@ async function upsertExecution({
|
|
|
144
154
|
index = defaultIndexAlias,
|
|
145
155
|
type = 'execution',
|
|
146
156
|
refresh,
|
|
147
|
-
}) {
|
|
157
|
+
}, writeConstraints = true) {
|
|
158
|
+
Object.keys(updates).forEach((key) => {
|
|
159
|
+
if (updates[key] === null && executionInvalidNullFields.includes(key)) {
|
|
160
|
+
throw new ValidationError(`Attempted Elasticsearch write with invalid key ${key} set to null. Please remove or change this field and retry`);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
148
164
|
const upsertDoc = {
|
|
149
|
-
...updates,
|
|
150
|
-
timestamp: Date.now(),
|
|
165
|
+
...removeNilProperties(updates),
|
|
166
|
+
timestamp: updates.timestamp || Date.now(),
|
|
151
167
|
};
|
|
168
|
+
|
|
169
|
+
let removeString = '';
|
|
170
|
+
// Set field removal for null values
|
|
171
|
+
Object.entries(updates).forEach(([fieldName, value]) => {
|
|
172
|
+
if (value === null) {
|
|
173
|
+
removeString += `ctx._source.remove('${fieldName}'); `;
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
let inlineDocWriteString = 'ctx._source.putAll(params.doc);';
|
|
178
|
+
if (removeString !== '') {
|
|
179
|
+
inlineDocWriteString += removeString;
|
|
180
|
+
}
|
|
181
|
+
let inline = inlineDocWriteString;
|
|
182
|
+
if (writeConstraints === true) {
|
|
183
|
+
inline = `
|
|
184
|
+
if (params.doc.status == "running") {
|
|
185
|
+
ctx._source.updatedAt = params.doc.updatedAt;
|
|
186
|
+
ctx._source.timestamp = params.doc.timestamp;
|
|
187
|
+
ctx._source.originalPayload = params.doc.originalPayload;
|
|
188
|
+
} else {
|
|
189
|
+
${inlineDocWriteString}
|
|
190
|
+
}
|
|
191
|
+
`;
|
|
192
|
+
}
|
|
152
193
|
return await esClient.update({
|
|
153
194
|
index,
|
|
154
195
|
type,
|
|
@@ -156,15 +197,7 @@ async function upsertExecution({
|
|
|
156
197
|
body: {
|
|
157
198
|
script: {
|
|
158
199
|
lang: 'painless',
|
|
159
|
-
inline
|
|
160
|
-
if (params.doc.status == "running") {
|
|
161
|
-
ctx._source.updatedAt = params.doc.updatedAt;
|
|
162
|
-
ctx._source.timestamp = params.doc.timestamp;
|
|
163
|
-
ctx._source.originalPayload = params.doc.originalPayload;
|
|
164
|
-
} else {
|
|
165
|
-
ctx._source.putAll(params.doc)
|
|
166
|
-
}
|
|
167
|
-
`,
|
|
200
|
+
inline,
|
|
168
201
|
params: {
|
|
169
202
|
doc: upsertDoc,
|
|
170
203
|
},
|
|
@@ -320,7 +353,7 @@ async function upsertGranule({
|
|
|
320
353
|
}, writeConstraints = true) {
|
|
321
354
|
Object.keys(updates).forEach((key) => {
|
|
322
355
|
if (updates[key] === null && granuleInvalidNullFields.includes(key)) {
|
|
323
|
-
throw new ValidationError(`Attempted
|
|
356
|
+
throw new ValidationError(`Attempted Elasticsearch write with invalid key ${key} set to null. Please remove or change this field and retry`);
|
|
324
357
|
}
|
|
325
358
|
});
|
|
326
359
|
// If the granule exists in 'deletedgranule', delete it first before inserting the granule
|
|
@@ -766,5 +799,6 @@ module.exports = {
|
|
|
766
799
|
deleteGranule,
|
|
767
800
|
deleteExecution,
|
|
768
801
|
deleteReconciliationReport,
|
|
802
|
+
executionInvalidNullFields,
|
|
769
803
|
granuleInvalidNullFields,
|
|
770
804
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cumulus/es-client",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "16.0.2-alpha.0",
|
|
4
4
|
"description": "Utilities for working with Elasticsearch",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CUMULUS",
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"author": "Cumulus Authors",
|
|
31
31
|
"license": "Apache-2.0",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@cumulus/common": "
|
|
34
|
-
"@cumulus/errors": "
|
|
35
|
-
"@cumulus/logger": "
|
|
36
|
-
"@cumulus/message": "
|
|
33
|
+
"@cumulus/common": "16.0.2-alpha.0",
|
|
34
|
+
"@cumulus/errors": "16.0.2-alpha.0",
|
|
35
|
+
"@cumulus/logger": "16.0.2-alpha.0",
|
|
36
|
+
"@cumulus/message": "16.0.2-alpha.0",
|
|
37
37
|
"@elastic/elasticsearch": "^5.6.20",
|
|
38
38
|
"aws-elasticsearch-connector": "8.2.0",
|
|
39
39
|
"aws-sdk": "^2.585.0",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"p-limit": "^1.2.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@cumulus/aws-client": "
|
|
46
|
-
"@cumulus/test-data": "
|
|
45
|
+
"@cumulus/aws-client": "16.0.2-alpha.0",
|
|
46
|
+
"@cumulus/test-data": "16.0.2-alpha.0",
|
|
47
47
|
"p-each-series": "^2.1.0"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "215833a8dbf46eff436099c9d056cf697df9903f"
|
|
50
50
|
}
|
package/search.js
CHANGED
|
@@ -23,6 +23,8 @@ const logDetails = {
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
const defaultIndexAlias = 'cumulus-alias';
|
|
26
|
+
const multipleRecordFoundString = 'More than one record was found!';
|
|
27
|
+
const recordNotFoundString = 'Record not found';
|
|
26
28
|
|
|
27
29
|
const getCredentials = () =>
|
|
28
30
|
new Promise((resolve, reject) => aws.config.getCredentials((err) => {
|
|
@@ -135,12 +137,6 @@ class BaseSearch {
|
|
|
135
137
|
this.frm = (page - 1) * this.size;
|
|
136
138
|
this.page = Number.parseInt((params.skip) ? params.skip : page, 10);
|
|
137
139
|
this.index = index || defaultIndexAlias;
|
|
138
|
-
|
|
139
|
-
if (this.type === process.env.CollectionsTable) {
|
|
140
|
-
this.hash = 'collectionName';
|
|
141
|
-
} else if (this.type === process.env.PdrsTable) {
|
|
142
|
-
this.hash = 'pdrName';
|
|
143
|
-
}
|
|
144
140
|
}
|
|
145
141
|
|
|
146
142
|
_buildSearch() {
|
|
@@ -234,10 +230,10 @@ class BaseSearch {
|
|
|
234
230
|
}).then((response) => response.body);
|
|
235
231
|
|
|
236
232
|
if (result.hits.total > 1) {
|
|
237
|
-
return { detail:
|
|
233
|
+
return { detail: multipleRecordFoundString };
|
|
238
234
|
}
|
|
239
235
|
if (result.hits.total === 0) {
|
|
240
|
-
return { detail:
|
|
236
|
+
return { detail: recordNotFoundString };
|
|
241
237
|
}
|
|
242
238
|
|
|
243
239
|
const resp = result.hits.hits[0]._source;
|
|
@@ -247,76 +243,7 @@ class BaseSearch {
|
|
|
247
243
|
|
|
248
244
|
async exists(id, parentId) {
|
|
249
245
|
const response = await this.get(id, parentId);
|
|
250
|
-
return response.detail !==
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
async granulesStats(key, value) {
|
|
254
|
-
const body = {
|
|
255
|
-
query: {
|
|
256
|
-
term: {
|
|
257
|
-
[`${key}.keyword`]: value,
|
|
258
|
-
},
|
|
259
|
-
},
|
|
260
|
-
aggs: {
|
|
261
|
-
statusCount: {
|
|
262
|
-
terms: {
|
|
263
|
-
field: 'status.keyword',
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
|
-
averageDuration: {
|
|
267
|
-
avg: {
|
|
268
|
-
field: 'duration',
|
|
269
|
-
},
|
|
270
|
-
},
|
|
271
|
-
granulesCount: {
|
|
272
|
-
value_count: {
|
|
273
|
-
field: 'granuleId.keyword',
|
|
274
|
-
},
|
|
275
|
-
},
|
|
276
|
-
},
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
const ag = await this.client.search({
|
|
280
|
-
index: this.index,
|
|
281
|
-
type: process.env.GranulesTable,
|
|
282
|
-
body: body,
|
|
283
|
-
size: 0,
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
const status = {
|
|
287
|
-
failed: 0,
|
|
288
|
-
ingesting: 0,
|
|
289
|
-
processing: 0,
|
|
290
|
-
archiving: 0,
|
|
291
|
-
cmr: 0,
|
|
292
|
-
completed: 0,
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
const item = ag.body.aggregations;
|
|
296
|
-
|
|
297
|
-
const newObj = {
|
|
298
|
-
averageDuration: item.averageDuration.value,
|
|
299
|
-
granules: item.granulesCount.value,
|
|
300
|
-
granulesStatus: { ...status },
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
item.statusCount.buckets.forEach((b) => {
|
|
304
|
-
newObj.granulesStatus[b.key] = b.doc_count;
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
if (newObj.granules > 0) {
|
|
308
|
-
newObj.progress = (
|
|
309
|
-
(
|
|
310
|
-
(newObj.granulesStatus.completed + newObj.granulesStatus.failed)
|
|
311
|
-
/ newObj.granules
|
|
312
|
-
)
|
|
313
|
-
* 100
|
|
314
|
-
);
|
|
315
|
-
} else {
|
|
316
|
-
newObj.progress = 0;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
return newObj;
|
|
246
|
+
return response.detail !== recordNotFoundString;
|
|
320
247
|
}
|
|
321
248
|
|
|
322
249
|
async query(searchParamsOverride) {
|
|
@@ -378,5 +305,7 @@ module.exports = {
|
|
|
378
305
|
BaseSearch,
|
|
379
306
|
Search,
|
|
380
307
|
defaultIndexAlias,
|
|
308
|
+
multipleRecordFoundString,
|
|
309
|
+
recordNotFoundString,
|
|
381
310
|
getLocalEsHost,
|
|
382
311
|
};
|