@terascope/elasticsearch-api 3.0.1 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +79 -56
- package/package.json +2 -2
- package/test/api-spec.js +1 -1
- package/types/index.d.ts +4 -0
package/index.js
CHANGED
|
@@ -23,6 +23,8 @@ const {
|
|
|
23
23
|
getTypeOf,
|
|
24
24
|
isProd
|
|
25
25
|
} = require('@terascope/utils');
|
|
26
|
+
const { ElasticsearchDistribution } = require('@terascope/types');
|
|
27
|
+
|
|
26
28
|
const { inspect } = require('util');
|
|
27
29
|
|
|
28
30
|
const DOCUMENT_EXISTS = 409;
|
|
@@ -73,8 +75,7 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
function search(query) {
|
|
76
|
-
|
|
77
|
-
if (esVersion >= 7) {
|
|
78
|
+
if (!isElasticsearch6()) {
|
|
78
79
|
if (query._sourceExclude) {
|
|
79
80
|
query._sourceExcludes = query._sourceExclude.slice();
|
|
80
81
|
delete query._sourceExclude;
|
|
@@ -228,31 +229,29 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
228
229
|
);
|
|
229
230
|
return Promise.resolve(true);
|
|
230
231
|
}
|
|
231
|
-
return client.cluster.stats({}).then((data) => {
|
|
232
|
-
if (!_checkVersion(data.nodes.versions[0])) {
|
|
233
|
-
return Promise.resolve();
|
|
234
|
-
}
|
|
235
|
-
return client.indices
|
|
236
|
-
.getSettings({})
|
|
237
|
-
.then((results) => {
|
|
238
|
-
const resultIndex = _verifyIndex(results, config.index);
|
|
239
|
-
if (resultIndex.found) {
|
|
240
|
-
resultIndex.indexWindowSize.forEach((ind) => {
|
|
241
|
-
logger.warn(
|
|
242
|
-
`max_result_window for index: ${ind.name} is set at ${ind.windowSize}. On very large indices it is possible that a slice can not be divided to stay below this limit. If that occurs an error will be thrown by Elasticsearch and the slice can not be processed. Increasing max_result_window in the Elasticsearch index settings will resolve the problem.`
|
|
243
|
-
);
|
|
244
|
-
});
|
|
245
|
-
} else {
|
|
246
|
-
const error = new TSError('index specified in reader does not exist', {
|
|
247
|
-
statusCode: 404,
|
|
248
|
-
});
|
|
249
|
-
return Promise.reject(error);
|
|
250
|
-
}
|
|
251
232
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
233
|
+
return client.indices
|
|
234
|
+
.getSettings({})
|
|
235
|
+
.then((results) => {
|
|
236
|
+
const settingsData = results.body && results.meta ? results.body : results;
|
|
237
|
+
const resultIndex = _verifyIndex(settingsData, config.index);
|
|
238
|
+
|
|
239
|
+
if (resultIndex.found) {
|
|
240
|
+
resultIndex.indexWindowSize.forEach((ind) => {
|
|
241
|
+
logger.warn(
|
|
242
|
+
`max_result_window for index: ${ind.name} is set at ${ind.windowSize}. On very large indices it is possible that a slice can not be divided to stay below this limit. If that occurs an error will be thrown by Elasticsearch and the slice can not be processed. Increasing max_result_window in the Elasticsearch index settings will resolve the problem.`
|
|
243
|
+
);
|
|
244
|
+
});
|
|
245
|
+
} else {
|
|
246
|
+
const error = new TSError('index specified in reader does not exist', {
|
|
247
|
+
statusCode: 404,
|
|
248
|
+
});
|
|
249
|
+
return Promise.reject(error);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return Promise.resolve();
|
|
253
|
+
})
|
|
254
|
+
.catch((err) => Promise.reject(new TSError(err)));
|
|
256
255
|
}
|
|
257
256
|
|
|
258
257
|
function putTemplate(template, name) {
|
|
@@ -340,7 +339,7 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
340
339
|
throw new Error(`Bulk send record is missing the action property${dbg}`);
|
|
341
340
|
}
|
|
342
341
|
|
|
343
|
-
if (
|
|
342
|
+
if (!isElasticsearch6()) {
|
|
344
343
|
const actionKey = getFirstKey(record.action);
|
|
345
344
|
const { _type, ...withoutTypeAction } = record.action[actionKey];
|
|
346
345
|
// if data is specified return both
|
|
@@ -357,10 +356,11 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
357
356
|
return record.data ? [record.action, record.data] : [record.action];
|
|
358
357
|
});
|
|
359
358
|
|
|
360
|
-
const
|
|
359
|
+
const response = await _clientRequest('bulk', { body });
|
|
360
|
+
const results = response.body ? response.body : response;
|
|
361
361
|
|
|
362
|
-
if (!
|
|
363
|
-
return
|
|
362
|
+
if (!results.errors) {
|
|
363
|
+
return results.items.reduce((c, item) => {
|
|
364
364
|
const [value] = Object.values(item);
|
|
365
365
|
// ignore non-successful status codes
|
|
366
366
|
if (value.status != null && value.status >= 400) return c;
|
|
@@ -370,7 +370,7 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
370
370
|
|
|
371
371
|
const {
|
|
372
372
|
retry, successful, error, reason
|
|
373
|
-
} = _filterRetryRecords(actionRecords,
|
|
373
|
+
} = _filterRetryRecords(actionRecords, results);
|
|
374
374
|
|
|
375
375
|
if (error) {
|
|
376
376
|
throw new Error(`bulk send error: ${reason}`);
|
|
@@ -631,14 +631,19 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
631
631
|
client
|
|
632
632
|
.search(queryParam)
|
|
633
633
|
.then((data) => {
|
|
634
|
-
const
|
|
634
|
+
const failuresReasons = [];
|
|
635
|
+
const results = data.body ? data.body : data;
|
|
636
|
+
const { failures, failed } = results._shards;
|
|
637
|
+
|
|
635
638
|
if (!failed) {
|
|
636
|
-
resolve(
|
|
639
|
+
resolve(results);
|
|
637
640
|
return;
|
|
638
641
|
}
|
|
639
642
|
|
|
643
|
+
failuresReasons.push(...failures);
|
|
644
|
+
|
|
640
645
|
const reasons = uniq(
|
|
641
|
-
flatten(
|
|
646
|
+
flatten(failuresReasons.map((shard) => shard.reason.type))
|
|
642
647
|
);
|
|
643
648
|
|
|
644
649
|
if (
|
|
@@ -665,13 +670,13 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
665
670
|
}
|
|
666
671
|
|
|
667
672
|
function _esV7adjustments(queryParam) {
|
|
668
|
-
if (
|
|
673
|
+
if (!isElasticsearch6()) {
|
|
669
674
|
queryParam.trackTotalHits = true;
|
|
670
675
|
}
|
|
671
676
|
}
|
|
672
677
|
|
|
673
678
|
function _adjustTypeForEs7(query) {
|
|
674
|
-
if (
|
|
679
|
+
if (!isElasticsearch6()) {
|
|
675
680
|
if (Array.isArray(query)) {
|
|
676
681
|
return _removeTypeFromBulkRequest(query);
|
|
677
682
|
}
|
|
@@ -682,7 +687,7 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
682
687
|
}
|
|
683
688
|
|
|
684
689
|
function _removeTypeFromBulkRequest(query) {
|
|
685
|
-
if (
|
|
690
|
+
if (isElasticsearch6()) return query;
|
|
686
691
|
|
|
687
692
|
return query.map((queryItem) => {
|
|
688
693
|
if (isSimpleObject(queryItem)) {
|
|
@@ -812,11 +817,6 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
812
817
|
};
|
|
813
818
|
}
|
|
814
819
|
|
|
815
|
-
function _checkVersion(str) {
|
|
816
|
-
const num = Number(str.replace(/\./g, ''));
|
|
817
|
-
return num >= 210;
|
|
818
|
-
}
|
|
819
|
-
|
|
820
820
|
function isAvailable(index, recordType) {
|
|
821
821
|
const query = {
|
|
822
822
|
index,
|
|
@@ -870,7 +870,7 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
870
870
|
});
|
|
871
871
|
});
|
|
872
872
|
}
|
|
873
|
-
|
|
873
|
+
// TODO: verifyClient needs to be checked with new client usage
|
|
874
874
|
/**
|
|
875
875
|
* Verify the state of the underlying es client.
|
|
876
876
|
* Will throw error if in fatal state, like the connection is closed.
|
|
@@ -894,16 +894,39 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
894
894
|
|
|
895
895
|
return true;
|
|
896
896
|
}
|
|
897
|
-
|
|
897
|
+
/** This is deprecated as an external api,
|
|
898
|
+
* please use getClientMetadata
|
|
899
|
+
* */
|
|
898
900
|
function getESVersion() {
|
|
899
|
-
const
|
|
901
|
+
const newClientVersion = get(client, '__meta.version');
|
|
902
|
+
const esVersion = newClientVersion || get(client, 'transport._config.apiVersion', '6.5');
|
|
903
|
+
|
|
900
904
|
if (esVersion && isString(esVersion)) {
|
|
901
905
|
const [majorVersion] = esVersion.split('.');
|
|
902
906
|
return toNumber(majorVersion);
|
|
903
907
|
}
|
|
908
|
+
|
|
904
909
|
return 6;
|
|
905
910
|
}
|
|
906
911
|
|
|
912
|
+
function getClientMetadata() {
|
|
913
|
+
const newClientVersion = get(client, '__meta.version');
|
|
914
|
+
const esVersion = newClientVersion || get(client, 'transport._config.apiVersion', '6.5');
|
|
915
|
+
const distribution = get(client, '__meta.distribution', ElasticsearchDistribution.elasticsearch);
|
|
916
|
+
|
|
917
|
+
return {
|
|
918
|
+
distribution,
|
|
919
|
+
version: esVersion
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function isElasticsearch6() {
|
|
924
|
+
const { distribution, version: esVersion } = getClientMetadata();
|
|
925
|
+
const parsedVersion = toNumber(esVersion.split('.', 1)[0]);
|
|
926
|
+
|
|
927
|
+
return distribution === ElasticsearchDistribution.elasticsearch && parsedVersion === 6;
|
|
928
|
+
}
|
|
929
|
+
|
|
907
930
|
function _fixMappingRequest(_params, isTemplate) {
|
|
908
931
|
if (!_params || !_params.body) {
|
|
909
932
|
throw new Error('Invalid mapping request');
|
|
@@ -911,17 +934,14 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
911
934
|
const params = cloneDeep(_params);
|
|
912
935
|
const defaultParams = {};
|
|
913
936
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
if (isTemplate) {
|
|
918
|
-
params.body.index_patterns = castArray(params.body.template).slice();
|
|
919
|
-
}
|
|
920
|
-
delete params.body.template;
|
|
937
|
+
if (params.body.template != null) {
|
|
938
|
+
if (isTemplate && params.body.index_patterns == null) {
|
|
939
|
+
params.body.index_patterns = castArray(params.body.template).slice();
|
|
921
940
|
}
|
|
941
|
+
delete params.body.template;
|
|
922
942
|
}
|
|
923
943
|
|
|
924
|
-
if (
|
|
944
|
+
if (!isElasticsearch6()) {
|
|
925
945
|
const typeMappings = get(params.body, 'mappings', {});
|
|
926
946
|
if (typeMappings.properties) {
|
|
927
947
|
defaultParams.includeTypeName = false;
|
|
@@ -935,6 +955,7 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
935
955
|
});
|
|
936
956
|
}
|
|
937
957
|
}
|
|
958
|
+
|
|
938
959
|
return Object.assign({}, defaultParams, params);
|
|
939
960
|
}
|
|
940
961
|
|
|
@@ -1033,8 +1054,8 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
1033
1054
|
|
|
1034
1055
|
function _verifyMapping(query, configMapping, recordType) {
|
|
1035
1056
|
const params = Object.assign({}, query);
|
|
1036
|
-
|
|
1037
|
-
if (
|
|
1057
|
+
|
|
1058
|
+
if (!isElasticsearch6()) {
|
|
1038
1059
|
if (recordType) {
|
|
1039
1060
|
params.includeTypeName = true;
|
|
1040
1061
|
}
|
|
@@ -1202,12 +1223,14 @@ module.exports = function elasticsearchApi(client, logger, _opConfig) {
|
|
|
1202
1223
|
indexRecovery,
|
|
1203
1224
|
indexSetup,
|
|
1204
1225
|
verifyClient,
|
|
1205
|
-
getESVersion,
|
|
1206
1226
|
validateGeoParameters,
|
|
1227
|
+
getClientMetadata,
|
|
1228
|
+
isElasticsearch6,
|
|
1207
1229
|
// The APIs below are deprecated and should be removed.
|
|
1208
1230
|
index_exists: indexExists,
|
|
1209
1231
|
index_create: indexCreate,
|
|
1210
1232
|
index_refresh: indexRefresh,
|
|
1211
1233
|
index_recovery: indexRecovery,
|
|
1234
|
+
getESVersion,
|
|
1212
1235
|
};
|
|
1213
1236
|
};
|
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.1.1",
|
|
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": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"test:watch": "ts-scripts test --watch . --"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@terascope/utils": "^0.44.
|
|
21
|
+
"@terascope/utils": "^0.44.2",
|
|
22
22
|
"bluebird": "^3.7.2"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
package/test/api-spec.js
CHANGED
|
@@ -360,7 +360,7 @@ describe('elasticsearch-api', () => {
|
|
|
360
360
|
stats: () => Promise.resolve({ _nodes: {} })
|
|
361
361
|
},
|
|
362
362
|
cluster: {
|
|
363
|
-
stats: () => Promise.resolve({ nodes: { versions: ['
|
|
363
|
+
stats: () => Promise.resolve({ nodes: { versions: ['6.8.1'] } })
|
|
364
364
|
},
|
|
365
365
|
__testing: {
|
|
366
366
|
start: 100,
|
package/types/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import * as es from 'elasticsearch';
|
|
5
5
|
import { Logger } from '@terascope/utils';
|
|
6
|
+
import { ClientMetadata } from '@terascope/types'
|
|
6
7
|
|
|
7
8
|
export = elasticsearchAPI;
|
|
8
9
|
|
|
@@ -44,7 +45,10 @@ declare namespace elasticsearchAPI {
|
|
|
44
45
|
indexSetup: (clusterName, newIndex, migrantIndexName, mapping, recordType, clientName) => Promise<boolean>;
|
|
45
46
|
verifyClient: () => boolean;
|
|
46
47
|
validateGeoParameters: (opConfig: any) => any;
|
|
48
|
+
/** This api is deprecated, please use getClientMetadata */
|
|
47
49
|
getESVersion: () => number;
|
|
50
|
+
getClientMetadata: () => ClientMetadata;
|
|
51
|
+
isElasticsearch6: () => boolean
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
/**
|