Merge branch 'master' into feature/ingest
This commit is contained in:
commit
d5ec1f8ed3
82 changed files with 994 additions and 727 deletions
|
@ -218,7 +218,7 @@ So, you've been assigned a pull to review. What's that look like?
|
|||
|
||||
Remember, someone is blocked by a pull awaiting review, make it count. Be thorough, the more action items you catch in the first review, the less back and forth will be required, and the better chance the pull has of being successful. Don't you like success?
|
||||
|
||||
1. **Understand the issue** that is being fixed, or the feature being added. Check the description on the pull, and check out the related issue. If you don't understand something, ask the person the submitter for clarification.
|
||||
1. **Understand the issue** that is being fixed, or the feature being added. Check the description on the pull, and check out the related issue. If you don't understand something, ask the submitter for clarification.
|
||||
1. **Reproduce the bug** (or the lack of feature I guess?) in the destination branch, usually `master`. The referenced issue will help you here. If you're unable to reproduce the issue, contact the issue submitter for clarification
|
||||
1. **Check out the pull** and test it. Is the issue fixed? Does it have nasty side effects? Try to create suspect inputs. If it operates on the value of a field try things like: strings (including an empty string), null, numbers, dates. Try to think of edge cases that might break the code.
|
||||
1. **Merge the target branch**. It is possible that tests or the linter have been updated in the target branch since the pull was submitted. Merging the pull could cause core to start failing.
|
||||
|
|
|
@ -79,3 +79,7 @@
|
|||
# Set the value of this setting to true to log all events, including system usage information
|
||||
# and all requests.
|
||||
# logging.verbose: false
|
||||
|
||||
# Set the interval in milliseconds to sample system and process performance
|
||||
# metrics. Minimum is 100ms. Defaults to 10000.
|
||||
# ops.interval: 10000
|
||||
|
|
|
@ -39,3 +39,4 @@ retrying.
|
|||
error messages.
|
||||
`logging.verbose`:: *Default: false* Set the value of this setting to `true` to log all events, including system usage
|
||||
information and all requests.
|
||||
`ops.interval`:: *Default: 10000* Set the interval in milliseconds to sample system and process performance metrics. Minimum is 100ms. Defaults to 10 seconds.
|
||||
|
|
|
@ -28,7 +28,7 @@ remove a range.
|
|||
or bottom _n_ elements of a given field to display, ordered by count or a custom metric.
|
||||
*Filters*:: You can specify a set of {ref}/search-aggregations-bucket-filters-aggregation.html[_filters_] for the data.
|
||||
You can specify a filter as a query string or in JSON format, just as in the Discover search bar. Click *Add Filter* to
|
||||
add another filter. Click the images:labelbutton.png[] *label* button to open the label field, where you can type in a
|
||||
add another filter. Click the image:images/labelbutton.png[] *label* button to open the label field, where you can type in a
|
||||
name to display on the visualization.
|
||||
*Significant Terms*:: Displays the results of the experimental
|
||||
{ref}/search-aggregations-bucket-significantterms-aggregation.html[_significant terms_] aggregation.
|
||||
|
|
|
@ -87,9 +87,9 @@
|
|||
"babel-runtime": "5.8.20",
|
||||
"bluebird": "2.9.34",
|
||||
"boom": "2.8.0",
|
||||
"bootstrap": "3.3.5",
|
||||
"bootstrap": "3.3.6",
|
||||
"brace": "0.5.1",
|
||||
"bunyan": "1.4.0",
|
||||
"bunyan": "1.7.1",
|
||||
"clipboard": "1.5.5",
|
||||
"commander": "2.8.1",
|
||||
"css-loader": "0.17.0",
|
||||
|
@ -156,7 +156,7 @@
|
|||
"grunt-cli": "0.1.13",
|
||||
"grunt-contrib-clean": "0.6.0",
|
||||
"grunt-contrib-copy": "0.8.1",
|
||||
"grunt-esvm": "2.1.1",
|
||||
"grunt-esvm": "3.0.3",
|
||||
"grunt-karma": "0.12.0",
|
||||
"grunt-run": "0.5.0",
|
||||
"grunt-s3": "0.2.0-alpha.3",
|
||||
|
@ -174,7 +174,6 @@
|
|||
"karma-ie-launcher": "0.2.0",
|
||||
"karma-mocha": "0.2.0",
|
||||
"karma-safari-launcher": "0.1.1",
|
||||
"libesvm": "3.3.0",
|
||||
"license-checker": "3.1.0",
|
||||
"load-grunt-config": "0.7.2",
|
||||
"makelogs": "3.0.0-beta3",
|
||||
|
|
|
@ -54,7 +54,7 @@ module.exports = function ({ Plugin }) {
|
|||
return reply.continue();
|
||||
}
|
||||
|
||||
function noCreateIndex({ path }, reply) {
|
||||
function noDirectIndex({ path }, reply) {
|
||||
const requestPath = trimRight(trim(path), '/');
|
||||
const matchPath = createPath(kibanaIndex);
|
||||
|
||||
|
@ -75,7 +75,7 @@ module.exports = function ({ Plugin }) {
|
|||
['PUT', 'POST', 'DELETE'],
|
||||
`/${kibanaIndex}/{paths*}`,
|
||||
{
|
||||
pre: [ noCreateIndex, noBulkCheck ]
|
||||
pre: [ noDirectIndex, noBulkCheck ]
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import _ from 'lodash';
|
||||
import Promise from 'bluebird';
|
||||
import sinon from 'sinon';
|
||||
import url from 'url';
|
||||
|
||||
import serverConfig from '../../../../../test/serverConfig';
|
||||
import checkEsVersion from '../check_es_version';
|
||||
|
||||
describe('plugins/elasticsearch', function () {
|
||||
|
@ -23,7 +25,7 @@ describe('plugins/elasticsearch', function () {
|
|||
status: {
|
||||
red: sinon.stub()
|
||||
},
|
||||
url: 'http://localhost:9210'
|
||||
url: url.format(serverConfig.servers.elasticsearch)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
import Promise from 'bluebird';
|
||||
import sinon from 'sinon';
|
||||
import expect from 'expect.js';
|
||||
import url from 'url';
|
||||
|
||||
const NoConnections = require('elasticsearch').errors.NoConnections;
|
||||
|
||||
import healthCheck from '../health_check';
|
||||
import serverConfig from '../../../../../test/serverConfig';
|
||||
|
||||
const esPort = serverConfig.servers.elasticsearch.port;
|
||||
const esUrl = url.format(serverConfig.servers.elasticsearch);
|
||||
|
||||
describe('plugins/elasticsearch', function () {
|
||||
describe('lib/health_check', function () {
|
||||
|
@ -39,7 +45,7 @@ describe('plugins/elasticsearch', function () {
|
|||
nodes: {
|
||||
'node-01': {
|
||||
version: '1.5.0',
|
||||
http_address: 'inet[/127.0.0.1:9210]',
|
||||
http_address: `inet[/127.0.0.1:${esPort}]`,
|
||||
ip: '127.0.0.1'
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +79,7 @@ describe('plugins/elasticsearch', function () {
|
|||
|
||||
it('should set the cluster red if the ping fails, then to green', function () {
|
||||
|
||||
get.withArgs('elasticsearch.url').returns('http://localhost:9210');
|
||||
get.withArgs('elasticsearch.url').returns(esUrl);
|
||||
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
|
||||
get.withArgs('kibana.index').returns('.my-kibana');
|
||||
client.ping.onCall(0).returns(Promise.reject(new NoConnections()));
|
||||
|
@ -85,7 +91,7 @@ describe('plugins/elasticsearch', function () {
|
|||
expect(plugin.status.yellow.args[0][0]).to.be('Waiting for Elasticsearch');
|
||||
sinon.assert.calledOnce(plugin.status.red);
|
||||
expect(plugin.status.red.args[0][0]).to.be(
|
||||
'Unable to connect to Elasticsearch at http://localhost:9210.'
|
||||
`Unable to connect to Elasticsearch at ${esUrl}.`
|
||||
);
|
||||
sinon.assert.calledTwice(client.ping);
|
||||
sinon.assert.calledOnce(client.nodes.info);
|
||||
|
@ -97,7 +103,7 @@ describe('plugins/elasticsearch', function () {
|
|||
});
|
||||
|
||||
it('should set the cluster red if the health check status is red, then to green', function () {
|
||||
get.withArgs('elasticsearch.url').returns('http://localhost:9210');
|
||||
get.withArgs('elasticsearch.url').returns(esUrl);
|
||||
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
|
||||
get.withArgs('kibana.index').returns('.my-kibana');
|
||||
client.ping.returns(Promise.resolve());
|
||||
|
@ -120,7 +126,7 @@ describe('plugins/elasticsearch', function () {
|
|||
});
|
||||
|
||||
it('should set the cluster yellow if the health check timed_out and create index', function () {
|
||||
get.withArgs('elasticsearch.url').returns('http://localhost:9210');
|
||||
get.withArgs('elasticsearch.url').returns(esUrl);
|
||||
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
|
||||
get.withArgs('kibana.index').returns('.my-kibana');
|
||||
client.ping.returns(Promise.resolve());
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div dashboard-app class="app-container dashboard-container">
|
||||
<navbar ng-show="chrome.getVisible()" name="dashboard">
|
||||
<span class="name" ng-if="dash.id" ng-bind="::dash.title" tooltip="{{::dash.title}}"></span>
|
||||
<span class="name" ng-if="dash.id" ng-bind="::dash.title" tooltip="{{::dash.title}}" tooltip-append-to-body="true"></span>
|
||||
|
||||
<form name="queryInput"
|
||||
class="fill inline-form"
|
||||
|
|
|
@ -3,8 +3,15 @@
|
|||
<h5 ng-show="!field.details.error">Quick Count <kbn-info info="Top 5 values based on documents in the table" placement="right"></kbn-info>
|
||||
<span ng-if="!field.details.error" class="small discover-field-details-count">
|
||||
(
|
||||
<a ng-show="field.indexed" ng-click="updateFilterInQuery('_exists_', field.name, '+')">{{::field.details.exists}}</a>
|
||||
<span ng-show="!field.indexed">{{::field.details.exists}}</span>
|
||||
<a
|
||||
ng-show="!indexPattern.metaFields.includes(field.name)"
|
||||
ng-click="updateFilterInQuery('_exists_', field.name, '+')">
|
||||
{{::field.details.exists}}
|
||||
</a>
|
||||
<span
|
||||
ng-show="indexPattern.metaFields.includes(field.name)">
|
||||
{{::field.details.exists}}
|
||||
</span>
|
||||
/{{::field.details.total}} records
|
||||
)
|
||||
</span>
|
||||
|
|
|
@ -81,6 +81,10 @@ module.exports = () => Joi.object({
|
|||
})
|
||||
.default(),
|
||||
|
||||
ops: Joi.object({
|
||||
interval: Joi.number().default(10000),
|
||||
}),
|
||||
|
||||
plugins: Joi.object({
|
||||
paths: Joi.array().items(Joi.string()).default([]),
|
||||
scanDirs: Joi.array().items(Joi.string()).default([]),
|
||||
|
|
|
@ -39,7 +39,7 @@ module.exports = function (kbnServer, server, config) {
|
|||
server.register({
|
||||
register: require('good'),
|
||||
options: {
|
||||
opsInterval: 5000,
|
||||
opsInterval: config.get('ops.interval'),
|
||||
requestHeaders: true,
|
||||
requestPayload: true,
|
||||
reporters: [
|
||||
|
|
|
@ -82,6 +82,7 @@ describe('Histogram Agg', function () {
|
|||
describe('extended_bounds', function () {
|
||||
it('writes when only eb.min is set', function () {
|
||||
var output = paramWriter.write({
|
||||
min_doc_count: true,
|
||||
extended_bounds: { min: 0 }
|
||||
});
|
||||
expect(output.params.extended_bounds).to.have.property('min', 0);
|
||||
|
@ -90,6 +91,7 @@ describe('Histogram Agg', function () {
|
|||
|
||||
it('writes when only eb.max is set', function () {
|
||||
var output = paramWriter.write({
|
||||
min_doc_count: true,
|
||||
extended_bounds: { max: 0 }
|
||||
});
|
||||
expect(output.params.extended_bounds).to.have.property('min', undefined);
|
||||
|
@ -98,6 +100,7 @@ describe('Histogram Agg', function () {
|
|||
|
||||
it('writes when both eb.min and eb.max are set', function () {
|
||||
var output = paramWriter.write({
|
||||
min_doc_count: true,
|
||||
extended_bounds: { min: 99, max: 100 }
|
||||
});
|
||||
expect(output.params.extended_bounds).to.have.property('min', 99);
|
||||
|
@ -106,10 +109,19 @@ describe('Histogram Agg', function () {
|
|||
|
||||
it('does not write when nothing is set', function () {
|
||||
var output = paramWriter.write({
|
||||
min_doc_count: true,
|
||||
extended_bounds: {}
|
||||
});
|
||||
expect(output.params).to.not.have.property('extended_bounds');
|
||||
});
|
||||
|
||||
it('does not write when min_doc_count is false', function () {
|
||||
var output = paramWriter.write({
|
||||
min_doc_count: false,
|
||||
extended_bounds: { min: 99, max: 100 }
|
||||
});
|
||||
expect(output.params).to.not.have.property('extended_bounds');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,12 +2,12 @@ import _ from 'lodash';
|
|||
import angular from 'angular';
|
||||
import AggTypesBucketsBucketAggTypeProvider from 'ui/agg_types/buckets/_bucket_agg_type';
|
||||
import AggTypesBucketsCreateFilterFiltersProvider from 'ui/agg_types/buckets/create_filter/filters';
|
||||
import CourierDataSourceDecorateQueryProvider from 'ui/courier/data_source/_decorate_query';
|
||||
import DecorateQueryProvider from 'ui/courier/data_source/_decorate_query';
|
||||
import filtersTemplate from 'ui/agg_types/controls/filters.html';
|
||||
export default function FiltersAggDefinition(Private, Notifier) {
|
||||
var BucketAggType = Private(AggTypesBucketsBucketAggTypeProvider);
|
||||
var createFilter = Private(AggTypesBucketsCreateFilterFiltersProvider);
|
||||
var decorateQuery = Private(CourierDataSourceDecorateQueryProvider);
|
||||
var decorateQuery = Private(DecorateQueryProvider);
|
||||
var notif = new Notifier({ location: 'Filters Agg' });
|
||||
|
||||
return new BucketAggType({
|
||||
|
|
|
@ -51,7 +51,7 @@ export default function HistogramAggDefinition(Private) {
|
|||
write: function (aggConfig, output) {
|
||||
var val = aggConfig.params.extended_bounds;
|
||||
|
||||
if (val.min != null || val.max != null) {
|
||||
if (aggConfig.params.min_doc_count && (val.min != null || val.max != null)) {
|
||||
output.params.extended_bounds = {
|
||||
min: val.min,
|
||||
max: val.max
|
||||
|
|
|
@ -3,7 +3,7 @@ import _ from 'lodash';
|
|||
import ConfigDefaultsProvider from 'ui/config/defaults';
|
||||
import ConfigDelayedUpdaterProvider from 'ui/config/_delayed_updater';
|
||||
import ConfigValsProvider from 'ui/config/_vals';
|
||||
import CourierDataSourceDocSourceProvider from 'ui/courier/data_source/doc_source';
|
||||
import DocSourceProvider from 'ui/courier/data_source/doc_source';
|
||||
import uiRoutes from 'ui/routes';
|
||||
import uiModules from 'ui/modules';
|
||||
import Notifier from 'ui/notify/notifier';
|
||||
|
@ -30,7 +30,7 @@ module.service('config', function (Private, kbnVersion, kbnIndex, $rootScope, bu
|
|||
// update once it is requested by calling #set() or #clear().
|
||||
var updater;
|
||||
|
||||
var DocSource = Private(CourierDataSourceDocSourceProvider);
|
||||
var DocSource = Private(DocSourceProvider);
|
||||
var doc = (new DocSource())
|
||||
.index(kbnIndex)
|
||||
.type('config')
|
||||
|
|
|
@ -1,45 +1,48 @@
|
|||
import errors from 'ui/errors';
|
||||
import _ from 'lodash';
|
||||
|
||||
import errors from 'ui/errors';
|
||||
import 'ui/es';
|
||||
import 'ui/promises';
|
||||
import 'ui/safe_confirm';
|
||||
import 'ui/index_patterns';
|
||||
import CourierDataSourceDocSourceProvider from 'ui/courier/data_source/doc_source';
|
||||
import CourierDataSourceSearchSourceProvider from 'ui/courier/data_source/search_source';
|
||||
import CourierFetchStrategySearchProvider from 'ui/courier/fetch/strategy/search';
|
||||
import CourierRequestQueueProvider from 'ui/courier/_request_queue';
|
||||
import CourierErrorHandlersProvider from 'ui/courier/_error_handlers';
|
||||
import CourierFetchFetchProvider from 'ui/courier/fetch/fetch';
|
||||
import CourierLooperDocProvider from 'ui/courier/looper/doc';
|
||||
import CourierLooperSearchProvider from 'ui/courier/looper/search';
|
||||
import CourierDataSourceRootSearchSourceProvider from 'ui/courier/data_source/_root_search_source';
|
||||
import CourierSavedObjectSavedObjectProvider from 'ui/courier/saved_object/saved_object';
|
||||
import CourierRedirectWhenMissingProvider from 'ui/courier/_redirect_when_missing';
|
||||
import uiModules from 'ui/modules';
|
||||
import Notifier from 'ui/notify/notifier';
|
||||
|
||||
import DocSourceProvider from './data_source/doc_source';
|
||||
import SearchSourceProvider from './data_source/search_source';
|
||||
import SearchStrategyProvider from './fetch/strategy/search';
|
||||
import RequestQueueProvider from './_request_queue';
|
||||
import ErrorHandlersProvider from './_error_handlers';
|
||||
import FetchProvider from './fetch';
|
||||
import DocLooperProvider from './looper/doc';
|
||||
import SearchLooperProvider from './looper/search';
|
||||
import RootSearchSourceProvider from './data_source/_root_search_source';
|
||||
import SavedObjectProvider from './saved_object';
|
||||
import RedirectWhenMissingProvider from './_redirect_when_missing';
|
||||
|
||||
|
||||
uiModules.get('kibana/courier')
|
||||
.service('courier', function ($rootScope, Private, Promise, indexPatterns, Notifier) {
|
||||
.service('courier', function ($rootScope, Private, Promise, indexPatterns) {
|
||||
function Courier() {
|
||||
var self = this;
|
||||
|
||||
var DocSource = Private(CourierDataSourceDocSourceProvider);
|
||||
var SearchSource = Private(CourierDataSourceSearchSourceProvider);
|
||||
var searchStrategy = Private(CourierFetchStrategySearchProvider);
|
||||
var DocSource = Private(DocSourceProvider);
|
||||
var SearchSource = Private(SearchSourceProvider);
|
||||
var searchStrategy = Private(SearchStrategyProvider);
|
||||
|
||||
var requestQueue = Private(CourierRequestQueueProvider);
|
||||
var errorHandlers = Private(CourierErrorHandlersProvider);
|
||||
var requestQueue = Private(RequestQueueProvider);
|
||||
var errorHandlers = Private(ErrorHandlersProvider);
|
||||
|
||||
var fetch = Private(CourierFetchFetchProvider);
|
||||
var docLooper = self.docLooper = Private(CourierLooperDocProvider);
|
||||
var searchLooper = self.searchLooper = Private(CourierLooperSearchProvider);
|
||||
var fetch = Private(FetchProvider);
|
||||
var docLooper = self.docLooper = Private(DocLooperProvider);
|
||||
var searchLooper = self.searchLooper = Private(SearchLooperProvider);
|
||||
|
||||
// expose some internal modules
|
||||
self.setRootSearchSource = Private(CourierDataSourceRootSearchSourceProvider).set;
|
||||
self.setRootSearchSource = Private(RootSearchSourceProvider).set;
|
||||
|
||||
self.SavedObject = Private(CourierSavedObjectSavedObjectProvider);
|
||||
self.SavedObject = Private(SavedObjectProvider);
|
||||
self.indexPatterns = indexPatterns;
|
||||
self.redirectWhenMissing = Private(CourierRedirectWhenMissingProvider);
|
||||
self.redirectWhenMissing = Private(RedirectWhenMissingProvider);
|
||||
|
||||
self.DocSource = DocSource;
|
||||
self.SearchSource = SearchSource;
|
||||
|
|
|
@ -2,7 +2,7 @@ import moment from 'moment';
|
|||
import expect from 'expect.js';
|
||||
import ngMock from 'ngMock';
|
||||
import _ from 'lodash';
|
||||
import CourierDataSourceDecorateQueryProvider from 'ui/courier/data_source/_decorate_query';
|
||||
import DecorateQueryProvider from 'ui/courier/data_source/_decorate_query';
|
||||
|
||||
describe('Query decorator', function () {
|
||||
|
||||
|
@ -29,7 +29,7 @@ describe('Query decorator', function () {
|
|||
|
||||
beforeEach(ngMock.inject(function (Private, $injector, _config_) {
|
||||
config = _config_;
|
||||
fn = Private(CourierDataSourceDecorateQueryProvider);
|
||||
fn = Private(DecorateQueryProvider);
|
||||
}));
|
||||
|
||||
it('should be a function', function () {
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
import 'ui/private';
|
||||
import ngMock from 'ngMock';
|
||||
import expect from 'expect.js';
|
||||
import CourierDataSourceNormalizeSortRequestProvider from 'ui/courier/data_source/_normalize_sort_request';
|
||||
import NormalizeSortRequestProvider from 'ui/courier/data_source/_normalize_sort_request';
|
||||
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
|
||||
|
||||
describe('SearchSource#normalizeSortRequest', function () {
|
||||
|
||||
|
||||
var normalizeSortRequest;
|
||||
var indexPattern;
|
||||
var normalizedSort;
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
normalizeSortRequest = Private(CourierDataSourceNormalizeSortRequestProvider);
|
||||
normalizeSortRequest = Private(NormalizeSortRequestProvider);
|
||||
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
|
||||
|
||||
normalizedSort = [{
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
import _ from 'lodash';
|
||||
import angular from 'angular';
|
||||
import CourierRequestQueueProvider from 'ui/courier/_request_queue';
|
||||
import CourierErrorHandlersProvider from 'ui/courier/_error_handlers';
|
||||
import CourierFetchFetchProvider from 'ui/courier/fetch/fetch';
|
||||
import CourierDataSourceDecorateQueryProvider from 'ui/courier/data_source/_decorate_query';
|
||||
|
||||
import 'ui/promises';
|
||||
|
||||
import RequestQueueProvider from '../_request_queue';
|
||||
import ErrorHandlersProvider from '../_error_handlers';
|
||||
import FetchProvider from '../fetch';
|
||||
import DecorateQueryProvider from './_decorate_query';
|
||||
|
||||
export default function SourceAbstractFactory(Private, Promise, PromiseEmitter) {
|
||||
var requestQueue = Private(CourierRequestQueueProvider);
|
||||
var errorHandlers = Private(CourierErrorHandlersProvider);
|
||||
var courierFetch = Private(CourierFetchFetchProvider);
|
||||
var requestQueue = Private(RequestQueueProvider);
|
||||
var errorHandlers = Private(ErrorHandlersProvider);
|
||||
var courierFetch = Private(FetchProvider);
|
||||
|
||||
function SourceAbstract(initialState, strategy) {
|
||||
var self = this;
|
||||
|
@ -268,7 +271,7 @@ export default function SourceAbstractFactory(Private, Promise, PromiseEmitter)
|
|||
.then(function () {
|
||||
if (type === 'search') {
|
||||
// This is down here to prevent the circular dependency
|
||||
var decorateQuery = Private(CourierDataSourceDecorateQueryProvider);
|
||||
var decorateQuery = Private(DecorateQueryProvider);
|
||||
|
||||
flatState.body = flatState.body || {};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
export default function DecorateQuery(config) {
|
||||
/**
|
||||
* Decorate queries with default parameters
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
import errors from 'ui/errors';
|
||||
import CourierRequestQueueProvider from 'ui/courier/_request_queue';
|
||||
import CourierFetchFetchProvider from 'ui/courier/fetch/fetch';
|
||||
import RequestQueueProvider from 'ui/courier/_request_queue';
|
||||
import FetchProvider from 'ui/courier/fetch/fetch';
|
||||
|
||||
export default function (Promise, Private, es) {
|
||||
var requestQueue = Private(CourierRequestQueueProvider);
|
||||
var courierFetch = Private(CourierFetchFetchProvider);
|
||||
var requestQueue = Private(RequestQueueProvider);
|
||||
var courierFetch = Private(FetchProvider);
|
||||
|
||||
/**
|
||||
* Backend for doUpdate and doIndex
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
export default function normalizeSortRequest(config) {
|
||||
var defaultSortOptions = config.get('sort:options');
|
||||
|
||||
|
@ -48,4 +49,3 @@ export default function normalizeSortRequest(config) {
|
|||
return normalized;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import CourierDataSourceSearchSourceProvider from 'ui/courier/data_source/search_source';
|
||||
import SearchSourceProvider from 'ui/courier/data_source/search_source';
|
||||
|
||||
export default function RootSearchSource(Private, $rootScope, timefilter, Notifier) {
|
||||
var SearchSource = Private(CourierDataSourceSearchSourceProvider);
|
||||
var SearchSource = Private(SearchSourceProvider);
|
||||
|
||||
var notify = new Notifier({ location: 'Root Search Source' });
|
||||
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import _ from 'lodash';
|
||||
import CourierDataSourceDocSendToEsProvider from 'ui/courier/data_source/_doc_send_to_es';
|
||||
import CourierDataSourceAbstractProvider from 'ui/courier/data_source/_abstract';
|
||||
import CourierFetchRequestDocProvider from 'ui/courier/fetch/request/doc';
|
||||
import CourierFetchStrategyDocProvider from 'ui/courier/fetch/strategy/doc';
|
||||
|
||||
import 'ui/es';
|
||||
import 'ui/storage';
|
||||
|
||||
import DocSendToEsProvider from './_doc_send_to_es';
|
||||
import AbstractDataSourceProvider from './_abstract';
|
||||
import DocRequestProvider from '../fetch/request/doc';
|
||||
import DocStrategyProvider from '../fetch/strategy/doc';
|
||||
|
||||
export default function DocSourceFactory(Private, Promise, es, sessionStorage) {
|
||||
var sendToEs = Private(CourierDataSourceDocSendToEsProvider);
|
||||
var SourceAbstract = Private(CourierDataSourceAbstractProvider);
|
||||
var DocRequest = Private(CourierFetchRequestDocProvider);
|
||||
var docStrategy = Private(CourierFetchStrategyDocProvider);
|
||||
var sendToEs = Private(DocSendToEsProvider);
|
||||
var SourceAbstract = Private(AbstractDataSourceProvider);
|
||||
var DocRequest = Private(DocRequestProvider);
|
||||
var docStrategy = Private(DocStrategyProvider);
|
||||
|
||||
_.class(DocSource).inherits(SourceAbstract);
|
||||
function DocSource(initialState) {
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import _ from 'lodash';
|
||||
import rootSearchSource from 'ui/courier/data_source/_root_search_source';
|
||||
import CourierDataSourceAbstractProvider from 'ui/courier/data_source/_abstract';
|
||||
import CourierFetchRequestSearchProvider from 'ui/courier/fetch/request/search';
|
||||
import CourierFetchRequestSegmentedProvider from 'ui/courier/fetch/request/segmented';
|
||||
import CourierFetchStrategySearchProvider from 'ui/courier/fetch/strategy/search';
|
||||
import CourierDataSourceNormalizeSortRequestProvider from 'ui/courier/data_source/_normalize_sort_request';
|
||||
|
||||
import NormalizeSortRequestProvider from './_normalize_sort_request';
|
||||
import rootSearchSource from './_root_search_source';
|
||||
import AbstractDataSourceProvider from './_abstract';
|
||||
import SearchRequestProvider from '../fetch/request/search';
|
||||
import SegmentedRequestProvider from '../fetch/request/segmented';
|
||||
import SearchStrategyProvider from '../fetch/strategy/search';
|
||||
|
||||
export default function SearchSourceFactory(Promise, Private) {
|
||||
var SourceAbstract = Private(CourierDataSourceAbstractProvider);
|
||||
var SearchRequest = Private(CourierFetchRequestSearchProvider);
|
||||
var SegmentedRequest = Private(CourierFetchRequestSegmentedProvider);
|
||||
var searchStrategy = Private(CourierFetchStrategySearchProvider);
|
||||
var normalizeSortRequest = Private(CourierDataSourceNormalizeSortRequestProvider);
|
||||
var SourceAbstract = Private(AbstractDataSourceProvider);
|
||||
var SearchRequest = Private(SearchRequestProvider);
|
||||
var SegmentedRequest = Private(SegmentedRequestProvider);
|
||||
var searchStrategy = Private(SearchStrategyProvider);
|
||||
var normalizeSortRequest = Private(NormalizeSortRequestProvider);
|
||||
|
||||
_.class(SearchSource).inherits(SourceAbstract);
|
||||
function SearchSource(initialState) {
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import sinon from 'auto-release-sinon';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ngMock';
|
||||
import CourierDataSourceDocSourceProvider from 'ui/courier/data_source/doc_source';
|
||||
import CourierFetchRequestDocProvider from 'ui/courier/fetch/request/doc';
|
||||
|
||||
import DocSourceProvider from '../../data_source/doc_source';
|
||||
import DocRequestProvider from '../request/doc';
|
||||
|
||||
describe('Courier DocFetchRequest class', function () {
|
||||
let storage;
|
||||
let source;
|
||||
let defer;
|
||||
let req;
|
||||
|
||||
var storage;
|
||||
var source;
|
||||
var defer;
|
||||
var req;
|
||||
|
||||
var setVersion;
|
||||
let setVersion;
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private, Promise, $injector) {
|
||||
var DocSource = Private(CourierDataSourceDocSourceProvider);
|
||||
var DocFetchRequest = Private(CourierFetchRequestDocProvider);
|
||||
const DocSource = Private(DocSourceProvider);
|
||||
const DocFetchRequest = Private(DocRequestProvider);
|
||||
|
||||
storage =
|
||||
$injector.get('localStorage').store =
|
||||
|
|
|
@ -2,11 +2,12 @@ import ngMock from 'ngMock';
|
|||
import expect from 'expect.js';
|
||||
import sinon from 'auto-release-sinon';
|
||||
|
||||
import FetchProvider from 'ui/courier/fetch';
|
||||
import IndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
|
||||
import searchResp from 'fixtures/search_response';
|
||||
import CourierDataSourceDocSourceProvider from 'ui/courier/data_source/doc_source';
|
||||
import CourierDataSourceSearchSourceProvider from 'ui/courier/data_source/search_source';
|
||||
|
||||
import FetchProvider from '../fetch';
|
||||
import DocSourceProvider from '../../data_source/doc_source';
|
||||
import SearchSourceProvider from '../../data_source/search_source';
|
||||
|
||||
describe('Fetch service', function () {
|
||||
require('testUtils/noDigestPromises').activateForSuite();
|
||||
|
@ -24,8 +25,8 @@ describe('Fetch service', function () {
|
|||
Promise = $injector.get('Promise');
|
||||
fetch = Private(FetchProvider);
|
||||
indexPattern = Private(IndexPatternProvider);
|
||||
DocSource = Private(CourierDataSourceDocSourceProvider);
|
||||
SearchSource = Private(CourierDataSourceSearchSourceProvider);
|
||||
DocSource = Private(DocSourceProvider);
|
||||
SearchSource = Private(SearchSourceProvider);
|
||||
}));
|
||||
|
||||
describe('#doc(docSource)', function () {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import _ from 'lodash';
|
||||
import sinon from 'auto-release-sinon';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ngMock';
|
||||
import CourierFetchFetchTheseProvider from 'ui/courier/fetch/_fetch_these';
|
||||
|
||||
import FetchTheseProvider from '../fetch_these';
|
||||
|
||||
describe('ui/courier/fetch/_fetch_these', () => {
|
||||
|
||||
let Promise;
|
||||
|
@ -22,15 +23,15 @@ describe('ui/courier/fetch/_fetch_these', () => {
|
|||
return fakeResponses;
|
||||
}
|
||||
|
||||
PrivateProvider.swap(require('ui/courier/fetch/_call_client'), FakeResponsesProvider);
|
||||
PrivateProvider.swap(require('ui/courier/fetch/_call_response_handlers'), FakeResponsesProvider);
|
||||
PrivateProvider.swap(require('ui/courier/fetch/_continue_incomplete'), FakeResponsesProvider);
|
||||
PrivateProvider.swap(require('ui/courier/fetch/call_client'), FakeResponsesProvider);
|
||||
PrivateProvider.swap(require('ui/courier/fetch/call_response_handlers'), FakeResponsesProvider);
|
||||
PrivateProvider.swap(require('ui/courier/fetch/continue_incomplete'), FakeResponsesProvider);
|
||||
}));
|
||||
|
||||
beforeEach(ngMock.inject((Private, $injector) => {
|
||||
$rootScope = $injector.get('$rootScope');
|
||||
Promise = $injector.get('Promise');
|
||||
fetchThese = Private(CourierFetchFetchTheseProvider);
|
||||
fetchThese = Private(FetchTheseProvider);
|
||||
request = mockRequest();
|
||||
requests = [ request ];
|
||||
}));
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
import CourierFetchRequestRequestProvider from 'ui/courier/fetch/request/request';
|
||||
|
||||
export default function CourierFetchIsRequestProvider(Private) {
|
||||
var AbstractRequest = Private(CourierFetchRequestRequestProvider);
|
||||
|
||||
return function isRequest(obj) {
|
||||
return obj instanceof AbstractRequest;
|
||||
};
|
||||
};
|
|
@ -1,29 +1,31 @@
|
|||
import _ from 'lodash';
|
||||
import CourierFetchIsRequestProvider from 'ui/courier/fetch/_is_request';
|
||||
import CourierFetchMergeDuplicateRequestsProvider from 'ui/courier/fetch/_merge_duplicate_requests';
|
||||
import CourierFetchReqStatusProvider from 'ui/courier/fetch/_req_status';
|
||||
|
||||
import IsRequestProvider from './is_request';
|
||||
import MergeDuplicatesRequestProvider from './merge_duplicate_requests';
|
||||
import ReqStatusProvider from './req_status';
|
||||
|
||||
export default function CourierFetchCallClient(Private, Promise, es, esShardTimeout, sessionId) {
|
||||
|
||||
var isRequest = Private(CourierFetchIsRequestProvider);
|
||||
var mergeDuplicateRequests = Private(CourierFetchMergeDuplicateRequestsProvider);
|
||||
const isRequest = Private(IsRequestProvider);
|
||||
const mergeDuplicateRequests = Private(MergeDuplicatesRequestProvider);
|
||||
|
||||
var ABORTED = Private(CourierFetchReqStatusProvider).ABORTED;
|
||||
var DUPLICATE = Private(CourierFetchReqStatusProvider).DUPLICATE;
|
||||
const ABORTED = Private(ReqStatusProvider).ABORTED;
|
||||
const DUPLICATE = Private(ReqStatusProvider).DUPLICATE;
|
||||
|
||||
function callClient(strategy, requests) {
|
||||
// merging docs can change status to DUPLICATE, capture new statuses
|
||||
var statuses = mergeDuplicateRequests(requests);
|
||||
const statuses = mergeDuplicateRequests(requests);
|
||||
|
||||
// get the actual list of requests that we will be fetching
|
||||
var executable = statuses.filter(isRequest);
|
||||
var execCount = executable.length;
|
||||
const executable = statuses.filter(isRequest);
|
||||
let execCount = executable.length;
|
||||
|
||||
// resolved by respond()
|
||||
var esPromise;
|
||||
var defer = Promise.defer();
|
||||
let esPromise;
|
||||
const defer = Promise.defer();
|
||||
|
||||
// for each respond with either the response or ABORTED
|
||||
var respond = function (responses) {
|
||||
const respond = function (responses) {
|
||||
responses = responses || [];
|
||||
return Promise.map(requests, function (req, i) {
|
||||
switch (statuses[i]) {
|
||||
|
@ -43,7 +45,7 @@ export default function CourierFetchCallClient(Private, Promise, es, esShardTime
|
|||
|
||||
|
||||
// handle a request being aborted while being fetched
|
||||
var requestWasAborted = Promise.method(function (req, i) {
|
||||
const requestWasAborted = Promise.method(function (req, i) {
|
||||
if (statuses[i] === ABORTED) {
|
||||
defer.reject(new Error('Request was aborted twice?'));
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
import { SearchTimeout } from 'ui/errors';
|
||||
import { RequestFailure } from 'ui/errors';
|
||||
import { ShardFailure } from 'ui/errors';
|
||||
import CourierFetchReqStatusProvider from 'ui/courier/fetch/_req_status';
|
||||
import CourierFetchNotifierProvider from 'ui/courier/fetch/_notifier';
|
||||
import { RequestFailure, SearchTimeout, ShardFailure } from 'ui/errors';
|
||||
|
||||
import ReqStatusProvider from './req_status';
|
||||
import NotifierProvider from './notifier';
|
||||
|
||||
export default function CourierFetchCallResponseHandlers(Private, Promise) {
|
||||
var ABORTED = Private(CourierFetchReqStatusProvider).ABORTED;
|
||||
var INCOMPLETE = Private(CourierFetchReqStatusProvider).INCOMPLETE;
|
||||
var notify = Private(CourierFetchNotifierProvider);
|
||||
const ABORTED = Private(ReqStatusProvider).ABORTED;
|
||||
const INCOMPLETE = Private(ReqStatusProvider).INCOMPLETE;
|
||||
const notify = Private(NotifierProvider);
|
||||
|
||||
|
||||
function callResponseHandlers(requests, responses) {
|
||||
|
@ -15,7 +15,7 @@ export default function CourierFetchCallResponseHandlers(Private, Promise) {
|
|||
return ABORTED;
|
||||
}
|
||||
|
||||
var resp = responses[i];
|
||||
let resp = responses[i];
|
||||
|
||||
if (resp.timed_out) {
|
||||
notify.warning(new SearchTimeout());
|
|
@ -1,10 +1,10 @@
|
|||
import CourierFetchReqStatusProvider from 'ui/courier/fetch/_req_status';
|
||||
import ReqStatusProvider from './req_status';
|
||||
|
||||
export default function CourierFetchContinueIncompleteRequests(Private) {
|
||||
var INCOMPLETE = Private(CourierFetchReqStatusProvider).INCOMPLETE;
|
||||
const INCOMPLETE = Private(ReqStatusProvider).INCOMPLETE;
|
||||
|
||||
function continueIncompleteRequests(strategy, requests, responses, fetchWithStrategy) {
|
||||
var incomplete = [];
|
||||
const incomplete = [];
|
||||
|
||||
responses.forEach(function (resp, i) {
|
||||
if (resp === INCOMPLETE) {
|
|
@ -1,18 +1,20 @@
|
|||
import _ from 'lodash';
|
||||
import CourierRequestQueueProvider from 'ui/courier/_request_queue';
|
||||
import CourierFetchFetchTheseProvider from 'ui/courier/fetch/_fetch_these';
|
||||
import CourierFetchCallResponseHandlersProvider from 'ui/courier/fetch/_call_response_handlers';
|
||||
import CourierFetchReqStatusProvider from 'ui/courier/fetch/_req_status';
|
||||
|
||||
import RequestQueueProvider from '../_request_queue';
|
||||
import FetchTheseProvider from './fetch_these';
|
||||
import CallResponseHandlersProvider from './call_response_handlers';
|
||||
import ReqStatusProvider from './req_status';
|
||||
|
||||
export default function fetchService(Private, Promise) {
|
||||
|
||||
var requestQueue = Private(CourierRequestQueueProvider);
|
||||
var fetchThese = Private(CourierFetchFetchTheseProvider);
|
||||
const requestQueue = Private(RequestQueueProvider);
|
||||
const fetchThese = Private(FetchTheseProvider);
|
||||
|
||||
var callResponseHandlers = Private(CourierFetchCallResponseHandlersProvider);
|
||||
var INCOMPLETE = Private(CourierFetchReqStatusProvider).INCOMPLETE;
|
||||
const callResponseHandlers = Private(CallResponseHandlersProvider);
|
||||
const INCOMPLETE = Private(ReqStatusProvider).INCOMPLETE;
|
||||
|
||||
function fetchQueued(strategy) {
|
||||
var requests = requestQueue.getStartable(strategy);
|
||||
const requests = requestQueue.getStartable(strategy);
|
||||
if (!requests.length) return Promise.resolve();
|
||||
else return fetchThese(requests);
|
||||
}
|
||||
|
@ -20,7 +22,7 @@ export default function fetchService(Private, Promise) {
|
|||
this.fetchQueued = fetchQueued;
|
||||
|
||||
function fetchASource(source, strategy) {
|
||||
var defer = Promise.defer();
|
||||
const defer = Promise.defer();
|
||||
|
||||
fetchThese([
|
||||
source._createRequest(defer)
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import CourierFetchNotifierProvider from 'ui/courier/fetch/_notifier';
|
||||
import CourierFetchForEachStrategyProvider from 'ui/courier/fetch/_for_each_strategy';
|
||||
import CourierFetchCallClientProvider from 'ui/courier/fetch/_call_client';
|
||||
import CourierFetchCallResponseHandlersProvider from 'ui/courier/fetch/_call_response_handlers';
|
||||
import CourierFetchContinueIncompleteProvider from 'ui/courier/fetch/_continue_incomplete';
|
||||
import CourierFetchReqStatusProvider from 'ui/courier/fetch/_req_status';
|
||||
import NotifierProvider from './notifier';
|
||||
import ForEachStrategyProvider from './for_each_strategy';
|
||||
import CallClientProvider from './call_client';
|
||||
import CallResponseHandlersProvider from './call_response_handlers';
|
||||
import ContinueIncompleteProvider from './continue_incomplete';
|
||||
import ReqStatusProvider from './req_status';
|
||||
|
||||
export default function FetchTheseProvider(Private, Promise) {
|
||||
var notify = Private(CourierFetchNotifierProvider);
|
||||
var forEachStrategy = Private(CourierFetchForEachStrategyProvider);
|
||||
const notify = Private(NotifierProvider);
|
||||
const forEachStrategy = Private(ForEachStrategyProvider);
|
||||
|
||||
// core tasks
|
||||
var callClient = Private(CourierFetchCallClientProvider);
|
||||
var callResponseHandlers = Private(CourierFetchCallResponseHandlersProvider);
|
||||
var continueIncomplete = Private(CourierFetchContinueIncompleteProvider);
|
||||
const callClient = Private(CallClientProvider);
|
||||
const callResponseHandlers = Private(CallResponseHandlersProvider);
|
||||
const continueIncomplete = Private(ContinueIncompleteProvider);
|
||||
|
||||
var ABORTED = Private(CourierFetchReqStatusProvider).ABORTED;
|
||||
var DUPLICATE = Private(CourierFetchReqStatusProvider).DUPLICATE;
|
||||
var INCOMPLETE = Private(CourierFetchReqStatusProvider).INCOMPLETE;
|
||||
const ABORTED = Private(ReqStatusProvider).ABORTED;
|
||||
const DUPLICATE = Private(ReqStatusProvider).DUPLICATE;
|
||||
const INCOMPLETE = Private(ReqStatusProvider).INCOMPLETE;
|
||||
|
||||
function fetchThese(requests) {
|
||||
return forEachStrategy(requests, function (strategy, reqsForStrategy) {
|
||||
|
@ -66,7 +66,7 @@ export default function FetchTheseProvider(Private, Promise) {
|
|||
}
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
var action = req.started ? req.continue : req.start;
|
||||
const action = req.started ? req.continue : req.start;
|
||||
resolve(action.call(req));
|
||||
})
|
||||
.catch(err => req.handleFailure(err));
|
|
@ -1,13 +1,13 @@
|
|||
import _ from 'lodash';
|
||||
export default function FetchForEachRequestStrategy(Private, Promise) {
|
||||
|
||||
export default function FetchForEachRequestStrategy(Private, Promise) {
|
||||
function forEachStrategy(requests, block) {
|
||||
block = Promise.method(block);
|
||||
var sets = [];
|
||||
const sets = [];
|
||||
|
||||
requests.forEach(function (req) {
|
||||
var strategy = req.strategy;
|
||||
var set = _.find(sets, { 0: strategy });
|
||||
const strategy = req.strategy;
|
||||
const set = _.find(sets, { 0: strategy });
|
||||
if (set) set[1].push(req);
|
||||
else sets.push([strategy, [req]]);
|
||||
});
|
9
src/ui/public/courier/fetch/is_request.js
Normal file
9
src/ui/public/courier/fetch/is_request.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import AbstractRequestProvider from './request';
|
||||
|
||||
export default function IsRequestProvider(Private) {
|
||||
const AbstractRequest = Private(AbstractRequestProvider);
|
||||
|
||||
return function isRequest(obj) {
|
||||
return obj instanceof AbstractRequest;
|
||||
};
|
||||
};
|
|
@ -1,17 +1,17 @@
|
|||
import CourierFetchIsRequestProvider from 'ui/courier/fetch/_is_request';
|
||||
import CourierFetchReqStatusProvider from 'ui/courier/fetch/_req_status';
|
||||
import IsRequestProvider from './is_request';
|
||||
import ReqStatusProvider from './req_status';
|
||||
|
||||
export default function FetchMergeDuplicateRequests(Private) {
|
||||
var isRequest = Private(CourierFetchIsRequestProvider);
|
||||
var DUPLICATE = Private(CourierFetchReqStatusProvider).DUPLICATE;
|
||||
const isRequest = Private(IsRequestProvider);
|
||||
const DUPLICATE = Private(ReqStatusProvider).DUPLICATE;
|
||||
|
||||
function mergeDuplicateRequests(requests) {
|
||||
// dedupe requests
|
||||
var index = {};
|
||||
const index = {};
|
||||
return requests.map(function (req) {
|
||||
if (!isRequest(req)) return req;
|
||||
|
||||
var iid = req.source._instanceid;
|
||||
const iid = req.source._instanceid;
|
||||
if (!index[iid]) {
|
||||
// this request is unique so far
|
||||
index[iid] = req;
|
|
@ -1,10 +1,11 @@
|
|||
import sinon from 'auto-release-sinon';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ngMock';
|
||||
import CourierFetchRequestSegmentedProvider from 'ui/courier/fetch/request/segmented';
|
||||
import CourierFetchRequestSearchProvider from 'ui/courier/fetch/request/search';
|
||||
describe('ui/courier/fetch/request/segmented', () => {
|
||||
|
||||
import SegmentedRequestProvider from '../segmented';
|
||||
import SearchRequestProvider from '../search';
|
||||
|
||||
describe('ui/courier/fetch/request/segmented', () => {
|
||||
let Promise;
|
||||
let $rootScope;
|
||||
let SegmentedReq;
|
||||
|
@ -16,8 +17,8 @@ describe('ui/courier/fetch/request/segmented', () => {
|
|||
beforeEach(ngMock.inject((Private, $injector) => {
|
||||
Promise = $injector.get('Promise');
|
||||
$rootScope = $injector.get('$rootScope');
|
||||
SegmentedReq = Private(CourierFetchRequestSegmentedProvider);
|
||||
searchReqStart = sinon.spy(Private(CourierFetchRequestSearchProvider).prototype, 'start');
|
||||
SegmentedReq = Private(SegmentedRequestProvider);
|
||||
searchReqStart = sinon.spy(Private(SearchRequestProvider).prototype, 'start');
|
||||
}));
|
||||
|
||||
describe('#start()', () => {
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import sinon from 'auto-release-sinon';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ngMock';
|
||||
|
||||
import StubbedSearchSourceProvider from 'fixtures/stubbed_search_source';
|
||||
import CourierFetchRequestSegmentedProvider from 'ui/courier/fetch/request/segmented';
|
||||
|
||||
import SegmentedRequestProvider from '../segmented';
|
||||
|
||||
describe('ui/courier/fetch/request/segmented/_createQueue', () => {
|
||||
|
||||
let Promise;
|
||||
|
@ -16,7 +19,7 @@ describe('ui/courier/fetch/request/segmented/_createQueue', () => {
|
|||
beforeEach(ngMock.inject((Private, $injector) => {
|
||||
Promise = $injector.get('Promise');
|
||||
$rootScope = $injector.get('$rootScope');
|
||||
SegmentedReq = Private(CourierFetchRequestSegmentedProvider);
|
||||
SegmentedReq = Private(SegmentedRequestProvider);
|
||||
|
||||
MockSource = class {
|
||||
constructor() {
|
||||
|
@ -29,7 +32,7 @@ describe('ui/courier/fetch/request/segmented/_createQueue', () => {
|
|||
const req = new SegmentedReq(new MockSource());
|
||||
req._queueCreated = null;
|
||||
|
||||
var promise = req._createQueue();
|
||||
const promise = req._createQueue();
|
||||
expect(req._queueCreated).to.be(false);
|
||||
await promise;
|
||||
expect(req._queueCreated).to.be(true);
|
||||
|
|
|
@ -6,7 +6,8 @@ import sinon from 'auto-release-sinon';
|
|||
import HitSortFnProv from 'plugins/kibana/discover/_hit_sort_fn';
|
||||
import NoDigestPromises from 'testUtils/noDigestPromises';
|
||||
import StubbedSearchSourceProvider from 'fixtures/stubbed_search_source';
|
||||
import CourierFetchRequestSegmentedProvider from 'ui/courier/fetch/request/segmented';
|
||||
|
||||
import SegmentedRequestProvider from '../segmented';
|
||||
|
||||
describe('Segmented Request Index Selection', function () {
|
||||
let Promise;
|
||||
|
@ -22,7 +23,7 @@ describe('Segmented Request Index Selection', function () {
|
|||
Promise = $injector.get('Promise');
|
||||
HitSortFn = Private(HitSortFnProv);
|
||||
$rootScope = $injector.get('$rootScope');
|
||||
SegmentedReq = Private(CourierFetchRequestSegmentedProvider);
|
||||
SegmentedReq = Private(SegmentedRequestProvider);
|
||||
|
||||
MockSource = class {
|
||||
constructor() {
|
||||
|
|
|
@ -6,7 +6,8 @@ import sinon from 'auto-release-sinon';
|
|||
import HitSortFnProv from 'plugins/kibana/discover/_hit_sort_fn';
|
||||
import NoDigestPromises from 'testUtils/noDigestPromises';
|
||||
import StubbedSearchSourceProvider from 'fixtures/stubbed_search_source';
|
||||
import CourierFetchRequestSegmentedProvider from 'ui/courier/fetch/request/segmented';
|
||||
|
||||
import SegmentedRequestProvider from '../segmented';
|
||||
|
||||
describe('Segmented Request Size Picking', function () {
|
||||
let Promise;
|
||||
|
@ -22,7 +23,7 @@ describe('Segmented Request Size Picking', function () {
|
|||
Promise = $injector.get('Promise');
|
||||
HitSortFn = Private(HitSortFnProv);
|
||||
$rootScope = $injector.get('$rootScope');
|
||||
SegmentedReq = Private(CourierFetchRequestSegmentedProvider);
|
||||
SegmentedReq = Private(SegmentedRequestProvider);
|
||||
|
||||
MockSource = class {
|
||||
constructor() {
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import EventsProvider from 'ui/events';
|
||||
export default function CourierSegmentedReqHandle(Private) {
|
||||
var Events = Private(EventsProvider);
|
||||
|
||||
|
||||
/**
|
||||
* Simple class for creating an object to send to the
|
||||
* requester of a SegmentedRequest. Since the SegmentedRequest
|
||||
* extends AbstractRequest, it wasn't able to be the event
|
||||
* emitter it was born to be. This provides a channel for
|
||||
* setting values on the segmented request, and an event
|
||||
* emitter for the request to speak outwardly
|
||||
*
|
||||
* @param {SegmentedRequest} - req - the requst this handle relates to
|
||||
*/
|
||||
_.class(SegmentedHandle).inherits(Events);
|
||||
function SegmentedHandle(req) {
|
||||
SegmentedHandle.Super.call(this);
|
||||
|
||||
// export a couple methods from the request
|
||||
this.setDirection = _.bindKey(req, 'setDirection');
|
||||
this.setSize = _.bindKey(req, 'setSize');
|
||||
this.setMaxSegments = _.bindKey(req, 'setMaxSegments');
|
||||
this.setSortFn = _.bindKey(req, 'setSortFn');
|
||||
}
|
||||
|
||||
return SegmentedHandle;
|
||||
};
|
|
@ -1,42 +1,43 @@
|
|||
import _ from 'lodash';
|
||||
import CourierFetchStrategyDocProvider from 'ui/courier/fetch/strategy/doc';
|
||||
import CourierFetchRequestRequestProvider from 'ui/courier/fetch/request/request';
|
||||
import DocStrategyProvider from '../strategy/doc';
|
||||
import AbstractRequestProvider from './request';
|
||||
|
||||
export default function DocRequestProvider(Private) {
|
||||
|
||||
var docStrategy = Private(CourierFetchStrategyDocProvider);
|
||||
var AbstractRequest = Private(CourierFetchRequestRequestProvider);
|
||||
const docStrategy = Private(DocStrategyProvider);
|
||||
const AbstractRequest = Private(AbstractRequestProvider);
|
||||
|
||||
_.class(DocRequest).inherits(AbstractRequest);
|
||||
function DocRequest(source, defer) {
|
||||
DocRequest.Super.call(this, source, defer);
|
||||
class DocRequest extends AbstractRequest {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
|
||||
this.type = 'doc';
|
||||
this.strategy = docStrategy;
|
||||
}
|
||||
|
||||
DocRequest.prototype.canStart = function () {
|
||||
var parent = DocRequest.Super.prototype.canStart.call(this);
|
||||
canStart() {
|
||||
const parent = super.canStart();
|
||||
if (!parent) return false;
|
||||
|
||||
var version = this.source._version;
|
||||
var storedVersion = this.source._getStoredVersion();
|
||||
const version = this.source._version;
|
||||
const storedVersion = this.source._getStoredVersion();
|
||||
|
||||
// conditions that equal "fetch This DOC!"
|
||||
var unknown = !version && !storedVersion;
|
||||
var mismatch = version !== storedVersion;
|
||||
const unknown = !version && !storedVersion;
|
||||
const mismatch = version !== storedVersion;
|
||||
|
||||
return Boolean(mismatch || (unknown && !this.started));
|
||||
};
|
||||
}
|
||||
|
||||
DocRequest.prototype.handleResponse = function (resp) {
|
||||
handleResponse(resp) {
|
||||
if (resp.found) {
|
||||
this.source._storeVersion(resp._version);
|
||||
} else {
|
||||
this.source._clearVersion();
|
||||
}
|
||||
|
||||
return DocRequest.Super.prototype.handleResponse.call(this, resp);
|
||||
};
|
||||
return super.handleResponse(resp);
|
||||
}
|
||||
}
|
||||
|
||||
return DocRequest;
|
||||
};
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import CourierErrorHandlersProvider from 'ui/courier/_error_handlers';
|
||||
import Notifier from 'ui/notify/notifier';
|
||||
|
||||
export default function RequestErrorHandlerFactory(Private) {
|
||||
var errHandlers = Private(CourierErrorHandlersProvider);
|
||||
import ErrorHandlersProvider from '../../_error_handlers';
|
||||
|
||||
var notify = new Notifier({
|
||||
export default function RequestErrorHandlerFactory(Private) {
|
||||
const errHandlers = Private(ErrorHandlersProvider);
|
||||
|
||||
const notify = new Notifier({
|
||||
location: 'Courier Fetch Error'
|
||||
});
|
||||
|
||||
function handleError(req, error) {
|
||||
var myHandlers = [];
|
||||
const myHandlers = [];
|
||||
|
||||
errHandlers.splice(0).forEach(function (handler) {
|
||||
(handler.source === req.source ? myHandlers : errHandlers).push(handler);
|
|
@ -1,28 +1,29 @@
|
|||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
|
||||
import errors from 'ui/errors';
|
||||
import CourierRequestQueueProvider from 'ui/courier/_request_queue';
|
||||
import CourierFetchRequestErrorHandlerProvider from 'ui/courier/fetch/request/_error_handler';
|
||||
|
||||
import RequestQueueProvider from '../../_request_queue';
|
||||
import ErrorHandlerRequestProvider from './error_handler';
|
||||
|
||||
export default function AbstractReqProvider(Private, Promise) {
|
||||
var requestQueue = Private(CourierRequestQueueProvider);
|
||||
var requestErrorHandler = Private(CourierFetchRequestErrorHandlerProvider);
|
||||
|
||||
function AbstractReq(source, defer) {
|
||||
if (!(this instanceof AbstractReq) || !this.constructor || this.constructor === AbstractReq) {
|
||||
throw new Error('The AbstractReq class should not be called directly');
|
||||
}
|
||||
const requestQueue = Private(RequestQueueProvider);
|
||||
const requestErrorHandler = Private(ErrorHandlerRequestProvider);
|
||||
|
||||
return class AbstractReq {
|
||||
constructor(source, defer) {
|
||||
this.source = source;
|
||||
this.defer = defer || Promise.defer();
|
||||
this._whenAbortedHandlers = [];
|
||||
|
||||
requestQueue.push(this);
|
||||
}
|
||||
|
||||
AbstractReq.prototype.canStart = function () {
|
||||
canStart() {
|
||||
return Boolean(!this.stopped && !this.source._fetchDisabled);
|
||||
};
|
||||
}
|
||||
|
||||
AbstractReq.prototype.start = function () {
|
||||
start() {
|
||||
if (this.started) {
|
||||
throw new TypeError('Unable to start request because it has already started');
|
||||
}
|
||||
|
@ -30,7 +31,7 @@ export default function AbstractReqProvider(Private, Promise) {
|
|||
this.started = true;
|
||||
this.moment = moment();
|
||||
|
||||
var source = this.source;
|
||||
const source = this.source;
|
||||
if (source.activeFetchCount) {
|
||||
source.activeFetchCount += 1;
|
||||
} else {
|
||||
|
@ -38,78 +39,72 @@ export default function AbstractReqProvider(Private, Promise) {
|
|||
}
|
||||
|
||||
source.history = [this];
|
||||
};
|
||||
}
|
||||
|
||||
AbstractReq.prototype.getFetchParams = function () {
|
||||
getFetchParams() {
|
||||
return this.source._flatten();
|
||||
};
|
||||
}
|
||||
|
||||
AbstractReq.prototype.transformResponse = function (resp) {
|
||||
transformResponse(resp) {
|
||||
return resp;
|
||||
};
|
||||
}
|
||||
|
||||
AbstractReq.prototype.filterError = function (resp) {
|
||||
filterError(resp) {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
AbstractReq.prototype.handleResponse = function (resp) {
|
||||
handleResponse(resp) {
|
||||
this.success = true;
|
||||
this.resp = resp;
|
||||
};
|
||||
}
|
||||
|
||||
AbstractReq.prototype.handleFailure = function (error) {
|
||||
handleFailure(error) {
|
||||
this.success = false;
|
||||
this.resp = error && error.resp;
|
||||
this.retry();
|
||||
return requestErrorHandler(this, error);
|
||||
};
|
||||
}
|
||||
|
||||
AbstractReq.prototype.isIncomplete = function () {
|
||||
isIncomplete() {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
AbstractReq.prototype.continue = function () {
|
||||
continue() {
|
||||
throw new Error('Unable to continue ' + this.type + ' request');
|
||||
};
|
||||
}
|
||||
|
||||
AbstractReq.prototype.retry = function () {
|
||||
var clone = this.clone();
|
||||
retry() {
|
||||
const clone = this.clone();
|
||||
this.abort();
|
||||
return clone;
|
||||
};
|
||||
}
|
||||
|
||||
// don't want people overriding this, so it becomes a natural
|
||||
// part of .abort() and .complete()
|
||||
function stop(then) {
|
||||
return function () {
|
||||
_markStopped() {
|
||||
if (this.stopped) return;
|
||||
|
||||
this.stopped = true;
|
||||
this.source.activeFetchCount -= 1;
|
||||
_.pull(requestQueue, this);
|
||||
then.call(this);
|
||||
};
|
||||
}
|
||||
|
||||
AbstractReq.prototype.abort = stop(function () {
|
||||
abort() {
|
||||
this._markStopped();
|
||||
this.defer = null;
|
||||
this.aborted = true;
|
||||
if (this._whenAborted) _.callEach(this._whenAborted);
|
||||
});
|
||||
_.callEach(this._whenAbortedHandlers);
|
||||
}
|
||||
|
||||
AbstractReq.prototype.whenAborted = function (cb) {
|
||||
this._whenAborted = (this._whenAborted || []);
|
||||
this._whenAborted.push(cb);
|
||||
};
|
||||
whenAborted(cb) {
|
||||
this._whenAbortedHandlers.push(cb);
|
||||
}
|
||||
|
||||
AbstractReq.prototype.complete = stop(function () {
|
||||
complete() {
|
||||
this._markStopped();
|
||||
this.ms = this.moment.diff() * -1;
|
||||
this.defer.resolve(this.resp);
|
||||
});
|
||||
}
|
||||
|
||||
AbstractReq.prototype.clone = function () {
|
||||
clone() {
|
||||
return new this.constructor(this.source, this.defer);
|
||||
}
|
||||
};
|
||||
|
||||
return AbstractReq;
|
||||
};
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
import _ from 'lodash';
|
||||
import CourierFetchStrategySearchProvider from 'ui/courier/fetch/strategy/search';
|
||||
import CourierFetchRequestRequestProvider from 'ui/courier/fetch/request/request';
|
||||
import SearchStrategyProvider from '../strategy/search';
|
||||
import AbstractRequestProvider from './request';
|
||||
|
||||
export default function SearchReqProvider(Private) {
|
||||
|
||||
var searchStrategy = Private(CourierFetchStrategySearchProvider);
|
||||
var AbstractRequest = Private(CourierFetchRequestRequestProvider);
|
||||
const searchStrategy = Private(SearchStrategyProvider);
|
||||
const AbstractRequest = Private(AbstractRequestProvider);
|
||||
|
||||
_.class(SearchReq).inherits(AbstractRequest);
|
||||
var Super = SearchReq.Super;
|
||||
function SearchReq(source, defer) {
|
||||
Super.call(this, source, defer);
|
||||
return class SearchReq extends AbstractRequest {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
|
||||
this.type = 'search';
|
||||
this.strategy = searchStrategy;
|
||||
}
|
||||
|
||||
return SearchReq;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
import { isNumber } from 'lodash';
|
||||
import _ from 'lodash';
|
||||
import CourierFetchRequestSearchProvider from 'ui/courier/fetch/request/search';
|
||||
import CourierFetchRequestSegmentedHandleProvider from 'ui/courier/fetch/request/_segmented_handle';
|
||||
export default function CourierSegmentedReqProvider(es, Private, Promise, Notifier, timefilter, config) {
|
||||
var SearchReq = Private(CourierFetchRequestSearchProvider);
|
||||
var SegmentedHandle = Private(CourierFetchRequestSegmentedHandleProvider);
|
||||
import { isNumber } from 'lodash';
|
||||
|
||||
var notify = new Notifier({
|
||||
import Notifier from 'ui/notify/notifier';
|
||||
|
||||
import SearchRequestProvider from './search';
|
||||
import SegmentedHandleProvider from './segmented_handle';
|
||||
|
||||
export default function SegmentedReqProvider(es, Private, Promise, timefilter, config) {
|
||||
const SearchReq = Private(SearchRequestProvider);
|
||||
const SegmentedHandle = Private(SegmentedHandleProvider);
|
||||
|
||||
const notify = new Notifier({
|
||||
location: 'Segmented Fetch'
|
||||
});
|
||||
|
||||
_.class(SegmentedReq).inherits(SearchReq);
|
||||
function SegmentedReq(source, defer, initFn) {
|
||||
SearchReq.call(this, source, defer);
|
||||
class SegmentedReq extends SearchReq {
|
||||
constructor(source, defer, initFn) {
|
||||
super(source, defer);
|
||||
|
||||
this.type = 'segmented';
|
||||
|
||||
|
@ -37,9 +41,7 @@ export default function CourierSegmentedReqProvider(es, Private, Promise, Notifi
|
|||
** SearchReq overrides
|
||||
*********/
|
||||
|
||||
SegmentedReq.prototype.start = function () {
|
||||
var self = this;
|
||||
|
||||
start() {
|
||||
this._complete = [];
|
||||
this._active = null;
|
||||
this._segments = [];
|
||||
|
@ -58,91 +60,90 @@ export default function CourierSegmentedReqProvider(es, Private, Promise, Notifi
|
|||
// give the request consumer a chance to receive each segment and set
|
||||
// parameters via the handle
|
||||
if (_.isFunction(this._initFn)) this._initFn(this._handle);
|
||||
return this._createQueue().then(function (queue) {
|
||||
self._all = queue.slice(0);
|
||||
return this._createQueue().then((queue) => {
|
||||
this._all = queue.slice(0);
|
||||
|
||||
// Send the initial fetch status
|
||||
self._reportStatus();
|
||||
this._reportStatus();
|
||||
|
||||
return SearchReq.prototype.start.call(self);
|
||||
return super.start();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype.continue = function () {
|
||||
continue() {
|
||||
return this._reportStatus();
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype.getFetchParams = function () {
|
||||
var self = this;
|
||||
|
||||
return self._getFlattenedSource().then(function (flatSource) {
|
||||
var params = _.cloneDeep(flatSource);
|
||||
getFetchParams() {
|
||||
return this._getFlattenedSource().then(flatSource => {
|
||||
const params = _.cloneDeep(flatSource);
|
||||
|
||||
// calculate the number of indices to fetch in this request in order to prevent
|
||||
// more than self._maxSegments requests. We use Math.max(1, n) to ensure that each request
|
||||
// more than this._maxSegments requests. We use Math.max(1, n) to ensure that each request
|
||||
// has at least one index pattern, and Math.floor() to make sure that if the
|
||||
// number of indices does not round out evenly the extra index is tacked onto the last
|
||||
// request, making sure the first request returns faster.
|
||||
var remainingSegments = self._maxSegments - self._segments.length;
|
||||
var indexCount = Math.max(1, Math.floor(self._queue.length / remainingSegments));
|
||||
const remainingSegments = this._maxSegments - this._segments.length;
|
||||
const indexCount = Math.max(1, Math.floor(this._queue.length / remainingSegments));
|
||||
|
||||
var indices = self._active = self._queue.splice(0, indexCount);
|
||||
const indices = this._active = this._queue.splice(0, indexCount);
|
||||
params.index = _.pluck(indices, 'index');
|
||||
|
||||
if (isNumber(self._desiredSize)) {
|
||||
params.body.size = self._pickSizeForIndices(indices);
|
||||
if (isNumber(this._desiredSize)) {
|
||||
params.body.size = this._pickSizeForIndices(indices);
|
||||
}
|
||||
|
||||
return params;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype.handleResponse = function (resp) {
|
||||
handleResponse(resp) {
|
||||
return this._consumeSegment(resp);
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype.filterError = function (resp) {
|
||||
filterError(resp) {
|
||||
if (/ClusterBlockException.*index\sclosed/.test(resp.error)) {
|
||||
this._consumeSegment(false);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype.isIncomplete = function () {
|
||||
var queueNotCreated = !this._queueCreated;
|
||||
var queueNotEmpty = this._queue.length > 0;
|
||||
isIncomplete() {
|
||||
const queueNotCreated = !this._queueCreated;
|
||||
const queueNotEmpty = this._queue.length > 0;
|
||||
return queueNotCreated || queueNotEmpty;
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype.clone = function () {
|
||||
clone() {
|
||||
return new SegmentedReq(this.source, this.defer, this._initFn);
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype.complete = function () {
|
||||
complete() {
|
||||
this._reportStatus();
|
||||
this._handle.emit('complete');
|
||||
return SearchReq.prototype.complete.call(this);
|
||||
};
|
||||
return super.complete();
|
||||
}
|
||||
|
||||
/*********
|
||||
** SegmentedReq specific methods
|
||||
*********/
|
||||
|
||||
|
||||
/**
|
||||
* Set the sort total number of segments to emit
|
||||
*
|
||||
* @param {number}
|
||||
*/
|
||||
SegmentedReq.prototype.setMaxSegments = function (maxSegments) {
|
||||
setMaxSegments(maxSegments) {
|
||||
this._maxSegments = Math.max(_.parseInt(maxSegments), 1);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sort direction for the request.
|
||||
*
|
||||
* @param {string} dir - one of 'asc' or 'desc'
|
||||
*/
|
||||
SegmentedReq.prototype.setDirection = function (dir) {
|
||||
setDirection(dir) {
|
||||
switch (dir) {
|
||||
case 'asc':
|
||||
case 'desc':
|
||||
|
@ -150,16 +151,16 @@ export default function CourierSegmentedReqProvider(es, Private, Promise, Notifi
|
|||
default:
|
||||
throw new TypeError('unknown sort direction "' + dir + '"');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the function that will be used to sort the rows
|
||||
*
|
||||
* @param {fn}
|
||||
*/
|
||||
SegmentedReq.prototype.setSortFn = function (sortFn) {
|
||||
setSortFn(sortFn) {
|
||||
this._sortFn = sortFn;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sort total number of documents to
|
||||
|
@ -171,50 +172,49 @@ export default function CourierSegmentedReqProvider(es, Private, Promise, Notifi
|
|||
*
|
||||
* @param {number|false}
|
||||
*/
|
||||
SegmentedReq.prototype.setSize = function (totalSize) {
|
||||
setSize(totalSize) {
|
||||
this._desiredSize = _.parseInt(totalSize);
|
||||
if (isNaN(this._desiredSize)) this._desiredSize = null;
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype._createQueue = function () {
|
||||
var self = this;
|
||||
var timeBounds = timefilter.getBounds();
|
||||
var indexPattern = self.source.get('index');
|
||||
self._queueCreated = false;
|
||||
_createQueue() {
|
||||
const timeBounds = timefilter.getBounds();
|
||||
const indexPattern = this.source.get('index');
|
||||
this._queueCreated = false;
|
||||
|
||||
return indexPattern.toDetailedIndexList(timeBounds.min, timeBounds.max, self._direction)
|
||||
.then(function (queue) {
|
||||
return indexPattern.toDetailedIndexList(timeBounds.min, timeBounds.max, this._direction)
|
||||
.then(queue => {
|
||||
if (!_.isArray(queue)) queue = [queue];
|
||||
|
||||
self._queue = queue;
|
||||
self._queueCreated = true;
|
||||
this._queue = queue;
|
||||
this._queueCreated = true;
|
||||
|
||||
return queue;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype._reportStatus = function () {
|
||||
_reportStatus() {
|
||||
return this._handle.emit('status', {
|
||||
total: this._queueCreated ? this._all.length : NaN,
|
||||
complete: this._queueCreated ? this._complete.length : NaN,
|
||||
remaining: this._queueCreated ? this._queue.length : NaN,
|
||||
hitCount: this._queueCreated ? this._mergedResp.hits.hits.length : NaN
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype._getFlattenedSource = function () {
|
||||
_getFlattenedSource() {
|
||||
return this.source._flatten();
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype._consumeSegment = function (seg) {
|
||||
var index = this._active;
|
||||
_consumeSegment(seg) {
|
||||
const index = this._active;
|
||||
this._complete.push(index);
|
||||
if (!seg) return; // segment was ignored/filtered, don't store it
|
||||
|
||||
var hadHits = _.get(this._mergedResp, 'hits.hits.length') > 0;
|
||||
var gotHits = _.get(seg, 'hits.hits.length') > 0;
|
||||
var firstHits = !hadHits && gotHits;
|
||||
var haveHits = hadHits || gotHits;
|
||||
const hadHits = _.get(this._mergedResp, 'hits.hits.length') > 0;
|
||||
const gotHits = _.get(seg, 'hits.hits.length') > 0;
|
||||
const firstHits = !hadHits && gotHits;
|
||||
const haveHits = hadHits || gotHits;
|
||||
|
||||
this._mergeSegment(seg);
|
||||
this.resp = _.omit(this._mergedResp, '_bucketIndex');
|
||||
|
@ -222,12 +222,12 @@ export default function CourierSegmentedReqProvider(es, Private, Promise, Notifi
|
|||
if (firstHits) this._handle.emit('first', seg);
|
||||
if (gotHits) this._handle.emit('segment', seg);
|
||||
if (haveHits) this._handle.emit('mergedSegment', this.resp);
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype._mergeHits = function (hits) {
|
||||
var mergedHits = this._mergedResp.hits.hits;
|
||||
var desiredSize = this._desiredSize;
|
||||
var sortFn = this._sortFn;
|
||||
_mergeHits(hits) {
|
||||
const mergedHits = this._mergedResp.hits.hits;
|
||||
const desiredSize = this._desiredSize;
|
||||
const sortFn = this._sortFn;
|
||||
|
||||
_.pushAll(hits, mergedHits);
|
||||
|
||||
|
@ -238,12 +238,12 @@ export default function CourierSegmentedReqProvider(es, Private, Promise, Notifi
|
|||
}
|
||||
|
||||
if (isNumber(desiredSize)) {
|
||||
mergedHits = this._mergedResp.hits.hits = mergedHits.slice(0, desiredSize);
|
||||
this._mergedResp.hits.hits = mergedHits.slice(0, desiredSize);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SegmentedReq.prototype._mergeSegment = notify.timed('merge response segment', function (seg) {
|
||||
var merged = this._mergedResp;
|
||||
_mergeSegment(seg) {
|
||||
const merged = this._mergedResp;
|
||||
|
||||
this._segments.push(seg);
|
||||
|
||||
|
@ -273,7 +273,7 @@ export default function CourierSegmentedReqProvider(es, Private, Promise, Notifi
|
|||
}
|
||||
|
||||
seg.aggregations[aggKey].buckets.forEach(function (bucket) {
|
||||
var mbucket = merged._bucketIndex[bucket.key];
|
||||
let mbucket = merged._bucketIndex[bucket.key];
|
||||
if (mbucket) {
|
||||
mbucket.doc_count += bucket.doc_count;
|
||||
return;
|
||||
|
@ -283,14 +283,14 @@ export default function CourierSegmentedReqProvider(es, Private, Promise, Notifi
|
|||
merged.aggregations[aggKey].buckets.push(mbucket);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
SegmentedReq.prototype._detectHitsWindow = function (hits) {
|
||||
_detectHitsWindow(hits) {
|
||||
hits = hits || [];
|
||||
var indexPattern = this.source.get('index');
|
||||
var desiredSize = this._desiredSize;
|
||||
const indexPattern = this.source.get('index');
|
||||
const desiredSize = this._desiredSize;
|
||||
|
||||
var size = _.size(hits);
|
||||
const size = _.size(hits);
|
||||
if (!isNumber(desiredSize) || size < desiredSize) {
|
||||
this._hitWindow = {
|
||||
size: size,
|
||||
|
@ -304,18 +304,18 @@ export default function CourierSegmentedReqProvider(es, Private, Promise, Notifi
|
|||
let max;
|
||||
|
||||
hits.forEach(function (deepHit) {
|
||||
var hit = indexPattern.flattenHit(deepHit);
|
||||
var time = hit[indexPattern.timeFieldName];
|
||||
const hit = indexPattern.flattenHit(deepHit);
|
||||
const time = hit[indexPattern.timeFieldName];
|
||||
if (min == null || time < min) min = time;
|
||||
if (max == null || time > max) max = time;
|
||||
});
|
||||
|
||||
this._hitWindow = { size, min, max };
|
||||
};
|
||||
}
|
||||
|
||||
SegmentedReq.prototype._pickSizeForIndices = function (indices) {
|
||||
var hitWindow = this._hitWindow;
|
||||
var desiredSize = this._desiredSize;
|
||||
_pickSizeForIndices(indices) {
|
||||
const hitWindow = this._hitWindow;
|
||||
const desiredSize = this._desiredSize;
|
||||
|
||||
if (!isNumber(desiredSize)) return null;
|
||||
// we don't have any hits yet, get us more info!
|
||||
|
@ -323,12 +323,15 @@ export default function CourierSegmentedReqProvider(es, Private, Promise, Notifi
|
|||
// the order of documents isn't important, just get us more
|
||||
if (!this._sortFn) return Math.max(desiredSize - hitWindow.size, 0);
|
||||
// if all of the documents in every index fall outside of our current doc set, we can ignore them.
|
||||
var someOverlap = indices.some(function (index) {
|
||||
const someOverlap = indices.some(function (index) {
|
||||
return index.min <= hitWindow.max && hitWindow.min <= index.max;
|
||||
});
|
||||
|
||||
return someOverlap ? desiredSize : 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
SegmentedReq.prototype.mergedSegment = notify.timed('merge response segment', SegmentedReq.prototype.mergedSegment);
|
||||
|
||||
return SegmentedReq;
|
||||
};
|
||||
|
|
40
src/ui/public/courier/fetch/request/segmented_handle.js
Normal file
40
src/ui/public/courier/fetch/request/segmented_handle.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
import EventsProvider from 'ui/events';
|
||||
|
||||
export default function CourierSegmentedReqHandle(Private) {
|
||||
const Events = Private(EventsProvider);
|
||||
|
||||
const segmentedRequest = Symbol('Actual Segmented Request');
|
||||
|
||||
/**
|
||||
* Simple class for creating an object to send to the
|
||||
* requester of a SegmentedRequest. Since the SegmentedRequest
|
||||
* extends AbstractRequest, it wasn't able to be the event
|
||||
* emitter it was born to be. This provides a channel for
|
||||
* setting values on the segmented request, and an event
|
||||
* emitter for the request to speak outwardly
|
||||
*
|
||||
* @param {SegmentedRequest} - req - the requst this handle relates to
|
||||
*/
|
||||
return class SegmentedHandle extends Events {
|
||||
constructor(req) {
|
||||
super();
|
||||
this[segmentedRequest] = req;
|
||||
}
|
||||
|
||||
setDirection(...args) {
|
||||
this[segmentedRequest].setDirection(...args);
|
||||
}
|
||||
|
||||
setSize(...args) {
|
||||
this[segmentedRequest].setSize(...args);
|
||||
}
|
||||
|
||||
setMaxSegments(...args) {
|
||||
this[segmentedRequest].setMaxSegments(...args);
|
||||
}
|
||||
|
||||
setSortFn(...args) {
|
||||
this[segmentedRequest].setSortFn(...args);
|
||||
}
|
||||
};
|
||||
};
|
|
@ -2,7 +2,9 @@ import _ from 'lodash';
|
|||
import sinon from 'auto-release-sinon';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ngMock';
|
||||
import CourierFetchStrategySearchProvider from 'ui/courier/fetch/strategy/search';
|
||||
|
||||
import SearchStrategyProvider from '../search';
|
||||
|
||||
describe('ui/courier/fetch/strategy/search', () => {
|
||||
|
||||
let Promise;
|
||||
|
@ -15,7 +17,7 @@ describe('ui/courier/fetch/strategy/search', () => {
|
|||
beforeEach(ngMock.inject((Private, $injector) => {
|
||||
Promise = $injector.get('Promise');
|
||||
$rootScope = $injector.get('$rootScope');
|
||||
search = Private(CourierFetchStrategySearchProvider);
|
||||
search = Private(SearchStrategyProvider);
|
||||
reqsFetchParams = [
|
||||
{
|
||||
index: ['logstash-123'],
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { toJson } from 'ui/utils/aggressive_parse';
|
||||
import _ from 'lodash';
|
||||
import angular from 'angular';
|
||||
|
||||
import { toJson } from 'ui/utils/aggressive_parse';
|
||||
|
||||
export default function FetchStrategyForSearch(Private, Promise, timefilter) {
|
||||
|
||||
return {
|
||||
|
@ -20,7 +22,7 @@ export default function FetchStrategyForSearch(Private, Promise, timefilter) {
|
|||
return indexList;
|
||||
}
|
||||
|
||||
var timeBounds = timefilter.getBounds();
|
||||
const timeBounds = timefilter.getBounds();
|
||||
return indexList.toIndexList(timeBounds.min, timeBounds.max);
|
||||
})
|
||||
.then(function (indexList) {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import _ from 'lodash';
|
||||
export default function LooperFactory($timeout, Notifier, Promise) {
|
||||
|
||||
import 'ui/promises';
|
||||
import Notifier from 'ui/notify/notifier';
|
||||
|
||||
export default function LooperFactory($timeout, Promise) {
|
||||
var notify = new Notifier();
|
||||
|
||||
function Looper(ms, fn) {
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import CourierFetchFetchProvider from 'ui/courier/fetch/fetch';
|
||||
import CourierLooperLooperProvider from 'ui/courier/looper/_looper';
|
||||
import CourierFetchStrategyDocProvider from 'ui/courier/fetch/strategy/doc';
|
||||
import FetchProvider from '../fetch';
|
||||
import LooperProvider from './_looper';
|
||||
import DocStrategyProvider from '../fetch/strategy/doc';
|
||||
|
||||
export default function DocLooperService(Private) {
|
||||
var fetch = Private(CourierFetchFetchProvider);
|
||||
var Looper = Private(CourierLooperLooperProvider);
|
||||
var docStrategy = Private(CourierFetchStrategyDocProvider);
|
||||
var fetch = Private(FetchProvider);
|
||||
var Looper = Private(LooperProvider);
|
||||
var DocStrategy = Private(DocStrategyProvider);
|
||||
|
||||
/**
|
||||
* The Looper which will manage the doc fetch interval
|
||||
* @type {Looper}
|
||||
*/
|
||||
var docLooper = new Looper(1500, function () {
|
||||
fetch.fetchQueued(docStrategy);
|
||||
fetch.fetchQueued(DocStrategy);
|
||||
});
|
||||
|
||||
return docLooper;
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import CourierFetchFetchProvider from 'ui/courier/fetch/fetch';
|
||||
import CourierFetchStrategySearchProvider from 'ui/courier/fetch/strategy/search';
|
||||
import CourierRequestQueueProvider from 'ui/courier/_request_queue';
|
||||
import CourierLooperLooperProvider from 'ui/courier/looper/_looper';
|
||||
import FetchProvider from '../fetch';
|
||||
import SearchStrategyProvider from '../fetch/strategy/search';
|
||||
import RequestQueueProvider from '../_request_queue';
|
||||
import LooperProvider from './_looper';
|
||||
|
||||
export default function SearchLooperService(Private, Promise, Notifier, $rootScope) {
|
||||
var fetch = Private(CourierFetchFetchProvider);
|
||||
var searchStrategy = Private(CourierFetchStrategySearchProvider);
|
||||
var requestQueue = Private(CourierRequestQueueProvider);
|
||||
var fetch = Private(FetchProvider);
|
||||
var searchStrategy = Private(SearchStrategyProvider);
|
||||
var requestQueue = Private(RequestQueueProvider);
|
||||
|
||||
var Looper = Private(CourierLooperLooperProvider);
|
||||
var Looper = Private(LooperProvider);
|
||||
var notif = new Notifier({ location: 'Search Looper' });
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import angular from 'angular';
|
||||
import errors from 'ui/errors';
|
||||
import _ from 'lodash';
|
||||
|
||||
import errors from 'ui/errors';
|
||||
import slugifyId from 'ui/utils/slugify_id';
|
||||
import CourierDataSourceDocSourceProvider from 'ui/courier/data_source/doc_source';
|
||||
import CourierDataSourceSearchSourceProvider from 'ui/courier/data_source/search_source';
|
||||
import UtilsMappingSetupProvider from 'ui/utils/mapping_setup';
|
||||
import MappingSetupProvider from 'ui/utils/mapping_setup';
|
||||
|
||||
import DocSourceProvider from '../data_source/doc_source';
|
||||
import SearchSourceProvider from '../data_source/search_source';
|
||||
|
||||
export default function SavedObjectFactory(es, kbnIndex, Promise, Private, Notifier, safeConfirm, indexPatterns) {
|
||||
|
||||
var DocSource = Private(CourierDataSourceDocSourceProvider);
|
||||
var SearchSource = Private(CourierDataSourceSearchSourceProvider);
|
||||
var mappingSetup = Private(UtilsMappingSetupProvider);
|
||||
var DocSource = Private(DocSourceProvider);
|
||||
var SearchSource = Private(SearchSourceProvider);
|
||||
var mappingSetup = Private(MappingSetupProvider);
|
||||
|
||||
function SavedObject(config) {
|
||||
if (!_.isObject(config)) config = {};
|
||||
|
|
|
@ -7,7 +7,7 @@ import errors from 'ui/errors';
|
|||
import IndexedArray from 'ui/IndexedArray';
|
||||
import FixturesLogstashFieldsProvider from 'fixtures/logstash_fields';
|
||||
import FixturesStubbedDocSourceResponseProvider from 'fixtures/stubbed_doc_source_response';
|
||||
import CourierDataSourceDocSourceProvider from 'ui/courier/data_source/doc_source';
|
||||
import DocSourceProvider from 'ui/courier/data_source/doc_source';
|
||||
import IndexPatternsMapperProvider from 'ui/index_patterns/_mapper';
|
||||
import UtilsMappingSetupProvider from 'ui/utils/mapping_setup';
|
||||
import IndexPatternsIntervalsProvider from 'ui/index_patterns/_intervals';
|
||||
|
@ -33,7 +33,7 @@ describe('index pattern', function () {
|
|||
mockLogstashFields = Private(FixturesLogstashFieldsProvider);
|
||||
docSourceResponse = Private(FixturesStubbedDocSourceResponseProvider);
|
||||
|
||||
DocSource = Private(CourierDataSourceDocSourceProvider);
|
||||
DocSource = Private(DocSourceProvider);
|
||||
sinon.stub(DocSource.prototype, 'doIndex');
|
||||
sinon.stub(DocSource.prototype, 'fetch');
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import RegistryFieldFormatsProvider from 'ui/registry/field_formats';
|
|||
import IndexPatternsGetIdsProvider from 'ui/index_patterns/_get_ids';
|
||||
import IndexPatternsMapperProvider from 'ui/index_patterns/_mapper';
|
||||
import IndexPatternsIntervalsProvider from 'ui/index_patterns/_intervals';
|
||||
import CourierDataSourceDocSourceProvider from 'ui/courier/data_source/doc_source';
|
||||
import DocSourceProvider from 'ui/courier/data_source/doc_source';
|
||||
import UtilsMappingSetupProvider from 'ui/utils/mapping_setup';
|
||||
import IndexPatternsFieldListProvider from 'ui/index_patterns/_field_list';
|
||||
import IndexPatternsFlattenHitProvider from 'ui/index_patterns/_flatten_hit';
|
||||
|
@ -19,7 +19,7 @@ export default function IndexPatternFactory(Private, timefilter, Notifier, confi
|
|||
var getIds = Private(IndexPatternsGetIdsProvider);
|
||||
var mapper = Private(IndexPatternsMapperProvider);
|
||||
var intervals = Private(IndexPatternsIntervalsProvider);
|
||||
var DocSource = Private(CourierDataSourceDocSourceProvider);
|
||||
var DocSource = Private(DocSourceProvider);
|
||||
var mappingSetup = Private(UtilsMappingSetupProvider);
|
||||
var FieldList = Private(IndexPatternsFieldListProvider);
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ export default function MapperService(Private, Promise, es, config, kbnIndex) {
|
|||
};
|
||||
|
||||
self.getIndicesForIndexPattern = function (indexPattern) {
|
||||
return es.indices.getAliases({
|
||||
return es.indices.getAlias({
|
||||
index: patternToWildcard(indexPattern.id)
|
||||
})
|
||||
.then(function (resp) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import _ from 'lodash';
|
||||
import CourierDataSourceDecorateQueryProvider from 'ui/courier/data_source/_decorate_query';
|
||||
import DecorateQueryProvider from 'ui/courier/data_source/_decorate_query';
|
||||
export default function GetQueryFromUser(es, Private) {
|
||||
var decorateQuery = Private(CourierDataSourceDecorateQueryProvider);
|
||||
var decorateQuery = Private(DecorateQueryProvider);
|
||||
|
||||
/**
|
||||
* Take text from the user and make it into a query object
|
||||
|
|
|
@ -11,6 +11,7 @@ var config;
|
|||
var formatIds = [
|
||||
'bytes',
|
||||
'date',
|
||||
'duration',
|
||||
'ip',
|
||||
'number',
|
||||
'percent',
|
||||
|
|
50
src/ui/public/stringify/__tests__/_duration.js
Normal file
50
src/ui/public/stringify/__tests__/_duration.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
import expect from 'expect.js';
|
||||
import ngMock from 'ngMock';
|
||||
import RegistryFieldFormatsProvider from 'ui/registry/field_formats';
|
||||
|
||||
describe('Duration Format', function () {
|
||||
let fieldFormats;
|
||||
let DurationFormat;
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
fieldFormats = Private(RegistryFieldFormatsProvider);
|
||||
DurationFormat = fieldFormats.getType('duration');
|
||||
}));
|
||||
|
||||
test({ inputFormat: 'seconds', outputFormat: 'humanize' })
|
||||
(-60, 'minus a minute')
|
||||
(60, 'a minute')
|
||||
(125, '2 minutes');
|
||||
|
||||
test({ inputFormat: 'minutes', outputFormat: 'humanize' })
|
||||
(-60, 'minus an hour')
|
||||
(60, 'an hour')
|
||||
(125, '2 hours');
|
||||
|
||||
test({ inputFormat: 'minutes', outputFormat: 'asHours' }) // outputPrecision defaults to: 2
|
||||
(-60, '-1.00')
|
||||
(60, '1.00')
|
||||
(125, '2.08');
|
||||
|
||||
test({ inputFormat: 'seconds', outputFormat: 'asSeconds', outputPrecision: 0 })
|
||||
(-60, '-60')
|
||||
(60, '60')
|
||||
(125, '125');
|
||||
|
||||
test({ inputFormat: 'seconds', outputFormat: 'asSeconds', outputPrecision: 2 })
|
||||
(-60, '-60.00')
|
||||
(-32.333, '-32.33')
|
||||
(60, '60.00')
|
||||
(125, '125.00');
|
||||
|
||||
function test({ inputFormat, outputFormat, outputPrecision }) {
|
||||
return function testFixture(input, output) {
|
||||
it(`should format ${input} ${inputFormat} through ${outputFormat}${outputPrecision ? `, ${outputPrecision} decimals` : ''}`, () => {
|
||||
const duration = new DurationFormat({ inputFormat, outputFormat, outputPrecision });
|
||||
expect(duration.convert(input)).to.eql(output);
|
||||
});
|
||||
return testFixture;
|
||||
};
|
||||
}
|
||||
});
|
|
@ -9,7 +9,7 @@ describe('IP Address Format', function () {
|
|||
fieldFormats = Private(RegistryFieldFormatsProvider);
|
||||
}));
|
||||
|
||||
it('convers a value from a decimal to a string', function () {
|
||||
it('converts a value from a decimal to a string', function () {
|
||||
var ip = fieldFormats.getInstance('ip');
|
||||
expect(ip.convert(1186489492)).to.be('70.184.100.148');
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@ import './_string';
|
|||
import './_url';
|
||||
import './_color';
|
||||
import './_date';
|
||||
import './_duration';
|
||||
import './_truncate';
|
||||
describe('Stringify Component', function () {
|
||||
});
|
||||
|
|
28
src/ui/public/stringify/editors/duration.html
Normal file
28
src/ui/public/stringify/editors/duration.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
<div class="editor-duration">
|
||||
<div class="form-group">
|
||||
<label>Input Format</label>
|
||||
<select
|
||||
ng-model="editor.formatParams.inputFormat"
|
||||
ng-options="inputFormat.kind as inputFormat.text for inputFormat in editor.field.format.type.inputFormats"
|
||||
class="form-control">
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Output Format</label>
|
||||
<select
|
||||
ng-model="editor.formatParams.outputFormat"
|
||||
ng-options="outputFormat.method as outputFormat.text for outputFormat in editor.field.format.type.outputFormats"
|
||||
class="form-control">
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" ng-hide="editor.field.format.isHuman()">
|
||||
<label>Decimal Places</label>
|
||||
<input type="number" min="0" max="20" ng-model="editor.formatParams.outputPrecision" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<field-format-editor-samples
|
||||
ng-model="editor.formatParams"
|
||||
inputs="cntrl.sampleInputs">
|
||||
</field-format-editor-samples>
|
||||
</div>
|
10
src/ui/public/stringify/editors/duration.less
Normal file
10
src/ui/public/stringify/editors/duration.less
Normal file
|
@ -0,0 +1,10 @@
|
|||
.editor-duration {
|
||||
display: flex;
|
||||
> .form-group {
|
||||
flex: 1 1 1%;
|
||||
padding-right: 5px;
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ import fieldFormats from 'ui/registry/field_formats';
|
|||
import stringifyUrl from 'ui/stringify/types/Url';
|
||||
import stringifyBytes from 'ui/stringify/types/Bytes';
|
||||
import stringifyDate from 'ui/stringify/types/Date';
|
||||
import stringifyDuration from 'ui/stringify/types/duration';
|
||||
import stringifyIp from 'ui/stringify/types/Ip';
|
||||
import stringifyNumber from 'ui/stringify/types/Number';
|
||||
import stringifyPercent from 'ui/stringify/types/Percent';
|
||||
|
@ -12,6 +13,7 @@ import stringifyTruncate from 'ui/stringify/types/truncate';
|
|||
fieldFormats.register(stringifyUrl);
|
||||
fieldFormats.register(stringifyBytes);
|
||||
fieldFormats.register(stringifyDate);
|
||||
fieldFormats.register(stringifyDuration);
|
||||
fieldFormats.register(stringifyIp);
|
||||
fieldFormats.register(stringifyNumber);
|
||||
fieldFormats.register(stringifyPercent);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import 'ui/stringify/editors/color.less';
|
||||
import _ from 'lodash';
|
||||
import IndexPatternsFieldFormatFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
import IndexPatternsFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
import colorTemplate from 'ui/stringify/editors/color.html';
|
||||
export default function _StringProvider(Private) {
|
||||
export default function ColorFormatProvider(Private) {
|
||||
|
||||
const FieldFormat = Private(IndexPatternsFieldFormatFieldFormatProvider);
|
||||
const FieldFormat = Private(IndexPatternsFieldFormatProvider);
|
||||
const DEFAULT_COLOR = {
|
||||
range: `${Number.NEGATIVE_INFINITY}:${Number.POSITIVE_INFINITY}`,
|
||||
text: '#000000',
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
import 'ui/field_format_editor/pattern/pattern';
|
||||
import IndexPatternsFieldFormatFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
import IndexPatternsFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
import BoundToConfigObjProvider from 'ui/bound_to_config_obj';
|
||||
import dateTemplate from 'ui/stringify/editors/date.html';
|
||||
export default function DateTimeFormatProvider(Private) {
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatFieldFormatProvider);
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatProvider);
|
||||
var BoundToConfigObj = Private(BoundToConfigObjProvider);
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import _ from 'lodash';
|
||||
import IndexPatternsFieldFormatFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
import IndexPatternsFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
export default function IpFormatProvider(Private) {
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatFieldFormatProvider);
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatProvider);
|
||||
|
||||
_.class(Ip).inherits(FieldFormat);
|
||||
function Ip(params) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import _ from 'lodash';
|
||||
import BoundToConfigObjProvider from 'ui/bound_to_config_obj';
|
||||
import StringifyTypesNumeralProvider from 'ui/stringify/types/_Numeral';
|
||||
export default function NumberFormatProvider(Private) {
|
||||
export default function PercentFormatProvider(Private) {
|
||||
var BoundToConfigObj = Private(BoundToConfigObjProvider);
|
||||
var Numeral = Private(StringifyTypesNumeralProvider);
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import _ from 'lodash';
|
||||
import noWhiteSpace from 'ui/utils/no_white_space';
|
||||
import angular from 'angular';
|
||||
import IndexPatternsFieldFormatFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
export default function _SourceProvider(Private, shortDotsFilter) {
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatFieldFormatProvider);
|
||||
import IndexPatternsFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
export default function _SourceFormatProvider(Private, shortDotsFilter) {
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatProvider);
|
||||
var template = _.template(noWhiteSpace(require('ui/stringify/types/_source.html')));
|
||||
|
||||
_.class(Source).inherits(FieldFormat);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import _ from 'lodash';
|
||||
import 'ui/field_format_editor/samples/samples';
|
||||
import IndexPatternsFieldFormatFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
export default function _StringProvider(Private) {
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatFieldFormatProvider);
|
||||
import IndexPatternsFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
export default function StringFormatProvider(Private) {
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatProvider);
|
||||
|
||||
|
||||
_.class(_String).inherits(FieldFormat);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import _ from 'lodash';
|
||||
import 'ui/field_format_editor/pattern/pattern';
|
||||
import 'ui/stringify/icons';
|
||||
import IndexPatternsFieldFormatFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
import IndexPatternsFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
import urlTemplate from 'ui/stringify/editors/url.html';
|
||||
export default function UrlFormatProvider(Private, highlightFilter) {
|
||||
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatFieldFormatProvider);
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatProvider);
|
||||
|
||||
|
||||
_.class(Url).inherits(FieldFormat);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import _ from 'lodash';
|
||||
import 'ui/field_format_editor/numeral/numeral';
|
||||
import IndexPatternsFieldFormatFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
import IndexPatternsFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
import BoundToConfigObjProvider from 'ui/bound_to_config_obj';
|
||||
export default function AbstractNumeralFormatProvider(Private) {
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatFieldFormatProvider);
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatProvider);
|
||||
var BoundToConfigObj = Private(BoundToConfigObjProvider);
|
||||
var numeral = require('numeral')();
|
||||
|
||||
|
|
98
src/ui/public/stringify/types/duration.js
Normal file
98
src/ui/public/stringify/types/duration.js
Normal file
|
@ -0,0 +1,98 @@
|
|||
import 'ui/stringify/editors/duration.less';
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
import IndexPatternsFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
import durationTemplate from 'ui/stringify/editors/duration.html';
|
||||
|
||||
export default function DurationFormatProvider(Private) {
|
||||
const ratioToSeconds = {
|
||||
picoseconds: 0.000000000001,
|
||||
nanoseconds: 0.000000001,
|
||||
microseconds: 0.000001
|
||||
};
|
||||
const FieldFormat = Private(IndexPatternsFieldFormatProvider);
|
||||
const HUMAN_FRIENDLY = 'humanize';
|
||||
const DEFAULT_OUTPUT_PRECISION = 2;
|
||||
const DEFAULT_INPUT_FORMAT = { text: 'Seconds', kind: 'seconds' };
|
||||
const inputFormats = [
|
||||
{ text: 'Picoseconds', kind: 'picoseconds' },
|
||||
{ text: 'Nanoseconds', kind: 'nanoseconds' },
|
||||
{ text: 'Microseconds', kind: 'microseconds' },
|
||||
{ text: 'Milliseconds', kind: 'milliseconds' },
|
||||
DEFAULT_INPUT_FORMAT,
|
||||
{ text: 'Minutes', kind: 'minutes' },
|
||||
{ text: 'Hours', kind: 'hours' },
|
||||
{ text: 'Days', kind: 'days' },
|
||||
{ text: 'Weeks', kind: 'weeks' },
|
||||
{ text: 'Months', kind: 'months' },
|
||||
{ text: 'Years', kind: 'years' }
|
||||
];
|
||||
const DEFAULT_OUTPUT_FORMAT = { text: 'Human Readable', method: 'humanize' };
|
||||
const outputFormats = [
|
||||
DEFAULT_OUTPUT_FORMAT,
|
||||
{ text: 'Milliseconds', method: 'asMilliseconds' },
|
||||
{ text: 'Seconds', method: 'asSeconds' },
|
||||
{ text: 'Minutes', method: 'asMinutes' },
|
||||
{ text: 'Hours', method: 'asHours' },
|
||||
{ text: 'Days', method: 'asDays' },
|
||||
{ text: 'Weeks', method: 'asWeeks' },
|
||||
{ text: 'Months', method: 'asMonths' },
|
||||
{ text: 'Years', method: 'asYears' }
|
||||
];
|
||||
|
||||
class Duration extends FieldFormat {
|
||||
isHuman() {
|
||||
return this.param('outputFormat') === HUMAN_FRIENDLY;
|
||||
}
|
||||
_convert(val) {
|
||||
const inputFormat = this.param('inputFormat');
|
||||
const outputFormat = this.param('outputFormat');
|
||||
const outputPrecision = this.param('outputPrecision');
|
||||
const human = this.isHuman();
|
||||
const prefix = val < 0 && human ? 'minus ' : '';
|
||||
const duration = parseInputAsDuration(val, inputFormat);
|
||||
const formatted = duration[outputFormat]();
|
||||
const precise = human ? formatted : formatted.toFixed(outputPrecision);
|
||||
return prefix + precise;
|
||||
}
|
||||
}
|
||||
|
||||
Duration.id = 'duration';
|
||||
Duration.title = 'Duration';
|
||||
Duration.fieldType = 'number';
|
||||
|
||||
Duration.inputFormats = inputFormats;
|
||||
Duration.outputFormats = outputFormats;
|
||||
|
||||
Duration.editor = {
|
||||
template: durationTemplate,
|
||||
controllerAs: 'cntrl',
|
||||
controller($scope, $interval) {
|
||||
this.sampleInputs = [
|
||||
-123,
|
||||
1,
|
||||
12,
|
||||
123,
|
||||
658,
|
||||
1988,
|
||||
3857,
|
||||
123292,
|
||||
923528271
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
Duration.paramDefaults = {
|
||||
inputFormat: DEFAULT_INPUT_FORMAT.kind,
|
||||
outputFormat: DEFAULT_OUTPUT_FORMAT.method,
|
||||
outputPrecision: DEFAULT_OUTPUT_PRECISION
|
||||
};
|
||||
|
||||
return Duration;
|
||||
|
||||
function parseInputAsDuration(val, inputFormat) {
|
||||
const ratio = ratioToSeconds[inputFormat] || 1;
|
||||
const kind = inputFormat in ratioToSeconds ? 'seconds' : inputFormat;
|
||||
return moment.duration(val * ratio, kind);
|
||||
}
|
||||
};
|
|
@ -1,7 +1,7 @@
|
|||
import _ from 'lodash';
|
||||
import IndexPatternsFieldFormatFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
import IndexPatternsFieldFormatProvider from 'ui/index_patterns/_field_format/FieldFormat';
|
||||
export default function TruncateFormatProvider(Private) {
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatFieldFormatProvider);
|
||||
var FieldFormat = Private(IndexPatternsFieldFormatProvider);
|
||||
var omission = '...';
|
||||
|
||||
_.class(Truncate).inherits(FieldFormat);
|
||||
|
|
|
@ -4,6 +4,9 @@ import Bluebird from 'bluebird';
|
|||
import 'elasticsearch-browser';
|
||||
import ngMock from 'ngMock';
|
||||
import sinon from 'sinon';
|
||||
import url from 'url';
|
||||
|
||||
import serverConfig from '../../../../../test/serverConfig';
|
||||
|
||||
describe('Scanner', function () {
|
||||
let es;
|
||||
|
@ -11,7 +14,7 @@ describe('Scanner', function () {
|
|||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (esFactory) {
|
||||
es = esFactory({
|
||||
host: 'http://localhost:9210',
|
||||
host: url.format(serverConfig.servers.elasticsearch),
|
||||
defer: function () {
|
||||
return Bluebird.defer();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ module.exports = function (grunt) {
|
|||
var resolve = require('path').resolve;
|
||||
var directory = resolve(__dirname, '../../esvm');
|
||||
var dataDir = resolve(directory, 'data_dir');
|
||||
var uiConfig = require('../../test/serverConfig');
|
||||
var serverConfig = require('../../test/serverConfig');
|
||||
|
||||
return {
|
||||
options: {
|
||||
|
@ -14,11 +14,6 @@ module.exports = function (grunt) {
|
|||
},
|
||||
http: {
|
||||
port: 9200
|
||||
},
|
||||
marvel: {
|
||||
agent: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -41,7 +36,7 @@ module.exports = function (grunt) {
|
|||
purge: true,
|
||||
config: {
|
||||
http: {
|
||||
port: 9210
|
||||
port: serverConfig.servers.elasticsearch.port
|
||||
},
|
||||
cluster: {
|
||||
name: 'esvm-test'
|
||||
|
@ -55,7 +50,7 @@ module.exports = function (grunt) {
|
|||
purge: true,
|
||||
config: {
|
||||
http: {
|
||||
port: uiConfig.servers.elasticsearch.port
|
||||
port: serverConfig.servers.elasticsearch.port
|
||||
},
|
||||
cluster: {
|
||||
name: 'esvm-ui'
|
||||
|
|
|
@ -13,7 +13,7 @@ describe('getUrl', function () {
|
|||
expect(url).to.be('http://localhost/foo');
|
||||
});
|
||||
|
||||
it('should convert to a secure url with port', function () {
|
||||
it('should convert to a url with port', function () {
|
||||
var url = getUrl({
|
||||
protocol: 'http',
|
||||
hostname: 'localhost',
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import url from 'url';
|
||||
import { defaultsDeep, set } from 'lodash';
|
||||
import { header as basicAuthHeader } from './base_auth';
|
||||
import { kibanaUser, kibanaServer } from '../shield';
|
||||
import KbnServer from '../../src/server/KbnServer';
|
||||
import fromRoot from '../../src/utils/fromRoot';
|
||||
import serverConfig from '../serverConfig';
|
||||
|
||||
const SERVER_DEFAULTS = {
|
||||
server: {
|
||||
|
@ -23,7 +25,7 @@ const SERVER_DEFAULTS = {
|
|||
enabled: false
|
||||
},
|
||||
elasticsearch: {
|
||||
url: 'http://localhost:9210',
|
||||
url: url.format(serverConfig.servers.elasticsearch),
|
||||
username: kibanaServer.username,
|
||||
password: kibanaServer.password
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue