-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API] Add CSV bulk indexing support to Kibana API #6844
Changes from 4 commits
40654d1
6ceca8b
19be188
602fff1
81d4865
89988b8
bfba35f
6dc9cc9
ab5e444
d50c452
ee16d41
bc65d95
417d8a3
b85952f
05b198a
08427ee
b34460a
475913d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ define(function (require) { | |
|
||
return function (bdd, scenarioManager, request) { | ||
const es = scenarioManager.client; | ||
bdd.describe('_bulk', function () { | ||
bdd.describe('_data', function () { | ||
|
||
bdd.beforeEach(function () { | ||
return es.indices.putTemplate({ | ||
|
@@ -27,31 +27,31 @@ define(function (require) { | |
}); | ||
|
||
bdd.it('should accept a multipart/form-data request with a csv file attached', function () { | ||
return request.post('/kibana/names/_bulk') | ||
return request.post('/kibana/names/_data') | ||
.attach('csv', 'test/unit/data/fake_names.csv') | ||
.expect(200); | ||
}); | ||
|
||
bdd.it('should also accept the raw csv data in the payload body', function () { | ||
var csvData = fs.readFileSync('test/unit/data/fake_names_big.csv', {encoding: 'utf8'}); | ||
|
||
return request.post('/kibana/names/_bulk') | ||
return request.post('/kibana/names/_data') | ||
.send(csvData) | ||
.expect(200); | ||
}); | ||
|
||
bdd.it('should return JSON results', function () { | ||
return request.post('/kibana/names/_bulk') | ||
return request.post('/kibana/names/_data') | ||
.attach('csv', 'test/unit/data/fake_names.csv') | ||
.expect('Content-Type', /json/) | ||
.expect(200); | ||
}); | ||
|
||
bdd.it('should index one document per row in the csv', function () { | ||
return request.post('/kibana/names/_bulk') | ||
return request.post('/kibana/names/_data') | ||
.attach('csv', 'test/unit/data/fake_names.csv') | ||
.expect(200) | ||
.then((bulkResponse) => { | ||
.then(() => { | ||
return es.indices.refresh() | ||
.then(() => { | ||
return es.count({ index: 'names' }) | ||
|
@@ -63,72 +63,72 @@ define(function (require) { | |
}); | ||
|
||
bdd.it('should stream a chunked response', function () { | ||
return request.post('/kibana/names/_bulk') | ||
return request.post('/kibana/names/_data') | ||
.attach('csv', 'test/unit/data/fake_names.csv') | ||
.expect('Transfer-Encoding', 'chunked') | ||
.expect(200); | ||
}); | ||
|
||
bdd.it('should respond with an array of one or more "result objects"', function () { | ||
return request.post('/kibana/names/_bulk') | ||
return request.post('/kibana/names/_data') | ||
.attach('csv', 'test/unit/data/fake_names_big.csv') | ||
.expect(200) | ||
.then((bulkResponse) => { | ||
expect(bulkResponse.body.length).to.be(14); | ||
.then((dataResponse) => { | ||
expect(dataResponse.body.length).to.be(14); | ||
}); | ||
}); | ||
|
||
bdd.describe('result objects', function () { | ||
|
||
bdd.it('should include a count of created documents', function () { | ||
return request.post('/kibana/names/_bulk') | ||
return request.post('/kibana/names/_data') | ||
.attach('csv', 'test/unit/data/fake_names.csv') | ||
.expect(200) | ||
.then((bulkResponse) => { | ||
expect(bulkResponse.body[0]).to.have.property('created'); | ||
expect(bulkResponse.body[0].created).to.be(100); | ||
.then((dataResponse) => { | ||
expect(dataResponse.body[0]).to.have.property('created'); | ||
expect(dataResponse.body[0].created).to.be(100); | ||
}); | ||
}); | ||
|
||
bdd.it('should report any indexing errors per document under an "errors.index" key', function () { | ||
return request.post('/kibana/names/_bulk') | ||
return request.post('/kibana/names/_data') | ||
.attach('csv', 'test/unit/data/fake_names_with_mapping_errors.csv') | ||
.expect(200) | ||
.then((bulkResponse) => { | ||
expect(bulkResponse.body[0]).to.have.property('created'); | ||
expect(bulkResponse.body[0].created).to.be(98); | ||
expect(bulkResponse.body[0]).to.have.property('errors'); | ||
expect(bulkResponse.body[0].errors).to.have.property('index'); | ||
expect(bulkResponse.body[0].errors.index.length).to.be(2); | ||
.then((dataResponse) => { | ||
expect(dataResponse.body[0]).to.have.property('created'); | ||
expect(dataResponse.body[0].created).to.be(98); | ||
expect(dataResponse.body[0]).to.have.property('errors'); | ||
expect(dataResponse.body[0].errors).to.have.property('index'); | ||
expect(dataResponse.body[0].errors.index.length).to.be(2); | ||
}); | ||
}); | ||
|
||
bdd.it('should report any csv parsing errors under an "errors.other" key', function () { | ||
return request.post('/kibana/names/_bulk') | ||
return request.post('/kibana/names/_data') | ||
.attach('csv', 'test/unit/data/fake_names_with_parse_errors.csv') | ||
.expect(200) | ||
.then((bulkResponse) => { | ||
.then((dataResponse) => { | ||
// parse errors immediately abort indexing | ||
expect(bulkResponse.body[0]).to.have.property('created'); | ||
expect(bulkResponse.body[0].created).to.be(0); | ||
expect(dataResponse.body[0]).to.have.property('created'); | ||
expect(dataResponse.body[0].created).to.be(0); | ||
|
||
expect(bulkResponse.body[0]).to.have.property('errors'); | ||
expect(bulkResponse.body[0].errors).to.have.property('other'); | ||
expect(bulkResponse.body[0].errors.other.length).to.be(1); | ||
expect(dataResponse.body[0]).to.have.property('errors'); | ||
expect(dataResponse.body[0].errors).to.have.property('other'); | ||
expect(dataResponse.body[0].errors.other.length).to.be(1); | ||
}); | ||
}); | ||
|
||
}); | ||
|
||
bdd.describe('optional parameters', function () { | ||
bdd.it('should accept a custom delimiter query string param for parsing the CSV', function () { | ||
return request.post('/kibana/names/_bulk?delimiter=|') | ||
return request.post('/kibana/names/_data?delimiter=|') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will the API handle the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would expect supertest (the request lib being used here) to handle the url encoding, so this should actually be testing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I don't think URL-encoding is working quite right (or I could be doing something wrong too). It works if I URL-encode
But it doesn't work if I use
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the problem is that you still have a comma instead of an ampersand in your header line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ugh, you're right. Sorry about that. I can confirm that URL-encoding the delimiter works as expected. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hah, no worries. Url encoding on the API side should really "just work" since Hapi handles all that. |
||
.attach('csv', 'test/unit/data/fake_names_pipe_delimited.csv') | ||
.expect(200) | ||
.then((bulkResponse) => { | ||
expect(bulkResponse.body[0]).to.have.property('created'); | ||
expect(bulkResponse.body[0].created).to.be(2); | ||
expect(bulkResponse.body[0]).to.not.have.property('errors'); | ||
.then((dataResponse) => { | ||
expect(dataResponse.body[0]).to.have.property('created'); | ||
expect(dataResponse.body[0].created).to.be(2); | ||
expect(dataResponse.body[0]).to.not.have.property('errors'); | ||
|
||
return es.indices.refresh(); | ||
}) | ||
|
@@ -160,7 +160,7 @@ define(function (require) { | |
} | ||
}) | ||
.then((res) => { | ||
return request.post('/kibana/names/_bulk?pipeline=true') | ||
return request.post('/kibana/names/_data?pipeline=true') | ||
.attach('csv', 'test/unit/data/fake_names.csv') | ||
.expect(200); | ||
}) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed this. The
|
could be passed in as%7C
because of URL encoding. Mind adding a test to make sure that works?