Compare commits

...

35 Commits

Author SHA1 Message Date
51b1011e65 Bumped v5.6.22 2020-03-13 14:47:38 +01:00
5d0b419c37 [Backport 5.x] Secure json parsing (#1111)
* Safe json parsing

* Updated test

Co-authored-by: Tomas Della Vedova <delvedor@users.noreply.github.com>
2020-03-13 09:30:07 +01:00
7529cd8205 Skip flaky test 2020-03-10 14:30:10 +01:00
96e0f67279 Another ci matrix fix 2020-03-10 14:17:56 +01:00
f0aab30ab5 Rename matrix column 2020-03-10 14:02:05 +01:00
6bae993f51 Move back to the previous Jenkins configuration
The new iterations of the run-elasticsearch.sh script do not play well
with Elasticsearch ≤ 6, so it's better to move to the previous working
configuration.
2020-03-10 12:52:15 +01:00
43b3adbb00 Migrate to GitHub Actions (#1104)
* Create nodejs.yml

* Run only on push

* Renamed jobs

* Removed .travis.yml

* Split coverage job and cleanup

* Skip flaky test

* Code coverage reporting

* Renamed codecov file

* Added backport action

* Updated integration test configuration

* Removed unused dependencies

* Fixes
2020-03-10 09:53:00 +01:00
b676f084df Updates .ci folder to latest incarnation (#1103)
* Updates .ci folder to latest incarnation

The .ci folder cleanup some of its cleanup/wait routines so that they
can be reused. It also significantly reduced the available environment
variable toggles. In lieu of those toggles `run-repository.sh` can now
start multiple nodes using `NUMBER_OF_NODES`

* update certs
2020-03-10 09:52:30 +01:00
642282017c Updated LICENSE 2020-03-04 11:04:41 +01:00
7aebd6b980 Bumped v5.6.21 2020-02-04 10:54:18 +01:00
5a0bcfd83f Skip compression in case of empty string body (#1080)
* Fix #1069

* Updated test

* Updated test
2020-02-04 10:31:14 +01:00
e23cc725f6 Fix typo in NoLivingConnectionsError (#1045)
Co-authored-by: Tomas Della Vedova <delvedor@users.noreply.github.com>
2020-02-04 10:30:26 +01:00
59f7204183 Merge branch '5.x' of https://github.com/elastic/elasticsearch-js into 5.x 2020-01-15 18:26:15 +01:00
e4edfde4f7 Change TransportRequestOptions.ignore to number[] (#1053) 2020-01-15 18:26:11 +01:00
eec7439514 Return super in example Transport subclass (#980)
If called without a callback, the request method returns a Promise, so
when calling into super.request, the result should be returned to
maintain promise behavior.
2019-12-19 13:38:07 +01:00
6610cf3638 [DOCS] Add EOL notice. (#1020) 2019-12-09 16:07:57 -08:00
af4b4d4bb6 Updated run-test script 2019-10-28 17:08:14 +01:00
9313a08733 Updated run-test script 2019-10-28 16:59:51 +01:00
77f4cb6c02 Updated CI configuration 2019-10-28 16:38:34 +01:00
6c13dc4f7b Updated CI configuration 2019-10-28 16:22:37 +01:00
4143c4c759 Updated run-test script 2019-10-28 16:07:44 +01:00
0980a51cfe Updated CI configuration 2019-10-28 16:00:49 +01:00
e4da7c1dbd Updated jobs/defaults.yml to use the new job matrix 2019-10-28 14:48:46 +01:00
d04e1a479c New CI configuration (#996)
* Removed old files

* Updated README

* New CI configuration

* Updated run-test script
2019-10-28 14:48:39 +01:00
c0cf2437fd Move back to jjbb (#995)
* Removed Jenkins pipelines configuration

* Restored jjbb definitions
2019-10-28 14:47:15 +01:00
d798b2cd37 Backport 7fef37cf90 2019-09-18 08:48:31 +02:00
1927aa85f7 Fix inaccurate description sniffEndpoint (#959) 2019-09-16 17:43:58 +02:00
0716d3b4e2 Add body and querystring to RequestOptions (#957) 2019-09-11 11:30:56 +02:00
6dd9d2737c Updated cron job definition (#939)
* Updated cron job definition

* Update .ci/Jenkinsfile

Co-Authored-By: Victor Martinez <victormartinezrubio@gmail.com>
2019-08-13 10:56:02 +02:00
4170fc702b Updated .travis.yml (#938) 2019-08-09 14:08:55 +02:00
dfc0556c4b Fixed es-docker.sh 2019-08-09 12:32:43 +02:00
dbe22f284a Test only oss integration test 2019-08-09 12:17:25 +02:00
2615338008 Use Jenkins pipelines (#937) 2019-08-09 12:16:03 +02:00
c6ff0dee17 Disable travis cache (#929) 2019-08-02 11:50:26 +02:00
00fef28230 Updated error handling in bulk example (#927) 2019-08-01 12:21:20 +02:00
35 changed files with 1004 additions and 223 deletions

185
.ci/Jenkinsfile vendored Normal file
View File

@ -0,0 +1,185 @@
#!/usr/bin/env groovy
@Library('apm@current') _
def NODE_JS_VERSIONS = [8,10,12]
def nodeJsVersion = NODE_JS_VERSIONS[randomNumber(min: 0, max:2)]
pipeline {
agent {
label 'docker && immutable'
}
environment {
REPO = 'elasticsearch-js'
BASE_DIR = "src/github.com/elastic/${env.REPO}"
NODE_JS_DEFAULT_VERSION = "${nodeJsVersion}"
NODE_JS_VERSIONS = "${NODE_JS_VERSIONS.join(',')}"
HOME = "${env.WORKSPACE}"
npm_config_cache = 'npm-cache'
}
options {
timeout(time: 1, unit: 'HOURS')
buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '20', daysToKeepStr: '30'))
timestamps()
ansiColor('xterm')
disableResume()
durabilityHint('PERFORMANCE_OPTIMIZED')
}
triggers {
issueCommentTrigger('(?i).*(?:jenkins\\W+)?run\\W+(?:the\\W+)?tests(?:\\W+please)?.*')
// env.CHANGE_ID as a value in case of a commit or a pr, which means
// that we will have a daily cron job only for branches that don't have an active pr
cron(env.CHANGE_ID ? '' : '@daily')
}
stages {
stage('Checkout') {
options { skipDefaultCheckout() }
steps {
deleteDir()
gitCheckout(basedir: "${BASE_DIR}", githubNotifyFirstTimeContributor: false)
stash allowEmpty: true, name: 'source', useDefaultExcludes: false
}
}
stage('Install dependencies') {
options { skipDefaultCheckout() }
steps {
deleteDir()
unstash 'source'
script {
buildDockerImage(image: "node:${env.NODE_JS_DEFAULT_VERSION}-alpine").inside(){
dir("${BASE_DIR}"){
sh(label: 'System info', script: 'node --version; npm --version')
sh(label: 'Install dependencies', script: 'npm install')
}
}
}
stash allowEmpty: true, name: 'source-dependencies', useDefaultExcludes: false
}
}
stage('License check') {
options { skipDefaultCheckout() }
steps {
withGithubNotify(context: 'License check') {
deleteDir()
unstash 'source-dependencies'
script {
buildDockerImage(image: "node:${env.NODE_JS_DEFAULT_VERSION}-alpine").inside(){
dir("${BASE_DIR}"){
sh(label: 'Check production dependencies licenses', script: 'npm run license-checker')
}
}
}
}
}
}
stage('Linter') {
options { skipDefaultCheckout() }
steps {
withGithubNotify(context: 'Linter') {
deleteDir()
unstash 'source-dependencies'
script {
buildDockerImage(image: "node:${env.NODE_JS_DEFAULT_VERSION}-alpine").inside(){
dir("${BASE_DIR}"){
sh(label: 'Lint code with standardjs', script: 'npm run lint')
}
}
}
}
}
}
stage('Unit test') {
failFast true
options { skipDefaultCheckout() }
steps {
withGithubNotify(context: 'Unit test') {
script {
def versions = env.NODE_JS_VERSIONS.split(',')
def parallelTasks = [:]
versions.each{ version ->
parallelTasks["Node.js v${version}"] = buildUnitTest(version: version)
}
parallel(parallelTasks)
}
}
}
}
stage('Integration test') {
options { skipDefaultCheckout() }
environment {
TEST_ES_SERVER = 'http://elasticsearch:9200'
}
steps {
withGithubNotify(context: 'Integration test OSS') {
deleteDir()
unstash 'source-dependencies'
dir("${BASE_DIR}"){
// Sometimes the docker registry fails and has random timeouts
// this block will retry a doker image 3 times before to fail.
retry(3) {
sleep randomNumber(min: 5, max: 10)
sh(label: 'Start Elasticsearch', script: './scripts/es-docker.sh --detach')
}
}
script {
buildDockerImage(fromDockerfile: true).inside('--network=elastic'){
dir("${BASE_DIR}"){
sh(label: 'Integration test', script: 'npm run test:integration | tee test-integration.tap')
sh(label: 'Generating test reporting', script: './node_modules/.bin/tap-mocha-reporter xunit < test-integration.tap > junit-integration.xml')
}
}
}
sh(label: 'Stop Elasticsearch', script: 'docker kill $(docker ps -q)')
junit(allowEmptyResults: true, keepLongStdio: true, testResults: "${BASE_DIR}/**/junit-*.xml")
}
}
}
}
}
// Sometimes the docker registry fails and has random timeouts
// this function will retry a doker image 3 times before to fail.
def buildDockerImage(args) {
def image
retry(3) {
sleep randomNumber(min: 5, max: 10)
if (args.fromDockerfile == true) {
image = docker.build('nodejs-image', "--build-arg NODE_JS_VERSION=${env.NODE_JS_DEFAULT_VERSION} ${BASE_DIR}/.ci/docker")
} else {
image = docker.image(args.image)
// make sure we have the latest available from Docker Hub
image.pull()
}
}
return image
}
def buildUnitTest(args) {
return {
node('docker && immutable') {
deleteDir()
unstash 'source'
script {
buildDockerImage(image: "node:${args.version}-alpine").inside(){
dir("${BASE_DIR}"){
sh(label: 'Install dependencies', script: 'npm install')
sh(label: 'Run unit test', script: 'npm run test:unit | tee test-unit.tap')
sh(label: 'Run behavior test', script: 'npm run test:behavior | tee test-behavior.tap')
sh(label: 'Run types test', script: 'npm run test:types')
sh(label: 'Generating test reporting', script: './node_modules/.bin/tap-mocha-reporter xunit < test-unit.tap > junit-unit.xml; ./node_modules/.bin/tap-mocha-reporter xunit < test-behavior.tap > junit-behavior.xml')
}
}
}
junit(allowEmptyResults: true, keepLongStdio: true, testResults: "${BASE_DIR}/**/junit-*.xml")
}
}
}

View File

@ -1,20 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDSTCCAjGgAwIBAgIUIwN+0zglsexRKwE1RGHvlCcmrdwwDQYJKoZIhvcNAQEL
BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l
cmF0ZWQgQ0EwHhcNMTkwMjEzMDcyMjQwWhcNMjIwMjEyMDcyMjQwWjA0MTIwMAYD
VQQDEylFbGFzdGljIENlcnRpZmljYXRlIFRvb2wgQXV0b2dlbmVyYXRlZCBDQTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANILs0JO0e7x29zeVx21qalK
XKdX+AMlGJPH75wWO/Jq6YHtxt1wYIg762krOBXfG6JsFSOIwIv5VrzGGRGjSPt9
OXQyXrDDiQvsBT3rpzLNdDs7KMl2tZswwv7w9ujgud0cYnS1MOpn81rfPc73DvMg
xuhplofDx6fn3++PjVRU2FNiIVWyEoaxRjCeGPMBubKZYaYbQA6vYM4Z+ByG727B
AyAER3t7xmvYti/EoO2hv2HQk5zgcj/Oq3AJKhnt8LH8fnfm3TnYNM1htvXqhN05
vsvhvm2PHfnA5qLlSr/3W0aI/U/PqfsFDCgyRV097sMIaKkmavb0Ue7aQ7lgtp0C
AwEAAaNTMFEwHQYDVR0OBBYEFDRKlCMowWR1rwxE0d1lTEQe5O71MB8GA1UdIwQY
MBaAFDRKlCMowWR1rwxE0d1lTEQe5O71MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
hvcNAQELBQADggEBAKbCJ95EBpeuvF70KEt6QU70k/SH1NRvM9YzKryV0D975Jvu
HOSm9HgSTULeAUFZIa4oYyf3QUfVoI+2T/aQrfXA3gfrJWsHURkyNmiHOFAbYHqi
xA6i249G2GTEjc1+le/M2N2CcDKAmurW6vSGK4upXQbPd6KmnhHREX74zkWjnOa+
+tibbSSOCT4Tmja2DbBxAPuivU9IB1g/hIUmbYQqKffQrBJA0658tz6w63a/Q7xN
pCvvbSgiMZ6qcVIcJkBT2IooYie+ax45pQECHthgIUcQAzfmIfqlU0Qfl8rDgAmn
0c1o6HQjKGU2aVGgSRuaaiHaSZjbPIZVS51sOoI=
MIIDSjCCAjKgAwIBAgIVAJQLm8V2LcaCTHUcoIfO+KL63nG3MA0GCSqGSIb3DQEB
CwUAMDQxMjAwBgNVBAMTKUVsYXN0aWMgQ2VydGlmaWNhdGUgVG9vbCBBdXRvZ2Vu
ZXJhdGVkIENBMB4XDTIwMDIyNjA1NTA1N1oXDTIzMDIyNTA1NTA1N1owNDEyMDAG
A1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5lcmF0ZWQgQ0Ew
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYyajkPvGtUOE5M1OowQfB
kWVrWjo1+LIxzgCeRHp0YztLtdVJ0sk2xoSrt2uZpxcPepdyOseLTjFJex1D2yCR
AEniIqcFif4G72nDih2LlbhpUe/+/MTryj8ZTkFTzI+eMmbQi5FFMaH+kwufmdt/
5/w8YazO18SxxJUlzMqzfNUrhM8vvvVdxgboU7PWhk28wZHCMHQovomHmzclhRpF
N0FMktA98vHHeRjH19P7rNhifSd7hZzoH3H148HVAKoPgqnZ6vW2O2YfAWOP6ulq
cyszr57p8fS9B2wSdlWW7nVHU1JuKcYD67CxbBS23BeGFgCj4tiNrmxO8S5Yf85v
AgMBAAGjUzBRMB0GA1UdDgQWBBSWAlip9eoPmnG4p4OFZeOUBlAbNDAfBgNVHSME
GDAWgBSWAlip9eoPmnG4p4OFZeOUBlAbNDAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
SIb3DQEBCwUAA4IBAQA19qqrMTWl7YyId+LR/QIHDrP4jfxmrEELrAL58q5Epc1k
XxZLzOBSXoBfBrPdv+3XklWqXrZjKWfdkux0Xmjnl4qul+srrZDLJVZG3I7IrITh
AmQUmL9MuPiMnAcxoGZp1xpijtW8Qmd2qnambbljWfkuVaa4hcVRfrAX6TciIQ21
bS5aeLGrPqR14h30YzDp0RMmTujEa1o6ExN0+RSTkE9m89Q6WdM69az8JW7YkWqm
I+UCG3TcLd3TXmN1zNQkq4y2ObDK4Sxy/2p6yFPI1Fds5w/zLfBOvvPQY61vEqs8
SCCcQIe7f6NDpIRIBlty1C9IaEHj7edyHjF6rtYb
-----END CERTIFICATE-----

27
.ci/certs/ca.key Normal file
View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpgIBAAKCAQEA2Mmo5D7xrVDhOTNTqMEHwZFla1o6NfiyMc4AnkR6dGM7S7XV
SdLJNsaEq7drmacXD3qXcjrHi04xSXsdQ9sgkQBJ4iKnBYn+Bu9pw4odi5W4aVHv
/vzE68o/GU5BU8yPnjJm0IuRRTGh/pMLn5nbf+f8PGGsztfEscSVJczKs3zVK4TP
L771XcYG6FOz1oZNvMGRwjB0KL6Jh5s3JYUaRTdBTJLQPfLxx3kYx9fT+6zYYn0n
e4Wc6B9x9ePB1QCqD4Kp2er1tjtmHwFjj+rpanMrM6+e6fH0vQdsEnZVlu51R1NS
binGA+uwsWwUttwXhhYAo+LYja5sTvEuWH/ObwIDAQABAoIBAQC8QDGnMnmPdWJ+
13FYY3cmwel+FXXjFDk5QpgK15A2rUz6a8XxO1d7d1wR+U84uH4v9Na6XQyWjaoD
EyPQnuJiyAtgkZLUHoY244PGR5NsePEQlBSCKmGeF5w/j1LvP/2e9EmP4wKdQYJY
nLxFNcgEBCFnFbKIU5n8fKa/klybCrwlBokenyBro02tqH4LL7h1YMRRrl97fv1V
e/y/0WcMN+KnMglfz6haimBRV2yamCCHHmBImC+wzOgT/quqlxPfI+a3ScHxuA65
3QyCavaqlPh+T3lXnN/Na4UWqFtzMmwgJX2x1zM5qiln46/JoDiXtagvV43L3rNs
LhPRFeIRAoGBAPhEB7nNpEDNjIRUL6WpebWS9brKAVY7gYn7YQrKGhhCyftyaiBZ
zYgxPaJdqYXf+DmkWlANGoYiwEs40QwkR/FZrvO4+Xh3n3dgtl59ZmieuoQvDsG+
RYIj+TfBaqhewhZNMMl7dxz7DeyQhyRCdsvl3VqJM0RuOsIrzrhCIEItAoGBAN+K
lgWI7swDpOEaLmu+IWMkGImh1LswXoZqIgi/ywZ7htZjPzidOIeUsMi+lrYsKojG
uU3sBxASsf9kYXDnuUuUbGT5M/N2ipXERt7klUAA/f5sg1IKlTrabaN/HGs/uNtf
Efa8v/h2VyTurdPCJ17TNpbOMDwX1qGM62tyt2CLAoGBAIHCnP8iWq18QeuQTO8b
a3/Z9hHRL22w4H4MI6aOB6GSlxuTq6CJD4IVqo9IwSg17fnCy2l3z9s4IqWuZqUf
+XJOW8ELd2jdrT2qEOfGR1Z7UCVyqxXcq1vgDYx0zZh/HpalddB5dcJx/c8do2Ty
UEE2PcHqYB9uNcvzNbLc7RtpAoGBALbuU0yePUTI6qGnajuTcQEPpeDjhRHWSFRZ
ABcG1N8uMS66Mx9iUcNp462zgeP8iqY5caUZtMHreqxT+gWKK7F0+as7386pwElF
QPXgO18QMMqHBIQb0vlBjJ1SRPBjSiSDTVEML1DljvTTOX7kEJHh6HdKrmBO5b54
cqMQUo53AoGBAPVWRPUXCqlBz914xKna0ZUh2aesRBg5BvOoq9ey9c52EIU5PXL5
0Isk8sWSsvhl3tjDPBH5WuL5piKgnCTqkVbEHmWu9s1T57Mw6NuxlPMLBWvyv4c6
tB9brOxv0ui3qGMuBsBoDKbkNnwXyOXLyFg7O+H4l016A3mLQzJM+NGV
-----END RSA PRIVATE KEY-----

View File

@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDIjCCAgqgAwIBAgIUI4QU6jA1dYSCbdIA6oAb2TBEluowDQYJKoZIhvcNAQEL
BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l
cmF0ZWQgQ0EwHhcNMTkwMjEzMDcyMzEzWhcNMjIwMjEyMDcyMzEzWjATMREwDwYD
VQQDEwhpbnN0YW5jZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJeT
yOy6EAScZxrULKjHePciiz38grivCrhFFV+dThaRCcl3DhDzb9Eny5q5iEw3WvLQ
Rqmf01jncNIhaocTt66VqveXaMubbE8O0LcG6e4kpFO+JtnVF8JTARTc+ux/1uD6
hO1VG/HItM7WQrQxh4hfB2u1AX2YQtoqEtXXEC+UHWfl4QzuzXjBnKCkO/L9/6Tf
yNFQWXxKnIiTs8Xm9sEhhSCBJPlLTQu+MX4vR2Uwj5XZmflDUr+ZTenl9qYxL6b3
SWhh/qEl4GAj1+tS7ZZOxE0237mUh3IIFYSWSaMm8K2m/BYHkLNWL5B1dMic0lsv
osSoYrQuCef4HQMCitsCAwEAAaNNMEswHQYDVR0OBBYEFFMg4l1GLW8lYbwASY+r
YeWYRzIiMB8GA1UdIwQYMBaAFDRKlCMowWR1rwxE0d1lTEQe5O71MAkGA1UdEwQC
MAAwDQYJKoZIhvcNAQELBQADggEBAEQrgh1xALpumQTzsjxFRGque/vlKTgRs5Kh
xtgapr6wjIbdq7dagee+4yNOKzS5lGVXCgwrJlHESv9qY0uumT/33vK2uduJ7NAd
fR2ZzyBnhMX+mkYhmGrGYCTUMUIwOIQYa4Evis4W+LHmCIDG03l7gLHfdIBe9VMO
pDZum8f6ng0MM49s8/rXODNYKw8kFyUhnfChqMi/2yggb1uUIfKlJJIchkgYjE13
zuC+fjo029Pq1jeMIdxugLf/7I/8NiW1Yj9aCXevUXG1qzHFEuKAinBXYOZO/vWS
LaEqOhwrzNynwgGpYAr7Rfgv4AflltYIIav4PZT03P7fbyAAf8s=
MIIDIzCCAgugAwIBAgIVAMTO6uVx9dLox2t0lY4IcBKZXb5WMA0GCSqGSIb3DQEB
CwUAMDQxMjAwBgNVBAMTKUVsYXN0aWMgQ2VydGlmaWNhdGUgVG9vbCBBdXRvZ2Vu
ZXJhdGVkIENBMB4XDTIwMDIyNjA1NTA1OVoXDTIzMDIyNTA1NTA1OVowEzERMA8G
A1UEAxMIaW5zdGFuY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDK
YLTOikVENiN/qYupOsoXd7VYYnryyfCC/dK4FC2aozkbqjFzBdvPGAasoc4yEiH5
CGeXMgJuOjk1maqetmdIsw00j4oHJviYsnGXzxxS5swhD7spcW4Uk4V4tAUzrbfT
vW/2WW/yYCLe5phVb2chz0jL+WYb4bBmdfs/t6RtP9RqsplYAmVp3gZ6lt2YNtvE
k9gz0TVk3DuO1TquIClfRYUjuywS6xDSvxJ8Jl91EfDWM8QU+9F+YAtiv74xl2U3
P0wwMqNvMxf9/3ak3lTQGsgO4L6cwbKpVLMMzxSVunZz/sgl19xy3qHHz1Qr2MjJ
/2c2J7vahUL4NPRkjJClAgMBAAGjTTBLMB0GA1UdDgQWBBS2Wn8E2VZv4oenY+pR
O8G3zfQXhzAfBgNVHSMEGDAWgBSWAlip9eoPmnG4p4OFZeOUBlAbNDAJBgNVHRME
AjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAvwPvCiJJ6v9jYcyvYY8I3gP0oCwrylpRL
n91UlgRSHUmuAObyOoVN5518gSV/bTU2SDrstcLkLFxHvnfpoGJoxsQEHuGxwDRI
nhYNd62EKLerehNM/F9ILKmvTh8f6QPCzjUuExTXv+63l2Sr6dBS7FHsGs6UKUYO
llM/y9wMZ1LCuZuBg9RhtgpFXRSgDM9Z7Begu0d/BPX9od/qAeZg9Arz4rwUiCN4
IJOMEBEPi5q1tgeS0Fb1Grpqd0Uz5tZKtEHNKzLG+zSMmkneL62Nk2HsmEFZKwzg
u2pU42UaUE596G6o78s1aLn9ICcElPHTjiuZNSiyuu9IzvFDjGQw
-----END CERTIFICATE-----

View File

@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDVjCCAj6gAwIBAgIULh42yRefYlRRl1hvt055LrUH0HwwDQYJKoZIhvcNAQEL
BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l
cmF0ZWQgQ0EwHhcNMjAwMjI4MDMzNzIwWhcNMjMwMjI3MDMzNzIwWjATMREwDwYD
VQQDEwhpbnN0YW5jZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIUP
t267NN21z+3ukajej8eojSXwP6zHxy7CUAp+sQ7bTq2XCKxkYX3CW9ThcS4cV9mL
ayYdWEYnbEDGYPQDo7Wk3Ih5OEXTMZb/yNEx5D4S2lGMOS5bCDdYx6GvwCMG4jNx
aMktosaxpprAJiHh2oLgQk0hQc/a9JfMo6kJKtuhjxsxjxLwcOHhuaUD7NS0Pjop
CJkSYcrL+nnQPQjKe4uLhAbSyiX914h4QX0CJ0e4z1ccdDX2PFWTrwaIf//vQhCR
wP2YKdfjR0JB4oDAlu85GsIs2cFLPysM5ufuNZO4fCr8uOwloKI8zZ2HhlIfBEcY
Gcy4g9N/9epmxMXZlGcCAwEAAaOBgDB+MB0GA1UdDgQWBBRefYm8DHHDdkTPHhS1
HEUwTb2uiDAfBgNVHSMEGDAWgBSWAlip9eoPmnG4p4OFZeOUBlAbNDAxBgNVHREE
KjAogglsb2NhbGhvc3SHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCA2VzMTAJBgNV
HRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQC+pauqM2wJjQaHyHu+kIm59P4b/5Oj
IH1cYCQfMB7Y2UMLxp0ew+f7o7zzE2DA52YYFDWy6J5DVWtSBPyeFGgX+RH+aA+9
Iv4cc9QpAs6aFjncorHrzNOrWLgCHIeRAxTR0CAkeP2dUZfDBuMpRyP6rAsYzyLH
Rb3/BfYJSI5vxgt5Ke49Y/ljDKFJTyDmAVrHQ4JWrseYE1UZ2eDkBXeiRlYE/QtB
YsrUSqdL6zvFZyUcilxDUUabNcA+GgeGZ2lAEA90F8vwi62QwRXo3Iv1Hz+6xc43
nFofDK9D8/qkrUD9iuhpx1974QwPhwWyjn9RZRpbZA4ngRL+szdRXR4N
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAhQ+3brs03bXP7e6RqN6Px6iNJfA/rMfHLsJQCn6xDttOrZcI
rGRhfcJb1OFxLhxX2YtrJh1YRidsQMZg9AOjtaTciHk4RdMxlv/I0THkPhLaUYw5
LlsIN1jHoa/AIwbiM3FoyS2ixrGmmsAmIeHaguBCTSFBz9r0l8yjqQkq26GPGzGP
EvBw4eG5pQPs1LQ+OikImRJhysv6edA9CMp7i4uEBtLKJf3XiHhBfQInR7jPVxx0
NfY8VZOvBoh//+9CEJHA/Zgp1+NHQkHigMCW7zkawizZwUs/Kwzm5+41k7h8Kvy4
7CWgojzNnYeGUh8ERxgZzLiD03/16mbExdmUZwIDAQABAoIBAEwhjulLMVc9JEfV
PP/qv0cUOBYh3LzF3T/yq4slq7Z9YgnOJYdFM8aZgqNNjc09KEJvE5JOLeiNu9Ff
768Nugg+2HM5MCo7SN9FYCfZLOcbMFCCM2FDcnMAV9A512vzD08xryuT8dNPZ6yZ
DfhK2hQRrb2lrpr3gwSrcGRRu3THqvq7X1RIjpLV3teDMeP8rQPAlpj8fmP+kdVV
5y1ihiDIo87McihG9FMavJtBDXQkUEuVw6eIeir8L/zHHD/ZwhYjNHZGWbrB88sz
CkJkfWh/FlA63tCVdJzkmnERALLTVy9mR0Sq6sUlnFhFNO2BRdWgYLrcp9McfTJC
e8+WsSECgYEAuwQ3nAaFL0jqYu1AREyKT/f3WUenf2UsX7dwwV2/yFtQvkzW7ji4
uZLnfUnZBojtHf35dRo+hDgtvhZhgZNAuPPsbOl/EIMTcbChEqV/3CSTFlhLFM1d
hfM9PoM+Bt/pyUNabjD1sWM0X7WeUhzcddshY3S4daBsNsLuOzweRRcCgYEAtiSS
4qiiGafYsY7gOHuAlOhs/00+1uWIFEHKgoHM9vzCxDN3LCmBdynHk8ZE2TAdhw+l
7xpu6LUxKQDfGmVZa9Epg0kQmVq9c54oQP57pJ3tR+68++insEkfnaZH8jblfq2s
sSkFrY3pdS19edq60nuft64kswKRUUkamCXTXTECgYBdoSfiMpV9bekC7DsPtq5M
iR3KEgi2zEViCmomNTRuL+GF1NyKWdWJ+xVwcYd5MRZdvKimyyPfeGzWTUg14i42
KtEEWgZmkukqMz8BIeCYq6sENeIpIQQgqv3PjU+Bi5r1S4Y7wsFPNRakkD4aaB6r
1rCppWcwZMeoxwEUoO2aswKBgBdDIIdWJi3EpAY5SyWrkEZ0UMdiZC4p7nE33ddB
IJ5CtdU9BXFcc652ZYjX/58FaCABvZ2F8LhDu92SwOusGfmNIxIjWL1dO2jywA1c
8wmZKd7P/M7nbdMz45fMzs9+d1zwbWfK53C8+R4AC1BuwQF0zHc3BHTgVRLelUjt
O8thAoGAdO2gHIqEsZzTgbvLbsh52eVbumjfNGnrnEv1fjb+o+/wAol8dymcmzbL
bZCRzoyA0qwU9kdPFgX46H6so6o1tUM2GQtVFoT6kDnPv7EkLQK0C4cDh6OOHxDU
NPvr/9fHhQd9EDWDvS1JnVMAdKDO6ELp3SoKGGmCXR2QplnqWAk=
-----END RSA PRIVATE KEY-----

7
.ci/docker/Dockerfile Normal file
View File

@ -0,0 +1,7 @@
ARG NODE_JS_VERSION=10
FROM node:${NODE_JS_VERSION}-alpine
RUN apk --no-cache add git
# Create app directory
WORKDIR /usr/src/app

67
.ci/functions/cleanup.sh Normal file
View File

@ -0,0 +1,67 @@
#!/usr/bin/env bash
#
# Shared cleanup routines between different steps
#
# Please source .ci/functions/imports.sh as a whole not just this file
#
# Version 1.0.0
# - Initial version after refactor
function cleanup_volume {
if [[ "$(docker volume ls -q -f name=$1)" ]]; then
echo -e "\033[34;1mINFO:\033[0m Removing volume $1\033[0m"
(docker volume rm "$1") || true
fi
}
function container_running {
if [[ "$(docker ps -q -f name=$1)" ]]; then
return 0;
else return 1;
fi
}
function cleanup_node {
if container_running "$1"; then
echo -e "\033[34;1mINFO:\033[0m Removing container $1\033[0m"
(docker container rm --force --volumes "$1") || true
fi
if [[ -n "$1" ]]; then
echo -e "\033[34;1mINFO:\033[0m Removing volume $1-${suffix}-data\033[0m"
cleanup_volume "$1-${suffix}-data"
fi
}
function cleanup_network {
if [[ "$(docker network ls -q -f name=$1)" ]]; then
echo -e "\033[34;1mINFO:\033[0m Removing network $1\033[0m"
(docker network rm "$1") || true
fi
}
function cleanup_trap {
status=$?
set +x
if [[ "$DETACH" != "true" ]]; then
echo -e "\033[34;1mINFO:\033[0m clean the network if not detached (start and exit)\033[0m"
cleanup_all_in_network "$1"
fi
# status is 0 or SIGINT
if [[ "$status" == "0" || "$status" == "130" ]]; then
echo -e "\n\033[32;1mSUCCESS run-tests\033[0m"
exit 0
else
echo -e "\n\033[31;1mFAILURE during run-tests\033[0m"
exit ${status}
fi
};
function cleanup_all_in_network {
if [[ -z "$(docker network ls -q -f name="^$1\$")" ]]; then
echo -e "\033[34;1mINFO:\033[0m $1 is already deleted\033[0m"
return 0
fi
containers=$(docker network inspect -f '{{ range $key, $value := .Containers }}{{ printf "%s\n" .Name}}{{ end }}' $1)
while read -r container; do
cleanup_node "$container"
done <<< "$containers"
cleanup_network $1
echo -e "\033[32;1mSUCCESS:\033[0m Cleaned up and exiting\033[0m"
};

60
.ci/functions/imports.sh Normal file
View File

@ -0,0 +1,60 @@
#!/usr/bin/env bash
#
# Sets up all the common variables and imports relevant functions
#
# Version 1.0.1
# - Initial version after refactor
# - Validate STACK_VERSION asap
function require_stack_version() {
if [[ -z $STACK_VERSION ]]; then
echo -e "\033[31;1mERROR:\033[0m Required environment variable [STACK_VERSION] not set\033[0m"
exit 1
fi
}
require_stack_version
if [[ -z $es_node_name ]]; then
# only set these once
set -euo pipefail
export TEST_SUITE=${TEST_SUITE-oss}
export RUNSCRIPTS=${RUNSCRIPTS-}
export DETACH=${DETACH-false}
export CLEANUP=${CLEANUP-false}
export es_node_name=instance
export elastic_password=changeme
export elasticsearch_image=elasticsearch
export elasticsearch_url=https://elastic:${elastic_password}@${es_node_name}:9200
if [[ $TEST_SUITE != "xpack" ]]; then
export elasticsearch_image=elasticsearch-${TEST_SUITE}
export elasticsearch_url=http://${es_node_name}:9200
fi
export external_elasticsearch_url=${elasticsearch_url/$es_node_name/localhost}
export elasticsearch_container="${elasticsearch_image}:${STACK_VERSION}"
export suffix=rest-test
export moniker=$(echo "$elasticsearch_container" | tr -C "[:alnum:]" '-')
export network_name=${moniker}${suffix}
export ssl_cert="${script_path}/certs/testnode.crt"
export ssl_key="${script_path}/certs/testnode.key"
export ssl_ca="${script_path}/certs/ca.crt"
fi
export script_path=$(dirname $(realpath -s $0))
source $script_path/functions/cleanup.sh
source $script_path/functions/wait-for-container.sh
trap "cleanup_trap ${network_name}" EXIT
if [[ "$CLEANUP" == "true" ]]; then
cleanup_all_in_network $network_name
exit 0
fi
echo -e "\033[34;1mINFO:\033[0m Creating network $network_name if it does not exist already \033[0m"
docker network inspect "$network_name" > /dev/null 2>&1 || docker network create "$network_name"

View File

@ -0,0 +1,36 @@
#!/usr/bin/env bash
#
# Exposes a routine scripts can call to wait for a container if that container set up a health command
#
# Please source .ci/functions/imports.sh as a whole not just this file
#
# Version 1.0.1
# - Initial version after refactor
# - Make sure wait_for_contiainer is silent
function wait_for_container {
set +x
until ! container_running "$1" || (container_running "$1" && [[ "$(docker inspect -f "{{.State.Health.Status}}" ${1})" != "starting" ]]); do
echo ""
docker inspect -f "{{range .State.Health.Log}}{{.Output}}{{end}}" ${1}
echo -e "\033[34;1mINFO:\033[0m waiting for node $1 to be up\033[0m"
sleep 2;
done;
# Always show logs if the container is running, this is very useful both on CI as well as while developing
if container_running $1; then
docker logs $1
fi
if ! container_running $1 || [[ "$(docker inspect -f "{{.State.Health.Status}}" ${1})" != "healthy" ]]; then
cleanup_all_in_network $2
echo
echo -e "\033[31;1mERROR:\033[0m Failed to start $1 in detached mode beyond health checks\033[0m"
echo -e "\033[31;1mERROR:\033[0m dumped the docker log before shutting the node down\033[0m"
return 1
else
echo
echo -e "\033[32;1mSUCCESS:\033[0m Detached and healthy: ${1} on docker network: ${network_name}\033[0m"
return 0
fi
}

View File

@ -1,4 +1,4 @@
---
##### GLOBAL METADATA
@ -42,11 +42,15 @@
- axis:
type: yaml
filename: .ci/test-matrix.yml
name: ELASTICSEARCH_VERSION
name: STACK_VERSION
- axis:
type: yaml
filename: .ci/test-matrix.yml
name: NODE_JS_VERSION
- axis:
type: yaml
filename: .ci/test-matrix.yml
name: TEST_SUITE
yaml-strategy:
exclude-key: exclude
filename: .ci/test-matrix.yml

14
.ci/packer_cache.sh Normal file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env bash
source /usr/local/bin/bash_standard_lib.sh
DOCKER_IMAGES="node:12-alpine
node:10-alpine
node:8-alpine
"
for di in ${DOCKER_IMAGES}
do
(retry 2 docker pull "${di}") || echo "Error pulling ${di} Docker image, we continue"
done

View File

@ -8,58 +8,56 @@
#
# - $ELASTICSEARCH_VERSION
# - $NODE_JS_VERSION
# - $TEST_SUITE
#
set -eo pipefail
set +x
export VAULT_TOKEN=$(vault write -field=token auth/approle/login role_id="$VAULT_ROLE_ID" secret_id="$VAULT_SECRET_ID")
export CODECOV_TOKEN=$(vault read -field=token secret/clients-ci/elasticsearch-js/codecov)
unset VAULT_ROLE_ID VAULT_SECRET_ID VAULT_TOKEN
set -x
ELASTICSEARCH_VERSION=${STACK_VERSION}
function cleanup {
docker container rm --force --volumes elasticsearch-oss > /dev/null 2>&1 || true
docker container rm --force --volumes elasticsearch-js-oss > /dev/null 2>&1 || true
docker network rm esnet-oss > /dev/null
}
trap cleanup EXIT
# create network and volume
docker network create esnet-oss
# create client image
docker build \
--file .ci/Dockerfile \
--tag elastic/elasticsearch-js \
--build-arg NODE_JS_VERSION=${NODE_JS_VERSION} \
.
# run elasticsearch oss
NODE_NAME="es1"
repo=$(pwd)
testnodecrt="/.ci/certs/testnode.crt"
testnodekey="/.ci/certs/testnode.key"
cacrt="/.ci/certs/ca.crt"
elasticsearch_image="elasticsearch"
elasticsearch_url="https://elastic:changeme@${NODE_NAME}:9200"
if [[ $TEST_SUITE != "xpack" ]]; then
elasticsearch_image="elasticsearch"
elasticsearch_url="http://${NODE_NAME}:9200"
fi
docker network create esnet
docker run \
--rm \
--env "node.attr.testattr=test" \
--env "path.repo=/tmp" \
--env "repositories.url.allowed_urls=http://snapshot.*" \
--env "discovery.zen.ping.unicast.hosts=elasticsearch" \
--env "discovery.zen.ping.unicast.hosts=${NODE_NAME}" \
--env "xpack.security.enabled=false" \
--env "xpack.monitoring.enabled=false" \
--env "xpack.ml.enabled=false" \
--env ES_JAVA_OPTS="-Xms1g -Xmx1g" \
--network=esnet-oss \
--name=elasticsearch-oss \
--network=esnet \
--name=$NODE_NAME \
--detach \
docker.elastic.co/elasticsearch/elasticsearch:${ELASTICSEARCH_VERSION}
# run the client unit and oss integration test
docker run \
--network=esnet-oss \
--env "TEST_ES_SERVER=http://elasticsearch-oss:9200" \
--env "CODECOV_TOKEN" \
--network=esnet \
--env "TEST_ES_SERVER=${elasticsearch_url}" \
--volume $(pwd):/usr/src/app \
--volume /usr/src/app/node_modules \
--name elasticsearch-js-oss \
--name elasticsearch-js \
--rm \
elastic/elasticsearch-js \
npm run ci
npm run test:integration

View File

@ -1,5 +1,5 @@
---
ELASTICSEARCH_VERSION:
STACK_VERSION:
- 5.6.16
NODE_JS_VERSION:
@ -7,4 +7,7 @@ NODE_JS_VERSION:
- 10
- 8
TEST_SUITE:
- oss
exclude: ~

16
.github/workflows/backport.yml vendored Normal file
View File

@ -0,0 +1,16 @@
name: Backport
on:
pull_request:
types:
- closed
- labeled
jobs:
backport:
runs-on: ubuntu-latest
name: Backport
steps:
- name: Backport
uses: tibdex/backport@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

120
.github/workflows/nodejs.yml vendored Normal file
View File

@ -0,0 +1,120 @@
name: Node CI
on: [push]
jobs:
test:
name: Test
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [10.x, 12.x, 13.x]
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install
run: |
npm install
- name: Lint
run: |
npm run lint
- name: Unit test
run: |
npm run test:unit
- name: Behavior test
run: |
npm run test:behavior
- name: Type Definitions
run: |
npm run test:types
test-node-v8:
name: Test
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [8.x]
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install
run: |
npm install
- name: Test
run: |
npm run test:unit -- --node-arg=--harmony-async-iteration
code-coverage:
name: Code coverage
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install
run: |
npm install
- name: Code coverage
run: |
npm run test:coverage
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
file: ./coverage.lcov
fail_ci_if_error: true
license:
name: License check
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install
run: |
npm install
- name: License checker
run: |
npm run license-checker

View File

@ -1,22 +0,0 @@
language: node_js
node_js:
- "12"
- "10"
- "8"
os:
- windows
- linux
install:
- npm install
script:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then npm run license-checker; fi
- npm run test
notifications:
email:
on_success: never
on_failure: always

View File

@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright 2020 Elastic and contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@ -2,7 +2,7 @@
# Elasticsearch Node.js client
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) [![Build Status](https://clients-ci.elastic.co/job/elastic+elasticsearch-js+master/badge/icon)](https://clients-ci.elastic.co/job/elastic+elasticsearch-js+master/) [![codecov](https://codecov.io/gh/elastic/elasticsearch-js/branch/master/graph/badge.svg)](https://codecov.io/gh/elastic/elasticsearch-js) [![NPM downloads](https://img.shields.io/npm/dm/@elastic/elasticsearch.svg?style=flat)](https://www.npmjs.com/package/@elastic/elasticsearch)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) [![Build Status](https://clients-ci.elastic.co/buildStatus/icon?job=elastic%2Belasticsearch-js%2Bmaster)](https://clients-ci.elastic.co/view/Javascript/job/elastic+elasticsearch-js+master/) [![codecov](https://codecov.io/gh/elastic/elasticsearch-js/branch/master/graph/badge.svg)](https://codecov.io/gh/elastic/elasticsearch-js) [![NPM downloads](https://img.shields.io/npm/dm/@elastic/elasticsearch.svg?style=flat)](https://www.npmjs.com/package/@elastic/elasticsearch)
The official Node.js client for Elasticsearch.

View File

@ -3,7 +3,7 @@ comment: off
coverage:
precision: 2
round: down
range: "90...100"
range: "95...100"
status:
project: yes

View File

@ -64,7 +64,7 @@ _Default:_ `false`
_Default:_ `false`
|`sniffEndpoint`
|`string` - Max request timeout for each request. +
|`string` - Endpoint to ping during a sniff. +
_Default:_ `'_nodes/_all/http'`
|`sniffOnConnectionFault`
@ -204,7 +204,7 @@ Sometimes you just need to inject a little snippet of your code and then continu
class MyTransport extends Transport {
request (params, options, callback) {
// your code
super.request(params, options, callback)
return super.request(params, options, callback)
}
}
----

View File

@ -8,57 +8,83 @@ This can greatly increase the indexing speed.
----
'use strict'
require('array.prototype.flatmap').shim()
const { Client } = require('@elastic/elasticsearch')
const client = new Client({ node: 'http://localhost:9200' })
const client = new Client({
node: 'http://localhost:9200'
})
async function run () {
const { body: bulkResponse } = await client.bulk({
// here we are forcing an index refresh,
// otherwise we will not get any result
// in the consequent search
refresh: true,
body: [
// operation to perform
{ index: { _index: 'game-of-thrones' } },
// the document to index
{
character: 'Ned Stark',
quote: 'Winter is coming.'
},
{ index: { _index: 'game-of-thrones' } },
{
character: 'Daenerys Targaryen',
quote: 'I am the blood of the dragon.'
},
{ index: { _index: 'game-of-thrones' } },
{
character: 'Tyrion Lannister',
quote: 'A mind needs books like a sword needs a whetstone.'
}
]
})
if (bulkResponse.errors) {
console.log(bulkResponse)
process.exit(1)
}
// Let's search!
const { body } = await client.search({
index: 'game-of-thrones',
await client.indices.create({
index: 'tweets',
body: {
query: {
match: {
quote: 'winter'
mappings: {
properties: {
id: { type: 'integer' },
text: { type: 'text' },
user: { type: 'keyword' },
time: { type: 'date' }
}
}
}
})
}, { ignore: [400] })
console.log(body.hits.hits)
const dataset = [{
id: 1,
text: 'If I fall, don\'t bring me back.',
user: 'jon',
date: new Date()
}, {
id: 2,
text: 'Witer is coming',
user: 'ned',
date: new Date()
}, {
id: 3,
text: 'A Lannister always pays his debts.',
user: 'tyrion',
date: new Date()
}, {
id: 4,
text: 'I am the blood of the dragon.',
user: 'daenerys',
date: new Date()
}, {
id: 5, // change this value to a string to see the bulk response with errors
text: 'A girl is Arya Stark of Winterfell. And I\'m going home.',
user: 'arya',
date: new Date()
}]
const body = dataset.flatMap(doc => [{ index: { _index: 'tweets' } }, doc])
const { body: bulkResponse } = await client.bulk({ refresh: true, body })
if (bulkResponse.errors) {
const erroredDocuments = []
// The items array has the same order of the dataset we just indexed.
// The presence of the `error` key indicates that the operation
// that we did for the document has failed.
bulkResponse.items.forEach((action, i) => {
const operation = Object.keys(action)[0]
if (action[operation].error) {
erroredDocuments.push({
// If the status is 429 it means that you can retry the document,
// otherwise it's very likely a mapping error, and you should
// fix the document before to try it again.
status: action[operation].status,
error: action[operation].error,
operation: body[i * 2],
document: body[i * 2 + 1]
})
}
})
console.log(erroredDocuments)
}
const { body: count } = await client.count({ index: 'tweets' })
console.log(count)
}
run().catch(console.log)
----
----

10
docs/page_header.html Normal file
View File

@ -0,0 +1,10 @@
<p>
<strong>WARNING</strong>: Version 5.x has passed its
<a href="https://www.elastic.co/support/eol">EOL date</a>.
</p>
<p>
This documentation is no longer being maintained and may be removed.
If you are running this version, we strongly advise you to upgrade.
For the latest information, see the
<a href="../current/index.html">current release documentation</a>.
</p>

2
lib/Connection.d.ts vendored
View File

@ -23,6 +23,8 @@ interface ConnectionOptions {
interface RequestOptions extends http.ClientRequestArgs {
asStream?: boolean;
body?: any;
querystring?: string;
}
export interface AgentOptions {

View File

@ -356,9 +356,9 @@ class ConnectionPool {
url: new URL(address),
id: ids[i],
roles: Object.assign({
[Connection.roles.MASTER]: true,
[Connection.roles.DATA]: true,
[Connection.roles.INGEST]: true,
[Connection.roles.MASTER]: false,
[Connection.roles.DATA]: false,
[Connection.roles.INGEST]: false,
[Connection.roles.ML]: false
}, roles)
})

View File

@ -6,6 +6,7 @@
const { stringify } = require('querystring')
const debug = require('debug')('elasticsearch')
const sjson = require('secure-json-parse')
const { SerializationError, DeserializationError } = require('./errors')
class Serializer {
@ -22,7 +23,7 @@ class Serializer {
deserialize (json) {
debug('Deserializing', json)
try {
var object = JSON.parse(json)
var object = sjson.parse(json)
} catch (err) {
throw new DeserializationError(err.message)
}

2
lib/Transport.d.ts vendored
View File

@ -80,7 +80,7 @@ export interface TransportRequestParams {
}
export interface TransportRequestOptions {
ignore?: [number];
ignore?: number[];
requestTimeout?: number | string;
maxRetries?: number;
asStream?: boolean;

View File

@ -108,7 +108,7 @@ class Transport {
if (meta.aborted === true) return
meta.connection = this.getConnection({ requestId: meta.request.id })
if (meta.connection === null) {
return callback(new NoLivingConnectionsError('There are not living connections'), result)
return callback(new NoLivingConnectionsError('There are no living connections'), result)
}
// TODO: make this assignment FAST
@ -123,15 +123,17 @@ class Transport {
return callback(err, result)
}
}
headers['Content-Type'] = headers['Content-Type'] || 'application/json'
if (compression === 'gzip') {
if (isStream(params.body) === false) {
params.body = intoStream(params.body).pipe(createGzip())
} else {
params.body = params.body.pipe(createGzip())
if (params.body !== '') {
headers['Content-Type'] = headers['Content-Type'] || 'application/json'
if (compression === 'gzip') {
if (isStream(params.body) === false) {
params.body = intoStream(params.body).pipe(createGzip())
} else {
params.body = params.body.pipe(createGzip())
}
headers['Content-Encoding'] = compression
}
headers['Content-Encoding'] = compression
}
if (isStream(params.body) === false) {

View File

@ -4,7 +4,7 @@
"main": "index.js",
"types": "index.d.ts",
"homepage": "http://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html",
"version": "5.6.20",
"version": "5.6.22",
"keywords": [
"elasticsearch",
"elastic",
@ -20,13 +20,14 @@
"test:unit": "tap test/unit/*.test.js -t 300 --no-coverage",
"test:behavior": "tap test/behavior/*.test.js -t 300 --no-coverage",
"test:integration": "tap test/integration/index.js -T --no-coverage",
"test:integration:report": "npm run test:integration | tap-mocha-reporter xunit > $WORKSPACE/test-report-junit.xml",
"test:types": "tsc --project ./test/types/tsconfig.json",
"test:coverage": "nyc npm run test:unit && nyc report --reporter=text-lcov > coverage.lcov && codecov",
"test:coverage": "nyc tap test/unit/*.test.js test/behavior/*.test.js -t 300 && nyc report --reporter=text-lcov > coverage.lcov",
"lint": "standard",
"lint:fix": "standard --fix",
"ci": "npm run license-checker && npm test && npm run test:integration && npm run test:coverage",
"license-checker": "license-checker --production --onlyAllow='MIT;Apache-2.0;Apache1.1;ISC;BSD-3-Clause;BSD-2-Clause'"
"license-checker": "license-checker --production --onlyAllow='MIT;Apache-2.0;Apache1.1;ISC;BSD-3-Clause;BSD-2-Clause'",
"elasticsearch": "./scripts/es-docker.sh",
"elasticsearch:xpack": "./scripts/es-docker-platinum.sh"
},
"author": {
"name": "Tomas Della Vedova",
@ -38,7 +39,6 @@
},
"devDependencies": {
"@types/node": "^12.6.2",
"codecov": "^3.3.0",
"convert-hrtime": "^3.0.0",
"dedent": "^0.7.0",
"deepmerge": "^4.0.0",
@ -57,7 +57,6 @@
"standard": "^13.0.2",
"stoppable": "^1.1.0",
"tap": "^14.4.1",
"tap-mocha-reporter": "^4.0.1",
"typescript": "^3.4.5",
"workq": "^2.1.0"
},
@ -67,7 +66,8 @@
"into-stream": "^5.1.0",
"ms": "^2.1.1",
"once": "^1.4.0",
"pump": "^3.0.0"
"pump": "^3.0.0",
"secure-json-parse": "^2.1.0"
},
"license": "Apache-2.0",
"repository": {

View File

@ -6,31 +6,66 @@ testnodekey="/.ci/certs/testnode.key"
cacrt="/.ci/certs/ca.crt"
# pass `--clean` to reemove the old snapshot
if [ "$1" != "" ]; then
if [ "$1" == "--clean" ]; then
docker rmi $(docker images --format '{{.Repository}}:{{.Tag}}' | grep '8.0.0-SNAPSHOT')
fi
exec docker run \
--rm \
-e "node.attr.testattr=test" \
-e "path.repo=/tmp" \
-e "repositories.url.allowed_urls=http://snapshot.*" \
-e "discovery.type=single-node" \
-e "ES_JAVA_OPTS=-Xms1g -Xmx1g" \
-e "ELASTIC_PASSWORD=changeme" \
-e "xpack.security.enabled=true" \
-e "xpack.license.self_generated.type=trial" \
-e "xpack.security.http.ssl.enabled=true" \
-e "xpack.security.http.ssl.verification_mode=certificate" \
-e "xpack.security.http.ssl.key=certs/testnode.key" \
-e "xpack.security.http.ssl.certificate=certs/testnode.crt" \
-e "xpack.security.http.ssl.certificate_authorities=certs/ca.crt" \
-e "xpack.security.transport.ssl.enabled=true" \
-e "xpack.security.transport.ssl.key=certs/testnode.key" \
-e "xpack.security.transport.ssl.certificate=certs/testnode.crt" \
-e "xpack.security.transport.ssl.certificate_authorities=certs/ca.crt" \
-v "$repo$testnodecrt:/usr/share/elasticsearch/config/certs/testnode.crt" \
-v "$repo$testnodekey:/usr/share/elasticsearch/config/certs/testnode.key" \
-v "$repo$cacrt:/usr/share/elasticsearch/config/certs/ca.crt" \
-p 9200:9200 \
docker.elastic.co/elasticsearch/elasticsearch:5.6.16
# Create the 'elastic' network if doesn't exist
exec docker network ls | grep elastic > /dev/null || docker network create elastic > /dev/null
if [ "$1" == "--detach" ]; then
exec docker run \
--rm \
-e "node.attr.testattr=test" \
-e "path.repo=/tmp" \
-e "repositories.url.allowed_urls=http://snapshot.*" \
-e "discovery.type=single-node" \
-e "ES_JAVA_OPTS=-Xms1g -Xmx1g" \
-e "ELASTIC_PASSWORD=changeme" \
-e "xpack.security.enabled=true" \
-e "xpack.license.self_generated.type=trial" \
-e "xpack.security.http.ssl.enabled=true" \
-e "xpack.security.http.ssl.verification_mode=certificate" \
-e "xpack.security.http.ssl.key=certs/testnode.key" \
-e "xpack.security.http.ssl.certificate=certs/testnode.crt" \
-e "xpack.security.http.ssl.certificate_authorities=certs/ca.crt" \
-e "xpack.security.transport.ssl.enabled=true" \
-e "xpack.security.transport.ssl.key=certs/testnode.key" \
-e "xpack.security.transport.ssl.certificate=certs/testnode.crt" \
-e "xpack.security.transport.ssl.certificate_authorities=certs/ca.crt" \
-v "$repo$testnodecrt:/usr/share/elasticsearch/config/certs/testnode.crt" \
-v "$repo$testnodekey:/usr/share/elasticsearch/config/certs/testnode.key" \
-v "$repo$cacrt:/usr/share/elasticsearch/config/certs/ca.crt" \
-p 9200:9200 \
--detach \
--network=elastic \
--name=elasticsearch \
docker.elastic.co/elasticsearch/elasticsearch:5.6.16
else
exec docker run \
--rm \
-e "node.attr.testattr=test" \
-e "path.repo=/tmp" \
-e "repositories.url.allowed_urls=http://snapshot.*" \
-e "discovery.type=single-node" \
-e "ES_JAVA_OPTS=-Xms1g -Xmx1g" \
-e "ELASTIC_PASSWORD=changeme" \
-e "xpack.security.enabled=true" \
-e "xpack.license.self_generated.type=trial" \
-e "xpack.security.http.ssl.enabled=true" \
-e "xpack.security.http.ssl.verification_mode=certificate" \
-e "xpack.security.http.ssl.key=certs/testnode.key" \
-e "xpack.security.http.ssl.certificate=certs/testnode.crt" \
-e "xpack.security.http.ssl.certificate_authorities=certs/ca.crt" \
-e "xpack.security.transport.ssl.enabled=true" \
-e "xpack.security.transport.ssl.key=certs/testnode.key" \
-e "xpack.security.transport.ssl.certificate=certs/testnode.crt" \
-e "xpack.security.transport.ssl.certificate_authorities=certs/ca.crt" \
-v "$repo$testnodecrt:/usr/share/elasticsearch/config/certs/testnode.crt" \
-v "$repo$testnodekey:/usr/share/elasticsearch/config/certs/testnode.key" \
-v "$repo$cacrt:/usr/share/elasticsearch/config/certs/ca.crt" \
-p 9200:9200 \
--network=elastic \
--name=elasticsearch \
docker.elastic.co/elasticsearch/elasticsearch:5.6.16
fi

View File

@ -1,15 +1,44 @@
#!/bin/bash
exec docker run \
--rm \
-e "node.attr.testattr=test" \
-e "path.repo=/tmp" \
-e "repositories.url.allowed_urls=http://snapshot.*" \
-e "discovery.zen.ping.unicast.hosts=elasticsearch" \
-e "xpack.security.enabled=false" \
-e "xpack.monitoring.enabled=false" \
-e "xpack.ml.enabled=false" \
-p 9200:9200 \
--network=elastic \
--name=elasticsearch \
docker.elastic.co/elasticsearch/elasticsearch:5.6.16
# Images are cached locally, it may be needed
# to delete an old image and download again
# the latest snapshot.
# pass `--clean` to reemove the old snapshot
if [ "$1" == "--clean" ]; then
docker rmi $(docker images --format '{{.Repository}}:{{.Tag}}' | grep '8.0.0-SNAPSHOT')
fi
# Create the 'elastic' network if doesn't exist
exec docker network ls | grep elastic > /dev/null || docker network create elastic > /dev/null
if [ "$1" == "--detach" ]; then
exec docker run \
--rm \
-e "node.attr.testattr=test" \
-e "path.repo=/tmp" \
-e "repositories.url.allowed_urls=http://snapshot.*" \
-e "discovery.zen.ping.unicast.hosts=elasticsearch" \
-e "xpack.security.enabled=false" \
-e "xpack.monitoring.enabled=false" \
-e "xpack.ml.enabled=false" \
-p 9200:9200 \
--detach \
--network=elastic \
--name=elasticsearch \
docker.elastic.co/elasticsearch/elasticsearch:5.6.16
else
exec docker run \
--rm \
-e "node.attr.testattr=test" \
-e "path.repo=/tmp" \
-e "repositories.url.allowed_urls=http://snapshot.*" \
-e "discovery.zen.ping.unicast.hosts=elasticsearch" \
-e "xpack.security.enabled=false" \
-e "xpack.monitoring.enabled=false" \
-e "xpack.ml.enabled=false" \
-p 9200:9200 \
--network=elastic \
--name=elasticsearch \
docker.elastic.co/elasticsearch/elasticsearch:5.6.16
fi

View File

@ -111,7 +111,7 @@ test('Should handle hostnames in publish_address', t => {
})
})
test('Sniff interval', t => {
test('Sniff interval', { skip: 'Flaky on CI' }, t => {
t.plan(10)
buildCluster(({ nodes, shutdown, kill }) => {

View File

@ -34,7 +34,6 @@ test('Should emit a request event when a request is performed', t => {
body: '',
querystring: 'q=foo%3Abar',
headers: {
'Content-Type': 'application/json',
'Content-Length': '0'
}
},
@ -87,7 +86,6 @@ test('Should emit a response event in case of a successful response', t => {
body: '',
querystring: 'q=foo%3Abar',
headers: {
'Content-Type': 'application/json',
'Content-Length': '0'
}
},
@ -138,7 +136,6 @@ test('Should emit a response event with the error set', t => {
body: '',
querystring: 'q=foo%3Abar',
headers: {
'Content-Type': 'application/json',
'Content-Length': '0'
}
},

View File

@ -969,7 +969,7 @@ test('sniff', t => {
})
})
t.test('sniffInterval', t => {
t.test('sniffInterval', { skip: 'Flaky on CI' }, t => {
t.plan(9)
class CustomConnectionPool extends ConnectionPool {
@ -1865,6 +1865,55 @@ test('Compress request', t => {
}
})
t.test('Should skip the compression for empty strings/null/undefined', t => {
t.plan(9)
function handler (req, res) {
t.strictEqual(req.headers['content-encoding'], undefined)
t.strictEqual(req.headers['content-type'], undefined)
res.end()
}
buildServer(handler, ({ port }, server) => {
const pool = new ConnectionPool({ Connection })
pool.addConnection(`http://localhost:${port}`)
const transport = new Transport({
emit: () => {},
connectionPool: pool,
serializer: new Serializer(),
maxRetries: 3,
compression: 'gzip',
requestTimeout: 30000,
sniffInterval: false,
sniffOnStart: false
})
transport.request({
method: 'DELETE',
path: '/hello',
body: ''
}, (err, { body }) => {
t.error(err)
transport.request({
method: 'GET',
path: '/hello',
body: null
}, (err, { body }) => {
t.error(err)
transport.request({
method: 'GET',
path: '/hello',
body: undefined
}, (err, { body }) => {
t.error(err)
server.stop()
})
})
})
})
})
t.end()
})
@ -2160,3 +2209,71 @@ test('Should pass request params and options to generateRequestId', t => {
transport.request(params, options, t.error)
})
test('Secure json parsing', t => {
t.test('__proto__ protection', t => {
t.plan(2)
function handler (req, res) {
res.setHeader('Content-Type', 'application/json;utf=8')
res.end('{"__proto__":{"a":1}}')
}
buildServer(handler, ({ port }, server) => {
const pool = new ConnectionPool({ Connection })
pool.addConnection(`http://localhost:${port}`)
const transport = new Transport({
emit: () => {},
connectionPool: pool,
serializer: new Serializer(),
maxRetries: 3,
requestTimeout: 30000,
sniffInterval: false,
sniffOnStart: false
})
transport.request({
method: 'GET',
path: '/hello'
}, (err, { body }) => {
t.true(err instanceof DeserializationError)
t.is(err.message, 'Object contains forbidden prototype property')
server.stop()
})
})
})
t.test('constructor protection', t => {
t.plan(2)
function handler (req, res) {
res.setHeader('Content-Type', 'application/json;utf=8')
res.end('{"constructor":{"prototype":{"bar":"baz"}}}')
}
buildServer(handler, ({ port }, server) => {
const pool = new ConnectionPool({ Connection })
pool.addConnection(`http://localhost:${port}`)
const transport = new Transport({
emit: () => {},
connectionPool: pool,
serializer: new Serializer(),
maxRetries: 3,
requestTimeout: 30000,
sniffInterval: false,
sniffOnStart: false
})
transport.request({
method: 'GET',
path: '/hello'
}, (err, { body }) => {
t.true(err instanceof DeserializationError)
t.is(err.message, 'Object contains forbidden prototype property')
server.stop()
})
})
})
t.end()
})