From 5ff56e200cf1624b62aa3bf01cd19828699273fd Mon Sep 17 00:00:00 2001 From: Matthew Bargar Date: Fri, 22 Sep 2017 13:18:44 -0400 Subject: [PATCH 1/5] Fallback on raw values instead of failing if index pattern is not found --- .../filter_bar/lib/map_geo_bounding_box.js | 25 ++++++++++++++----- .../public/filter_bar/lib/map_geo_polygon.js | 23 +++++++++++++---- src/ui/public/filter_bar/lib/map_phrase.js | 19 ++++++++++---- src/ui/public/filter_bar/lib/map_range.js | 24 +++++++++++++----- src/ui/public/filter_bar/lib/map_script.js | 24 ++++++------------ 5 files changed, 77 insertions(+), 38 deletions(-) diff --git a/src/ui/public/filter_bar/lib/map_geo_bounding_box.js b/src/ui/public/filter_bar/lib/map_geo_bounding_box.js index 5a73f44db9159..3835030f5b3f3 100644 --- a/src/ui/public/filter_bar/lib/map_geo_bounding_box.js +++ b/src/ui/public/filter_bar/lib/map_geo_bounding_box.js @@ -1,20 +1,33 @@ import _ from 'lodash'; +import { SavedObjectNotFound } from '../../errors'; export function FilterBarLibMapGeoBoundingBoxProvider(Promise, courier) { return function (filter) { if (filter.geo_bounding_box) { - return courier - .indexPatterns - .get(filter.meta.index).then(function (indexPattern) { + function getParams(indexPattern) { const type = 'geo_bounding_box'; const key = _.keys(filter.geo_bounding_box) .filter(key => key !== 'ignore_unmapped')[0]; - const field = indexPattern.fields.byName[key]; const params = filter.geo_bounding_box[key]; - const topLeft = field.format.convert(params.top_left); - const bottomRight = field.format.convert(params.bottom_right); + const topLeft = indexPattern + ? indexPattern.fields.byName[key].format.convert(params.top_left) + : JSON.stringify(params.top_left); + const bottomRight = indexPattern + ? indexPattern.fields.byName[key].format.convert(params.bottom_right) + : JSON.stringify(params.bottom_right); const value = topLeft + ' to ' + bottomRight; return { type, key, value, params }; + } + + return courier + .indexPatterns + .get(filter.meta.index) + .then(getParams) + .catch((error) => { + if (error instanceof SavedObjectNotFound) { + return getParams(); + } + throw error; }); } return Promise.reject(filter); diff --git a/src/ui/public/filter_bar/lib/map_geo_polygon.js b/src/ui/public/filter_bar/lib/map_geo_polygon.js index f7553303a52bd..2a5ebe6c9591a 100644 --- a/src/ui/public/filter_bar/lib/map_geo_polygon.js +++ b/src/ui/public/filter_bar/lib/map_geo_polygon.js @@ -1,19 +1,32 @@ import _ from 'lodash'; +import { SavedObjectNotFound } from '../../errors'; export function FilterBarLibMapGeoPolygonProvider(Promise, courier) { return function (filter) { if (filter.geo_polygon) { - return courier - .indexPatterns - .get(filter.meta.index).then(function (indexPattern) { + function getParams(indexPattern) { const type = 'geo_polygon'; const key = _.keys(filter.geo_polygon) .filter(key => key !== 'ignore_unmapped')[0]; - const field = indexPattern.fields.byName[key]; const params = filter.geo_polygon[key]; - const points = params.points.map((point) => field.format.convert(point)); + const points = params.points.map((point) => { + return indexPattern + ? indexPattern.fields.byName[key].format.convert(point) + : JSON.stringify(point); + }); const value = points.join(', '); return { type, key, value, params }; + } + + return courier + .indexPatterns + .get(filter.meta.index) + .then(getParams) + .catch((error) => { + if (error instanceof SavedObjectNotFound) { + return getParams(); + } + throw error; }); } return Promise.reject(filter); diff --git a/src/ui/public/filter_bar/lib/map_phrase.js b/src/ui/public/filter_bar/lib/map_phrase.js index 8bbd78cd48994..860152a3e4f78 100644 --- a/src/ui/public/filter_bar/lib/map_phrase.js +++ b/src/ui/public/filter_bar/lib/map_phrase.js @@ -1,4 +1,5 @@ import _ from 'lodash'; +import { SavedObjectNotFound } from '../../errors'; export function FilterBarLibMapPhraseProvider(Promise, courier) { return function (filter) { @@ -7,16 +8,24 @@ export function FilterBarLibMapPhraseProvider(Promise, courier) { return Promise.reject(filter); } - return courier - .indexPatterns - .get(filter.meta.index).then(function (indexPattern) { + function getParams(indexPattern) { const type = 'phrase'; const key = isScriptedPhraseFilter ? filter.meta.field : Object.keys(filter.query.match)[0]; - const field = indexPattern.fields.byName[key]; const params = isScriptedPhraseFilter ? filter.script.script.params : filter.query.match[key]; const query = isScriptedPhraseFilter ? params.value : params.query; - const value = field.format.convert(query); + const value = indexPattern ? indexPattern.fields.byName[key].format.convert(query) : query; return { type, key, value, params }; + } + + return courier + .indexPatterns + .get(filter.meta.index) + .then(getParams) + .catch((error) => { + if (error instanceof SavedObjectNotFound) { + return getParams(); + } + throw error; }); }; } diff --git a/src/ui/public/filter_bar/lib/map_range.js b/src/ui/public/filter_bar/lib/map_range.js index a8c94a14f4101..452ab76a66fd4 100644 --- a/src/ui/public/filter_bar/lib/map_range.js +++ b/src/ui/public/filter_bar/lib/map_range.js @@ -1,4 +1,5 @@ import { has, get } from 'lodash'; +import { SavedObjectNotFound } from '../../errors'; export function FilterBarLibMapRangeProvider(Promise, courier) { return function (filter) { @@ -7,13 +8,9 @@ export function FilterBarLibMapRangeProvider(Promise, courier) { return Promise.reject(filter); } - return courier - .indexPatterns - .get(filter.meta.index) - .then(function (indexPattern) { + function getParams(indexPattern) { const type = 'range'; const key = isScriptedRangeFilter ? filter.meta.field : Object.keys(filter.range)[0]; - const convert = indexPattern.fields.byName[key].format.getConverterFor('text'); const params = isScriptedRangeFilter ? filter.script.script.params : filter.range[key]; let left = has(params, 'gte') ? params.gte : params.gt; @@ -22,9 +19,24 @@ export function FilterBarLibMapRangeProvider(Promise, courier) { let right = has(params, 'lte') ? params.lte : params.lt; if (right == null) right = Infinity; - const value = `${convert(left)} to ${convert(right)}`; + let value = `${left} to ${right}`; + if (indexPattern) { + const convert = indexPattern.fields.byName[key].format.getConverterFor('text'); + value = `${convert(left)} to ${convert(right)}`; + } return { type, key, value, params }; + } + + return courier + .indexPatterns + .get(filter.meta.index) + .then(getParams) + .catch((error) => { + if (error instanceof SavedObjectNotFound) { + return getParams(); + } + throw error; }); }; diff --git a/src/ui/public/filter_bar/lib/map_script.js b/src/ui/public/filter_bar/lib/map_script.js index 90674aa3f6017..828c6da9fa20e 100644 --- a/src/ui/public/filter_bar/lib/map_script.js +++ b/src/ui/public/filter_bar/lib/map_script.js @@ -1,23 +1,15 @@ -export function FilterBarLibMapScriptProvider(Promise, courier) { +export function FilterBarLibMapScriptProvider(Promise) { return function (filter) { if (filter.script) { - return courier - .indexPatterns - .get(filter.meta.index).then(function (indexPattern) { - const type = 'scripted'; - const key = filter.meta.field; - const field = indexPattern.fields.byName[key]; + const type = 'scripted'; + const key = filter.meta.field; - let value; - if (filter.meta.formattedValue) { - value = filter.meta.formattedValue; - } else { - value = filter.script.script.params.value; - value = field.format.convert(value); - } + let value = ''; + if (filter.meta.formattedValue) { + value = filter.meta.formattedValue; + } - return { type, key, value }; - }); + return Promise.resolve({ type, key, value }); } return Promise.reject(filter); }; From 1e41623c59425ae8dc807a75b4456f1f4b161bbd Mon Sep 17 00:00:00 2001 From: Matthew Bargar Date: Fri, 22 Sep 2017 13:46:29 -0400 Subject: [PATCH 2/5] Update test --- src/ui/public/filter_bar/lib/__tests__/map_script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/public/filter_bar/lib/__tests__/map_script.js b/src/ui/public/filter_bar/lib/__tests__/map_script.js index a64e88a2d04f7..1a4b05860a00b 100644 --- a/src/ui/public/filter_bar/lib/__tests__/map_script.js +++ b/src/ui/public/filter_bar/lib/__tests__/map_script.js @@ -22,7 +22,7 @@ describe('Filter Bar Directive', function () { it('should return the key and value for matching filters', function (done) { const filter = { - meta: { index: 'logstash-*', field: 'script number' }, + meta: { index: 'logstash-*', field: 'script number', formattedValue: '35' }, script: { script: { inline: 'doc["script number"].value * 5', params: { value: 35 } } } }; mapScript(filter).then(function (result) { From 15c7162f1e693479c5ea7c3dcc65e23480e53ea2 Mon Sep 17 00:00:00 2001 From: Matthew Bargar Date: Wed, 27 Sep 2017 16:20:33 -0400 Subject: [PATCH 3/5] Add clarifying comment --- src/ui/public/filter_bar/lib/map_geo_bounding_box.js | 5 +++++ src/ui/public/filter_bar/lib/map_geo_polygon.js | 5 +++++ src/ui/public/filter_bar/lib/map_phrase.js | 5 +++++ src/ui/public/filter_bar/lib/map_range.js | 4 ++++ 4 files changed, 19 insertions(+) diff --git a/src/ui/public/filter_bar/lib/map_geo_bounding_box.js b/src/ui/public/filter_bar/lib/map_geo_bounding_box.js index 3835030f5b3f3..99ba8b92ed4a4 100644 --- a/src/ui/public/filter_bar/lib/map_geo_bounding_box.js +++ b/src/ui/public/filter_bar/lib/map_geo_bounding_box.js @@ -9,6 +9,11 @@ export function FilterBarLibMapGeoBoundingBoxProvider(Promise, courier) { const key = _.keys(filter.geo_bounding_box) .filter(key => key !== 'ignore_unmapped')[0]; const params = filter.geo_bounding_box[key]; + + // Sometimes a filter will end up with an invalid index param. This could happen for a lot of reasons, + // for example a user might manually edit the url or the index pattern's ID might change due to + // external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback + // on displaying the raw value if the index is invalid. const topLeft = indexPattern ? indexPattern.fields.byName[key].format.convert(params.top_left) : JSON.stringify(params.top_left); diff --git a/src/ui/public/filter_bar/lib/map_geo_polygon.js b/src/ui/public/filter_bar/lib/map_geo_polygon.js index 2a5ebe6c9591a..8466c8479057c 100644 --- a/src/ui/public/filter_bar/lib/map_geo_polygon.js +++ b/src/ui/public/filter_bar/lib/map_geo_polygon.js @@ -9,6 +9,11 @@ export function FilterBarLibMapGeoPolygonProvider(Promise, courier) { const key = _.keys(filter.geo_polygon) .filter(key => key !== 'ignore_unmapped')[0]; const params = filter.geo_polygon[key]; + + // Sometimes a filter will end up with an invalid index param. This could happen for a lot of reasons, + // for example a user might manually edit the url or the index pattern's ID might change due to + // external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback + // on displaying the raw value if the index is invalid. const points = params.points.map((point) => { return indexPattern ? indexPattern.fields.byName[key].format.convert(point) diff --git a/src/ui/public/filter_bar/lib/map_phrase.js b/src/ui/public/filter_bar/lib/map_phrase.js index 860152a3e4f78..3f924a2ef4b9c 100644 --- a/src/ui/public/filter_bar/lib/map_phrase.js +++ b/src/ui/public/filter_bar/lib/map_phrase.js @@ -13,6 +13,11 @@ export function FilterBarLibMapPhraseProvider(Promise, courier) { const key = isScriptedPhraseFilter ? filter.meta.field : Object.keys(filter.query.match)[0]; const params = isScriptedPhraseFilter ? filter.script.script.params : filter.query.match[key]; const query = isScriptedPhraseFilter ? params.value : params.query; + + // Sometimes a filter will end up with an invalid index param. This could happen for a lot of reasons, + // for example a user might manually edit the url or the index pattern's ID might change due to + // external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback + // on displaying the raw value if the index is invalid. const value = indexPattern ? indexPattern.fields.byName[key].format.convert(query) : query; return { type, key, value, params }; } diff --git a/src/ui/public/filter_bar/lib/map_range.js b/src/ui/public/filter_bar/lib/map_range.js index 452ab76a66fd4..dcd82486ea5c4 100644 --- a/src/ui/public/filter_bar/lib/map_range.js +++ b/src/ui/public/filter_bar/lib/map_range.js @@ -19,6 +19,10 @@ export function FilterBarLibMapRangeProvider(Promise, courier) { let right = has(params, 'lte') ? params.lte : params.lt; if (right == null) right = Infinity; + // Sometimes a filter will end up with an invalid index param. This could happen for a lot of reasons, + // for example a user might manually edit the url or the index pattern's ID might change due to + // external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback + // on displaying the raw value if the index is invalid. let value = `${left} to ${right}`; if (indexPattern) { const convert = indexPattern.fields.byName[key].format.getConverterFor('text'); From 8c7b19837721084e721f48dfedb0901388e3a159 Mon Sep 17 00:00:00 2001 From: Matthew Bargar Date: Wed, 27 Sep 2017 16:27:40 -0400 Subject: [PATCH 4/5] Fixed indentation --- src/ui/public/filter_bar/lib/map_geo_bounding_box.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/public/filter_bar/lib/map_geo_bounding_box.js b/src/ui/public/filter_bar/lib/map_geo_bounding_box.js index 99ba8b92ed4a4..31a21a3b5c1e4 100644 --- a/src/ui/public/filter_bar/lib/map_geo_bounding_box.js +++ b/src/ui/public/filter_bar/lib/map_geo_bounding_box.js @@ -15,11 +15,11 @@ export function FilterBarLibMapGeoBoundingBoxProvider(Promise, courier) { // external factors e.g. a reindex. We only need the index in order to grab the field formatter, so we fallback // on displaying the raw value if the index is invalid. const topLeft = indexPattern - ? indexPattern.fields.byName[key].format.convert(params.top_left) - : JSON.stringify(params.top_left); + ? indexPattern.fields.byName[key].format.convert(params.top_left) + : JSON.stringify(params.top_left); const bottomRight = indexPattern - ? indexPattern.fields.byName[key].format.convert(params.bottom_right) - : JSON.stringify(params.bottom_right); + ? indexPattern.fields.byName[key].format.convert(params.bottom_right) + : JSON.stringify(params.bottom_right); const value = topLeft + ' to ' + bottomRight; return { type, key, value, params }; } From 32f54ef782fa39533e433b6ab753c8b2fd7a0edd Mon Sep 17 00:00:00 2001 From: Matthew Bargar Date: Wed, 27 Sep 2017 16:43:16 -0400 Subject: [PATCH 5/5] Remove map_script which no longer seems to be used --- .../filter_bar/lib/__tests__/map_script.js | 69 ------------------- src/ui/public/filter_bar/lib/map_filter.js | 2 - src/ui/public/filter_bar/lib/map_script.js | 16 ----- 3 files changed, 87 deletions(-) delete mode 100644 src/ui/public/filter_bar/lib/__tests__/map_script.js delete mode 100644 src/ui/public/filter_bar/lib/map_script.js diff --git a/src/ui/public/filter_bar/lib/__tests__/map_script.js b/src/ui/public/filter_bar/lib/__tests__/map_script.js deleted file mode 100644 index 1a4b05860a00b..0000000000000 --- a/src/ui/public/filter_bar/lib/__tests__/map_script.js +++ /dev/null @@ -1,69 +0,0 @@ -import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import { FilterBarLibMapScriptProvider } from 'ui/filter_bar/lib/map_script'; - -describe('Filter Bar Directive', function () { - describe('mapScript()', function () { - let mapScript; - let $rootScope; - - beforeEach(ngMock.module( - 'kibana', - 'kibana/courier', - function ($provide) { - $provide.service('courier', require('fixtures/mock_courier')); - } - )); - - beforeEach(ngMock.inject(function (Private, _$rootScope_) { - $rootScope = _$rootScope_; - mapScript = Private(FilterBarLibMapScriptProvider); - })); - - it('should return the key and value for matching filters', function (done) { - const filter = { - meta: { index: 'logstash-*', field: 'script number', formattedValue: '35' }, - script: { script: { inline: 'doc["script number"].value * 5', params: { value: 35 } } } - }; - mapScript(filter).then(function (result) { - expect(result).to.have.property('key', 'script number'); - expect(result).to.have.property('value', '35'); - done(); - }); - $rootScope.$apply(); - }); - - it('should return undefined for none matching', function (done) { - const filter = { meta: { index: 'logstash-*' }, query: { query_string: { query: 'foo:bar' } } }; - mapScript(filter).catch(function (result) { - expect(result).to.be(filter); - done(); - }); - $rootScope.$apply(); - }); - - it('should return a value for a range/histogram filter from a scripted field', (done) => { - const filter = { - meta: { - index: 'logstash-*', - formattedValue: '1,000.00 to 2,000.00', - field: 'script number' - }, - script: { - script: { - params: { - gte: 1000, - lt: 2000, - value: '>=1,000.00 <2,000.00' - } - } - } - }; - mapScript(filter).then((result) => { - expect(result).to.have.property('value', filter.meta.formattedValue); - done(); - }); - $rootScope.$apply(); - }); - }); -}); diff --git a/src/ui/public/filter_bar/lib/map_filter.js b/src/ui/public/filter_bar/lib/map_filter.js index a186258c047bc..50c080098ae6f 100644 --- a/src/ui/public/filter_bar/lib/map_filter.js +++ b/src/ui/public/filter_bar/lib/map_filter.js @@ -9,7 +9,6 @@ import { FilterBarLibMapMissingProvider } from './map_missing'; import { FilterBarLibMapQueryStringProvider } from './map_query_string'; import { FilterBarLibMapGeoBoundingBoxProvider } from './map_geo_bounding_box'; import { FilterBarLibMapGeoPolygonProvider } from './map_geo_polygon'; -import { FilterBarLibMapScriptProvider } from './map_script'; import { FilterBarLibMapDefaultProvider } from './map_default'; export function FilterBarLibMapFilterProvider(Promise, Private) { @@ -42,7 +41,6 @@ export function FilterBarLibMapFilterProvider(Promise, Private) { Private(FilterBarLibMapQueryStringProvider), Private(FilterBarLibMapGeoBoundingBoxProvider), Private(FilterBarLibMapGeoPolygonProvider), - Private(FilterBarLibMapScriptProvider), Private(FilterBarLibMapDefaultProvider), ]; diff --git a/src/ui/public/filter_bar/lib/map_script.js b/src/ui/public/filter_bar/lib/map_script.js deleted file mode 100644 index 828c6da9fa20e..0000000000000 --- a/src/ui/public/filter_bar/lib/map_script.js +++ /dev/null @@ -1,16 +0,0 @@ -export function FilterBarLibMapScriptProvider(Promise) { - return function (filter) { - if (filter.script) { - const type = 'scripted'; - const key = filter.meta.field; - - let value = ''; - if (filter.meta.formattedValue) { - value = filter.meta.formattedValue; - } - - return Promise.resolve({ type, key, value }); - } - return Promise.reject(filter); - }; -}