@terascope/elasticsearch-api 3.1.1 → 3.2.2
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/index.js +22 -3
- package/package.json +15 -5
- package/test/bulk-send-limit-spec.js +43 -0
- package/test/helpers/config.js +22 -0
- package/test/helpers/data.js +10023 -0
- package/test/helpers/elasticsearch.js +130 -0
package/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// polyfill because opensearch has references to an api that won't exist
|
|
4
|
+
// on the client side, should be able to remove in the future
|
|
5
|
+
require('setimmediate');
|
|
6
|
+
|
|
3
7
|
const Promise = require('bluebird');
|
|
4
8
|
const {
|
|
5
9
|
isTest,
|
|
@@ -28,6 +32,7 @@ const { ElasticsearchDistribution } = require('@terascope/types');
|
|
|
28
32
|
const { inspect } = require('util');
|
|
29
33
|
|
|
30
34
|
const DOCUMENT_EXISTS = 409;
|
|
35
|
+
const TOO_MANY_REQUESTS = 429;
|
|
31
36
|
|
|
32
37
|
// Module to manage persistence in Elasticsearch.
|
|
33
38
|
// All functions in this module return promises that must be resolved to get the final result.
|
|
@@ -102,7 +107,10 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
102
107
|
|
|
103
108
|
function _runRequest() {
|
|
104
109
|
clientBase[endpoint](query)
|
|
105
|
-
.then(
|
|
110
|
+
.then((rawResponse) => {
|
|
111
|
+
const response = get(rawResponse, 'body', rawResponse);
|
|
112
|
+
resolve(response);
|
|
113
|
+
})
|
|
106
114
|
.catch(errHandler);
|
|
107
115
|
}
|
|
108
116
|
|
|
@@ -290,7 +298,7 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
290
298
|
continue;
|
|
291
299
|
}
|
|
292
300
|
|
|
293
|
-
if (item.error.type === 'es_rejected_execution_exception') {
|
|
301
|
+
if (item.status === TOO_MANY_REQUESTS || item.error.type === 'es_rejected_execution_exception') {
|
|
294
302
|
if (actionRecords[i] == null) {
|
|
295
303
|
// this error should not happen in production,
|
|
296
304
|
// only in tests where the bulk function is mocked
|
|
@@ -927,6 +935,13 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
927
935
|
return distribution === ElasticsearchDistribution.elasticsearch && parsedVersion === 6;
|
|
928
936
|
}
|
|
929
937
|
|
|
938
|
+
function isElasticsearch8() {
|
|
939
|
+
const { distribution, version: esVersion } = getClientMetadata();
|
|
940
|
+
const parsedVersion = toNumber(esVersion.split('.', 1)[0]);
|
|
941
|
+
|
|
942
|
+
return distribution === ElasticsearchDistribution.elasticsearch && parsedVersion === 8;
|
|
943
|
+
}
|
|
944
|
+
|
|
930
945
|
function _fixMappingRequest(_params, isTemplate) {
|
|
931
946
|
if (!_params || !_params.body) {
|
|
932
947
|
throw new Error('Invalid mapping request');
|
|
@@ -956,6 +971,10 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
956
971
|
}
|
|
957
972
|
}
|
|
958
973
|
|
|
974
|
+
if (isElasticsearch8(client)) {
|
|
975
|
+
delete defaultParams.includeTypeName;
|
|
976
|
+
}
|
|
977
|
+
|
|
959
978
|
return Object.assign({}, defaultParams, params);
|
|
960
979
|
}
|
|
961
980
|
|
|
@@ -1049,7 +1068,7 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
1049
1068
|
});
|
|
1050
1069
|
return Promise.reject(error);
|
|
1051
1070
|
});
|
|
1052
|
-
});
|
|
1071
|
+
}).catch((err) => Promise.reject(err));
|
|
1053
1072
|
}
|
|
1054
1073
|
|
|
1055
1074
|
function _verifyMapping(query, configMapping, recordType) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@terascope/elasticsearch-api",
|
|
3
3
|
"displayName": "Elasticsearch API",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.2.2",
|
|
5
5
|
"description": "Elasticsearch client api used across multiple services, handles retries and exponential backoff",
|
|
6
6
|
"homepage": "https://github.com/terascope/teraslice/tree/master/packages/elasticsearch-api#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -14,15 +14,25 @@
|
|
|
14
14
|
"typings": "types/index.d.ts",
|
|
15
15
|
"scripts": {
|
|
16
16
|
"test": "ts-scripts test . --",
|
|
17
|
+
"test:7": "ELASTICSEARCH_VERSION='7.9.3' yarn run test",
|
|
18
|
+
"test:8": "ELASTICSEARCH_VERSION='8.1.2' yarn run test",
|
|
17
19
|
"test:debug": "ts-scripts test --debug . --",
|
|
20
|
+
"test:legacy": "LEGACY_CLIENT=true yarn run test",
|
|
21
|
+
"test:opensearch": "TEST_OPENSEARCH='true' yarn run test",
|
|
18
22
|
"test:watch": "ts-scripts test --watch . --"
|
|
19
23
|
},
|
|
20
24
|
"dependencies": {
|
|
21
|
-
"@terascope/utils": "^0.44.
|
|
22
|
-
"bluebird": "^3.7.2"
|
|
25
|
+
"@terascope/utils": "^0.44.4",
|
|
26
|
+
"bluebird": "^3.7.2",
|
|
27
|
+
"setimmediate": "^1.0.5"
|
|
23
28
|
},
|
|
24
29
|
"devDependencies": {
|
|
25
|
-
"@
|
|
30
|
+
"@opensearch-project/opensearch": "^1.0.2",
|
|
31
|
+
"@types/elasticsearch": "^5.0.40",
|
|
32
|
+
"elasticsearch": "^15.4.1",
|
|
33
|
+
"elasticsearch6": "npm:@elastic/elasticsearch@^6.7.0",
|
|
34
|
+
"elasticsearch7": "npm:@elastic/elasticsearch@^7.0.0",
|
|
35
|
+
"elasticsearch8": "npm:@elastic/elasticsearch@^8.0.0"
|
|
26
36
|
},
|
|
27
37
|
"engines": {
|
|
28
38
|
"node": "^12.22.0 || >=14.17.0",
|
|
@@ -33,6 +43,6 @@
|
|
|
33
43
|
"registry": "https://registry.npmjs.org/"
|
|
34
44
|
},
|
|
35
45
|
"terascope": {
|
|
36
|
-
"testSuite": "
|
|
46
|
+
"testSuite": "restrained"
|
|
37
47
|
}
|
|
38
48
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { debugLogger, chunk, pMap } = require('@terascope/utils');
|
|
4
|
+
const elasticsearchAPI = require('../index');
|
|
5
|
+
const { data } = require('./helpers/data');
|
|
6
|
+
const { TEST_INDEX_PREFIX } = require('./helpers/config');
|
|
7
|
+
const {
|
|
8
|
+
makeClient, cleanupIndex,
|
|
9
|
+
waitForData, formatUploadData
|
|
10
|
+
} = require('./helpers/elasticsearch');
|
|
11
|
+
|
|
12
|
+
const THREE_MINUTES = 3 * 60 * 1000;
|
|
13
|
+
|
|
14
|
+
jest.setTimeout(THREE_MINUTES + 30000);
|
|
15
|
+
|
|
16
|
+
describe('bulkSend can work with congested queues', () => {
|
|
17
|
+
const logger = debugLogger('congested_test');
|
|
18
|
+
const index = `${TEST_INDEX_PREFIX}_congested_queues_`;
|
|
19
|
+
|
|
20
|
+
let client;
|
|
21
|
+
let api;
|
|
22
|
+
|
|
23
|
+
beforeAll(async () => {
|
|
24
|
+
client = await makeClient();
|
|
25
|
+
await cleanupIndex(client, index);
|
|
26
|
+
api = elasticsearchAPI(client, logger);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
afterAll(async () => {
|
|
30
|
+
await cleanupIndex(client, index);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('can get correct data even with congested queues', async () => {
|
|
34
|
+
const chunkedData = chunk(data, 50);
|
|
35
|
+
|
|
36
|
+
await pMap(chunkedData, async (cData) => {
|
|
37
|
+
const formattedData = formatUploadData(index, cData);
|
|
38
|
+
return api.bulkSend(formattedData);
|
|
39
|
+
}, { concurrency: 9 });
|
|
40
|
+
|
|
41
|
+
await waitForData(client, index, data.length, logger, THREE_MINUTES);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
TEST_INDEX_PREFIX = 'teratest_',
|
|
5
|
+
ELASTICSEARCH_HOST = 'http://localhost:9200',
|
|
6
|
+
ELASTICSEARCH_API_VERSION = '6.5',
|
|
7
|
+
ELASTICSEARCH_VERSION = '6.8.6',
|
|
8
|
+
OPENSEARCH_USER = 'admin',
|
|
9
|
+
OPENSEARCH_PASSWORD = 'admin',
|
|
10
|
+
OPENSEARCH_VERSION = '1.3.0',
|
|
11
|
+
RESTRAINED_OPENSEARCH_PORT = process.env.RESTRAINED_OPENSEARCH_PORT || '49206',
|
|
12
|
+
RESTRAINED_OPENSEARCH_HOST = `http://${OPENSEARCH_USER}:${OPENSEARCH_PASSWORD}@http://localhost:${RESTRAINED_OPENSEARCH_PORT}`,
|
|
13
|
+
} = process.env;
|
|
14
|
+
|
|
15
|
+
module.exports = {
|
|
16
|
+
TEST_INDEX_PREFIX,
|
|
17
|
+
ELASTICSEARCH_HOST,
|
|
18
|
+
ELASTICSEARCH_API_VERSION,
|
|
19
|
+
ELASTICSEARCH_VERSION,
|
|
20
|
+
RESTRAINED_OPENSEARCH_HOST,
|
|
21
|
+
OPENSEARCH_VERSION
|
|
22
|
+
};
|