Co-authored-by: Tomas Della Vedova <delvedor@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
ea2c8d2d4d
commit
28d8ff799e
@ -84,3 +84,17 @@ const client = new Client({
|
||||
Serializer: MySerializer
|
||||
})
|
||||
----
|
||||
|
||||
[discrete]
|
||||
==== Migrate to v8
|
||||
|
||||
The Node.js client can be configured to emit an HTTP header
|
||||
``Accept: application/vnd.elasticsearch+json; compatible-with=7``
|
||||
which signals to Elasticsearch that the client is requesting
|
||||
``7.x`` version of request and response bodies. This allows for
|
||||
upgrading from 7.x to 8.x version of Elasticsearch without upgrading
|
||||
everything at once. Elasticsearch should be upgraded first after
|
||||
the compatibility header is configured and clients should be upgraded
|
||||
second.
|
||||
To enable to setting, configure the environment variable
|
||||
``ELASTIC_CLIENT_APIVERSIONING`` to ``true``.
|
||||
|
||||
4
index.js
4
index.js
@ -116,6 +116,10 @@ class Client extends ESAPI {
|
||||
disablePrototypePoisoningProtection: false
|
||||
}, opts)
|
||||
|
||||
if (process.env.ELASTIC_CLIENT_APIVERSIONING === 'true') {
|
||||
options.headers = Object.assign({ accept: 'application/vnd.elasticsearch+json; compatible-with=7' }, options.headers)
|
||||
}
|
||||
|
||||
this[kInitialOptions] = options
|
||||
this[kExtensions] = []
|
||||
this.name = options.name
|
||||
|
||||
@ -38,6 +38,7 @@ 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 kApiVersioning = Symbol('api versioning')
|
||||
|
||||
class Transport {
|
||||
constructor (opts) {
|
||||
@ -64,6 +65,7 @@ class Transport {
|
||||
this.generateRequestId = opts.generateRequestId || generateRequestId()
|
||||
this.name = opts.name
|
||||
this.opaqueIdPrefix = opts.opaqueIdPrefix
|
||||
this[kApiVersioning] = process.env.ELASTIC_CLIENT_APIVERSIONING === 'true'
|
||||
|
||||
this.nodeFilter = opts.nodeFilter || defaultNodeFilter
|
||||
if (typeof opts.nodeSelector === 'function') {
|
||||
@ -295,7 +297,8 @@ class Transport {
|
||||
// - the request is not a HEAD request
|
||||
// - the payload is not an empty string
|
||||
if (result.headers['content-type'] !== undefined &&
|
||||
result.headers['content-type'].indexOf('application/json') > -1 &&
|
||||
(result.headers['content-type'].indexOf('application/json') > -1 ||
|
||||
result.headers['content-type'].indexOf('application/vnd.elasticsearch+json') > -1) &&
|
||||
isHead === false &&
|
||||
payload !== ''
|
||||
) {
|
||||
@ -369,7 +372,7 @@ class Transport {
|
||||
}
|
||||
|
||||
if (params.body !== '') {
|
||||
headers['content-type'] = headers['content-type'] || 'application/json'
|
||||
headers['content-type'] = headers['content-type'] || (this[kApiVersioning] ? 'application/vnd.elasticsearch+json; compatible-with=7' : 'application/json')
|
||||
}
|
||||
|
||||
// handle ndjson body
|
||||
@ -386,7 +389,7 @@ class Transport {
|
||||
params.body = params.bulkBody
|
||||
}
|
||||
if (params.body !== '') {
|
||||
headers['content-type'] = headers['content-type'] || 'application/x-ndjson'
|
||||
headers['content-type'] = headers['content-type'] || (this[kApiVersioning] ? 'application/vnd.elasticsearch+x-ndjson; compatible-with=7' : 'application/x-ndjson')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1422,6 +1422,56 @@ test('Disable prototype poisoning protection', t => {
|
||||
})
|
||||
})
|
||||
|
||||
test('API compatibility header (json)', t => {
|
||||
t.plan(4)
|
||||
|
||||
function handler (req, res) {
|
||||
t.equal(req.headers.accept, 'application/vnd.elasticsearch+json; compatible-with=7')
|
||||
t.equal(req.headers['content-type'], 'application/vnd.elasticsearch+json; compatible-with=7')
|
||||
res.setHeader('Content-Type', 'application/vnd.elasticsearch+json; compatible-with=7')
|
||||
res.end(JSON.stringify({ hello: 'world' }))
|
||||
}
|
||||
|
||||
buildServer(handler, ({ port }, server) => {
|
||||
process.env.ELASTIC_CLIENT_APIVERSIONING = 'true'
|
||||
const client = new Client({
|
||||
node: `http://localhost:${port}`
|
||||
})
|
||||
|
||||
client.index({ index: 'foo', body: {} }, (err, { body }) => {
|
||||
t.error(err)
|
||||
t.same(body, { hello: 'world' })
|
||||
server.stop()
|
||||
delete process.env.ELASTIC_CLIENT_APIVERSIONING
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('API compatibility header (x-ndjson)', t => {
|
||||
t.plan(4)
|
||||
|
||||
function handler (req, res) {
|
||||
t.equal(req.headers.accept, 'application/vnd.elasticsearch+json; compatible-with=7')
|
||||
t.equal(req.headers['content-type'], 'application/vnd.elasticsearch+x-ndjson; compatible-with=7')
|
||||
res.setHeader('Content-Type', 'application/vnd.elasticsearch+json; compatible-with=7')
|
||||
res.end(JSON.stringify({ hello: 'world' }))
|
||||
}
|
||||
|
||||
buildServer(handler, ({ port }, server) => {
|
||||
process.env.ELASTIC_CLIENT_APIVERSIONING = 'true'
|
||||
const client = new Client({
|
||||
node: `http://localhost:${port}`
|
||||
})
|
||||
|
||||
client.bulk({ index: 'foo', body: [{}, {}] }, (err, { body }) => {
|
||||
t.error(err)
|
||||
t.same(body, { hello: 'world' })
|
||||
server.stop()
|
||||
delete process.env.ELASTIC_CLIENT_APIVERSIONING
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Bearer auth', t => {
|
||||
t.plan(3)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user