-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5183 from epixa/4342-preflight-field-stats
Create indexList via field stats for wildcard patterns
- Loading branch information
Showing
5 changed files
with
285 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
src/ui/public/index_patterns/__tests__/calculate_indices.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
describe('ui/index_patterns/_calculate_indices', () => { | ||
const _ = require('lodash'); | ||
const sinon = require('auto-release-sinon'); | ||
const expect = require('expect.js'); | ||
const ngMock = require('ngMock'); | ||
|
||
let Promise; | ||
let $rootScope; | ||
let calculateIndices; | ||
let error; | ||
let response; | ||
let transportRequest; | ||
let config; | ||
let constraints; | ||
|
||
beforeEach(ngMock.module('kibana', ($provide) => { | ||
error = undefined; | ||
response = { indices: { 'mock-*': 'irrelevant, is ignored' } }; | ||
transportRequest = sinon.spy((options, fn) => fn(error, response)); | ||
$provide.value('es', _.set({}, 'transport.request', transportRequest)); | ||
})); | ||
|
||
beforeEach(ngMock.inject((Private, $injector) => { | ||
$rootScope = $injector.get('$rootScope'); | ||
Promise = $injector.get('Promise'); | ||
calculateIndices = Private(require('ui/index_patterns/_calculate_indices')); | ||
})); | ||
|
||
describe('transport configuration', () => { | ||
it('is POST', () => { | ||
run(); | ||
expect(config.method).to.equal('POST'); | ||
}); | ||
it('uses pattern path for _field_stats', () => { | ||
run(); | ||
expect(config.path).to.equal('/wat-*-no/_field_stats'); | ||
}); | ||
it('has level indices', () => { | ||
run(); | ||
expect(config.query.level).to.equal('indices'); | ||
}); | ||
it('includes time field', () => { | ||
run(); | ||
expect(_.includes(config.body.fields, '@something')).to.be(true); | ||
}); | ||
it('no constraints by default', () => { | ||
run(); | ||
expect(_.size(constraints['@something'])).to.equal(0); | ||
}); | ||
|
||
context('when given start', () => { | ||
beforeEach(() => run({ start: '1234567890' })); | ||
it('includes min_value', () => { | ||
expect(constraints['@something']).to.have.property('min_value'); | ||
}); | ||
it('min_value is gte', () => { | ||
expect(constraints['@something'].min_value).to.have.property('gte'); | ||
}); | ||
}); | ||
|
||
context('when given stop', () => { | ||
beforeEach(() => run({ stop: '1234567890' })); | ||
it('includes max_value', () => { | ||
expect(constraints['@something']).to.have.property('max_value'); | ||
}); | ||
it('max_value is lt', () => { | ||
expect(constraints['@something'].max_value).to.have.property('lt'); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('returned promise', () => { | ||
it('is rejected by transport errors', () => { | ||
error = 'something'; | ||
|
||
let reason; | ||
calculateIndices('one', 'two').then(null, val => reason = val); | ||
$rootScope.$apply(); | ||
|
||
expect(reason).to.equal(error); | ||
}); | ||
it('is fulfilled by array of indices in successful response', () => { | ||
|
||
let indices; | ||
calculateIndices('one', 'two').then(val => indices = val); | ||
$rootScope.$apply(); | ||
|
||
expect(_.first(indices)).to.equal('mock-*'); | ||
}); | ||
}); | ||
|
||
function run({ start = undefined, stop = undefined } = {}) { | ||
calculateIndices('wat-*-no', '@something', start, stop); | ||
$rootScope.$apply(); | ||
config = _.first(transportRequest.firstCall.args); | ||
constraints = config.body.index_constraints; | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
define(function (require) { | ||
const _ = require('lodash'); | ||
const moment = require('moment'); | ||
|
||
return function CalculateIndicesFactory(Promise, es) { | ||
|
||
// Uses the field stats api to determine the names of indices that need to | ||
// be queried against that match the given pattern and fall within the | ||
// given time range | ||
function calculateIndices(...args) { | ||
const options = compileOptions(...args); | ||
return sendRequest(options); | ||
}; | ||
|
||
// creates the configuration hash that must be passed to the elasticsearch | ||
// client | ||
function compileOptions(pattern, timeFieldName, start, stop) { | ||
const constraints = {}; | ||
if (start) { | ||
constraints.min_value = { gte: moment(start).valueOf() }; | ||
} | ||
if (stop) { | ||
constraints.max_value = { lt: moment(stop).valueOf() }; | ||
} | ||
|
||
return { | ||
method: 'POST', | ||
path: `/${pattern}/_field_stats`, | ||
query: { | ||
level: 'indices' | ||
}, | ||
body: { | ||
fields: [ timeFieldName ], | ||
index_constraints: { | ||
[timeFieldName]: constraints | ||
} | ||
} | ||
}; | ||
} | ||
|
||
// executes a request to elasticsearch with the given configuration hash | ||
function sendRequest(options) { | ||
return new Promise(function (resolve, reject) { | ||
es.transport.request(options, function (err, response) { | ||
if (err) return reject(err); | ||
const indices = _.map(response.indices, (info, index) => index); | ||
resolve(indices); | ||
}); | ||
}); | ||
} | ||
|
||
return calculateIndices; | ||
}; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters