Compare commits

...

9 Commits

13 changed files with 252 additions and 65 deletions

View File

@ -1,6 +1,6 @@
---
STACK_VERSION:
- 7.x-SNAPSHOT
- 7.15.0-SNAPSHOT
NODE_JS_VERSION:
- 16

View File

@ -61,7 +61,7 @@ jobs:
- name: Runs Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 7.x-SNAPSHOT
stack-version: 7.15.0-SNAPSHOT
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
@ -93,7 +93,7 @@ jobs:
- name: Runs Elasticsearch
uses: elastic/elastic-github-actions/elasticsearch@master
with:
stack-version: 8.0.0-SNAPSHOT
stack-version: 7.15.0-SNAPSHOT
- name: Use Node.js 14.x
uses: actions/setup-node@v1

View File

@ -31,7 +31,7 @@ function NodesApi (transport, ConfigurationError) {
this[kConfigurationError] = ConfigurationError
}
NodesApi.prototype.clearMeteringArchive = function nodesClearMeteringArchiveApi (params, options, callback) {
NodesApi.prototype.clearRepositoriesMeteringArchive = function nodesClearRepositoriesMeteringArchiveApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)
// check required parameters
@ -68,7 +68,7 @@ NodesApi.prototype.clearMeteringArchive = function nodesClearMeteringArchiveApi
return this.transport.request(request, options, callback)
}
NodesApi.prototype.getMeteringInfo = function nodesGetMeteringInfoApi (params, options, callback) {
NodesApi.prototype.getRepositoriesMeteringInfo = function nodesGetRepositoriesMeteringInfoApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)
// check required parameters
@ -259,8 +259,8 @@ NodesApi.prototype.usage = function nodesUsageApi (params, options, callback) {
}
Object.defineProperties(NodesApi.prototype, {
clear_metering_archive: { get () { return this.clearMeteringArchive } },
get_metering_info: { get () { return this.getMeteringInfo } },
clear_repositories_metering_archive: { get () { return this.clearRepositoriesMeteringArchive } },
get_repositories_metering_info: { get () { return this.getRepositoriesMeteringInfo } },
hot_threads: { get () { return this.hotThreads } },
reload_secure_settings: { get () { return this.reloadSecureSettings } }
})

View File

@ -29,17 +29,18 @@ const snakeCase = { ignoreUnavailable: 'ignore_unavailable', expandWildcards: 'e
function openPointInTimeApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)
// check required parameters
if (params.index == null) {
const err = new this[kConfigurationError]('Missing required parameter: index')
return handleError(err, callback)
}
let { method, body, index, ...querystring } = params
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring)
let path = ''
if ((index) != null) {
if (method == null) method = 'POST'
path = '/' + encodeURIComponent(index) + '/' + '_pit'
} else {
if (method == null) method = 'POST'
path = '/' + '_pit'
}
// build request object
const request = {

View File

@ -1032,6 +1032,27 @@ SecurityApi.prototype.putUser = function securityPutUserApi (params, options, ca
return this.transport.request(request, options, callback)
}
SecurityApi.prototype.queryApiKeys = function securityQueryApiKeysApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)
let { method, body, ...querystring } = params
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring)
let path = ''
if (method == null) method = body == null ? 'GET' : 'POST'
path = '/' + '_security' + '/' + '_query' + '/' + 'api_key'
// build request object
const request = {
method,
path,
body: body || '',
querystring
}
return this.transport.request(request, options, callback)
}
SecurityApi.prototype.samlAuthenticate = function securitySamlAuthenticateApi (params, options, callback) {
;[params, options, callback] = normalizeArguments(params, options, callback)
@ -1228,6 +1249,7 @@ Object.defineProperties(SecurityApi.prototype, {
put_role: { get () { return this.putRole } },
put_role_mapping: { get () { return this.putRoleMapping } },
put_user: { get () { return this.putUser } },
query_api_keys: { get () { return this.queryApiKeys } },
saml_authenticate: { get () { return this.samlAuthenticate } },
saml_complete_logout: { get () { return this.samlCompleteLogout } },
saml_invalidate: { get () { return this.samlInvalidate } },

View File

@ -2025,12 +2025,12 @@ export interface Mtermvectors<T = RequestBody> extends Generic {
body?: T;
}
export interface NodesClearMeteringArchive extends Generic {
export interface NodesClearRepositoriesMeteringArchive extends Generic {
node_id: string | string[];
max_archive_version: number;
}
export interface NodesGetMeteringInfo extends Generic {
export interface NodesGetRepositoriesMeteringInfo extends Generic {
node_id: string | string[];
}
@ -2079,7 +2079,7 @@ export interface NodesUsage extends Generic {
}
export interface OpenPointInTime extends Generic {
index?: string | string[];
index: string | string[];
preference?: string;
routing?: string;
ignore_unavailable?: boolean;
@ -2476,6 +2476,10 @@ export interface SecurityPutUser<T = RequestBody> extends Generic {
body: T;
}
export interface SecurityQueryApiKeys<T = RequestBody> extends Generic {
body?: T;
}
export interface SecuritySamlAuthenticate<T = RequestBody> extends Generic {
body: T;
}

View File

@ -4132,8 +4132,8 @@ link:{ref}/indices-delete-index.html[Documentation] +
|`boolean` - Ignore if a wildcard expression resolves to no concrete indices (default: false)
|`expand_wildcards` or `expandWildcards`
|`'open' \| 'closed' \| 'hidden' \| 'none' \| 'all'` - Whether wildcard expressions should get expanded to open or closed indices (default: open) +
_Default:_ `open`
|`'open' \| 'closed' \| 'hidden' \| 'none' \| 'all'` - Whether wildcard expressions should get expanded to open, closed, or hidden indices +
_Default:_ `open,closed`
|===
@ -8369,11 +8369,11 @@ _Default:_ `true`
|===
[discrete]
=== nodes.clearMeteringArchive
=== nodes.clearRepositoriesMeteringArchive
*Stability:* experimental
[source,ts]
----
client.nodes.clearMeteringArchive({
client.nodes.clearRepositoriesMeteringArchive({
node_id: string | string[],
max_archive_version: number
})
@ -8390,11 +8390,11 @@ link:{ref}/clear-repositories-metering-archive-api.html[Documentation] +
|===
[discrete]
=== nodes.getMeteringInfo
=== nodes.getRepositoriesMeteringInfo
*Stability:* experimental
[source,ts]
----
client.nodes.getMeteringInfo({
client.nodes.getRepositoriesMeteringInfo({
node_id: string | string[]
})
----
@ -9256,9 +9256,9 @@ _Default:_ `5`
client.searchMvt({
index: string | string[],
field: string,
zoom: integer,
x: integer,
y: integer,
zoom: number,
x: number,
y: number,
exact_bounds: boolean,
extent: number,
grid_precision: number,
@ -9277,13 +9277,13 @@ link:{ref}/search-vector-tile-api.html[Documentation] +
|`string` - Field containing geospatial data to return
|`zoom`
|`integer` - Zoom level for the vector tile to search
|`number` - Zoom level for the vector tile to search
|`x`
|`integer` - X coordinate for the vector tile to search
|`number` - X coordinate for the vector tile to search
|`y`
|`integer` - Y coordinate for the vector tile to search
|`number` - Y coordinate for the vector tile to search
|`exact_bounds` or `exactBounds`
|`boolean` - If false, the meta layer's feature is the bounding box of the tile. If true, the meta layer's feature is a bounding box resulting from a `geo_bounds` aggregation.
@ -10250,6 +10250,23 @@ link:{ref}/security-api-put-user.html[Documentation] +
|===
[discrete]
=== security.queryApiKeys
[source,ts]
----
client.security.queryApiKeys({
body: object
})
----
link:{ref}/security-api-query-api-key.html[Documentation] +
[cols=2*]
|===
|`body`
|`object` - From, size, query, sort and search_after
|===
[discrete]
=== security.samlAuthenticate

40
index.d.ts vendored
View File

@ -1926,22 +1926,22 @@ declare class Client {
mtermvectors<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params: RequestParams.Mtermvectors<TRequestBody>, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
mtermvectors<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params: RequestParams.Mtermvectors<TRequestBody>, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
nodes: {
clear_metering_archive<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.NodesClearMeteringArchive, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
clear_metering_archive<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
clear_metering_archive<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesClearMeteringArchive, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
clear_metering_archive<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesClearMeteringArchive, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
clearMeteringArchive<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.NodesClearMeteringArchive, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
clearMeteringArchive<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
clearMeteringArchive<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesClearMeteringArchive, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
clearMeteringArchive<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesClearMeteringArchive, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
get_metering_info<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.NodesGetMeteringInfo, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
get_metering_info<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
get_metering_info<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesGetMeteringInfo, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
get_metering_info<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesGetMeteringInfo, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
getMeteringInfo<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.NodesGetMeteringInfo, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
getMeteringInfo<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
getMeteringInfo<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesGetMeteringInfo, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
getMeteringInfo<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesGetMeteringInfo, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
clear_repositories_metering_archive<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.NodesClearRepositoriesMeteringArchive, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
clear_repositories_metering_archive<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
clear_repositories_metering_archive<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesClearRepositoriesMeteringArchive, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
clear_repositories_metering_archive<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesClearRepositoriesMeteringArchive, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
clearRepositoriesMeteringArchive<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.NodesClearRepositoriesMeteringArchive, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
clearRepositoriesMeteringArchive<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
clearRepositoriesMeteringArchive<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesClearRepositoriesMeteringArchive, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
clearRepositoriesMeteringArchive<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesClearRepositoriesMeteringArchive, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
get_repositories_metering_info<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.NodesGetRepositoriesMeteringInfo, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
get_repositories_metering_info<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
get_repositories_metering_info<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesGetRepositoriesMeteringInfo, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
get_repositories_metering_info<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesGetRepositoriesMeteringInfo, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
getRepositoriesMeteringInfo<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.NodesGetRepositoriesMeteringInfo, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
getRepositoriesMeteringInfo<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
getRepositoriesMeteringInfo<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesGetRepositoriesMeteringInfo, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
getRepositoriesMeteringInfo<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesGetRepositoriesMeteringInfo, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
hot_threads<TResponse = Record<string, any>, TContext = Context>(params?: RequestParams.NodesHotThreads, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
hot_threads<TResponse = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
hot_threads<TResponse = Record<string, any>, TContext = Context>(params: RequestParams.NodesHotThreads, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
@ -2466,6 +2466,14 @@ declare class Client {
putUser<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
putUser<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params: RequestParams.SecurityPutUser<TRequestBody>, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
putUser<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params: RequestParams.SecurityPutUser<TRequestBody>, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
query_api_keys<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params?: RequestParams.SecurityQueryApiKeys<TRequestBody>, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
query_api_keys<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
query_api_keys<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params: RequestParams.SecurityQueryApiKeys<TRequestBody>, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
query_api_keys<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params: RequestParams.SecurityQueryApiKeys<TRequestBody>, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
queryApiKeys<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params?: RequestParams.SecurityQueryApiKeys<TRequestBody>, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
queryApiKeys<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
queryApiKeys<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params: RequestParams.SecurityQueryApiKeys<TRequestBody>, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
queryApiKeys<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params: RequestParams.SecurityQueryApiKeys<TRequestBody>, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>): TransportRequestCallback
saml_authenticate<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params?: RequestParams.SecuritySamlAuthenticate<TRequestBody>, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>
saml_authenticate<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(callback: callbackFn<TResponse, TContext>): TransportRequestCallback
saml_authenticate<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params: RequestParams.SecuritySamlAuthenticate<TRequestBody>, callback: callbackFn<TResponse, TContext>): TransportRequestCallback

View File

@ -323,9 +323,9 @@ function getAuth (node) {
function isHttpConnection (node) {
if (Array.isArray(node)) {
return node.some((n) => new URL(n).protocol === 'http:')
return node.some((n) => (typeof n === 'string' ? new URL(n).protocol : n.url.protocol) === 'http:')
} else {
return new URL(node).protocol === 'http:'
return (typeof node === 'string' ? new URL(node).protocol : node.url.protocol) === 'http:'
}
}

View File

@ -36,13 +36,13 @@ const {
const noop = () => {}
const productCheckEmitter = new EventEmitter()
const clientVersion = require('../package.json').version
const userAgent = `elasticsearch-js/${clientVersion} (${os.platform()} ${os.release()}-${os.arch()}; Node.js ${process.version})`
const MAX_BUFFER_LENGTH = buffer.constants.MAX_LENGTH
const MAX_STRING_LENGTH = buffer.constants.MAX_STRING_LENGTH
const kProductCheck = Symbol('product check')
const kApiVersioning = Symbol('api versioning')
const kEventEmitter = Symbol('event emitter')
class Transport {
constructor (opts) {
@ -71,6 +71,7 @@ class Transport {
this.opaqueIdPrefix = opts.opaqueIdPrefix
this[kProductCheck] = 0 // 0 = to be checked, 1 = checking, 2 = checked-ok, 3 checked-notok, 4 checked-nodefault
this[kApiVersioning] = process.env.ELASTIC_CLIENT_APIVERSIONING === 'true'
this[kEventEmitter] = new EventEmitter()
this.nodeFilter = opts.nodeFilter || defaultNodeFilter
if (typeof opts.nodeSelector === 'function') {
@ -182,6 +183,7 @@ class Transport {
const makeRequest = () => {
if (meta.aborted === true) {
this.emit('request', new RequestAbortedError(), result)
return process.nextTick(callback, new RequestAbortedError(), result)
}
meta.connection = this.getConnection({ requestId: meta.request.id })
@ -420,8 +422,6 @@ class Transport {
// handles request timeout
params.timeout = toMs(options.requestTimeout || this.requestTimeout)
if (options.asStream === true) params.asStream = true
meta.request.params = params
meta.request.options = options
// handle compression
if (params.body !== '' && params.body != null) {
@ -452,6 +452,8 @@ class Transport {
}
}
meta.request.params = params
meta.request.options = options
// still need to check the product or waiting for the check to finish
if (this[kProductCheck] === 0 || this[kProductCheck] === 1) {
// let pass info requests
@ -459,7 +461,7 @@ class Transport {
prepareRequest()
} else {
// wait for product check to finish
productCheckEmitter.once('product-check', (error, status) => {
this[kEventEmitter].once('product-check', (error, status) => {
if (status === false) {
const err = error || new ProductNotSupportedError(result)
if (this[kProductCheck] === 4) {
@ -559,49 +561,52 @@ class Transport {
debug('Product check failed', err)
if (err.statusCode === 401 || err.statusCode === 403) {
this[kProductCheck] = 2
process.emitWarning('The client is unable to verify that the server is Elasticsearch due to security privileges on the server side. Some functionality may not be compatible if the server is running an unsupported product.')
productCheckEmitter.emit('product-check', null, true)
process.emitWarning(
'The client is unable to verify that the server is Elasticsearch due to security privileges on the server side. Some functionality may not be compatible if the server is running an unsupported product.',
'ProductNotSupportedSecurityError'
)
this[kEventEmitter].emit('product-check', null, true)
} else {
this[kProductCheck] = 0
productCheckEmitter.emit('product-check', err, false)
this[kEventEmitter].emit('product-check', err, false)
}
} else {
debug('Checking elasticsearch version', result.body, result.headers)
if (result.body.version == null || typeof result.body.version.number !== 'string') {
debug('Can\'t access Elasticsearch version')
return productCheckEmitter.emit('product-check', null, false)
return this[kEventEmitter].emit('product-check', null, false)
}
const tagline = result.body.tagline
const version = result.body.version.number.split('.')
const major = Number(version[0])
const minor = Number(version[1])
if (major < 6) {
return productCheckEmitter.emit('product-check', null, false)
return this[kEventEmitter].emit('product-check', null, false)
} else if (major >= 6 && major < 7) {
if (tagline !== 'You Know, for Search') {
debug('Bad tagline')
return productCheckEmitter.emit('product-check', null, false)
return this[kEventEmitter].emit('product-check', null, false)
}
} else if (major === 7 && minor < 14) {
if (tagline !== 'You Know, for Search') {
debug('Bad tagline')
return productCheckEmitter.emit('product-check', null, false)
return this[kEventEmitter].emit('product-check', null, false)
}
if (result.body.version.build_flavor !== 'default') {
debug('Bad build_flavor')
this[kProductCheck] = 4
return productCheckEmitter.emit('product-check', null, false)
return this[kEventEmitter].emit('product-check', null, false)
}
} else {
if (result.headers['x-elastic-product'] !== 'Elasticsearch') {
debug('x-elastic-product not recognized')
return productCheckEmitter.emit('product-check', null, false)
return this[kEventEmitter].emit('product-check', null, false)
}
}
debug('Valid Elasticsearch distribution')
this[kProductCheck] = 2
productCheckEmitter.emit('product-check', null, true)
this[kEventEmitter].emit('product-check', null, true)
}
})
}

View File

@ -20,7 +20,7 @@
'use strict'
const { test } = require('tap')
const { Client } = require('../../')
const { Client, errors } = require('../../')
const {
connection: {
MockConnectionTimeout,
@ -470,7 +470,7 @@ test('Errors v6', t => {
})
test('Auth error - 401', t => {
t.plan(8)
t.plan(9)
const MockConnection = buildMockConnection({
onRequest (params) {
return {
@ -487,6 +487,7 @@ test('Auth error - 401', t => {
process.on('warning', onWarning)
function onWarning (warning) {
t.equal(warning.name, 'ProductNotSupportedSecurityError')
t.equal(warning.message, 'The client is unable to verify that the server is Elasticsearch due to security privileges on the server side. Some functionality may not be compatible if the server is running an unsupported product.')
}
@ -524,7 +525,7 @@ test('Auth error - 401', t => {
})
test('Auth error - 403', t => {
t.plan(8)
t.plan(9)
const MockConnection = buildMockConnection({
onRequest (params) {
return {
@ -541,6 +542,7 @@ test('Auth error - 403', t => {
process.on('warning', onWarning)
function onWarning (warning) {
t.equal(warning.name, 'ProductNotSupportedSecurityError')
t.equal(warning.message, 'The client is unable to verify that the server is Elasticsearch due to security privileges on the server side. Some functionality may not be compatible if the server is running an unsupported product.')
}
@ -1245,3 +1247,102 @@ test('No multiple checks with child clients', t => {
})
}, 100)
})
test('Observability events should have all the expected properties', t => {
t.plan(5)
const MockConnection = buildMockConnection({
onRequest (params) {
return {
statusCode: 200,
body: {
name: '1ef419078577',
cluster_name: 'docker-cluster',
cluster_uuid: 'cQ5pAMvRRTyEzObH4L5mTA',
tagline: 'You Know, for Search'
}
}
}
})
const client = new Client({
node: 'http://localhost:9200',
Connection: MockConnection
})
client.on('request', (e, event) => {
t.ok(event.meta.request.params)
t.ok(event.meta.request.options)
})
client.search({
index: 'foo',
body: {
query: {
match_all: {}
}
}
}, (err, result) => {
t.equal(err.message, 'The client noticed that the server is not Elasticsearch and we do not support this unknown product.')
})
})
test('Abort a request while running the product check', t => {
t.plan(4)
const MockConnection = buildMockConnection({
onRequest (params) {
return {
statusCode: 200,
headers: {
'x-elastic-product': 'Elasticsearch'
},
body: {
name: '1ef419078577',
cluster_name: 'docker-cluster',
cluster_uuid: 'cQ5pAMvRRTyEzObH4L5mTA',
version: {
number: '8.0.0-SNAPSHOT',
build_flavor: 'default',
build_type: 'docker',
build_hash: '5fb4c050958a6b0b6a70a6fb3e616d0e390eaac3',
build_date: '2021-07-10T01:45:02.136546168Z',
build_snapshot: true,
lucene_version: '8.9.0',
minimum_wire_compatibility_version: '7.15.0',
minimum_index_compatibility_version: '7.0.0'
},
tagline: 'You Know, for Search'
}
}
}
})
const client = new Client({
node: 'http://localhost:9200',
Connection: MockConnection
})
client.on('request', (err, event) => {
if (event.meta.request.params.path.includes('search')) {
t.ok(err instanceof errors.RequestAbortedError)
}
})
// the response event won't be executed for the search
client.on('response', (err, event) => {
t.error(err)
t.equal(event.meta.request.params.path, '/')
})
const req = client.search({
index: 'foo',
body: {
query: {
match_all: {}
}
}
}, (err, result) => {
t.ok(err instanceof errors.RequestAbortedError)
})
setImmediate(() => req.abort())
})

View File

@ -2,7 +2,6 @@
"name": "parcel-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"build": "parcel build index.js --no-source-maps"

View File

@ -1586,6 +1586,36 @@ test('caFingerprint can\'t be configured over http / 3', t => {
}
})
test('caFingerprint can\'t be configured over http / 4', t => {
t.plan(2)
try {
new Client({ // eslint-disable-line
node: { url: new URL('http://localhost:9200') },
caFingerprint: 'FO:OB:AR'
})
t.fail('shuld throw')
} catch (err) {
t.ok(err instanceof errors.ConfigurationError)
t.equal(err.message, 'You can\'t configure the caFingerprint with a http connection')
}
})
test('caFingerprint can\'t be configured over http / 5', t => {
t.plan(2)
try {
new Client({ // eslint-disable-line
nodes: [{ url: new URL('http://localhost:9200') }],
caFingerprint: 'FO:OB:AR'
})
t.fail('should throw')
} catch (err) {
t.ok(err instanceof errors.ConfigurationError)
t.equal(err.message, 'You can\'t configure the caFingerprint with a http connection')
}
})
test('Error body that is not a json', t => {
t.plan(5)