diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 93d49dc18d417..be2b4533e22db 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -132,7 +132,7 @@ /x-pack/test/functional_basic/apps/transform/ @elastic/ml-ui # Maps -/x-pack/plugins/maps/ @elastic/kibana-gis +#CC# /x-pack/plugins/maps/ @elastic/kibana-gis /x-pack/test/api_integration/apis/maps/ @elastic/kibana-gis /x-pack/test/functional/apps/maps/ @elastic/kibana-gis /x-pack/test/functional/es_archives/maps/ @elastic/kibana-gis diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getfieldattrs.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getfieldattrs.md index 0c1fbe7d0d1b6..a0b54c6de50c9 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getfieldattrs.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getfieldattrs.md @@ -8,8 +8,6 @@ ```typescript getFieldAttrs: () => { - [x: string]: { - customLabel: string; - }; + [x: string]: FieldAttrSet; }; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md index 3383116f404b2..6bd2cbc24283f 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md @@ -27,7 +27,7 @@ export declare class IndexPattern implements IIndexPattern | [flattenHit](./kibana-plugin-plugins-data-public.indexpattern.flattenhit.md) | | (hit: Record<string, any>, deep?: boolean) => Record<string, any> | | | [formatField](./kibana-plugin-plugins-data-public.indexpattern.formatfield.md) | | FormatFieldFn | | | [formatHit](./kibana-plugin-plugins-data-public.indexpattern.formathit.md) | | {
(hit: Record<string, any>, type?: string): any;
formatField: FormatFieldFn;
} | | -| [getFieldAttrs](./kibana-plugin-plugins-data-public.indexpattern.getfieldattrs.md) | | () => {
[x: string]: {
customLabel: string;
};
} | | +| [getFieldAttrs](./kibana-plugin-plugins-data-public.indexpattern.getfieldattrs.md) | | () => {
[x: string]: FieldAttrSet;
} | | | [getOriginalSavedObjectBody](./kibana-plugin-plugins-data-public.indexpattern.getoriginalsavedobjectbody.md) | | () => {
fieldAttrs?: string | undefined;
title?: string | undefined;
timeFieldName?: string | undefined;
intervalName?: string | undefined;
fields?: string | undefined;
sourceFilters?: string | undefined;
fieldFormatMap?: string | undefined;
typeMeta?: string | undefined;
type?: string | undefined;
} | Get last saved saved object fields | | [id](./kibana-plugin-plugins-data-public.indexpattern.id.md) | | string | | | [intervalName](./kibana-plugin-plugins-data-public.indexpattern.intervalname.md) | | string | undefined | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.disablelanguageswitcher.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.disablelanguageswitcher.md new file mode 100644 index 0000000000000..c11edd95a891b --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.disablelanguageswitcher.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [QueryStringInputProps](./kibana-plugin-plugins-data-public.querystringinputprops.md) > [disableLanguageSwitcher](./kibana-plugin-plugins-data-public.querystringinputprops.disablelanguageswitcher.md) + +## QueryStringInputProps.disableLanguageSwitcher property + +Signature: + +```typescript +disableLanguageSwitcher?: boolean; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.icontype.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.icontype.md new file mode 100644 index 0000000000000..4b1c5b84557e7 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.icontype.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [QueryStringInputProps](./kibana-plugin-plugins-data-public.querystringinputprops.md) > [iconType](./kibana-plugin-plugins-data-public.querystringinputprops.icontype.md) + +## QueryStringInputProps.iconType property + +Signature: + +```typescript +iconType?: string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.md index d503980da7947..90c604d131800 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinputprops.md @@ -18,6 +18,8 @@ export interface QueryStringInputProps | [className](./kibana-plugin-plugins-data-public.querystringinputprops.classname.md) | string | | | [dataTestSubj](./kibana-plugin-plugins-data-public.querystringinputprops.datatestsubj.md) | string | | | [disableAutoFocus](./kibana-plugin-plugins-data-public.querystringinputprops.disableautofocus.md) | boolean | | +| [disableLanguageSwitcher](./kibana-plugin-plugins-data-public.querystringinputprops.disablelanguageswitcher.md) | boolean | | +| [iconType](./kibana-plugin-plugins-data-public.querystringinputprops.icontype.md) | string | | | [indexPatterns](./kibana-plugin-plugins-data-public.querystringinputprops.indexpatterns.md) | Array<IIndexPattern | string> | | | [isInvalid](./kibana-plugin-plugins-data-public.querystringinputprops.isinvalid.md) | boolean | | | [languageSwitcherPopoverAnchorPosition](./kibana-plugin-plugins-data-public.querystringinputprops.languageswitcherpopoveranchorposition.md) | PopoverAnchorPosition | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getfieldattrs.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getfieldattrs.md index b1e38258353c3..f98acd766ac33 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getfieldattrs.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getfieldattrs.md @@ -8,8 +8,6 @@ ```typescript getFieldAttrs: () => { - [x: string]: { - customLabel: string; - }; + [x: string]: FieldAttrSet; }; ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md index 5103af52f1b43..e5e2dfd0999db 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md @@ -27,7 +27,7 @@ export declare class IndexPattern implements IIndexPattern | [flattenHit](./kibana-plugin-plugins-data-server.indexpattern.flattenhit.md) | | (hit: Record<string, any>, deep?: boolean) => Record<string, any> | | | [formatField](./kibana-plugin-plugins-data-server.indexpattern.formatfield.md) | | FormatFieldFn | | | [formatHit](./kibana-plugin-plugins-data-server.indexpattern.formathit.md) | | {
(hit: Record<string, any>, type?: string): any;
formatField: FormatFieldFn;
} | | -| [getFieldAttrs](./kibana-plugin-plugins-data-server.indexpattern.getfieldattrs.md) | | () => {
[x: string]: {
customLabel: string;
};
} | | +| [getFieldAttrs](./kibana-plugin-plugins-data-server.indexpattern.getfieldattrs.md) | | () => {
[x: string]: FieldAttrSet;
} | | | [getOriginalSavedObjectBody](./kibana-plugin-plugins-data-server.indexpattern.getoriginalsavedobjectbody.md) | | () => {
fieldAttrs?: string | undefined;
title?: string | undefined;
timeFieldName?: string | undefined;
intervalName?: string | undefined;
fields?: string | undefined;
sourceFilters?: string | undefined;
fieldFormatMap?: string | undefined;
typeMeta?: string | undefined;
type?: string | undefined;
} | Get last saved saved object fields | | [id](./kibana-plugin-plugins-data-server.indexpattern.id.md) | | string | | | [intervalName](./kibana-plugin-plugins-data-server.indexpattern.intervalname.md) | | string | undefined | | diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts index 47ad5860801bc..52672c71dcce4 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts @@ -18,7 +18,7 @@ */ import _, { each, reject } from 'lodash'; -import { FieldAttrs } from '../..'; +import { FieldAttrs, FieldAttrSet } from '../..'; import { DuplicateField } from '../../../../kibana_utils/common'; import { ES_FIELD_TYPES, KBN_FIELD_TYPES, IIndexPattern, IFieldType } from '../../../common'; @@ -135,8 +135,19 @@ export class IndexPattern implements IIndexPattern { const newFieldAttrs = { ...this.fieldAttrs }; this.fields.forEach((field) => { + const attrs: FieldAttrSet = {}; + let hasAttr = false; if (field.customLabel) { - newFieldAttrs[field.name] = { customLabel: field.customLabel }; + attrs.customLabel = field.customLabel; + hasAttr = true; + } + if (field.count) { + attrs.count = field.count; + hasAttr = true; + } + + if (hasAttr) { + newFieldAttrs[field.name] = attrs; } else { delete newFieldAttrs[field.name]; } @@ -298,7 +309,9 @@ export class IndexPattern implements IIndexPattern { timeFieldName: this.timeFieldName, intervalName: this.intervalName, sourceFilters: this.sourceFilters ? JSON.stringify(this.sourceFilters) : undefined, - fields: this.fields ? JSON.stringify(this.fields) : undefined, + fields: this.fields + ? JSON.stringify(this.fields.filter((field) => field.scripted)) + : undefined, fieldFormatMap, type: this.type, typeMeta: this.typeMeta ? JSON.stringify(this.typeMeta) : undefined, diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts index bf227615f76a1..2e9c27735a8d1 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts @@ -155,15 +155,11 @@ describe('IndexPatterns', () => { // Create a normal index patterns const pattern = await indexPatterns.get('foo'); - - expect(pattern.version).toBe('fooa'); indexPatterns.clearCache(); // Create the same one - we're going to handle concurrency const samePattern = await indexPatterns.get('foo'); - expect(samePattern.version).toBe('fooaa'); - // This will conflict because samePattern did a save (from refreshFields) // but the resave should work fine pattern.title = 'foo2'; diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts index 82c8cf4abc5ac..e09246ae8cd3e 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts @@ -197,22 +197,6 @@ export class IndexPatternsService { } }; - private isFieldRefreshRequired(specs?: IndexPatternFieldMap): boolean { - if (!specs) { - return true; - } - - return Object.values(specs).every((spec) => { - // See https://github.com/elastic/kibana/pull/8421 - const hasFieldCaps = 'aggregatable' in spec && 'searchable' in spec; - - // See https://github.com/elastic/kibana/pull/11969 - const hasDocValuesFlag = 'readFromDocValues' in spec; - - return !hasFieldCaps || !hasDocValuesFlag; - }); - } - /** * Get field list by providing { pattern } * @param options @@ -299,8 +283,8 @@ export class IndexPatternsService { values: { id, title }, }), }); + throw err; } - return fields; }; /** @@ -309,7 +293,11 @@ export class IndexPatternsService { */ fieldArrayToMap = (fields: FieldSpec[], fieldAttrs?: FieldAttrs) => fields.reduce((collector, field) => { - collector[field.name] = { ...field, customLabel: fieldAttrs?.[field.name]?.customLabel }; + collector[field.name] = { + ...field, + customLabel: fieldAttrs?.[field.name]?.customLabel, + count: fieldAttrs?.[field.name]?.count, + }; return collector; }, {}); @@ -372,25 +360,20 @@ export class IndexPatternsService { ? JSON.parse(savedObject.attributes.fieldAttrs) : {}; - const isFieldRefreshRequired = this.isFieldRefreshRequired(spec.fields); - let isSaveRequired = isFieldRefreshRequired; try { - spec.fields = isFieldRefreshRequired - ? await this.refreshFieldSpecMap( - spec.fields || {}, - id, - spec.title as string, - { - pattern: title as string, - metaFields: await this.config.get(UI_SETTINGS.META_FIELDS), - type, - rollupIndex: typeMeta?.params?.rollupIndex, - }, - spec.fieldAttrs - ) - : spec.fields; + spec.fields = await this.refreshFieldSpecMap( + spec.fields || {}, + id, + spec.title as string, + { + pattern: title as string, + metaFields: await this.config.get(UI_SETTINGS.META_FIELDS), + type, + rollupIndex: typeMeta?.params?.rollup_index, + }, + spec.fieldAttrs + ); } catch (err) { - isSaveRequired = false; if (err instanceof IndexPatternMissingIndices) { this.onNotification({ title: (err as any).message, @@ -412,23 +395,6 @@ export class IndexPatternsService { : {}; const indexPattern = await this.create(spec, true); - if (isSaveRequired) { - try { - this.updateSavedObject(indexPattern); - } catch (err) { - this.onError(err, { - title: i18n.translate('data.indexPatterns.fetchFieldSaveErrorTitle', { - defaultMessage: - 'Error saving after fetching fields for index pattern {title} (ID: {id})', - values: { - id: indexPattern.id, - title: indexPattern.title, - }, - }), - }); - } - } - indexPattern.resetOriginalSavedObjectBody(); return indexPattern; }; diff --git a/src/plugins/data/common/index_patterns/types.ts b/src/plugins/data/common/index_patterns/types.ts index 28b077f4bfdf3..8d9b29175162e 100644 --- a/src/plugins/data/common/index_patterns/types.ts +++ b/src/plugins/data/common/index_patterns/types.ts @@ -52,7 +52,12 @@ export interface IndexPatternAttributes { } export interface FieldAttrs { - [key: string]: { customLabel: string }; + [key: string]: FieldAttrSet; +} + +export interface FieldAttrSet { + customLabel?: string; + count?: number; } export type OnNotification = (toastInputFields: ToastInputFields) => void; diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index fc9b8d4839ea3..5a707393b39f4 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1151,9 +1151,7 @@ export class IndexPattern implements IIndexPattern { }; // (undocumented) getFieldAttrs: () => { - [x: string]: { - customLabel: string; - }; + [x: string]: FieldAttrSet; }; // (undocumented) getFieldByName(name: string): IndexPatternField | undefined; @@ -1798,6 +1796,10 @@ export interface QueryStringInputProps { // (undocumented) disableAutoFocus?: boolean; // (undocumented) + disableLanguageSwitcher?: boolean; + // (undocumented) + iconType?: string; + // (undocumented) indexPatterns: Array; // (undocumented) isInvalid?: boolean; @@ -2362,6 +2364,7 @@ export const UI_SETTINGS: { // src/plugins/data/common/es_query/filters/phrase_filter.ts:33:3 - (ae-forgotten-export) The symbol "PhraseFilterMeta" needs to be exported by the entry point index.d.ts // src/plugins/data/common/es_query/filters/phrases_filter.ts:31:3 - (ae-forgotten-export) The symbol "PhrasesFilterMeta" needs to be exported by the entry point index.d.ts // src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:64:5 - (ae-forgotten-export) The symbol "FormatFieldFn" needs to be exported by the entry point index.d.ts +// src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:135:7 - (ae-forgotten-export) The symbol "FieldAttrSet" needs to be exported by the entry point index.d.ts // src/plugins/data/common/search/aggs/types.ts:113:51 - (ae-forgotten-export) The symbol "AggTypesRegistryStart" needs to be exported by the entry point index.d.ts // src/plugins/data/public/field_formats/field_formats_service.ts:67:3 - (ae-forgotten-export) The symbol "FormatFactory" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "FILTERS" needs to be exported by the entry point index.d.ts diff --git a/src/plugins/data/public/ui/query_string_input/_query_bar.scss b/src/plugins/data/public/ui/query_string_input/_query_bar.scss index 1ff24c61954e7..3e3982dd58e57 100644 --- a/src/plugins/data/public/ui/query_string_input/_query_bar.scss +++ b/src/plugins/data/public/ui/query_string_input/_query_bar.scss @@ -19,11 +19,12 @@ z-index: $euiZContentMenu; resize: none !important; // When in the group, it will autosize height: $euiFormControlHeight; - // Unlike most inputs within layout control groups, the text area still needs a border. - // These adjusts help it sit above the control groups shadow to line up correctly. + // Unlike most inputs within layout control groups, the text area still needs a border + // for multi-line content. These adjusts help it sit above the control groups + // shadow to line up correctly. padding: $euiSizeS; padding-top: $euiSizeS + 3px; - transform: translateY(-1px) translateX(-1px); + box-shadow: 0 0 0 1px $euiFormBorderColor; &:not(:focus):not(:invalid) { @include euiYScrollWithShadows; @@ -40,6 +41,17 @@ overflow-x: auto; overflow-y: auto; white-space: normal; + box-shadow: 0 0 0 1px $euiFormBorderColor; + } + + @include euiFormControlWithIcon($isIconOptional: true); + ~ .euiFormControlLayoutIcons { + // By default form control layout icon is vertically centered, but our textarea + // can expand to be multi-line, so we position it with padding that matches + // the parent textarea padding + z-index: $euiZContentMenu + 1; + top: $euiSizeS + 3px; + bottom: unset; } } diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.test.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.test.tsx index 7d0ad4b3be097..c26f1898a4084 100644 --- a/src/plugins/data/public/ui/query_string_input/query_string_input.test.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_string_input.test.tsx @@ -29,7 +29,7 @@ import { mount } from 'enzyme'; import { waitFor } from '@testing-library/dom'; import { render } from '@testing-library/react'; -import { EuiTextArea } from '@elastic/eui'; +import { EuiTextArea, EuiIcon } from '@elastic/eui'; import { QueryLanguageSwitcher } from './language_switcher'; import { QueryStringInput } from './'; @@ -172,6 +172,30 @@ describe('QueryStringInput', () => { expect(mockCallback).toHaveBeenCalledWith({ query: '', language: 'lucene' }); }); + it('Should not show the language switcher when disabled', () => { + const component = mount( + wrapQueryStringInputInContext({ + query: luceneQuery, + onSubmit: noop, + indexPatterns: [stubIndexPatternWithFields], + disableLanguageSwitcher: true, + }) + ); + expect(component.find(QueryLanguageSwitcher).exists()).toBeFalsy(); + }); + + it('Should show an icon when an iconType is specified', () => { + const component = mount( + wrapQueryStringInputInContext({ + query: luceneQuery, + onSubmit: noop, + indexPatterns: [stubIndexPatternWithFields], + iconType: 'search', + }) + ); + expect(component.find(EuiIcon).exists()).toBeTruthy(); + }); + it('Should call onSubmit when the user hits enter inside the query bar', () => { const mockCallback = jest.fn(); diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx index bc9e2ed6a83ce..a6d22ce3eb473 100644 --- a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx @@ -31,6 +31,7 @@ import { EuiLink, htmlIdGenerator, EuiPortal, + EuiIcon, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -55,6 +56,7 @@ export interface QueryStringInputProps { persistedLog?: PersistedLog; bubbleSubmitEvent?: boolean; placeholder?: string; + disableLanguageSwitcher?: boolean; languageSwitcherPopoverAnchorPosition?: PopoverAnchorPosition; onBlur?: () => void; onChange?: (query: Query) => void; @@ -64,6 +66,7 @@ export interface QueryStringInputProps { size?: SuggestionsListSize; className?: string; isInvalid?: boolean; + iconType?: string; } interface Props extends QueryStringInputProps { @@ -608,13 +611,17 @@ export default class QueryStringInputUI extends Component { 'aria-owns': 'kbnTypeahead__items', }; const ariaCombobox = { ...isSuggestionsVisible, role: 'combobox' }; - const className = classNames( + const containerClassName = classNames( 'euiFormControlLayout euiFormControlLayout--group kbnQueryBar__wrap', this.props.className ); + const inputClassName = classNames( + 'kbnQueryBar__textarea', + this.props.iconType ? 'kbnQueryBar__textarea--withIcon' : null + ); return ( -
+
{this.props.prepend}
{ onClick={this.onClickInput} onBlur={this.onInputBlur} onFocus={this.handleOnFocus} - className="kbnQueryBar__textarea" + className={inputClassName} fullWidth rows={1} id={this.textareaId} @@ -678,6 +685,15 @@ export default class QueryStringInputUI extends Component { > {this.getQueryString()} + {this.props.iconType ? ( +
+
+ ) : null}
{
- - + {this.props.disableLanguageSwitcher ? null : ( + + )}
); } diff --git a/src/plugins/data/public/ui/typeahead/constants.ts b/src/plugins/data/public/ui/typeahead/constants.ts index 0e28891a14535..8a3e5206d5d5e 100644 --- a/src/plugins/data/public/ui/typeahead/constants.ts +++ b/src/plugins/data/public/ui/typeahead/constants.ts @@ -33,4 +33,4 @@ export const SUGGESTIONS_LIST_REQUIRED_BOTTOM_SPACE = 250; * A distance in px to display suggestions list right under the query input without a gap * @public */ -export const SUGGESTIONS_LIST_REQUIRED_TOP_OFFSET = 1; +export const SUGGESTIONS_LIST_REQUIRED_TOP_OFFSET = 0; diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index 72a4e11e4b587..74ba83aea2067 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -616,9 +616,7 @@ export class IndexPattern implements IIndexPattern { }; // (undocumented) getFieldAttrs: () => { - [x: string]: { - customLabel: string; - }; + [x: string]: FieldAttrSet; }; // (undocumented) getFieldByName(name: string): IndexPatternField | undefined; @@ -1220,6 +1218,7 @@ export function usageProvider(core: CoreSetup_2): SearchUsage; // src/plugins/data/common/es_query/filters/meta_filter.ts:54:3 - (ae-forgotten-export) The symbol "FilterMeta" needs to be exported by the entry point index.d.ts // src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:58:45 - (ae-forgotten-export) The symbol "IndexPatternFieldMap" needs to be exported by the entry point index.d.ts // src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:64:5 - (ae-forgotten-export) The symbol "FormatFieldFn" needs to be exported by the entry point index.d.ts +// src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:135:7 - (ae-forgotten-export) The symbol "FieldAttrSet" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index.ts:40:23 - (ae-forgotten-export) The symbol "buildCustomFilter" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index.ts:40:23 - (ae-forgotten-export) The symbol "buildFilter" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index.ts:71:21 - (ae-forgotten-export) The symbol "getEsQueryConfig" needs to be exported by the entry point index.d.ts diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx index 67a20c428040f..a8a4c87c56198 100644 --- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx @@ -58,19 +58,6 @@ const mappingConflictHeader = i18n.translate( } ); -const confirmMessage = i18n.translate('indexPatternManagement.editIndexPattern.refreshLabel', { - defaultMessage: 'This action resets the popularity counter of each field.', -}); - -const confirmModalOptionsRefresh = { - confirmButtonText: i18n.translate('indexPatternManagement.editIndexPattern.refreshButton', { - defaultMessage: 'Refresh', - }), - title: i18n.translate('indexPatternManagement.editIndexPattern.refreshHeader', { - defaultMessage: 'Refresh field list?', - }), -}; - const confirmModalOptionsDelete = { confirmButtonText: i18n.translate('indexPatternManagement.editIndexPattern.deleteButton', { defaultMessage: 'Delete', @@ -118,16 +105,6 @@ export const EditIndexPattern = withRouter( setDefaultIndex(indexPattern.id || ''); }, [uiSettings, indexPattern.id]); - const refreshFields = () => { - overlays.openConfirm(confirmMessage, confirmModalOptionsRefresh).then(async (isConfirmed) => { - if (isConfirmed) { - await data.indexPatterns.refreshFields(indexPattern); - await data.indexPatterns.updateSavedObject(indexPattern); - setFields(indexPattern.getNonScriptedFields()); - } - }); - }; - const removePattern = () => { async function doRemove() { if (indexPattern.id === defaultIndex) { @@ -190,7 +167,6 @@ export const EditIndexPattern = withRouter( diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index_header.tsx b/src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index_header.tsx index 8ca8c6453c7e9..aeeea6dec9a58 100644 --- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index_header.tsx +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/index_header/index_header.tsx @@ -26,7 +26,6 @@ interface IndexHeaderProps { indexPattern: IIndexPattern; defaultIndex?: string; setDefault?: () => void; - refreshFields?: () => void; deleteIndexPatternClick?: () => void; } @@ -44,14 +43,6 @@ const setDefaultTooltip = i18n.translate( } ); -const refreshAriaLabel = i18n.translate('indexPatternManagement.editIndexPattern.refreshAria', { - defaultMessage: 'Reload field list.', -}); - -const refreshTooltip = i18n.translate('indexPatternManagement.editIndexPattern.refreshTooltip', { - defaultMessage: 'Refresh field list.', -}); - const removeAriaLabel = i18n.translate('indexPatternManagement.editIndexPattern.removeAria', { defaultMessage: 'Remove index pattern.', }); @@ -64,7 +55,6 @@ export function IndexHeader({ defaultIndex, indexPattern, setDefault, - refreshFields, deleteIndexPatternClick, }: IndexHeaderProps) { return ( @@ -90,20 +80,6 @@ export function IndexHeader({ )} - {refreshFields && ( - - - - - - )} - {deleteIndexPatternClick && ( diff --git a/src/plugins/vis_type_timeseries/common/constants.ts b/src/plugins/vis_type_timeseries/common/constants.ts index f1bc479ef0f46..ef933f37d9434 100644 --- a/src/plugins/vis_type_timeseries/common/constants.ts +++ b/src/plugins/vis_type_timeseries/common/constants.ts @@ -19,4 +19,11 @@ export const MAX_BUCKETS_SETTING = 'metrics:max_buckets'; export const INDEXES_SEPARATOR = ','; + export const AUTO_INTERVAL = 'auto'; + + +export const ROUTES = { + VIS_DATA: '/api/metrics/vis/data', +}; + diff --git a/src/plugins/vis_type_timeseries/common/panel_types.ts b/src/plugins/vis_type_timeseries/common/panel_types.ts index 6a9420ab6e4c1..6aed5528c23a5 100644 --- a/src/plugins/vis_type_timeseries/common/panel_types.ts +++ b/src/plugins/vis_type_timeseries/common/panel_types.ts @@ -17,11 +17,11 @@ * under the License. */ -export const PANEL_TYPES = { - TABLE: 'table', - GAUGE: 'gauge', - MARKDOWN: 'markdown', - TOP_N: 'top_n', - TIMESERIES: 'timeseries', - METRIC: 'metric', -}; +export enum PANEL_TYPES { + TABLE = 'table', + GAUGE = 'gauge', + MARKDOWN = 'markdown', + TOP_N = 'top_n', + TIMESERIES = 'timeseries', + METRIC = 'metric', +} diff --git a/src/plugins/vis_type_timeseries/common/types.ts b/src/plugins/vis_type_timeseries/common/types.ts index 8973060848b41..f8e1b740fc646 100644 --- a/src/plugins/vis_type_timeseries/common/types.ts +++ b/src/plugins/vis_type_timeseries/common/types.ts @@ -19,8 +19,37 @@ import { TypeOf } from '@kbn/config-schema'; import { metricsItems, panel, seriesItems, visPayloadSchema } from './vis_schema'; +import { PANEL_TYPES } from './panel_types'; +import { TimeseriesUIRestrictions } from './ui_restrictions'; export type SeriesItemsSchema = TypeOf; export type MetricsItemsSchema = TypeOf; export type PanelSchema = TypeOf; export type VisPayload = TypeOf; + +interface PanelData { + id: string; + label: string; + data: Array<[number, number]>; +} + +// series data is not fully typed yet +interface SeriesData { + [key: string]: { + annotations: { + [key: string]: unknown[]; + }; + id: string; + series: PanelData[]; + error?: unknown; + }; +} + +export type TimeseriesVisData = SeriesData & { + type: PANEL_TYPES; + uiRestrictions: TimeseriesUIRestrictions; + /** + * series array is responsible only for "table" vis type + */ + series?: unknown[]; +}; diff --git a/src/plugins/vis_type_timeseries/common/ui_restrictions.ts b/src/plugins/vis_type_timeseries/common/ui_restrictions.ts index e2911eb2d70e3..1be428f1b9354 100644 --- a/src/plugins/vis_type_timeseries/common/ui_restrictions.ts +++ b/src/plugins/vis_type_timeseries/common/ui_restrictions.ts @@ -63,7 +63,7 @@ export const DEFAULT_UI_RESTRICTION: UIRestrictions = { * @constant * @public */ -export const limitOfSeries = { +export const limitOfSeries: Partial> = { [PANEL_TYPES.GAUGE]: 1, [PANEL_TYPES.METRIC]: 2, }; diff --git a/src/plugins/vis_type_timeseries/common/vis_schema.ts b/src/plugins/vis_type_timeseries/common/vis_schema.ts index 9649f2a22d41d..a90fa752ad7dc 100644 --- a/src/plugins/vis_type_timeseries/common/vis_schema.ts +++ b/src/plugins/vis_type_timeseries/common/vis_schema.ts @@ -253,7 +253,14 @@ export const panel = schema.object({ ), time_field: stringOptionalNullable, time_range_mode: stringOptionalNullable, - type: stringRequired, + type: schema.oneOf([ + schema.literal('table'), + schema.literal('gauge'), + schema.literal('markdown'), + schema.literal('top_n'), + schema.literal('timeseries'), + schema.literal('metric'), + ]), }); export const visPayloadSchema = schema.object({ @@ -269,7 +276,6 @@ export const visPayloadSchema = schema.object({ }) ), }), - savedObjectId: schema.maybe(schema.string()), timerange: schema.object({ timezone: stringRequired, min: stringRequired, diff --git a/src/plugins/vis_type_timeseries/public/application/components/no_data.js b/src/plugins/vis_type_timeseries/public/application/components/no_data.js deleted file mode 100644 index 1968f1858a46c..0000000000000 --- a/src/plugins/vis_type_timeseries/public/application/components/no_data.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import React from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiIcon, EuiSpacer, EuiText } from '@elastic/eui'; - -export function NoDataComponent() { - return ( -
- - -
- ); -} diff --git a/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx b/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx new file mode 100644 index 0000000000000..5b5c99b970854 --- /dev/null +++ b/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx @@ -0,0 +1,115 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useCallback, useEffect } from 'react'; + +import { IUiSettingsClient } from 'src/core/public'; +import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; +import { PersistedState } from 'src/plugins/visualizations/public'; + +// @ts-expect-error +import { ErrorComponent } from './error'; +import { TimeseriesVisTypes } from './vis_types'; +import { TimeseriesVisParams } from '../../metrics_fn'; +import { TimeseriesVisData } from '../../../common/types'; + +interface TimeseriesVisualizationProps { + className?: string; + getConfig: IUiSettingsClient['get']; + handlers: IInterpreterRenderHandlers; + model: TimeseriesVisParams; + visData: TimeseriesVisData; + uiState: PersistedState; +} + +function TimeseriesVisualization({ + className = 'tvbVis', + visData, + model, + handlers, + uiState, + getConfig, +}: TimeseriesVisualizationProps) { + const onBrush = useCallback( + (gte: string, lte: string) => { + handlers.event({ + name: 'applyFilter', + data: { + timeFieldName: '*', + filters: [ + { + range: { + '*': { + gte, + lte, + }, + }, + }, + ], + }, + }); + }, + [handlers] + ); + + const handleUiState = useCallback( + (field: string, value: { column: string; order: string }) => { + uiState.set(field, value); + // reload visualization because data might need to be re-fetched + uiState.emit('reload'); + }, + [uiState] + ); + + useEffect(() => { + handlers.done(); + }); + + // Show the error panel + const error = visData[model.id]?.error; + if (error) { + return ( +
+ +
+ ); + } + + const VisComponent = TimeseriesVisTypes[model.type]; + + if (VisComponent) { + return ( + + ); + } + + return
; +} + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { TimeseriesVisualization as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js index 57adecd9d598b..083ccaf8e5073 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js @@ -23,10 +23,8 @@ import * as Rx from 'rxjs'; import { share } from 'rxjs/operators'; import { isEqual, isEmpty, debounce } from 'lodash'; import { VisEditorVisualization } from './vis_editor_visualization'; -import { Visualization } from './visualization'; import { VisPicker } from './vis_picker'; import { PanelConfig } from './panel_config'; -import { createBrushHandler } from '../lib/create_brush_handler'; import { fetchFields } from '../lib/fetch_fields'; import { extractIndexPatterns } from '../../../common/extract_index_patterns'; import { getSavedObjectsClient, getUISettings, getDataStart, getCoreStart } from '../../services'; @@ -49,7 +47,6 @@ export class VisEditor extends Component { visFields: props.visFields, extractedIndexPatterns: [''], }; - this.onBrush = createBrushHandler((data) => props.vis.API.events.applyFilter(data)); this.visDataSubject = new Rx.BehaviorSubject(this.props.visData); this.visData$ = this.visDataSubject.asObservable().pipe(share()); @@ -71,12 +68,6 @@ export class VisEditor extends Component { return this.props.config.get(...args); }; - handleUiState = (field, value) => { - this.props.vis.uiState.set(field, value); - // reload visualization because data might need to be re-fetched - this.props.vis.uiState.emit('reload'); - }; - updateVisState = debounce(() => { this.props.vis.params = this.state.model; this.props.embeddableHandler.reload(); @@ -101,16 +92,14 @@ export class VisEditor extends Component { dirty = false; } - if (this.props.isEditorMode) { - const extractedIndexPatterns = extractIndexPatterns(nextModel); - if (!isEqual(this.state.extractedIndexPatterns, extractedIndexPatterns)) { - fetchFields(extractedIndexPatterns).then((visFields) => - this.setState({ - visFields, - extractedIndexPatterns, - }) - ); - } + const extractedIndexPatterns = extractIndexPatterns(nextModel); + if (!isEqual(this.state.extractedIndexPatterns, extractedIndexPatterns)) { + fetchFields(extractedIndexPatterns).then((visFields) => + this.setState({ + visFields, + extractedIndexPatterns, + }) + ); } this.setState({ @@ -141,23 +130,6 @@ export class VisEditor extends Component { }; render() { - if (!this.props.isEditorMode) { - if (!this.props.visParams || !this.props.visData) { - return null; - } - return ( - - ); - } - const { model } = this.state; if (model) { @@ -211,23 +183,12 @@ export class VisEditor extends Component { } componentDidMount() { - this.props.renderComplete(); - - if (this.props.isEditorMode && this.props.eventEmitter) { - this.props.eventEmitter.on('updateEditor', this.updateModel); - } - } - - componentDidUpdate() { - this.props.renderComplete(); + this.props.eventEmitter.on('updateEditor', this.updateModel); } componentWillUnmount() { this.updateVisState.cancel(); - - if (this.props.isEditorMode && this.props.eventEmitter) { - this.props.eventEmitter.off('updateEditor', this.updateModel); - } + this.props.eventEmitter.off('updateEditor', this.updateModel); } } @@ -241,7 +202,6 @@ VisEditor.propTypes = { visFields: PropTypes.object, renderComplete: PropTypes.func, config: PropTypes.object, - isEditorMode: PropTypes.bool, savedObj: PropTypes.object, timeRange: PropTypes.object, appState: PropTypes.object, diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/vis.js index 325e9c8372736..5a6d5f39d0c97 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/vis.js @@ -101,4 +101,8 @@ GaugeVisualization.propTypes = { getConfig: PropTypes.func, }; -export const gauge = visWithSplits(GaugeVisualization); +const gauge = visWithSplits(GaugeVisualization); + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { gauge as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts b/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts new file mode 100644 index 0000000000000..56e58b4da3458 --- /dev/null +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts @@ -0,0 +1,69 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { lazy } from 'react'; + +import { IUiSettingsClient } from 'src/core/public'; +import { PersistedState } from 'src/plugins/visualizations/public'; + +import { TimeseriesVisParams } from '../../../metrics_fn'; +import { TimeseriesVisData } from '../../../../common/types'; + +/** + * Lazy load each visualization type, since the only one is presented on the screen at the same time. + * Disable typescript errors since the components are not typed yet. + */ + +// @ts-expect-error +const timeseries = lazy(() => import('./timeseries/vis')); +// @ts-expect-error +const metric = lazy(() => import('./metric/vis')); +// @ts-expect-error +const topN = lazy(() => import('./top_n/vis')); +// @ts-expect-error +const table = lazy(() => import('./table/vis')); +// @ts-expect-error +const gauge = lazy(() => import('./gauge/vis')); +// @ts-expect-error +const markdown = lazy(() => import('./markdown/vis')); + +export const TimeseriesVisTypes: Record> = { + timeseries, + metric, + top_n: topN, + table, + gauge, + markdown, +}; + +export interface TimeseriesVisProps { + model: TimeseriesVisParams; + onBrush: (gte: string, lte: string) => void; + onUiState: ( + field: string, + value: { + column: string; + order: string; + } + ) => void; + uiState: PersistedState; + visData: TimeseriesVisData; + dateFormat: string; + getConfig: IUiSettingsClient['get']; +} diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/vis.js index a4e7738e92318..e68b9e5ed8467 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/vis.js @@ -30,7 +30,7 @@ import { isBackgroundInverted } from '../../../lib/set_is_reversed'; const getMarkdownId = (id) => `markdown-${id}`; -export function MarkdownVisualization(props) { +function MarkdownVisualization(props) { const { backgroundColor, model, visData, dateFormat } = props; const series = get(visData, `${model.id}.series`, []); const variables = convertSeriesToVars(series, model, dateFormat, props.getConfig); @@ -106,3 +106,7 @@ MarkdownVisualization.propTypes = { dateFormat: PropTypes.string, getConfig: PropTypes.func, }; + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { MarkdownVisualization as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/vis.js index 5fe7afe47df9b..7069a32fa2b50 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/vis.js @@ -95,4 +95,8 @@ MetricVisualization.propTypes = { getConfig: PropTypes.func, }; -export const metric = visWithSplits(MetricVisualization); +const metric = visWithSplits(MetricVisualization); + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { metric as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js index 92109e1a37426..a31be694cd172 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js @@ -46,7 +46,7 @@ function getColor(rules, colorKey, value) { return color; } -export class TableVis extends Component { +class TableVis extends Component { constructor(props) { super(props); @@ -260,3 +260,7 @@ TableVis.propTypes = { pageNumber: PropTypes.number, getConfig: PropTypes.func, }; + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { TableVis as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js index f936710bf2b81..b752699fa1548 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js @@ -34,7 +34,7 @@ import { createXaxisFormatter } from '../../lib/create_xaxis_formatter'; import { STACKED_OPTIONS } from '../../../visualizations/constants'; import { getCoreStart } from '../../../../services'; -export class TimeseriesVisualization extends Component { +class TimeseriesVisualization extends Component { static propTypes = { model: PropTypes.object, onBrush: PropTypes.func, @@ -44,7 +44,8 @@ export class TimeseriesVisualization extends Component { }; xAxisFormatter = (interval) => (val) => { - const { scaledDataFormat, dateFormat } = this.props.visData; + const scaledDataFormat = this.props.getConfig('dateFormat:scaled'); + const { dateFormat } = this.props; if (!scaledDataFormat || !dateFormat) { return val; @@ -245,3 +246,7 @@ export class TimeseriesVisualization extends Component { ); } } + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { TimeseriesVisualization as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/vis.js index 1c2ebb8264ef3..92311b3f33afb 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/vis.js @@ -48,7 +48,7 @@ function sortSeries(visData, model) { }, []); } -export function TopNVisualization(props) { +function TopNVisualization(props) { const { backgroundColor, model, visData } = props; const series = sortSeries(visData, model).map((item) => { @@ -111,3 +111,7 @@ TopNVisualization.propTypes = { visData: PropTypes.object, getConfig: PropTypes.func, }; + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { TopNVisualization as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/visualization.js b/src/plugins/vis_type_timeseries/public/application/components/visualization.js deleted file mode 100644 index 8b8218653f97c..0000000000000 --- a/src/plugins/vis_type_timeseries/public/application/components/visualization.js +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import PropTypes from 'prop-types'; -import React from 'react'; -import _ from 'lodash'; - -import { TimeseriesVisualization } from './vis_types/timeseries/vis'; -import { metric } from './vis_types/metric/vis'; -import { TopNVisualization as topN } from './vis_types/top_n/vis'; -import { TableVis as table } from './vis_types/table/vis'; -import { gauge } from './vis_types/gauge/vis'; -import { MarkdownVisualization as markdown } from './vis_types/markdown/vis'; -import { ErrorComponent } from './error'; -import { NoDataComponent } from './no_data'; - -const types = { - timeseries: TimeseriesVisualization, - metric, - top_n: topN, - table, - gauge, - markdown, -}; - -export function Visualization(props) { - const { visData, model } = props; - // Show the error panel - const error = _.get(visData, `${model.id}.error`); - if (error) { - return ( -
- -
- ); - } - - const path = visData.type === 'table' ? 'series' : `${model.id}.series`; - const noData = _.get(visData, path, []).length === 0; - if (noData) { - return ( -
- -
- ); - } - - const component = types[model.type]; - if (component) { - return React.createElement(component, { - dateFormat: props.dateFormat, - backgroundColor: props.backgroundColor, - model: props.model, - onBrush: props.onBrush, - onChange: props.onChange, - onUiState: props.onUiState, - uiState: props.uiState, - visData: visData.type === model.type ? visData : {}, - getConfig: props.getConfig, - }); - } - return
; -} - -Visualization.propTypes = { - backgroundColor: PropTypes.string, - className: PropTypes.string, - model: PropTypes.object, - onBrush: PropTypes.func, - onChange: PropTypes.func, - onUiState: PropTypes.func, - uiState: PropTypes.object, - visData: PropTypes.object, - dateFormat: PropTypes.string, - getConfig: PropTypes.func, -}; - -Visualization.defaultProps = { - className: 'tvbVis', -}; diff --git a/src/plugins/vis_type_timeseries/public/application/editor_controller.js b/src/plugins/vis_type_timeseries/public/application/editor_controller.js index f21b5f947bca7..548bf2623fc1a 100644 --- a/src/plugins/vis_type_timeseries/public/application/editor_controller.js +++ b/src/plugins/vis_type_timeseries/public/application/editor_controller.js @@ -70,7 +70,6 @@ export class EditorController { visParams={this.state.vis.params} timeRange={params.timeRange} renderComplete={() => {}} - isEditorMode={true} appState={params.appState} embeddableHandler={this.embeddableHandler} eventEmitter={this.eventEmitter} diff --git a/src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.test.ts b/src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.test.ts deleted file mode 100644 index a9568b5be9d3f..0000000000000 --- a/src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { createBrushHandler } from './create_brush_handler'; -import { ExprVisAPIEvents } from '../../../../visualizations/public'; - -describe('brushHandler', () => { - let onBrush: ReturnType; - let applyFilter: ExprVisAPIEvents['applyFilter']; - - beforeEach(() => { - applyFilter = jest.fn(); - - onBrush = createBrushHandler(applyFilter); - }); - - test('returns brushHandler() should updates timefilter through vis.API.events.applyFilter', () => { - const gte = '2017-01-01T00:00:00Z'; - const lte = '2017-01-01T00:10:00Z'; - - onBrush(gte, lte); - - expect(applyFilter).toHaveBeenCalledWith({ - timeFieldName: '*', - filters: [ - { - range: { '*': { gte: '2017-01-01T00:00:00Z', lte: '2017-01-01T00:10:00Z' } }, - }, - ], - }); - }); -}); diff --git a/src/plugins/vis_type_timeseries/public/metrics_fn.ts b/src/plugins/vis_type_timeseries/public/metrics_fn.ts index 8652d703f963e..60acd35b22402 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_fn.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_fn.ts @@ -17,38 +17,36 @@ * under the License. */ -import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; import { KibanaContext } from '../../data/public'; import { ExpressionFunctionDefinition, Render } from '../../expressions/public'; -// @ts-ignore +import { PanelSchema, TimeseriesVisData } from '../common/types'; import { metricsRequestHandler } from './request_handler'; type Input = KibanaContext | null; -type Output = Promise>; +type Output = Promise>; interface Arguments { params: string; uiState: string; - savedObjectId: string | null; } -type VisParams = Required; +export type TimeseriesVisParams = PanelSchema; -interface RenderValue { - visType: 'metrics'; - visData: Input; - visConfig: VisParams; - uiState: any; +export interface TimeseriesRenderValue { + visData: TimeseriesVisData | {}; + visParams: TimeseriesVisParams; } -export const createMetricsFn = (): ExpressionFunctionDefinition< +export type TimeseriesExpressionFunctionDefinition = ExpressionFunctionDefinition< 'tsvb', Input, Arguments, Output -> => ({ +>; + +export const createMetricsFn = (): TimeseriesExpressionFunctionDefinition => ({ name: 'tsvb', type: 'render', inputTypes: ['kibana_context', 'null'], @@ -66,37 +64,22 @@ export const createMetricsFn = (): ExpressionFunctionDefinition< default: '"{}"', help: '', }, - savedObjectId: { - types: ['null', 'string'], - default: null, - help: '', - }, }, async fn(input, args) { - const params = JSON.parse(args.params); - const uiStateParams = JSON.parse(args.uiState); - const savedObjectId = args.savedObjectId; - const { PersistedState } = await import('../../visualizations/public'); - const uiState = new PersistedState(uiStateParams); + const visParams: TimeseriesVisParams = JSON.parse(args.params); + const uiState = JSON.parse(args.uiState); const response = await metricsRequestHandler({ - timeRange: get(input, 'timeRange', null), - query: get(input, 'query', null), - filters: get(input, 'filters', null), - visParams: params, + input, + visParams, uiState, - savedObjectId, }); - response.visType = 'metrics'; - return { type: 'render', - as: 'visualization', + as: 'timeseries_vis', value: { - uiState, - visType: 'metrics', - visConfig: params, + visParams, visData: response, }, }; diff --git a/src/plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts index 01b6ea0768338..2b75f69620629 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_type.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts @@ -19,12 +19,9 @@ import { i18n } from '@kbn/i18n'; -// @ts-ignore -import { metricsRequestHandler } from './request_handler'; import { EditorController } from './application'; -// @ts-ignore import { PANEL_TYPES } from '../common/panel_types'; -import { VisEditor } from './application/components/vis_editor_lazy'; +import { toExpressionAst } from './to_ast'; import { VIS_EVENT_TO_TRIGGER, VisGroups, VisParams } from '../../visualizations/public'; import { getDataStart } from './services'; import { INDEXES_SEPARATOR } from '../common/constants'; @@ -73,7 +70,6 @@ export const metricsVisDefinition = { show_grid: 1, tooltip_mode: 'show_all', }, - component: VisEditor, }, editor: EditorController, options: { @@ -81,7 +77,7 @@ export const metricsVisDefinition = { showFilterBar: false, showIndexSelection: false, }, - requestHandler: metricsRequestHandler, + toExpressionAst, getSupportedTriggers: () => { return [VIS_EVENT_TO_TRIGGER.applyFilter]; }, @@ -102,5 +98,4 @@ export const metricsVisDefinition = { return []; }, - responseHandler: 'none', }; diff --git a/src/plugins/vis_type_timeseries/public/plugin.ts b/src/plugins/vis_type_timeseries/public/plugin.ts index d98e55bdb340c..d36b3611680af 100644 --- a/src/plugins/vis_type_timeseries/public/plugin.ts +++ b/src/plugins/vis_type_timeseries/public/plugin.ts @@ -36,6 +36,7 @@ import { } from './services'; import { DataPublicPluginStart } from '../../data/public'; import { ChartsPluginSetup } from '../../charts/public'; +import { getTimeseriesVisRenderer } from './timeseries_vis_renderer'; /** @internal */ export interface MetricsPluginSetupDependencies { @@ -62,9 +63,14 @@ export class MetricsPlugin implements Plugin, void> { { expressions, visualizations, charts }: MetricsPluginSetupDependencies ) { expressions.registerFunction(createMetricsFn); + expressions.registerRenderer( + getTimeseriesVisRenderer({ + uiSettings: core.uiSettings, + }) + ); setUISettings(core.uiSettings); setChartsSetup(charts); - visualizations.createReactVisualization(metricsVisDefinition); + visualizations.createBaseVisualization(metricsVisDefinition); } public start(core: CoreStart, { data }: MetricsPluginStartDependencies) { diff --git a/src/plugins/vis_type_timeseries/public/request_handler.js b/src/plugins/vis_type_timeseries/public/request_handler.ts similarity index 54% rename from src/plugins/vis_type_timeseries/public/request_handler.js rename to src/plugins/vis_type_timeseries/public/request_handler.ts index 12b7f3d417ef6..aa45453515277 100644 --- a/src/plugins/vis_type_timeseries/public/request_handler.js +++ b/src/plugins/vis_type_timeseries/public/request_handler.ts @@ -17,57 +17,52 @@ * under the License. */ +import { KibanaContext } from '../../data/public'; + import { getTimezone, validateInterval } from './application'; import { getUISettings, getDataStart, getCoreStart } from './services'; -import { MAX_BUCKETS_SETTING } from '../common/constants'; +import { MAX_BUCKETS_SETTING, ROUTES } from '../common/constants'; +import { TimeseriesVisParams } from './metrics_fn'; +import { TimeseriesVisData } from '../common/types'; + +interface MetricsRequestHandlerParams { + input: KibanaContext | null; + uiState: Record; + visParams: TimeseriesVisParams; +} export const metricsRequestHandler = async ({ + input, uiState, - timeRange, - filters, - query, visParams, - savedObjectId, -}) => { +}: MetricsRequestHandlerParams): Promise => { const config = getUISettings(); const timezone = getTimezone(config); - const uiStateObj = uiState.get(visParams.type, {}); + const uiStateObj = uiState[visParams.type] ?? {}; const dataSearch = getDataStart(); - const parsedTimeRange = dataSearch.query.timefilter.timefilter.calculateBounds(timeRange); - const scaledDataFormat = config.get('dateFormat:scaled'); - const dateFormat = config.get('dateFormat'); + const parsedTimeRange = dataSearch.query.timefilter.timefilter.calculateBounds(input?.timeRange!); if (visParams && visParams.id && !visParams.isModelInvalid) { - try { - const maxBuckets = config.get(MAX_BUCKETS_SETTING); + const maxBuckets = config.get(MAX_BUCKETS_SETTING); - validateInterval(parsedTimeRange, visParams, maxBuckets); + validateInterval(parsedTimeRange, visParams, maxBuckets); - const resp = await getCoreStart().http.post('/api/metrics/vis/data', { - body: JSON.stringify({ - timerange: { - timezone, - ...parsedTimeRange, - }, - query, - filters, - panels: [visParams], - state: uiStateObj, - savedObjectId: savedObjectId || 'unsaved', - sessionId: dataSearch.search.session.getSessionId(), - }), - }); + const resp = await getCoreStart().http.post(ROUTES.VIS_DATA, { + body: JSON.stringify({ + timerange: { + timezone, + ...parsedTimeRange, + }, + query: input?.query, + filters: input?.filters, + panels: [visParams], + state: uiStateObj, + sessionId: dataSearch.search.session.getSessionId(), + }), + }); - return { - dateFormat, - scaledDataFormat, - timezone, - ...resp, - }; - } catch (error) { - return Promise.reject(error); - } + return resp; } - return Promise.resolve({}); + return {}; }; diff --git a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx new file mode 100644 index 0000000000000..67ed487d29378 --- /dev/null +++ b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx @@ -0,0 +1,72 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { lazy } from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; + +import { IUiSettingsClient } from 'kibana/public'; +import { VisualizationContainer } from '../../visualizations/public'; +import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers'; +import { TimeseriesRenderValue, TimeseriesVisParams } from './metrics_fn'; +import { TimeseriesVisData } from '../common/types'; + +const TimeseriesVisualization = lazy( + () => import('./application/components/timeseries_visualization') +); + +const checkIfDataExists = (visData: TimeseriesVisData | {}, model: TimeseriesVisParams) => { + if ('type' in visData) { + const data = visData.type === 'table' ? visData.series : visData?.[model.id]?.series; + return Boolean(data?.length); + } + + return false; +}; + +export const getTimeseriesVisRenderer: (deps: { + uiSettings: IUiSettingsClient; +}) => ExpressionRenderDefinition = ({ uiSettings }) => ({ + name: 'timeseries_vis', + reuseDomNode: true, + render: async (domNode, config, handlers) => { + handlers.onDestroy(() => { + unmountComponentAtNode(domNode); + }); + + const showNoResult = !checkIfDataExists(config.visData, config.visParams); + + render( + + + , + domNode + ); + }, +}); diff --git a/src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.ts b/src/plugins/vis_type_timeseries/public/to_ast.ts similarity index 59% rename from src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.ts rename to src/plugins/vis_type_timeseries/public/to_ast.ts index 38002c7552952..58de0269fd27f 100644 --- a/src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.ts +++ b/src/plugins/vis_type_timeseries/public/to_ast.ts @@ -17,23 +17,17 @@ * under the License. */ -import { ExprVisAPIEvents } from '../../../../visualizations/public'; +import { buildExpression, buildExpressionFunction } from '../../expressions/public'; +import { Vis } from '../../visualizations/public'; +import { TimeseriesExpressionFunctionDefinition, TimeseriesVisParams } from './metrics_fn'; -export const createBrushHandler = (applyFilter: ExprVisAPIEvents['applyFilter']) => ( - gte: string, - lte: string -) => { - return applyFilter({ - timeFieldName: '*', - filters: [ - { - range: { - '*': { - gte, - lte, - }, - }, - }, - ], +export const toExpressionAst = (vis: Vis) => { + const timeseries = buildExpressionFunction('tsvb', { + params: JSON.stringify(vis.params), + uiState: JSON.stringify(vis.uiState), }); + + const ast = buildExpression([timeseries]); + + return ast.toAst(); }; diff --git a/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts b/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts index fcb66d2e12fd1..aefbe0ea78d4b 100644 --- a/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts +++ b/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts @@ -20,46 +20,37 @@ import { FakeRequest, RequestHandlerContext } from 'kibana/server'; import _ from 'lodash'; import { first, map } from 'rxjs/operators'; + +import { Filter, Query } from 'src/plugins/data/common'; import { getPanelData } from './vis_data/get_panel_data'; import { Framework } from '../plugin'; import { ReqFacade } from './search_strategies/strategies/abstract_search_strategy'; - -interface GetVisDataResponse { - [key: string]: GetVisDataPanel; -} - -interface GetVisDataPanel { - id: string; - series: GetVisDataSeries[]; -} - -interface GetVisDataSeries { - id: string; - label: string; - data: GetVisDataDataPoint[]; -} - -type GetVisDataDataPoint = [number, number]; +import { TimeseriesVisData } from '../../common/types'; export interface GetVisDataOptions { - timerange?: any; - panels?: any; - filters?: any; - state?: any; - query?: any; + timerange: { + min: number | string; + max: number | string; + timezone?: string; + }; + panels: unknown[]; + filters?: Filter[]; + state?: Record; + query?: Query | Query[]; + sessionId?: string; } export type GetVisData = ( requestContext: RequestHandlerContext, options: GetVisDataOptions, framework: Framework -) => Promise; +) => Promise; export function getVisData( requestContext: RequestHandlerContext, request: FakeRequest & { body: GetVisDataOptions }, framework: Framework -): Promise { +): Promise { // NOTE / TODO: This facade has been put in place to make migrating to the New Platform easier. It // removes the need to refactor many layers of dependencies on "req", and instead just augments the top // level object passed from here. The layers should be refactored fully at some point, but for now @@ -81,10 +72,10 @@ export function getVisData( .toPromise(); }, }; - const promises = (reqFacade.payload as GetVisDataOptions).panels.map(getPanelData(reqFacade)); + const promises = reqFacade.payload.panels.map(getPanelData(reqFacade)); return Promise.all(promises).then((res) => { return res.reduce((acc, data) => { return _.assign(acc as any, data); }, {}); - }) as Promise; + }) as Promise; } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_active_series.ts b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_active_series.ts index 235235cf6a3be..b7644f6582761 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_active_series.ts +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_active_series.ts @@ -29,7 +29,8 @@ export const getActiveSeries = (panel: PanelSchema) => { } // Toogle visibility functionality for 'gauge', 'markdown' is not accessible - const shouldNotApplyFilter = [PANEL_TYPES.GAUGE, PANEL_TYPES.MARKDOWN].includes(panel.type); + const shouldNotApplyFilter = + PANEL_TYPES.GAUGE === panel.type || PANEL_TYPES.MARKDOWN === panel.type; return visibleSeries.filter((series) => !series.hidden || shouldNotApplyFilter); }; diff --git a/src/plugins/vis_type_timeseries/server/routes/vis.ts b/src/plugins/vis_type_timeseries/server/routes/vis.ts index 1ca8b57ab230f..bba086720da0a 100644 --- a/src/plugins/vis_type_timeseries/server/routes/vis.ts +++ b/src/plugins/vis_type_timeseries/server/routes/vis.ts @@ -21,6 +21,7 @@ import { IRouter, KibanaRequest } from 'kibana/server'; import { schema } from '@kbn/config-schema'; import { getVisData, GetVisDataOptions } from '../lib/get_vis_data'; import { visPayloadSchema } from '../../common/vis_schema'; +import { ROUTES } from '../../common/constants'; import { ValidationTelemetryServiceSetup } from '../index'; import { Framework } from '../plugin'; @@ -33,7 +34,7 @@ export const visDataRoutes = ( ) => { router.post( { - path: '/api/metrics/vis/data', + path: ROUTES.VIS_DATA, validate: { body: escapeHatch, }, @@ -43,11 +44,9 @@ export const visDataRoutes = ( visPayloadSchema.validate(request.body); } catch (error) { logFailedValidation(); - const savedObjectId = - (typeof request.body === 'object' && (request.body as any).savedObjectId) || - 'unavailable'; + framework.logger.warn( - `Request validation error: ${error.message} (saved object id: ${savedObjectId}). This most likely means your TSVB visualization contains outdated configuration. You can report this problem under https://github.com/elastic/kibana/issues/new?template=Bug_report.md` + `Request validation error: ${error.message}. This most likely means your TSVB visualization contains outdated configuration. You can report this problem under https://github.com/elastic/kibana/issues/new?template=Bug_report.md` ); } diff --git a/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap b/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap index 978c67fb71721..94c5da872b1cb 100644 --- a/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap +++ b/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap @@ -3,6 +3,7 @@ exports[`VisualizationNoResults should render according to snapshot 1`] = `
+
{showNoResult ? handlers.done()} /> : children} diff --git a/src/plugins/visualizations/public/components/visualization_noresults.tsx b/src/plugins/visualizations/public/components/visualization_noresults.tsx index c77ef4490a4b3..90d5353185229 100644 --- a/src/plugins/visualizations/public/components/visualization_noresults.tsx +++ b/src/plugins/visualizations/public/components/visualization_noresults.tsx @@ -30,7 +30,7 @@ export class VisualizationNoResults extends React.Component +
diff --git a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap index 2c6cfc6fb7462..03a355c604c4d 100644 --- a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap +++ b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap @@ -4,8 +4,6 @@ exports[`visualize loader pipeline helpers: build pipeline buildPipeline calls t exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles input_control_vis function 1`] = `"input_control_vis visConfig='{\\"some\\":\\"nested\\",\\"data\\":{\\"here\\":true}}' "`; -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles metrics/tsvb function 1`] = `"tsvb params='{\\"foo\\":\\"bar\\"}' uiState='{}' "`; - exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles region_map function with buckets 1`] = `"regionmap visConfig='{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},\\"bucket\\":1}' "`; exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles region_map function without buckets 1`] = `"regionmap visConfig='{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"}}' "`; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts index 0c210a04d2007..653542bd8837d 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts @@ -101,12 +101,6 @@ describe('visualize loader pipeline helpers: build pipeline', () => { expect(actual).toMatchSnapshot(); }); - it('handles metrics/tsvb function', () => { - const params = { foo: 'bar' }; - const actual = buildPipelineVisFunction.metrics(params, schemasDef, uiState); - expect(actual).toMatchSnapshot(); - }); - describe('handles region_map function', () => { it('without buckets', () => { const params = { metric: {} }; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.ts b/src/plugins/visualizations/public/legacy/build_pipeline.ts index 3593d62b9d2e6..d412ec918a71a 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.ts @@ -222,13 +222,6 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { input_control_vis: (params) => { return `input_control_vis ${prepareJson('visConfig', params)}`; }, - metrics: ({ title, ...params }, schemas, uiState = {}) => { - const paramsJson = prepareJson('params', params); - const uiStateJson = prepareJson('uiState', uiState); - - const paramsArray = [paramsJson, uiStateJson].filter((param) => Boolean(param)); - return `tsvb ${paramsArray.join(' ')}`; - }, region_map: (params, schemas) => { const visConfig = { ...params, diff --git a/test/functional/apps/dashboard/dashboard_filtering.js b/test/functional/apps/dashboard/dashboard_filtering.js index 0be4fbbebe7c5..b3812af38c348 100644 --- a/test/functional/apps/dashboard/dashboard_filtering.js +++ b/test/functional/apps/dashboard/dashboard_filtering.js @@ -92,7 +92,7 @@ export default function ({ getService, getPageObjects }) { }); it('tsvb time series shows no data message', async () => { - expect(await testSubjects.exists('noTSVBDataMessage')).to.be(true); + expect(await testSubjects.exists('timeseriesVis > visNoResult')).to.be(true); }); it('metric value shows no data', async () => { diff --git a/test/functional/apps/management/_index_pattern_popularity.js b/test/functional/apps/management/_index_pattern_popularity.js index 530b8e1111a0c..e2fcf50ef2c12 100644 --- a/test/functional/apps/management/_index_pattern_popularity.js +++ b/test/functional/apps/management/_index_pattern_popularity.js @@ -60,7 +60,7 @@ export default function ({ getService, getPageObjects }) { // check that it is 0 (previous increase was cancelled const popularity = await PageObjects.settings.getPopularity(); log.debug('popularity = ' + popularity); - expect(popularity).to.be('0'); + expect(popularity).to.be(''); }); it('can be saved', async function () { diff --git a/test/functional/apps/timelion/_expression_typeahead.js b/test/functional/apps/timelion/_expression_typeahead.js index d1e974942a362..5d834f1a055de 100644 --- a/test/functional/apps/timelion/_expression_typeahead.js +++ b/test/functional/apps/timelion/_expression_typeahead.js @@ -86,7 +86,7 @@ export default function ({ getPageObjects }) { await PageObjects.timelion.updateExpression(',split'); await PageObjects.timelion.clickSuggestion(); const suggestions = await PageObjects.timelion.getSuggestionItemsText(); - expect(suggestions.length).to.eql(52); + expect(suggestions.length).to.eql(51); expect(suggestions[0].includes('@message.raw')).to.eql(true); await PageObjects.timelion.clickSuggestion(10); }); diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts index 37634d0248b04..0e305eaafc82f 100644 --- a/test/functional/page_objects/visual_builder_page.ts +++ b/test/functional/page_objects/visual_builder_page.ts @@ -549,7 +549,7 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro public async checkPreviewIsDisabled(): Promise { log.debug(`Check no data message is present`); - await testSubjects.existOrFail('noTSVBDataMessage', { timeout: 5000 }); + await testSubjects.existOrFail('timeseriesVis > visNoResult', { timeout: 5000 }); } public async cloneSeries(nth: number = 0): Promise { diff --git a/test/new_visualize_flow/fixtures/es_archiver/kibana/data.json b/test/new_visualize_flow/fixtures/es_archiver/kibana/data.json new file mode 100644 index 0000000000000..14d67f9bfbc34 --- /dev/null +++ b/test/new_visualize_flow/fixtures/es_archiver/kibana/data.json @@ -0,0 +1,4229 @@ +{ + "type": "doc", + "value": { + "id": "search:a16d1990-3dca-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "search": "7.4.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "search": { + "columns": [ + "animal", + "isDog", + "name", + "sound", + "weightLbs" + ], + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"language\":\"lucene\",\"query\":\"weightLbs:>40\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "sort": [ + [ + "weightLbs", + "desc" + ] + ], + "title": "animal weights", + "version": 1 + }, + "type": "search", + "updated_at": "2018-04-11T20:55:26.317Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "config:6.3.0", + "index": ".kibana_1", + "source": { + "config": { + "buildNum": 8467, + "defaultIndex": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c" + }, + "references": [ + ], + "type": "config", + "updated_at": "2018-04-11T20:43:55.434Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:61c58ad0-3dd3-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[{\"meta\":{\"negate\":false,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"animal\",\"value\":\"dog\",\"params\":{\"query\":\"dog\",\"type\":\"phrase\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"animal\":{\"query\":\"dog\",\"type\":\"phrase\"}}},\"$state\":{\"store\":\"appState\"}}],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[{\"gridData\":{\"w\":24,\"h\":15,\"x\":0,\"y\":0,\"i\":\"1\"},\"version\":\"7.3.0\",\"panelIndex\":\"1\",\"embeddableConfig\":{},\"panelRefName\":\"panel_0\"},{\"gridData\":{\"w\":24,\"h\":15,\"x\":24,\"y\":0,\"i\":\"2\"},\"version\":\"7.3.0\",\"panelIndex\":\"2\",\"embeddableConfig\":{},\"panelRefName\":\"panel_1\"}]", + "refreshInterval": { + "display": "Off", + "pause": false, + "value": 0 + }, + "timeFrom": "Mon Apr 09 2018 17:56:08 GMT-0400", + "timeRestore": true, + "timeTo": "Wed Apr 11 2018 17:56:08 GMT-0400", + "title": "dashboard with filter", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + }, + { + "id": "50643b60-3dd3-11e8-b2b9-5d5dc1715159", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "a16d1990-3dca-11e8-8660-4d65aa086b3c", + "name": "panel_1", + "type": "search" + } + ], + "type": "dashboard", + "updated_at": "2018-04-11T21:57:52.253Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:2ae34a60-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[{\"gridData\":{\"w\":24,\"h\":15,\"x\":0,\"y\":0,\"i\":\"1\"},\"version\":\"7.3.0\",\"panelIndex\":\"1\",\"embeddableConfig\":{},\"panelRefName\":\"panel_0\"},{\"gridData\":{\"w\":24,\"h\":15,\"x\":24,\"y\":0,\"i\":\"2\"},\"version\":\"7.3.0\",\"panelIndex\":\"2\",\"embeddableConfig\":{},\"panelRefName\":\"panel_1\"}]", + "timeRestore": false, + "title": "couple panels", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "145ced90-3dcb-11e8-8660-4d65aa086b3c", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "e2023110-3dcb-11e8-8660-4d65aa086b3c", + "name": "panel_1", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:03:29.670Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:76d03330-3dd3-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "and_descriptions_has_underscores", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "dashboard_with_underscores", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T21:58:27.555Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:9b780cd0-3dd3-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "* hi & $%!!@# 漢字 ^--=++[]{};'~`~<>?,./:\";'\\|\\\\ special chars", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:00:07.322Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:6c0b16e0-3dd3-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "dashboard-name-has-dashes", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T21:58:09.486Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:19523860-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "im empty too", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:03:00.198Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:14616b50-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "im empty", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:02:51.909Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:33bb8ad0-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[{\"panelIndex\":\"1\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_0\"},{\"panelIndex\":\"2\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"2\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_1\"},{\"panelIndex\":\"3\",\"gridData\":{\"x\":0,\"y\":15,\"w\":24,\"h\":15,\"i\":\"3\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_2\"}]", + "timeRestore": false, + "title": "few panels", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "145ced90-3dcb-11e8-8660-4d65aa086b3c", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "e2023110-3dcb-11e8-8660-4d65aa086b3c", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "4b5d6ef0-3dcb-11e8-8660-4d65aa086b3c", + "name": "panel_2", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:03:44.509Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:60659030-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "zz 2", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:04:59.443Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:65227c00-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "zz 3", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:05:07.392Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:6803a2f0-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "zz 4", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:05:12.223Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:6b18f940-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "zz 5", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:05:17.396Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:6e12ff60-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "zz 6", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:05:22.390Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:4f0fd980-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "zz", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:04:30.360Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:3de0bda0-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "1", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:04:01.530Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:46c8b580-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "2", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:04:16.472Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:708fe640-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "zz 7", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:05:26.564Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:7b8d50a0-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "Hi i have a lot of words in my dashboard name! It's pretty long i wonder what it'll look like", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:05:45.002Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:7e42d3b0-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "bye", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:05:49.547Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:846988b0-3dd4-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[]", + "timeRestore": false, + "title": "last", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + ], + "type": "dashboard", + "updated_at": "2018-04-11T22:05:59.867Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:cbd3bc30-3e5a-11e8-9fc3-39e49624228e", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"weightLbs:<50\",\"language\":\"lucene\"},\"filter\":[{\"meta\":{\"negate\":true,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"name.keyword\",\"value\":\"Fee Fee\",\"params\":{\"query\":\"Fee Fee\",\"type\":\"phrase\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"name.keyword\":{\"query\":\"Fee Fee\",\"type\":\"phrase\"}}},\"$state\":{\"store\":\"appState\"}}],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":true,\"useMargins\":true,\"hidePanelTitles\":true}", + "panelsJSON": "[{\"panelIndex\":\"1\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_0\"},{\"panelIndex\":\"2\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"2\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_1\"},{\"panelIndex\":\"3\",\"gridData\":{\"x\":0,\"y\":15,\"w\":24,\"h\":15,\"i\":\"3\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_2\"}]", + "timeRestore": false, + "title": "bug", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + }, + { + "id": "771b4f10-3e59-11e8-9fc3-39e49624228e", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "befdb6b0-3e59-11e8-9fc3-39e49624228e", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "4c0c3f90-3e5a-11e8-9fc3-39e49624228e", + "name": "panel_2", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2018-04-12T14:07:12.243Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:5bac3a80-3e5b-11e8-9fc3-39e49624228e", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "dashboard with scripted filter, negated filter and query", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"language\":\"lucene\",\"query\":\"weightLbs:<50\"},\"filter\":[{\"$state\":{\"store\":\"appState\"},\"meta\":{\"alias\":null,\"disabled\":false,\"key\":\"name.keyword\",\"negate\":true,\"params\":{\"query\":\"Fee Fee\",\"type\":\"phrase\"},\"type\":\"phrase\",\"value\":\"Fee Fee\",\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"name.keyword\":{\"query\":\"Fee Fee\",\"type\":\"phrase\"}}}},{\"$state\":{\"store\":\"appState\"},\"meta\":{\"alias\":\"is dog\",\"disabled\":false,\"field\":\"isDog\",\"key\":\"isDog\",\"negate\":false,\"params\":{\"value\":true},\"type\":\"phrase\",\"value\":\"true\",\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index\"},\"script\":{\"script\":{\"inline\":\"boolean compare(Supplier s, def v) {return s.get() == v;}compare(() -> { return doc['animal.keyword'].value == 'dog' }, params.value);\",\"lang\":\"painless\",\"params\":{\"value\":true}}}}],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":true,\"hidePanelTitles\":false,\"useMargins\":true}", + "panelsJSON": "[{\"panelIndex\":\"1\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_0\"},{\"panelIndex\":\"3\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"3\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_1\"},{\"panelIndex\":\"4\",\"gridData\":{\"x\":0,\"y\":15,\"w\":24,\"h\":15,\"i\":\"4\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_2\"}]", + "refreshInterval": { + "display": "Off", + "pause": false, + "section": 0, + "value": 0 + }, + "timeFrom": "Wed Apr 12 2017 10:06:21 GMT-0400", + "timeRestore": true, + "timeTo": "Thu Apr 12 2018 10:06:21 GMT-0400", + "title": "filters", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + }, + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", + "type": "index-pattern" + }, + { + "id": "771b4f10-3e59-11e8-9fc3-39e49624228e", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "4c0c3f90-3e5a-11e8-9fc3-39e49624228e", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "50643b60-3dd3-11e8-b2b9-5d5dc1715159", + "name": "panel_2", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2018-04-12T14:11:13.576Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "index-pattern:f908c8e0-3e6d-11e8-bbb9-e15942d5d48c", + "index": ".kibana_1", + "source": { + "index-pattern": { + "fields": "[{\"name\":\"_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_source\",\"type\":\"_source\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"activity level\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"barking level\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"breed\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"breed.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"size\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"size.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"trainability\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]", + "title": "dogbreeds" + }, + "migrationVersion": { + "index-pattern": "7.6.0" + }, + "references": [ + ], + "type": "index-pattern", + "updated_at": "2018-04-12T16:24:29.357Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:84908bb0-a32e-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.10425, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:04:37.610Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:04:37.611Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:84908bb1-a32e-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "home", + "minutesOnScreen": 0.5708666666666666, + "numberOfClicks": 1, + "timestamp": "2020-05-31T11:04:37.610Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:04:37.611Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:951d7420-a32e-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 1.3920166666666667, + "numberOfClicks": 39, + "timestamp": "2020-05-31T11:05:05.378Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:05:05.378Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:a79fc3f0-a32e-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.45816666666666667, + "numberOfClicks": 8, + "timestamp": "2020-05-31T11:05:36.431Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:05:36.431Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:bc30cf80-a32e-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.5057333333333333, + "numberOfClicks": 14, + "timestamp": "2020-05-31T11:06:10.935Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:06:10.936Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:df4781d0-a32e-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.3740833333333333, + "numberOfClicks": 1, + "timestamp": "2020-05-31T11:07:09.804Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:07:09.805Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:dffd3d40-a32e-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.02105, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:07:10.996Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:07:10.996Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:e05dd3d0-a32e-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.010416666666666666, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:07:11.629Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:07:11.629Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:cfc85fe0-a32e-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.5466333333333333, + "numberOfClicks": 16, + "timestamp": "2020-05-31T11:06:43.806Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:06:43.806Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:00710a20-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.8720333333333333, + "numberOfClicks": 14, + "timestamp": "2020-05-31T11:08:05.442Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:08:05.442Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:e1454da0-a32e-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.01815, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:07:13.146Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:07:13.146Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:0eb5d750-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.33895, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:08:29.380Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:08:29.381Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:2e09dc50-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.08756666666666667, + "numberOfClicks": 3, + "timestamp": "2020-05-31T11:09:21.941Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:09:21.941Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:25916f20-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.5207166666666667, + "numberOfClicks": 5, + "timestamp": "2020-05-31T11:09:07.730Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:09:07.730Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:1e9c4690-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.38158333333333333, + "numberOfClicks": 17, + "timestamp": "2020-05-31T11:08:56.057Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:08:56.057Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:1f41ae50-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.0183, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:08:57.141Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:08:57.141Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:26923d50-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.0285, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:09:09.413Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:09:09.413Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:1024f7b0-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.0401, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:08:31.787Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:08:31.787Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:10f7d810-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.012, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:08:33.169Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:08:33.169Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:34f010c0-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.28990000000000005, + "numberOfClicks": 4, + "timestamp": "2020-05-31T11:09:33.515Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:09:33.516Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:35665230-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.012216666666666667, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:09:34.291Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:09:34.291Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:404deaa0-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.24620000000000003, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:09:52.586Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:09:52.586Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:415ac6c0-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.015816666666666666, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:09:54.348Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:09:54.348Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:40c898e0-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.013533333333333333, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:09:53.390Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:09:53.390Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:434a13a0-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.011566666666666666, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:09:57.594Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:09:57.594Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:42de5980-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.042, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:09:56.888Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:09:56.888Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:ffde98b0-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 2.983433333333333, + "numberOfClicks": 31, + "timestamp": "2020-05-31T11:15:13.979Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:15:13.979Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:46ca9260-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.3946, + "numberOfClicks": 4, + "timestamp": "2020-05-31T11:17:12.966Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:17:12.966Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:47072630-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.006116666666666667, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:17:13.363Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:17:13.363Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:3805bfc0-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.19001666666666667, + "numberOfClicks": 2, + "timestamp": "2020-05-31T11:16:48.188Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:16:48.188Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:38af4630-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.018766666666666668, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:16:49.299Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:16:49.299Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:3136e3e0-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.012466666666666666, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:16:36.766Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:16:36.766Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:fd3cebc0-a32f-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.5283, + "numberOfClicks": 17, + "timestamp": "2020-05-31T11:15:09.564Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:15:09.564Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:6463c800-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.28708333333333336, + "numberOfClicks": 10, + "timestamp": "2020-05-31T11:18:02.624Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:18:02.624Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:57b7c340-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.4411833333333333, + "numberOfClicks": 11, + "timestamp": "2020-05-31T11:17:41.364Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:17:41.364Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:67dbd7c0-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 2.4508833333333335, + "numberOfClicks": 5, + "timestamp": "2020-05-31T11:18:08.444Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:18:08.444Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:6bf41f20-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 2.5884833333333335, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:18:15.314Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:18:15.314Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:6c5ccc00-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.011383333333333334, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:18:16.000Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:18:16.000Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:6ce7f500-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.015066666666666667, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:18:16.912Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:18:16.912Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:5a178530-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.067, + "numberOfClicks": 3, + "timestamp": "2020-05-31T11:17:45.347Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:17:45.347Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:d10c66b0-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.030199999999999998, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:21:04.923Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:21:04.923Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:cd5aa950-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 2.2735666666666665, + "numberOfClicks": 21, + "timestamp": "2020-05-31T11:20:58.724Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:20:58.725Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:b2dee050-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.08906666666666667, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:20:14.293Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:20:14.293Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:d194a980-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.018183333333333333, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:21:05.816Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:21:05.816Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:72b406e0-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.14396666666666666, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:18:26.638Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:18:26.638Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:6d8e6e30-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.0179, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:18:18.003Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:18:18.003Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:5e085850-3e6e-11e8-bbb9-e15942d5d48c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "f908c8e0-3e6d-11e8-bbb9-e15942d5d48c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-12T16:27:17.973Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "non timebased line chart - dog data", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"non timebased line chart - dog data\",\"type\":\"line\",\"params\":{\"type\":\"line\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Max trainability\"}}],\"seriesParams\":[{\"show\":\"true\",\"type\":\"line\",\"mode\":\"normal\",\"data\":{\"label\":\"Max trainability\",\"id\":\"1\"},\"valueAxis\":\"ValueAxis-1\",\"drawLinesBetweenPoints\":true,\"showCircles\":true},{\"show\":true,\"mode\":\"normal\",\"type\":\"line\",\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"data\":{\"id\":\"3\",\"label\":\"Max barking level\"},\"valueAxis\":\"ValueAxis-1\"},{\"show\":true,\"mode\":\"normal\",\"type\":\"line\",\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"data\":{\"id\":\"4\",\"label\":\"Max activity level\"},\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"max\",\"schema\":\"metric\",\"params\":{\"field\":\"trainability\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"breed.keyword\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}},{\"id\":\"3\",\"enabled\":true,\"type\":\"max\",\"schema\":\"metric\",\"params\":{\"field\":\"barking level\"}},{\"id\":\"4\",\"enabled\":true,\"type\":\"max\",\"schema\":\"metric\",\"params\":{\"field\":\"activity level\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:a5d56330-3e6e-11e8-bbb9-e15942d5d48c", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "I have two visualizations that are created off a non time based index", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"useMargins\":true,\"hidePanelTitles\":false}", + "panelsJSON": "[{\"gridData\":{\"w\":24,\"h\":15,\"x\":0,\"y\":0,\"i\":\"1\"},\"version\":\"7.3.0\",\"panelIndex\":\"1\",\"embeddableConfig\":{},\"panelRefName\":\"panel_0\"},{\"gridData\":{\"w\":24,\"h\":15,\"x\":24,\"y\":0,\"i\":\"2\"},\"version\":\"7.3.0\",\"panelIndex\":\"2\",\"embeddableConfig\":{},\"panelRefName\":\"panel_1\"}]", + "timeRestore": false, + "title": "Non time based", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "5e085850-3e6e-11e8-bbb9-e15942d5d48c", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "8bc8d6c0-3e6e-11e8-bbb9-e15942d5d48c", + "name": "panel_1", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2018-04-12T16:29:18.435Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:d2525040-3dcd-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "I have one of every visualization type since the last time I was created!", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}", + "panelsJSON": "[{\"panelIndex\":\"1\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_0\"},{\"panelIndex\":\"2\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"2\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_1\"},{\"panelIndex\":\"3\",\"gridData\":{\"x\":0,\"y\":15,\"w\":24,\"h\":15,\"i\":\"3\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_2\"},{\"panelIndex\":\"4\",\"gridData\":{\"x\":24,\"y\":15,\"w\":24,\"h\":15,\"i\":\"4\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_3\"},{\"panelIndex\":\"5\",\"gridData\":{\"x\":0,\"y\":30,\"w\":24,\"h\":15,\"i\":\"5\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_4\"},{\"panelIndex\":\"6\",\"gridData\":{\"x\":24,\"y\":30,\"w\":24,\"h\":15,\"i\":\"6\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_5\"},{\"panelIndex\":\"7\",\"gridData\":{\"x\":0,\"y\":45,\"w\":24,\"h\":15,\"i\":\"7\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_6\"},{\"panelIndex\":\"8\",\"gridData\":{\"x\":24,\"y\":45,\"w\":24,\"h\":15,\"i\":\"8\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_7\"},{\"panelIndex\":\"9\",\"gridData\":{\"x\":0,\"y\":60,\"w\":24,\"h\":15,\"i\":\"9\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_8\"},{\"panelIndex\":\"10\",\"gridData\":{\"x\":24,\"y\":60,\"w\":24,\"h\":15,\"i\":\"10\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_9\"},{\"panelIndex\":\"11\",\"gridData\":{\"x\":0,\"y\":75,\"w\":24,\"h\":15,\"i\":\"11\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_10\"},{\"panelIndex\":\"12\",\"gridData\":{\"x\":24,\"y\":75,\"w\":24,\"h\":15,\"i\":\"12\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_11\"},{\"panelIndex\":\"13\",\"gridData\":{\"x\":0,\"y\":90,\"w\":24,\"h\":15,\"i\":\"13\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_12\"},{\"panelIndex\":\"14\",\"gridData\":{\"x\":24,\"y\":90,\"w\":24,\"h\":15,\"i\":\"14\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_13\"},{\"panelIndex\":\"15\",\"gridData\":{\"x\":0,\"y\":105,\"w\":24,\"h\":15,\"i\":\"15\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_14\"},{\"panelIndex\":\"16\",\"gridData\":{\"x\":24,\"y\":105,\"w\":24,\"h\":15,\"i\":\"16\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_15\"},{\"panelIndex\":\"17\",\"gridData\":{\"x\":0,\"y\":120,\"w\":24,\"h\":15,\"i\":\"17\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_16\"},{\"panelIndex\":\"18\",\"gridData\":{\"x\":24,\"y\":120,\"w\":24,\"h\":15,\"i\":\"18\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_17\"},{\"panelIndex\":\"19\",\"gridData\":{\"x\":0,\"y\":135,\"w\":24,\"h\":15,\"i\":\"19\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_18\"},{\"panelIndex\":\"20\",\"gridData\":{\"x\":24,\"y\":135,\"w\":24,\"h\":15,\"i\":\"20\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_19\"},{\"panelIndex\":\"21\",\"gridData\":{\"x\":0,\"y\":150,\"w\":24,\"h\":15,\"i\":\"21\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_20\"},{\"panelIndex\":\"22\",\"gridData\":{\"x\":24,\"y\":150,\"w\":24,\"h\":15,\"i\":\"22\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_21\"},{\"panelIndex\":\"23\",\"gridData\":{\"x\":0,\"y\":165,\"w\":24,\"h\":15,\"i\":\"23\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_22\"},{\"panelIndex\":\"24\",\"gridData\":{\"x\":24,\"y\":165,\"w\":24,\"h\":15,\"i\":\"24\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_23\"},{\"panelIndex\":\"25\",\"gridData\":{\"x\":0,\"y\":180,\"w\":24,\"h\":15,\"i\":\"25\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_24\"},{\"panelIndex\":\"26\",\"gridData\":{\"x\":24,\"y\":180,\"w\":24,\"h\":15,\"i\":\"26\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_25\"},{\"panelIndex\":\"27\",\"gridData\":{\"x\":0,\"y\":195,\"w\":24,\"h\":15,\"i\":\"27\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_26\"},{\"panelIndex\":\"28\",\"gridData\":{\"x\":24,\"y\":195,\"w\":24,\"h\":15,\"i\":\"28\"},\"embeddableConfig\":{},\"version\":\"7.3.0\",\"panelRefName\":\"panel_27\"},{\"panelIndex\":\"29\",\"gridData\":{\"x\":0,\"y\":210,\"w\":24,\"h\":15,\"i\":\"29\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_28\"},{\"gridData\":{\"w\":24,\"h\":15,\"x\":24,\"y\":210,\"i\":\"30\"},\"version\":\"7.3.0\",\"panelIndex\":\"30\",\"embeddableConfig\":{},\"panelRefName\":\"panel_29\"}]", + "refreshInterval": { + "display": "Off", + "pause": false, + "value": 0 + }, + "timeFrom": "Mon Apr 09 2018 17:56:08 GMT-0400", + "timeRestore": true, + "timeTo": "Wed Apr 11 2018 17:56:08 GMT-0400", + "title": "dashboard with everything", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "e6140540-3dca-11e8-8660-4d65aa086b3c", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "3525b840-3dcb-11e8-8660-4d65aa086b3c", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "4b5d6ef0-3dcb-11e8-8660-4d65aa086b3c", + "name": "panel_2", + "type": "visualization" + }, + { + "id": "37a541c0-3dcc-11e8-8660-4d65aa086b3c", + "name": "panel_3", + "type": "visualization" + }, + { + "id": "ffa2e0c0-3dcb-11e8-8660-4d65aa086b3c", + "name": "panel_4", + "type": "visualization" + }, + { + "id": "e2023110-3dcb-11e8-8660-4d65aa086b3c", + "name": "panel_5", + "type": "visualization" + }, + { + "id": "145ced90-3dcb-11e8-8660-4d65aa086b3c", + "name": "panel_6", + "type": "visualization" + }, + { + "id": "2d1b1620-3dcd-11e8-8660-4d65aa086b3c", + "name": "panel_7", + "type": "visualization" + }, + { + "id": "42535e30-3dcd-11e8-8660-4d65aa086b3c", + "name": "panel_8", + "type": "visualization" + }, + { + "id": "42535e30-3dcd-11e8-8660-4d65aa086b3c", + "name": "panel_9", + "type": "visualization" + }, + { + "id": "4c0f47e0-3dcd-11e8-8660-4d65aa086b3c", + "name": "panel_10", + "type": "visualization" + }, + { + "id": "11ae2bd0-3dcc-11e8-8660-4d65aa086b3c", + "name": "panel_11", + "type": "visualization" + }, + { + "id": "3fe22200-3dcb-11e8-8660-4d65aa086b3c", + "name": "panel_12", + "type": "visualization" + }, + { + "id": "4ca00ba0-3dcc-11e8-8660-4d65aa086b3c", + "name": "panel_13", + "type": "visualization" + }, + { + "id": "78803be0-3dcd-11e8-8660-4d65aa086b3c", + "name": "panel_14", + "type": "visualization" + }, + { + "id": "b92ae920-3dcc-11e8-8660-4d65aa086b3c", + "name": "panel_15", + "type": "visualization" + }, + { + "id": "e4d8b430-3dcc-11e8-8660-4d65aa086b3c", + "name": "panel_16", + "type": "visualization" + }, + { + "id": "f81134a0-3dcc-11e8-8660-4d65aa086b3c", + "name": "panel_17", + "type": "visualization" + }, + { + "id": "cc43fab0-3dcc-11e8-8660-4d65aa086b3c", + "name": "panel_18", + "type": "visualization" + }, + { + "id": "02a2e4e0-3dcd-11e8-8660-4d65aa086b3c", + "name": "panel_19", + "type": "visualization" + }, + { + "id": "df815d20-3dcc-11e8-8660-4d65aa086b3c", + "name": "panel_20", + "type": "visualization" + }, + { + "id": "c40f4d40-3dcc-11e8-8660-4d65aa086b3c", + "name": "panel_21", + "type": "visualization" + }, + { + "id": "7fda8ee0-3dcd-11e8-8660-4d65aa086b3c", + "name": "panel_22", + "type": "visualization" + }, + { + "id": "a16d1990-3dca-11e8-8660-4d65aa086b3c", + "name": "panel_23", + "type": "search" + }, + { + "id": "be5accf0-3dca-11e8-8660-4d65aa086b3c", + "name": "panel_24", + "type": "search" + }, + { + "id": "ca5ada40-3dca-11e8-8660-4d65aa086b3c", + "name": "panel_25", + "type": "search" + }, + { + "id": "771b4f10-3e59-11e8-9fc3-39e49624228e", + "name": "panel_26", + "type": "visualization" + }, + { + "id": "5e085850-3e6e-11e8-bbb9-e15942d5d48c", + "name": "panel_27", + "type": "visualization" + }, + { + "id": "8bc8d6c0-3e6e-11e8-bbb9-e15942d5d48c", + "name": "panel_28", + "type": "visualization" + }, + { + "id": "befdb6b0-3e59-11e8-9fc3-39e49624228e", + "name": "panel_29", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2018-04-16T16:05:02.915Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:29bd0240-4197-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + }, + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-16T16:56:53.092Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"meta\":{\"negate\":false,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"geo.src\",\"value\":\"CN\",\"params\":{\"query\":\"CN\",\"type\":\"phrase\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"geo.src\":{\"query\":\"CN\",\"type\":\"phrase\"}}},\"$state\":{\"store\":\"appState\"}}],\"query\":{\"query\":\"bytes >= 10000\",\"language\":\"kuery\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Kuery: pie bytes with kuery and filter", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Kuery: pie bytes with kuery and filter\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"bytes\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":10,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "index-pattern:0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "index-pattern": { + "fieldFormatMap": "{\"machine.ram\":{\"id\":\"number\",\"params\":{\"pattern\":\"0,0.[000] b\"}}}", + "fields": "[{\"name\":\"@message\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@message.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"@tags\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@tags.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"@timestamp\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_source\",\"type\":\"_source\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"agent\",\"type\":\"string\",\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"agent.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"bytes\",\"type\":\"number\",\"count\":3,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"clientip\",\"type\":\"ip\",\"count\":3,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"extension\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"extension.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.coordinates\",\"type\":\"geo_point\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.dest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.src\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.srcdest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"headings\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"headings.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"host\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"host.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"id\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"index.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"ip\",\"type\":\"ip\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"links\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"links.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"machine.os\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"machine.os.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"machine.ram\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"memory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"meta.char\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"meta.related\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"meta.user.firstname\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"meta.user.lastname\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"phpmemory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"referer\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:modified_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:published_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:section\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.article:section.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:tag\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.article:tag.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:description.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:image.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:image:height\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:image:height.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:image:width\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:image:width.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:site_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:site_name.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:title.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:type.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:url.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:card\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:card.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:description.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:image.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:site\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:site.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:title.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.url.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"request\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"request.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"response\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"response.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"spaces\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"spaces.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"url.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"utc_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"xss\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"xss.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]", + "timeFieldName": "@timestamp", + "title": "logstash-*" + }, + "migrationVersion": { + "index-pattern": "7.6.0" + }, + "references": [ + ], + "type": "index-pattern", + "updated_at": "2018-04-16T16:57:12.263Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "search:55d37a30-4197-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "search": "7.4.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + }, + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + } + ], + "search": { + "columns": [ + "agent", + "bytes", + "clientip" + ], + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"clientip : 73.14.212.83\",\"language\":\"kuery\"},\"filter\":[{\"meta\":{\"negate\":false,\"disabled\":false,\"alias\":null,\"type\":\"range\",\"key\":\"bytes\",\"value\":\"100 to 1,000\",\"params\":{\"gte\":100,\"lt\":1000},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"range\":{\"bytes\":{\"gte\":100,\"lt\":1000}},\"$state\":{\"store\":\"appState\"}}],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "sort": [ + [ + "@timestamp", + "desc" + ] + ], + "title": "Bytes and kuery in saved search with filter", + "version": 1 + }, + "type": "search", + "updated_at": "2018-04-16T16:58:07.059Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:b60de070-4197-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "Bytes bytes and more bytes", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}", + "panelsJSON": "[{\"panelIndex\":\"1\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"1\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_0\"},{\"panelIndex\":\"2\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"2\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_1\"},{\"panelIndex\":\"3\",\"gridData\":{\"x\":0,\"y\":15,\"w\":24,\"h\":15,\"i\":\"3\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_2\"},{\"panelIndex\":\"4\",\"gridData\":{\"x\":24,\"y\":15,\"w\":17,\"h\":8,\"i\":\"4\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_3\"},{\"panelIndex\":\"5\",\"gridData\":{\"x\":0,\"y\":30,\"w\":18,\"h\":13,\"i\":\"5\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_4\"},{\"panelIndex\":\"6\",\"gridData\":{\"x\":24,\"y\":37,\"w\":24,\"h\":12,\"i\":\"6\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_5\"},{\"panelIndex\":\"7\",\"gridData\":{\"x\":18,\"y\":30,\"w\":9,\"h\":7,\"i\":\"7\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_6\"},{\"panelIndex\":\"8\",\"gridData\":{\"x\":28,\"y\":23,\"w\":15,\"h\":13,\"i\":\"8\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_7\"},{\"panelIndex\":\"9\",\"gridData\":{\"x\":0,\"y\":43,\"w\":24,\"h\":15,\"i\":\"9\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_8\"},{\"panelIndex\":\"10\",\"gridData\":{\"x\":24,\"y\":49,\"w\":18,\"h\":12,\"i\":\"10\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_9\"},{\"panelIndex\":\"11\",\"gridData\":{\"x\":0,\"y\":58,\"w\":24,\"h\":15,\"i\":\"11\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_10\"},{\"panelIndex\":\"12\",\"gridData\":{\"x\":24,\"y\":61,\"w\":5,\"h\":4,\"i\":\"12\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_11\"},{\"panelIndex\":\"13\",\"gridData\":{\"x\":0,\"y\":73,\"w\":17,\"h\":6,\"i\":\"13\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_12\"},{\"panelIndex\":\"14\",\"gridData\":{\"x\":24,\"y\":65,\"w\":24,\"h\":15,\"i\":\"14\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_13\"},{\"panelIndex\":\"15\",\"gridData\":{\"x\":0,\"y\":79,\"w\":24,\"h\":6,\"i\":\"15\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_14\"},{\"panelIndex\":\"16\",\"gridData\":{\"x\":24,\"y\":80,\"w\":24,\"h\":15,\"i\":\"16\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_15\"},{\"panelIndex\":\"17\",\"gridData\":{\"x\":0,\"y\":85,\"w\":13,\"h\":11,\"i\":\"17\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_16\"},{\"panelIndex\":\"18\",\"gridData\":{\"x\":24,\"y\":95,\"w\":23,\"h\":11,\"i\":\"18\"},\"version\":\"7.3.0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_17\"}]", + "refreshInterval": { + "display": "Off", + "pause": false, + "value": 0 + }, + "timeFrom": "Mon Apr 09 2018 17:56:08 GMT-0400", + "timeRestore": true, + "timeTo": "Wed Apr 11 2018 17:56:08 GMT-0400", + "title": "All about those bytes", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "7ff2c4c0-4191-11e8-bb13-d53698fb349a", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "03d2afd0-4192-11e8-bb13-d53698fb349a", + "name": "panel_1", + "type": "visualization" + }, + { + "id": "63983430-4192-11e8-bb13-d53698fb349a", + "name": "panel_2", + "type": "visualization" + }, + { + "id": "0ca8c600-4195-11e8-bb13-d53698fb349a", + "name": "panel_3", + "type": "visualization" + }, + { + "id": "c10c6b00-4191-11e8-bb13-d53698fb349a", + "name": "panel_4", + "type": "visualization" + }, + { + "id": "760a9060-4190-11e8-bb13-d53698fb349a", + "name": "panel_5", + "type": "visualization" + }, + { + "id": "1dcdfe30-4192-11e8-bb13-d53698fb349a", + "name": "panel_6", + "type": "visualization" + }, + { + "id": "584c0300-4191-11e8-bb13-d53698fb349a", + "name": "panel_7", + "type": "visualization" + }, + { + "id": "b3e70d00-4190-11e8-bb13-d53698fb349a", + "name": "panel_8", + "type": "visualization" + }, + { + "id": "df72ad40-4194-11e8-bb13-d53698fb349a", + "name": "panel_9", + "type": "visualization" + }, + { + "id": "9bebe980-4192-11e8-bb13-d53698fb349a", + "name": "panel_10", + "type": "visualization" + }, + { + "id": "9fb4c670-4194-11e8-bb13-d53698fb349a", + "name": "panel_11", + "type": "visualization" + }, + { + "id": "35417e50-4194-11e8-bb13-d53698fb349a", + "name": "panel_12", + "type": "visualization" + }, + { + "id": "039e4770-4194-11e8-bb13-d53698fb349a", + "name": "panel_13", + "type": "visualization" + }, + { + "id": "76c7f020-4194-11e8-bb13-d53698fb349a", + "name": "panel_14", + "type": "visualization" + }, + { + "id": "8090dcb0-4195-11e8-bb13-d53698fb349a", + "name": "panel_15", + "type": "visualization" + }, + { + "id": "29bd0240-4197-11e8-bb13-d53698fb349a", + "name": "panel_16", + "type": "visualization" + }, + { + "id": "55d37a30-4197-11e8-bb13-d53698fb349a", + "name": "panel_17", + "type": "search" + } + ], + "type": "dashboard", + "updated_at": "2018-04-16T17:00:48.503Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:78803be0-3dcd-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:32.127Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: tag cloud", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: tag cloud\",\"type\":\"tagcloud\",\"params\":{\"scale\":\"linear\",\"orientation\":\"single\",\"minFontSize\":18,\"maxFontSize\":72,\"showLabel\":true},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"geo.src\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:3fe22200-3dcb-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:32.130Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: pie", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: pie\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"bytes\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:4ca00ba0-3dcc-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:32.131Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: region map", + "uiStateJSON": "{\"mapZoom\":2,\"mapCenter\":[8.754794702435618,-9.140625000000002]}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: region map\",\"type\":\"region_map\",\"params\":{\"legendPosition\":\"bottomright\",\"addTooltip\":true,\"colorSchema\":\"Yellow to Red\",\"selectedLayer\":{\"attribution\":\"

Made with NaturalEarth | Elastic Maps Service

\",\"name\":\"World Countries\",\"weight\":1,\"format\":{\"type\":\"geojson\"},\"url\":\"https://staging-dot-elastic-layer.appspot.com/blob/5715999101812736?elastic_tile_service_tos=agree&my_app_version=6.3.0\",\"fields\":[{\"name\":\"iso2\",\"description\":\"Two letter abbreviation\"},{\"name\":\"iso3\",\"description\":\"Three letter abbreviation\"},{\"name\":\"name\",\"description\":\"Country name\"}],\"created_at\":\"2017-07-31T16:00:19.996450\",\"tags\":[],\"id\":5715999101812736,\"layerId\":\"elastic_maps_service.World Countries\"},\"selectedJoinField\":{\"name\":\"iso2\",\"description\":\"Two letter abbreviation\"},\"isDisplayWarning\":true,\"wms\":{\"enabled\":false,\"options\":{\"format\":\"image/png\",\"transparent\":true},\"baseLayersAreLoaded\":{},\"tmsLayers\":[{\"id\":\"road_map\",\"url\":\"https://tiles-stage.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=6.3.0\",\"minZoom\":0,\"maxZoom\":10,\"attribution\":\"

© OpenStreetMap contributors | Elastic Maps Service

\",\"subdomains\":[]}],\"selectedTmsLayer\":{\"id\":\"road_map\",\"url\":\"https://tiles-stage.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=6.3.0\",\"minZoom\":0,\"maxZoom\":10,\"attribution\":\"

© OpenStreetMap contributors | Elastic Maps Service

\",\"subdomains\":[]}},\"mapZoom\":2,\"mapCenter\":[0,0],\"outlineWeight\":1,\"showAllShapes\":true},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"geo.src\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:11ae2bd0-3dcc-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:32.133Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: metric", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: metric\",\"type\":\"metric\",\"params\":{\"addTooltip\":true,\"addLegend\":false,\"type\":\"metric\",\"metric\":{\"percentageMode\":false,\"useRanges\":false,\"colorSchema\":\"Green to Red\",\"metricColorMode\":\"None\",\"colorsRange\":[{\"from\":0,\"to\":10000}],\"labels\":{\"show\":true},\"invertColors\":false,\"style\":{\"bgFill\":\"#000\",\"bgColor\":false,\"labelColor\":false,\"subText\":\"\",\"fontSize\":60}}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"bytes\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:145ced90-3dcb-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:32.134Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: heatmap", + "uiStateJSON": "{\"vis\":{\"defaultColors\":{\"0 - 15\":\"rgb(247,252,245)\",\"15 - 30\":\"rgb(199,233,192)\",\"30 - 45\":\"rgb(116,196,118)\",\"45 - 60\":\"rgb(35,139,69)\"}}}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: heatmap\",\"type\":\"heatmap\",\"params\":{\"type\":\"heatmap\",\"addTooltip\":true,\"addLegend\":true,\"enableHover\":false,\"legendPosition\":\"right\",\"times\":[],\"colorsNumber\":4,\"colorSchema\":\"Greens\",\"setColorRange\":false,\"colorsRange\":[],\"invertColors\":false,\"percentageMode\":false,\"valueAxes\":[{\"show\":false,\"id\":\"ValueAxis-1\",\"type\":\"value\",\"scale\":{\"type\":\"linear\",\"defaultYExtents\":false},\"labels\":{\"show\":false,\"rotate\":0,\"overwriteColor\":false,\"color\":\"#555\"}}]},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"bytes\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"geo.src\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:e2023110-3dcb-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:32.135Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: guage", + "uiStateJSON": "{\"vis\":{\"colors\":{\"0 - 50000\":\"#EF843C\",\"75000 - 10000000\":\"#3F6833\"},\"defaultColors\":{\"0 - 5000000\":\"rgb(0,104,55)\",\"50000000 - 74998990099\":\"rgb(165,0,38)\"}}}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: guage\",\"type\":\"gauge\",\"params\":{\"addLegend\":true,\"addTooltip\":true,\"gauge\":{\"backStyle\":\"Full\",\"colorSchema\":\"Green to Red\",\"colorsRange\":[{\"from\":0,\"to\":5000000},{\"from\":50000000,\"to\":74998990099}],\"extendRange\":true,\"gaugeColorMode\":\"Labels\",\"gaugeStyle\":\"Full\",\"gaugeType\":\"Arc\",\"invertColors\":false,\"labels\":{\"color\":\"black\",\"show\":true},\"orientation\":\"vertical\",\"percentageMode\":false,\"scale\":{\"color\":\"#333\",\"labels\":false,\"show\":true},\"style\":{\"bgColor\":false,\"bgFill\":\"#eee\",\"bgMask\":false,\"bgWidth\":0.9,\"fontSize\":60,\"labelColor\":true,\"mask\":false,\"maskBars\":50,\"subText\":\"\",\"width\":0.9},\"type\":\"meter\",\"alignment\":\"horizontal\"},\"isDisplayWarning\":false,\"type\":\"gauge\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"machine.ram\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:b92ae920-3dcc-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:31.110Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Rendering Test: timelion", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: timelion\",\"type\":\"timelion\",\"params\":{\"expression\":\".es(*, metric=avg:bytes, split=ip:5)\",\"interval\":\"auto\"},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:e4d8b430-3dcc-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:31.106Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Rendering Test: tsvb-guage", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: tsvb-guage\",\"type\":\"metrics\",\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"gauge\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"metrics\":[{\"id\":\"61ca57f2-469d-11e7-af02-69e470af7417\",\"type\":\"avg\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"split_color_mode\":\"gradient\"},{\"id\":\"d18e5970-3dcc-11e8-a2f6-c162ca6cf6ea\",\"color\":\"rgba(160,70,216,1)\",\"split_mode\":\"filter\",\"metrics\":[{\"id\":\"d18e5971-3dcc-11e8-a2f6-c162ca6cf6ea\",\"type\":\"avg\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"filter\":{\"query\":\"bytes:>1000\",\"language\":\"lucene\"},\"split_color_mode\":\"gradient\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"logstash-*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"show_grid\":1,\"background_color_rules\":[{\"id\":\"c50bd5b0-3dcc-11e8-a2f6-c162ca6cf6ea\"}],\"bar_color_rules\":[{\"id\":\"cd25a820-3dcc-11e8-a2f6-c162ca6cf6ea\"}],\"gauge_color_rules\":[{\"id\":\"e0be22e0-3dcc-11e8-a2f6-c162ca6cf6ea\"}],\"gauge_width\":10,\"gauge_inner_width\":10,\"gauge_style\":\"half\"},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:4c0f47e0-3dcd-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:31.111Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Rendering Test: markdown", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: markdown\",\"type\":\"markdown\",\"params\":{\"fontSize\":20,\"openLinksInNewTab\":false,\"markdown\":\"I'm a markdown!\"},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:2d1b1620-3dcd-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "control_0_index_pattern", + "type": "index-pattern" + }, + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "control_1_index_pattern", + "type": "index-pattern" + }, + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "control_2_index_pattern", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:31.123Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Rendering Test: input control", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: input control\",\"type\":\"input_control_vis\",\"params\":{\"controls\":[{\"id\":\"1523481142694\",\"fieldName\":\"bytes\",\"parent\":\"\",\"label\":\"Bytes Input List\",\"type\":\"list\",\"options\":{\"type\":\"terms\",\"multiselect\":true,\"size\":5,\"order\":\"desc\"},\"indexPatternRefName\":\"control_0_index_pattern\"},{\"id\":\"1523481163654\",\"fieldName\":\"bytes\",\"parent\":\"\",\"label\":\"Bytes range\",\"type\":\"range\",\"options\":{\"decimalPlaces\":0,\"step\":1},\"indexPatternRefName\":\"control_1_index_pattern\"},{\"id\":\"1523481176519\",\"fieldName\":\"sound.keyword\",\"parent\":\"\",\"label\":\"Animal sounds\",\"type\":\"list\",\"options\":{\"type\":\"terms\",\"multiselect\":true,\"size\":5,\"order\":\"desc\"},\"indexPatternRefName\":\"control_2_index_pattern\"}],\"updateFiltersOnChange\":false,\"useTimeFilter\":false,\"pinFilters\":false},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:8bc8d6c0-3e6e-11e8-bbb9-e15942d5d48c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "f908c8e0-3e6d-11e8-bbb9-e15942d5d48c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + }, + { + "id": "f908c8e0-3e6d-11e8-bbb9-e15942d5d48c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:31.173Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"meta\":{\"negate\":false,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"size.keyword\",\"value\":\"extra large\",\"params\":{\"query\":\"extra large\",\"type\":\"phrase\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"size.keyword\":{\"query\":\"extra large\",\"type\":\"phrase\"}}},\"$state\":{\"store\":\"appState\"}}],\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: non timebased line chart - dog data - with filter", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"aggs\":[{\"enabled\":true,\"id\":\"1\",\"params\":{\"field\":\"trainability\"},\"schema\":\"metric\",\"type\":\"max\"},{\"enabled\":true,\"id\":\"2\",\"params\":{\"field\":\"breed.keyword\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"size\":5},\"schema\":\"segment\",\"type\":\"terms\"},{\"enabled\":true,\"id\":\"3\",\"params\":{\"field\":\"barking level\"},\"schema\":\"metric\",\"type\":\"max\"},{\"enabled\":true,\"id\":\"4\",\"params\":{\"field\":\"activity level\"},\"schema\":\"metric\",\"type\":\"max\"}],\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"labels\":{\"show\":true,\"truncate\":100},\"position\":\"bottom\",\"scale\":{\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{},\"type\":\"category\"}],\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"legendPosition\":\"right\",\"seriesParams\":[{\"data\":{\"id\":\"1\",\"label\":\"Max trainability\"},\"drawLinesBetweenPoints\":true,\"mode\":\"normal\",\"show\":\"true\",\"showCircles\":true,\"type\":\"line\",\"valueAxis\":\"ValueAxis-1\"},{\"data\":{\"id\":\"3\",\"label\":\"Max barking level\"},\"drawLinesBetweenPoints\":true,\"mode\":\"normal\",\"show\":true,\"showCircles\":true,\"type\":\"line\",\"valueAxis\":\"ValueAxis-1\"},{\"data\":{\"id\":\"4\",\"label\":\"Max activity level\"},\"drawLinesBetweenPoints\":true,\"mode\":\"normal\",\"show\":true,\"showCircles\":true,\"type\":\"line\",\"valueAxis\":\"ValueAxis-1\"}],\"times\":[],\"type\":\"line\",\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"labels\":{\"filter\":false,\"rotate\":0,\"show\":true,\"truncate\":100},\"name\":\"LeftAxis-1\",\"position\":\"left\",\"scale\":{\"mode\":\"normal\",\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{\"text\":\"Max trainability\"},\"type\":\"value\"}]},\"title\":\"Rendering Test: non timebased line chart - dog data - with filter\",\"type\":\"line\"}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:42535e30-3dcd-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "control_0_index_pattern", + "type": "index-pattern" + }, + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "control_1_index_pattern", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:31.124Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Rendering Test: input control parent", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: input control parent\",\"type\":\"input_control_vis\",\"params\":{\"controls\":[{\"id\":\"1523481216736\",\"fieldName\":\"animal.keyword\",\"parent\":\"\",\"label\":\"Animal type\",\"type\":\"list\",\"options\":{\"type\":\"terms\",\"multiselect\":true,\"size\":5,\"order\":\"desc\"},\"indexPatternRefName\":\"control_0_index_pattern\"},{\"id\":\"1523481176519\",\"fieldName\":\"sound.keyword\",\"parent\":\"1523481216736\",\"label\":\"Animal sounds\",\"type\":\"list\",\"options\":{\"type\":\"terms\",\"multiselect\":true,\"size\":5,\"order\":\"desc\"},\"indexPatternRefName\":\"control_1_index_pattern\"}],\"updateFiltersOnChange\":false,\"useTimeFilter\":false,\"pinFilters\":false},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:7fda8ee0-3dcd-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:30.344Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Rendering Test: vega", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: vega\",\"type\":\"vega\",\"params\":{\"spec\":\"{\\n/*\\n\\nWelcome to Vega visualizations. Here you can design your own dataviz from scratch using a declarative language called Vega, or its simpler form Vega-Lite. In Vega, you have the full control of what data is loaded, even from multiple sources, how that data is transformed, and what visual elements are used to show it. Use help icon to view Vega examples, tutorials, and other docs. Use the wrench icon to reformat this text, or to remove comments.\\n\\nThis example graph shows the document count in all indexes in the current time range. You might need to adjust the time filter in the upper right corner.\\n*/\\n\\n $schema: https://vega.github.io/schema/vega-lite/v2.json\\n title: Event counts from all indexes\\n\\n // Define the data source\\n data: {\\n url: {\\n/*\\nAn object instead of a string for the \\\"url\\\" param is treated as an Elasticsearch query. Anything inside this object is not part of the Vega language, but only understood by Kibana and Elasticsearch server. This query counts the number of documents per time interval, assuming you have a @timestamp field in your data.\\n\\nKibana has a special handling for the fields surrounded by \\\"%\\\". They are processed before the the query is sent to Elasticsearch. This way the query becomes context aware, and can use the time range and the dashboard filters.\\n*/\\n\\n // Apply dashboard context filters when set\\n %context%: true\\n // Filter the time picker (upper right corner) with this field\\n %timefield%: @timestamp\\n\\n/*\\nSee .search() documentation for : https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference.html#api-search\\n*/\\n\\n // Which index to search\\n index: _all\\n // Aggregate data by the time field into time buckets, counting the number of documents in each bucket.\\n body: {\\n aggs: {\\n time_buckets: {\\n date_histogram: {\\n // Use date histogram aggregation on @timestamp field\\n field: @timestamp\\n // The interval value will depend on the daterange picker (true), or use an integer to set an approximate bucket count\\n interval: {%autointerval%: true}\\n // Make sure we get an entire range, even if it has no data\\n extended_bounds: {\\n // Use the current time range's start and end\\n min: {%timefilter%: \\\"min\\\"}\\n max: {%timefilter%: \\\"max\\\"}\\n }\\n // Use this for linear (e.g. line, area) graphs. Without it, empty buckets will not show up\\n min_doc_count: 0\\n }\\n }\\n }\\n // Speed up the response by only including aggregation results\\n size: 0\\n }\\n }\\n/*\\nElasticsearch will return results in this format:\\n\\naggregations: {\\n time_buckets: {\\n buckets: [\\n {\\n key_as_string: 2015-11-30T22:00:00.000Z\\n key: 1448920800000\\n doc_count: 0\\n },\\n {\\n key_as_string: 2015-11-30T23:00:00.000Z\\n key: 1448924400000\\n doc_count: 0\\n }\\n ...\\n ]\\n }\\n}\\n\\nFor our graph, we only need the list of bucket values. Use the format.property to discard everything else.\\n*/\\n format: {property: \\\"aggregations.time_buckets.buckets\\\"}\\n }\\n\\n // \\\"mark\\\" is the graphics element used to show our data. Other mark values are: area, bar, circle, line, point, rect, rule, square, text, and tick. See https://vega.github.io/vega-lite/docs/mark.html\\n mark: line\\n\\n // \\\"encoding\\\" tells the \\\"mark\\\" what data to use and in what way. See https://vega.github.io/vega-lite/docs/encoding.html\\n encoding: {\\n x: {\\n // The \\\"key\\\" value is the timestamp in milliseconds. Use it for X axis.\\n field: key\\n type: temporal\\n axis: {title: false} // Customize X axis format\\n }\\n y: {\\n // The \\\"doc_count\\\" is the count per bucket. Use it for Y axis.\\n field: doc_count\\n type: quantitative\\n axis: {title: \\\"Document count\\\"}\\n }\\n }\\n}\\n\"},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:02a2e4e0-3dcd-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:30.351Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Rendering Test: tsvb-table", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: tsvb-table\",\"type\":\"metrics\",\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"table\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"metrics\":[{\"id\":\"61ca57f2-469d-11e7-af02-69e470af7417\",\"type\":\"avg\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"split_color_mode\":\"gradient\"},{\"id\":\"d18e5970-3dcc-11e8-a2f6-c162ca6cf6ea\",\"color\":\"rgba(160,70,216,1)\",\"split_mode\":\"filter\",\"metrics\":[{\"id\":\"d18e5971-3dcc-11e8-a2f6-c162ca6cf6ea\",\"type\":\"avg\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"filter\":{\"query\":\"bytes:>1000\",\"language\":\"lucene\"},\"split_color_mode\":\"gradient\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"logstash-*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"show_grid\":1,\"background_color_rules\":[{\"id\":\"c50bd5b0-3dcc-11e8-a2f6-c162ca6cf6ea\"}],\"bar_color_rules\":[{\"id\":\"cd25a820-3dcc-11e8-a2f6-c162ca6cf6ea\"}],\"gauge_color_rules\":[{\"id\":\"e0be22e0-3dcc-11e8-a2f6-c162ca6cf6ea\"}],\"gauge_width\":10,\"gauge_inner_width\":10,\"gauge_style\":\"half\",\"markdown\":\"\\nHi Avg last bytes: {{ average_of_bytes.last.raw }}\",\"pivot_id\":\"bytes\",\"pivot_label\":\"Hello\"},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:f81134a0-3dcc-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:30.355Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Rendering Test: tsvb-markdown", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: tsvb-markdown\",\"type\":\"metrics\",\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"markdown\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"metrics\":[{\"id\":\"61ca57f2-469d-11e7-af02-69e470af7417\",\"type\":\"avg\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"split_color_mode\":\"gradient\"},{\"id\":\"d18e5970-3dcc-11e8-a2f6-c162ca6cf6ea\",\"color\":\"rgba(160,70,216,1)\",\"split_mode\":\"filter\",\"metrics\":[{\"id\":\"d18e5971-3dcc-11e8-a2f6-c162ca6cf6ea\",\"type\":\"avg\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"filter\":{\"query\":\"bytes:>1000\",\"language\":\"lucene\"},\"split_color_mode\":\"gradient\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"logstash-*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"show_grid\":1,\"background_color_rules\":[{\"id\":\"c50bd5b0-3dcc-11e8-a2f6-c162ca6cf6ea\"}],\"bar_color_rules\":[{\"id\":\"cd25a820-3dcc-11e8-a2f6-c162ca6cf6ea\"}],\"gauge_color_rules\":[{\"id\":\"e0be22e0-3dcc-11e8-a2f6-c162ca6cf6ea\"}],\"gauge_width\":10,\"gauge_inner_width\":10,\"gauge_style\":\"half\",\"markdown\":\"\\nHi Avg last bytes: {{ average_of_bytes.last.raw }}\"},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:df815d20-3dcc-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:30.349Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Rendering Test: tsvb-topn", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: tsvb-topn\",\"type\":\"metrics\",\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"top_n\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"metrics\":[{\"id\":\"61ca57f2-469d-11e7-af02-69e470af7417\",\"type\":\"avg\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"split_color_mode\":\"gradient\"},{\"id\":\"d18e5970-3dcc-11e8-a2f6-c162ca6cf6ea\",\"color\":\"rgba(160,70,216,1)\",\"split_mode\":\"filter\",\"metrics\":[{\"id\":\"d18e5971-3dcc-11e8-a2f6-c162ca6cf6ea\",\"type\":\"avg\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"filter\":{\"query\":\"bytes:>1000\",\"language\":\"lucene\"},\"split_color_mode\":\"gradient\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"logstash-*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"show_grid\":1,\"background_color_rules\":[{\"id\":\"c50bd5b0-3dcc-11e8-a2f6-c162ca6cf6ea\"}],\"bar_color_rules\":[{\"id\":\"cd25a820-3dcc-11e8-a2f6-c162ca6cf6ea\"}]},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:cc43fab0-3dcc-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:30.353Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Rendering Test: tsvb-metric", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: tsvb-metric\",\"type\":\"metrics\",\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"metric\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"metrics\":[{\"id\":\"61ca57f2-469d-11e7-af02-69e470af7417\",\"type\":\"sum_of_squares\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"split_color_mode\":\"gradient\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"logstash-*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"show_grid\":1,\"background_color_rules\":[{\"id\":\"c50bd5b0-3dcc-11e8-a2f6-c162ca6cf6ea\"}]},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:c40f4d40-3dcc-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:30.347Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Rendering Test: tsvb-ts", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: tsvb-ts\",\"type\":\"metrics\",\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"timeseries\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"metrics\":[{\"id\":\"61ca57f2-469d-11e7-af02-69e470af7417\",\"type\":\"count\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"split_color_mode\":\"gradient\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"show_grid\":1},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:ffa2e0c0-3dcb-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:33.153Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: goal", + "uiStateJSON": "{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: goal\",\"type\":\"goal\",\"params\":{\"addTooltip\":true,\"addLegend\":false,\"isDisplayWarning\":false,\"type\":\"gauge\",\"gauge\":{\"verticalSplit\":false,\"autoExtend\":false,\"percentageMode\":true,\"gaugeType\":\"Arc\",\"gaugeStyle\":\"Full\",\"backStyle\":\"Full\",\"orientation\":\"vertical\",\"useRanges\":false,\"colorSchema\":\"Green to Red\",\"gaugeColorMode\":\"None\",\"colorsRange\":[{\"from\":0,\"to\":4000}],\"invertColors\":false,\"labels\":{\"show\":true,\"color\":\"black\"},\"scale\":{\"show\":false,\"labels\":false,\"color\":\"#333\",\"width\":2},\"type\":\"meter\",\"style\":{\"bgFill\":\"#000\",\"bgColor\":false,\"labelColor\":false,\"subText\":\"\",\"fontSize\":60}}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"geo.src\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":2,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:37a541c0-3dcc-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + }, + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:33.156Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"meta\":{\"negate\":true,\"disabled\":false,\"alias\":null,\"type\":\"range\",\"key\":\"bytes\",\"value\":\"0 to 10,000\",\"params\":{\"gte\":0,\"lt\":10000},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"range\":{\"bytes\":{\"gte\":0,\"lt\":10000}},\"$state\":{\"store\":\"appState\"}}],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: geo map", + "uiStateJSON": "{\"mapZoom\":4,\"mapCenter\":[35.460669951495305,-85.60546875000001]}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: geo map\",\"type\":\"tile_map\",\"params\":{\"mapType\":\"Scaled Circle Markers\",\"isDesaturated\":true,\"addTooltip\":true,\"heatClusterSize\":1.5,\"legendPosition\":\"bottomright\",\"mapZoom\":2,\"mapCenter\":[0,0],\"wms\":{\"enabled\":false,\"options\":{\"format\":\"image/png\",\"transparent\":true},\"baseLayersAreLoaded\":{},\"tmsLayers\":[{\"id\":\"road_map\",\"url\":\"https://tiles-stage.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=6.3.0\",\"minZoom\":0,\"maxZoom\":10,\"attribution\":\"

© OpenStreetMap contributors | Elastic Maps Service

\",\"subdomains\":[]}],\"selectedTmsLayer\":{\"id\":\"road_map\",\"url\":\"https://tiles-stage.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=6.3.0\",\"minZoom\":0,\"maxZoom\":10,\"attribution\":\"

© OpenStreetMap contributors | Elastic Maps Service

\",\"subdomains\":[]}}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"geohash_grid\",\"schema\":\"segment\",\"params\":{\"field\":\"geo.coordinates\",\"autoPrecision\":true,\"isFilteredByCollar\":true,\"useGeocentroid\":true,\"precision\":3}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:4b5d6ef0-3dcb-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:33.162Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: datatable", + "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: datatable\",\"type\":\"table\",\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMeticsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"clientip\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:3525b840-3dcb-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:33.163Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: bar", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: bar\",\"type\":\"horizontal_bar\",\"params\":{\"type\":\"histogram\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":200},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":75,\"filter\":true,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":true,\"type\":\"histogram\",\"mode\":\"normal\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"valueAxis\":\"ValueAxis-1\",\"drawLinesBetweenPoints\":true,\"showCircles\":true}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"geo.src\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":3,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:e6140540-3dca-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + }, + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:33.165Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"meta\":{\"negate\":true,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"geo.src\",\"value\":\"CN\",\"params\":{\"query\":\"CN\",\"type\":\"phrase\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"geo.src\":{\"query\":\"CN\",\"type\":\"phrase\"}}},\"$state\":{\"store\":\"appState\"}}],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: area with not filter", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: area with not filter\",\"type\":\"area\",\"params\":{\"type\":\"area\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":\"true\",\"type\":\"area\",\"mode\":\"stacked\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"interpolate\":\"linear\",\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"filters\",\"schema\":\"group\",\"params\":{\"filters\":[{\"input\":{\"query\":\"bytes:>1000\",\"language\":\"lucene\"},\"label\":\"\"},{\"input\":{\"query\":\"bytes:>10\",\"language\":\"lucene\"}}]}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:4c0c3f90-3e5a-11e8-9fc3-39e49624228e", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + }, + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:33.166Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"meta\":{\"field\":\"isDog\",\"negate\":false,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"isDog\",\"value\":\"true\",\"params\":{\"value\":true},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"script\":{\"script\":{\"inline\":\"boolean compare(Supplier s, def v) {return s.get() == v;}compare(() -> { return doc['animal.keyword'].value == 'dog' }, params.value);\",\"lang\":\"painless\",\"params\":{\"value\":true}}},\"$state\":{\"store\":\"appState\"}}],\"query\":{\"query\":\"weightLbs:>40\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: scripted filter and query", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: scripted filter and query\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"sound.keyword\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:50643b60-3dd3-11e8-b2b9-5d5dc1715159", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:34.195Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Rendering Test: animal sounds pie", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: animal sounds pie\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"sound.keyword\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:771b4f10-3e59-11e8-9fc3-39e49624228e", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "a16d1990-3dca-11e8-8660-4d65aa086b3c", + "name": "search_0", + "type": "search" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:34.200Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}" + }, + "savedSearchRefName": "search_0", + "title": "Rendering Test: animal weights linked to search", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Rendering Test: animal weights linked to search\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"name.keyword\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:76c7f020-4194-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:34.583Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Filter Bytes Test: tsvb top n with bytes filter", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: tsvb top n with bytes filter\",\"type\":\"metrics\",\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"top_n\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"filters\",\"metrics\":[{\"id\":\"482d6560-4194-11e8-a461-7d278185cba4\",\"type\":\"avg\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"terms_field\":\"clientip\",\"filter\":{\"query\":\"Filter Bytes Test:>1000\",\"language\":\"lucene\"},\"override_index_pattern\":0,\"series_index_pattern\":\"logstash-*\",\"series_time_field\":\"utc_time\",\"series_interval\":\"1m\",\"value_template\":\"\",\"split_filters\":[{\"filter\":{\"query\":\"Filter Bytes Test:>100\",\"language\":\"lucene\"},\"label\":\"\",\"color\":\"#68BC00\",\"id\":\"39a107e0-4194-11e8-a461-7d278185cba4\"}],\"split_color_mode\":\"gradient\"},{\"id\":\"4fd5b150-4194-11e8-a461-7d278185cba4\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"metrics\":[{\"id\":\"4fd5b151-4194-11e8-a461-7d278185cba4\",\"type\":\"avg\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"filter\":{\"query\":\"Filter Bytes Test:>3000\",\"language\":\"lucene\"},\"split_color_mode\":\"gradient\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"logstash-*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"show_grid\":1,\"background_color_rules\":[{\"id\":\"06893260-4194-11e8-a461-7d278185cba4\"}],\"bar_color_rules\":[{\"id\":\"36a0e740-4194-11e8-a461-7d278185cba4\"}]},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:0ca8c600-4195-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "control_0_index_pattern", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:35.229Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Filter Bytes Test: input control with filter", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: input control with filter\",\"type\":\"input_control_vis\",\"params\":{\"controls\":[{\"id\":\"1523896850250\",\"fieldName\":\"bytes\",\"parent\":\"\",\"label\":\"Byte Options\",\"type\":\"list\",\"options\":{\"type\":\"terms\",\"multiselect\":true,\"size\":10,\"order\":\"desc\"},\"indexPatternRefName\":\"control_0_index_pattern\"}],\"updateFiltersOnChange\":false,\"useTimeFilter\":false,\"pinFilters\":false},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:039e4770-4194-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:35.220Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Filter Bytes Test: tsvb time series with bytes filter split by clientip", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: tsvb time series with bytes filter split by clientip\",\"type\":\"metrics\",\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"timeseries\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"terms\",\"metrics\":[{\"value\":\"\",\"id\":\"61ca57f2-469d-11e7-af02-69e470af7417\",\"type\":\"sum\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"terms_field\":\"clientip\",\"filter\":{\"query\":\"Filter Bytes Test:>1000\",\"language\":\"lucene\"},\"split_color_mode\":\"gradient\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"logstash-*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"show_grid\":1},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:760a9060-4190-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + }, + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:35.235Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"meta\":{\"negate\":false,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"geo.src\",\"value\":\"US\",\"params\":{\"query\":\"US\",\"type\":\"phrase\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"geo.src\":{\"query\":\"US\",\"type\":\"phrase\"}}},\"$state\":{\"store\":\"appState\"}}],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Filter Bytes Test: max bytes in US - area chart with filter", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: max bytes in US - area chart with filter\",\"type\":\"area\",\"params\":{\"type\":\"area\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Max bytes\"}}],\"seriesParams\":[{\"show\":\"true\",\"type\":\"area\",\"mode\":\"stacked\",\"data\":{\"label\":\"Max bytes\",\"id\":\"1\"},\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"interpolate\":\"linear\",\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"max\",\"schema\":\"metric\",\"params\":{\"field\":\"bytes\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"min_doc_count\":1,\"extended_bounds\":{}}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:b3e70d00-4190-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:35.236Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Filter Bytes Test: standard deviation heatmap with other bucket", + "uiStateJSON": "{\"vis\":{\"defaultColors\":{\"-4,000 - 1,000\":\"rgb(247,252,245)\",\"1,000 - 6,000\":\"rgb(199,233,192)\",\"6,000 - 11,000\":\"rgb(116,196,118)\",\"11,000 - 16,000\":\"rgb(35,139,69)\"}}}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: standard deviation heatmap with other bucket\",\"type\":\"heatmap\",\"params\":{\"type\":\"heatmap\",\"addTooltip\":true,\"addLegend\":true,\"enableHover\":false,\"legendPosition\":\"right\",\"times\":[],\"colorsNumber\":4,\"colorSchema\":\"Greens\",\"setColorRange\":false,\"colorsRange\":[],\"invertColors\":false,\"percentageMode\":false,\"valueAxes\":[{\"show\":false,\"id\":\"ValueAxis-1\",\"type\":\"value\",\"scale\":{\"type\":\"linear\",\"defaultYExtents\":false},\"labels\":{\"show\":false,\"rotate\":0,\"overwriteColor\":false,\"color\":\"#555\"}}]},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"std_dev\",\"schema\":\"metric\",\"params\":{\"field\":\"bytes\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"geo.src\",\"otherBucket\":true,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":10,\"order\":\"desc\",\"orderBy\":\"_term\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:c10c6b00-4191-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:36.267Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Filter Bytes Test: max bytes guage percent mode", + "uiStateJSON": "{\"vis\":{\"defaultColors\":{\"0 - 1\":\"rgb(0,104,55)\",\"1 - 15\":\"rgb(255,255,190)\",\"15 - 100\":\"rgb(165,0,38)\"}}}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: max bytes guage percent mode\",\"type\":\"gauge\",\"params\":{\"type\":\"gauge\",\"addTooltip\":true,\"addLegend\":true,\"isDisplayWarning\":false,\"gauge\":{\"extendRange\":true,\"percentageMode\":true,\"gaugeType\":\"Arc\",\"gaugeStyle\":\"Full\",\"backStyle\":\"Full\",\"orientation\":\"vertical\",\"colorSchema\":\"Green to Red\",\"gaugeColorMode\":\"Labels\",\"colorsRange\":[{\"from\":0,\"to\":500},{\"from\":500,\"to\":7500},{\"from\":7500,\"to\":50000}],\"invertColors\":false,\"labels\":{\"show\":true,\"color\":\"black\"},\"scale\":{\"show\":true,\"labels\":false,\"color\":\"#333\"},\"type\":\"meter\",\"style\":{\"bgWidth\":0.9,\"width\":0.9,\"mask\":false,\"bgMask\":false,\"maskBars\":50,\"bgFill\":\"#eee\",\"bgColor\":false,\"subText\":\"Im subtext\",\"fontSize\":60,\"labelColor\":true},\"alignment\":\"horizontal\"}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"max\",\"schema\":\"metric\",\"params\":{\"field\":\"bytes\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:03d2afd0-4192-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:36.269Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Filter Bytes Test: Goal unique count", + "uiStateJSON": "{\"vis\":{\"defaultColors\":{\"0 - 10000\":\"rgb(0,104,55)\"}}}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: Goal unique count\",\"type\":\"goal\",\"params\":{\"addTooltip\":true,\"addLegend\":false,\"isDisplayWarning\":false,\"type\":\"gauge\",\"gauge\":{\"verticalSplit\":false,\"autoExtend\":false,\"percentageMode\":false,\"gaugeType\":\"Arc\",\"gaugeStyle\":\"Full\",\"backStyle\":\"Full\",\"orientation\":\"vertical\",\"useRanges\":false,\"colorSchema\":\"Green to Red\",\"gaugeColorMode\":\"None\",\"colorsRange\":[{\"from\":0,\"to\":10000}],\"invertColors\":false,\"labels\":{\"show\":true,\"color\":\"black\"},\"scale\":{\"show\":false,\"labels\":false,\"color\":\"#333\",\"width\":2},\"type\":\"meter\",\"style\":{\"bgFill\":\"#000\",\"bgColor\":false,\"labelColor\":false,\"subText\":\"\",\"fontSize\":60}}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"bytes\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:7ff2c4c0-4191-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:36.270Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Filter Bytes Test: Data table top hit with significant terms geo.src", + "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: Data table top hit with significant terms geo.src\",\"type\":\"table\",\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMeticsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"top_hits\",\"schema\":\"metric\",\"params\":{\"field\":\"bytes\",\"aggregate\":\"average\",\"size\":1,\"sortField\":\"@timestamp\",\"sortOrder\":\"desc\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"significant_terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"geo.src\",\"size\":10}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:df72ad40-4194-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + }, + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:36.276Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"meta\":{\"negate\":true,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"bytes\",\"value\":\"0\",\"params\":{\"query\":0,\"type\":\"phrase\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"bytes\":{\"query\":0,\"type\":\"phrase\"}}},\"$state\":{\"store\":\"appState\"}}],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Filter Bytes Test: tag cloud with not 0 bytes filter", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: tag cloud with not 0 bytes filter\",\"type\":\"tagcloud\",\"params\":{\"scale\":\"linear\",\"orientation\":\"single\",\"minFontSize\":18,\"maxFontSize\":72,\"showLabel\":true},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"bytes\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:63983430-4192-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + }, + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:06:36.275Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"meta\":{\"negate\":false,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"geo.src\",\"value\":\"US\",\"params\":{\"query\":\"US\",\"type\":\"phrase\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"geo.src\":{\"query\":\"US\",\"type\":\"phrase\"}}},\"$state\":{\"store\":\"appState\"}}],\"query\":{\"query\":\"Filter Bytes Test:>5000\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Filter Bytes Test: geo map with filter and query bytes > 5000 in US geo.src, heatmap setting", + "uiStateJSON": "{\"mapZoom\":7,\"mapCenter\":[42.98857645832184,-75.49804687500001]}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: geo map with filter and query bytes > 5000 in US geo.src, heatmap setting\",\"type\":\"tile_map\",\"params\":{\"mapType\":\"Heatmap\",\"isDesaturated\":true,\"addTooltip\":true,\"heatClusterSize\":1.5,\"legendPosition\":\"bottomright\",\"mapZoom\":2,\"mapCenter\":[0,0],\"wms\":{\"enabled\":false,\"options\":{\"format\":\"image/png\",\"transparent\":true},\"baseLayersAreLoaded\":{},\"tmsLayers\":[{\"id\":\"road_map\",\"url\":\"https://tiles-stage.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=6.3.0\",\"minZoom\":0,\"maxZoom\":10,\"attribution\":\"

© OpenStreetMap contributors | Elastic Maps Service

\",\"subdomains\":[]}],\"selectedTmsLayer\":{\"id\":\"road_map\",\"url\":\"https://tiles-stage.elastic.co/v2/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana&my_app_version=6.3.0\",\"minZoom\":0,\"maxZoom\":10,\"attribution\":\"

© OpenStreetMap contributors | Elastic Maps Service

\",\"subdomains\":[]}}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"geohash_grid\",\"schema\":\"segment\",\"params\":{\"field\":\"geo.coordinates\",\"autoPrecision\":true,\"isFilteredByCollar\":true,\"useGeocentroid\":true,\"precision\":4}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "search:be5accf0-3dca-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "search": "7.4.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "search": { + "columns": [ + "agent", + "bytes", + "clientip" + ], + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "sort": [ + [ + "@timestamp", + "desc" + ] + ], + "title": "Rendering Test: saved search", + "version": 1 + }, + "type": "search", + "updated_at": "2018-04-17T15:09:39.805Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "search:ca5ada40-3dca-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "search": "7.4.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + }, + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + } + ], + "search": { + "columns": [ + "agent", + "bytes", + "clientip" + ], + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[{\"meta\":{\"negate\":false,\"type\":\"phrase\",\"key\":\"bytes\",\"value\":\"1,607\",\"params\":{\"query\":1607,\"type\":\"phrase\"},\"disabled\":false,\"alias\":null,\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"bytes\":{\"query\":1607,\"type\":\"phrase\"}}},\"$state\":{\"store\":\"appState\"}}],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "sort": [ + [ + "@timestamp", + "desc" + ] + ], + "title": "Filter Bytes Test: search with filter", + "version": 1 + }, + "type": "search", + "updated_at": "2018-04-17T15:09:55.976Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:9bebe980-4192-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T15:59:42.648Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Filter Bytes Test: timelion split 5 on bytes", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: timelion split 5 on bytes\",\"type\":\"timelion\",\"params\":{\"expression\":\".es(*, split=bytes:5)\",\"interval\":\"auto\"},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:1dcdfe30-4192-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T15:59:56.976Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"bytes:>100\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Filter Bytes Test: min bytes metric with query", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: min bytes metric with query\",\"type\":\"metric\",\"params\":{\"addTooltip\":true,\"addLegend\":false,\"type\":\"metric\",\"metric\":{\"percentageMode\":false,\"useRanges\":false,\"colorSchema\":\"Green to Red\",\"metricColorMode\":\"None\",\"colorsRange\":[{\"from\":0,\"to\":10000}],\"labels\":{\"show\":true},\"invertColors\":false,\"style\":{\"bgFill\":\"#000\",\"bgColor\":false,\"labelColor\":false,\"subText\":\"\",\"fontSize\":60}}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"min\",\"schema\":\"metric\",\"params\":{\"field\":\"bytes\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:35417e50-4194-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T16:06:03.785Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Filter Bytes Test: tsvb metric with custom interval and bytes filter", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: tsvb metric with custom interval and bytes filter\",\"type\":\"metrics\",\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"metric\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"everything\",\"metrics\":[{\"value\":\"\",\"id\":\"61ca57f2-469d-11e7-af02-69e470af7417\",\"type\":\"sum\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"terms_field\":\"clientip\",\"filter\":{\"query\":\"Filter Bytes Test:>1000\",\"language\":\"lucene\"},\"override_index_pattern\":1,\"series_index_pattern\":\"logstash-*\",\"series_time_field\":\"utc_time\",\"series_interval\":\"1d\",\"value_template\":\"{{value}} custom template\",\"split_color_mode\":\"gradient\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"logstash-*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"show_grid\":1,\"background_color_rules\":[{\"id\":\"06893260-4194-11e8-a461-7d278185cba4\"}]},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:9fb4c670-4194-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T16:32:59.086Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Filter Bytes Test: tsvb markdown", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: tsvb markdown\",\"type\":\"metrics\",\"params\":{\"id\":\"61ca57f0-469d-11e7-af02-69e470af7417\",\"type\":\"markdown\",\"series\":[{\"id\":\"61ca57f1-469d-11e7-af02-69e470af7417\",\"color\":\"#68BC00\",\"split_mode\":\"filters\",\"metrics\":[{\"id\":\"482d6560-4194-11e8-a461-7d278185cba4\",\"type\":\"avg\",\"field\":\"bytes\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"number\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"terms_field\":\"clientip\",\"filter\":{\"query\":\"Filter Bytes Test:>1000\",\"language\":\"lucene\"},\"override_index_pattern\":0,\"series_index_pattern\":\"logstash-*\",\"series_time_field\":\"utc_time\",\"series_interval\":\"1m\",\"value_template\":\"\",\"split_filters\":[{\"filter\":{\"query\":\"bytes:>1000\",\"language\":\"lucene\"},\"label\":\"\",\"color\":\"#68BC00\",\"id\":\"39a107e0-4194-11e8-a461-7d278185cba4\"}],\"label\":\"\",\"var_name\":\"\",\"split_color_mode\":\"gradient\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"logstash-*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"show_grid\":1,\"background_color_rules\":[{\"id\":\"06893260-4194-11e8-a461-7d278185cba4\"}],\"bar_color_rules\":[{\"id\":\"36a0e740-4194-11e8-a461-7d278185cba4\"}],\"markdown\":\"{{bytes_1000.last.formatted}}\"},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:befdb6b0-3e59-11e8-9fc3-39e49624228e", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + }, + { + "id": "a16d1990-3dca-11e8-8660-4d65aa086b3c", + "name": "search_0", + "type": "search" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T17:16:27.743Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[{\"meta\":{\"negate\":false,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"animal.keyword\",\"value\":\"dog\",\"params\":{\"query\":\"dog\",\"type\":\"phrase\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"animal.keyword\":{\"query\":\"dog\",\"type\":\"phrase\"}}},\"$state\":{\"store\":\"appState\"}}],\"query\":{\"language\":\"lucene\",\"query\":\"\"}}" + }, + "savedSearchRefName": "search_0", + "title": "Filter Test: animals: linked to search with filter", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Test: animals: linked to search with filter\",\"type\":\"pie\",\"params\":{\"addLegend\":true,\"addTooltip\":true,\"isDonut\":true,\"labels\":{\"last_level\":true,\"show\":false,\"truncate\":100,\"values\":true},\"legendPosition\":\"right\",\"type\":\"pie\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"name.keyword\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:584c0300-4191-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-04-17T18:36:30.315Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"bytes:>9000\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Filter Bytes Test: split by geo with query", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: split by geo with query\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"sum\",\"schema\":\"metric\",\"params\":{\"field\":\"bytes\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"geo.src\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "config:7.0.0-alpha1", + "index": ".kibana_1", + "source": { + "config": { + "buildNum": null, + "dateFormat:tz": "UTC", + "defaultIndex": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "notifications:lifetime:banner": 3600000, + "notifications:lifetime:error": 3600000, + "notifications:lifetime:info": 3600000, + "notifications:lifetime:warning": 3600000 + }, + "references": [ + ], + "type": "config", + "updated_at": "2018-04-17T19:25:03.632Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:8090dcb0-4195-11e8-bb13-d53698fb349a", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + ], + "type": "visualization", + "updated_at": "2018-04-17T19:28:21.967Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Filter Bytes Test: vega", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Filter Bytes Test: vega\",\"type\":\"vega\",\"params\":{\"spec\":\"{ \\nconfig: { kibana: { renderer: \\\"svg\\\" }},\\n/*\\n\\nWelcome to Vega visualizations. Here you can design your own dataviz from scratch using a declarative language called Vega, or its simpler form Vega-Lite. In Vega, you have the full control of what data is loaded, even from multiple sources, how that data is transformed, and what visual elements are used to show it. Use help icon to view Vega examples, tutorials, and other docs. Use the wrench icon to reformat this text, or to remove comments.\\n\\nThis example graph shows the document count in all indexes in the current time range. You might need to adjust the time filter in the upper right corner.\\n*/\\n\\n $schema: https://vega.github.io/schema/vega-lite/v2.json\\n title: Event counts from all indexes\\n\\n // Define the data source\\n data: {\\n url: {\\n/*\\nAn object instead of a string for the \\\"url\\\" param is treated as an Elasticsearch query. Anything inside this object is not part of the Vega language, but only understood by Kibana and Elasticsearch server. This query counts the number of documents per time interval, assuming you have a @timestamp field in your data.\\n\\nKibana has a special handling for the fields surrounded by \\\"%\\\". They are processed before the the query is sent to Elasticsearch. This way the query becomes context aware, and can use the time range and the dashboard filters.\\n*/\\n\\n // Apply dashboard context filters when set\\n %context%: true\\n // Filter the time picker (upper right corner) with this field\\n %timefield%: @timestamp\\n\\n/*\\nSee .search() documentation for : https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference.html#api-search\\n*/\\n\\n // Which index to search\\n index: _all\\n // Aggregate data by the time field into time buckets, counting the number of documents in each bucket.\\n body: {\\n aggs: {\\n time_buckets: {\\n date_histogram: {\\n // Use date histogram aggregation on @timestamp field\\n field: @timestamp\\n // The interval value will depend on the daterange picker (true), or use an integer to set an approximate bucket count\\n interval: {%autointerval%: true}\\n // Make sure we get an entire range, even if it has no data\\n extended_bounds: {\\n // Use the current time range's start and end\\n min: {%timefilter%: \\\"min\\\"}\\n max: {%timefilter%: \\\"max\\\"}\\n }\\n // Use this for linear (e.g. line, area) graphs. Without it, empty buckets will not show up\\n min_doc_count: 0\\n }\\n }\\n }\\n // Speed up the response by only including aggregation results\\n size: 0\\n }\\n }\\n/*\\nElasticsearch will return results in this format:\\n\\naggregations: {\\n time_buckets: {\\n buckets: [\\n {\\n key_as_string: 2015-11-30T22:00:00.000Z\\n key: 1448920800000\\n doc_count: 0\\n },\\n {\\n key_as_string: 2015-11-30T23:00:00.000Z\\n key: 1448924400000\\n doc_count: 0\\n }\\n ...\\n ]\\n }\\n}\\n\\nFor our graph, we only need the list of bucket values. Use the format.property to discard everything else.\\n*/\\n format: {property: \\\"aggregations.time_buckets.buckets\\\"}\\n }\\n\\n // \\\"mark\\\" is the graphics element used to show our data. Other mark values are: area, bar, circle, line, point, rect, rule, square, text, and tick. See https://vega.github.io/vega-lite/docs/mark.html\\n mark: line\\n\\n // \\\"encoding\\\" tells the \\\"mark\\\" what data to use and in what way. See https://vega.github.io/vega-lite/docs/encoding.html\\n encoding: {\\n x: {\\n // The \\\"key\\\" value is the timestamp in milliseconds. Use it for X axis.\\n field: key\\n type: temporal\\n axis: {title: false} // Customize X axis format\\n }\\n y: {\\n // The \\\"doc_count\\\" is the count per bucket. Use it for Y axis.\\n field: doc_count\\n type: quantitative\\n axis: {title: \\\"Document count\\\"}\\n }\\n }\\n}\\n\"},\"aggs\":[]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "config:6.2.4", + "index": ".kibana_1", + "source": { + "config": { + "buildNum": 16627, + "defaultIndex": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "xPackMonitoring:showBanner": false + }, + "references": [ + ], + "type": "config", + "updated_at": "2018-05-09T20:50:57.021Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:edb65990-53ca-11e8-b481-c9426d020fcd", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-05-09T20:52:47.144Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "table created in 6_2", + "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", + "version": 1, + "visState": "{\"title\":\"table created in 6_2\",\"type\":\"table\",\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMeticsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"weightLbs\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"animal.keyword\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:0644f890-53cb-11e8-b481-c9426d020fcd", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2018-05-09T20:53:28.345Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"filter\":[],\"query\":{\"query\":\"weightLbs:>10\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "Weight in lbs pie created in 6.2", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Weight in lbs pie created in 6.2\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"weightLbs\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:1b2f47b0-53cb-11e8-b481-c9426d020fcd", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"language\":\"lucene\",\"query\":\"weightLbs:>15\"},\"filter\":[{\"meta\":{\"field\":\"isDog\",\"negate\":false,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"isDog\",\"value\":\"true\",\"params\":{\"value\":true},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"script\":{\"script\":{\"inline\":\"boolean compare(Supplier s, def v) {return s.get() == v;}compare(() -> { return doc['animal.keyword'].value == 'dog' }, params.value);\",\"lang\":\"painless\",\"params\":{\"value\":true}}},\"$state\":{\"store\":\"appState\"}}],\"highlightAll\":true,\"version\":true}" + }, + "optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":false,\"useMargins\":true}", + "panelsJSON": "[{\"gridData\":{\"w\":24,\"h\":12,\"x\":24,\"y\":0,\"i\":\"4\"},\"panelIndex\":\"4\",\"version\":\"7.3.0\",\"panelRefName\":\"panel_0\",\"embeddableConfig\":{}},{\"gridData\":{\"w\":24,\"h\":12,\"x\":0,\"y\":0,\"i\":\"5\"},\"version\":\"7.3.0\",\"panelIndex\":\"5\",\"panelRefName\":\"panel_1\",\"embeddableConfig\":{}}]", + "refreshInterval": { + "display": "Off", + "pause": false, + "value": 0 + }, + "timeFrom": "Mon Apr 09 2018 17:56:08 GMT-0400", + "timeRestore": true, + "timeTo": "Wed Apr 11 2018 17:56:08 GMT-0400", + "title": "Animal Weights (created in 6.2)", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + }, + { + "id": "edb65990-53ca-11e8-b481-c9426d020fcd", + "name": "panel_0", + "type": "visualization" + }, + { + "id": "0644f890-53cb-11e8-b481-c9426d020fcd", + "name": "panel_1", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2018-05-09T20:54:03.435Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "index-pattern:a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "index": ".kibana_1", + "source": { + "index-pattern": { + "fieldFormatMap": "{\"weightLbs\":{\"id\":\"number\",\"params\":{\"pattern\":\"0,0.0\"}},\"is_dog\":{\"id\":\"boolean\"},\"isDog\":{\"id\":\"boolean\"}}", + "fields": "[{\"name\":\"@timestamp\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_source\",\"type\":\"_source\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"animal\",\"type\":\"string\",\"count\":3,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"animal.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"name\",\"type\":\"string\",\"count\":1,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"name.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"sound\",\"type\":\"string\",\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"sound.keyword\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"weightLbs\",\"type\":\"number\",\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"isDog\",\"type\":\"boolean\",\"count\":0,\"scripted\":true,\"script\":\"return doc['animal.keyword'].value == 'dog'\",\"lang\":\"painless\",\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false}]", + "timeFieldName": "@timestamp", + "title": "animals-*" + }, + "migrationVersion": { + "index-pattern": "7.6.0" + }, + "references": [ + ], + "type": "index-pattern", + "updated_at": "2018-05-09T20:55:44.314Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "search:6351c590-53cb-11e8-b481-c9426d020fcd", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "search": "7.4.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + }, + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + } + ], + "search": { + "columns": [ + "animal", + "sound", + "weightLbs" + ], + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"language\":\"lucene\",\"query\":\"weightLbs:>10\"},\"filter\":[{\"meta\":{\"negate\":false,\"disabled\":false,\"alias\":null,\"type\":\"phrase\",\"key\":\"sound.keyword\",\"value\":\"growl\",\"params\":{\"query\":\"growl\",\"type\":\"phrase\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"},\"query\":{\"match\":{\"sound.keyword\":{\"query\":\"growl\",\"type\":\"phrase\"}}},\"$state\":{\"store\":\"appState\"}}],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "sort": [ + [ + "@timestamp", + "desc" + ] + ], + "title": "Search created in 6.2", + "version": 1 + }, + "type": "search", + "updated_at": "2018-05-09T20:56:04.457Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "visualization:47b5cf60-9e93-11ea-853e-adc0effaf76d", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "visualization": "7.8.0" + }, + "references": [ + { + "id": "1b1789d0-9e93-11ea-853e-adc0effaf76d", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2020-05-25T15:16:27.743Z", + "visualization": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "vis with missing index pattern", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"type\":\"pie\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}}],\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100}},\"title\":\"vis with missing index pattern\"}" + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:502e63a0-9e93-11ea-853e-adc0effaf76d", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}" + }, + "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}", + "panelsJSON": "[{\"version\":\"7.3.0\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"6cfbe6cc-1872-4cb4-9455-a02eeb75127e\"},\"panelIndex\":\"6cfbe6cc-1872-4cb4-9455-a02eeb75127e\",\"embeddableConfig\":{},\"panelRefName\":\"panel_0\"}]", + "timeRestore": false, + "title": "dashboard with missing index pattern", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "47b5cf60-9e93-11ea-853e-adc0effaf76d", + "name": "panel_0", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2020-05-25T15:16:27.743Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:d9ce6000-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.2313, + "numberOfClicks": 0, + "timestamp": "2020-05-31T11:21:19.616Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:21:19.616Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:dc1d0af0-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 0.06526666666666667, + "numberOfClicks": 3, + "timestamp": "2020-05-31T11:21:23.487Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:21:23.487Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:f22c7920-a330-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 0.5732333333333333, + "numberOfClicks": 13, + "timestamp": "2020-05-31T11:22:00.498Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-05-31T11:22:00.498Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "dashboard:6eb8a840-a32e-11ea-88c2-d56dd2b14bd7", + "index": ".kibana_1", + "source": { + "dashboard": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\n \"query\": {\n \"language\": \"kuery\",\n \"query\": \"\"\n },\n \"filter\": [\n {\n \"meta\": {\n \"alias\": null,\n \"negate\": false,\n \"disabled\": true,\n \"type\": \"phrase\",\n \"key\": \"name\",\n \"params\": {\n \"query\": \"moo\"\n },\n \"indexRefName\": \"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index\"\n },\n \"query\": {\n \"match_phrase\": {\n \"name\": \"moo\"\n }\n },\n \"$state\": {\n \"store\": \"appState\"\n }\n },\n {\n \"meta\": {\n \"alias\": null,\n \"negate\": false,\n \"disabled\": true,\n \"type\": \"phrase\",\n \"key\": \"baad-field\",\n \"params\": {\n \"query\": \"moo\"\n },\n \"indexRefName\": \"kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index\"\n },\n \"query\": {\n \"match_phrase\": {\n \"baad-field\": \"moo\"\n }\n },\n \"$state\": {\n \"store\": \"appState\"\n }\n },\n {\n \"meta\": {\n \"alias\": null,\n \"negate\": false,\n \"disabled\": false,\n \"type\": \"phrase\",\n \"key\": \"@timestamp\",\n \"params\": {\n \"query\": \"123\"\n },\n \"indexRefName\": \"kibanaSavedObjectMeta.searchSourceJSON.filter[2].meta.index\"\n },\n \"query\": {\n \"match_phrase\": {\n \"@timestamp\": \"123\"\n }\n },\n \"$state\": {\n \"store\": \"appState\"\n }\n },\n {\n \"meta\": {\n \"alias\": null,\n \"negate\": false,\n \"disabled\": false,\n \"type\": \"exists\",\n \"key\": \"extension\",\n \"value\": \"exists\",\n \"indexRefName\": \"kibanaSavedObjectMeta.searchSourceJSON.filter[3].meta.index\"\n },\n \"exists\": {\n \"field\": \"extension\"\n },\n \"$state\": {\n \"store\": \"appState\"\n }\n },\n {\n \"meta\": {\n \"alias\": null,\n \"negate\": false,\n \"disabled\": false,\n \"type\": \"phrase\",\n \"key\": \"banana\",\n \"params\": {\n \"query\": \"yellow\"\n }\n },\n \"query\": {\n \"match_phrase\": {\n \"banana\": \"yellow\"\n }\n },\n \"$state\": {\n \"store\": \"appState\"\n }\n }\n ]\n}" + }, + "optionsJSON": "{\n \"hidePanelTitles\": false,\n \"useMargins\": true\n}", + "panelsJSON": "[\n {\n \"version\": \"8.0.0\",\n \"gridData\": {\n \"x\": 0,\n \"y\": 0,\n \"w\": 24,\n \"h\": 15,\n \"i\": \"94a3dc1d-508a-4d42-a480-65b158925ba0\"\n },\n \"panelIndex\": \"94a3dc1d-508a-4d42-a480-65b158925ba0\",\n \"embeddableConfig\": {},\n \"panelRefName\": \"panel_0\"\n }\n]", + "refreshInterval": { + "pause": true, + "value": 0 + }, + "timeFrom": "now-10y", + "timeRestore": true, + "timeTo": "now", + "title": "dashboard with bad filters", + "version": 1 + }, + "migrationVersion": { + "dashboard": "7.3.0" + }, + "references": [ + { + "id": "a0f483a0-3dc9-11e8-8660-bad-index", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index", + "type": "index-pattern" + }, + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[1].meta.index", + "type": "index-pattern" + }, + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[2].meta.index", + "type": "index-pattern" + }, + { + "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[3].meta.index", + "type": "index-pattern" + }, + { + "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c", + "name": "kibanaSavedObjectMeta.searchSourceJSON.filter[4].meta.index", + "type": "index-pattern" + }, + { + "id": "50643b60-3dd3-11e8-b2b9-5d5dc1715159", + "name": "panel_0", + "type": "visualization" + } + ], + "type": "dashboard", + "updated_at": "2020-06-04T09:26:04.272Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "config:8.0.0", + "index": ".kibana_1", + "source": { + "config": { + "accessibility:disableAnimations": true, + "buildNum": null, + "dateFormat:tz": "UTC", + "defaultIndex": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c" + }, + "references": [ + ], + "type": "config", + "updated_at": "2020-06-04T09:22:54.572Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:b2a73c00-a645-11ea-b4c2-47e842e5fce5", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 1.2560333333333333, + "numberOfClicks": 19, + "timestamp": "2020-06-04T09:28:06.848Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-06-04T09:28:06.848Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "ui-metric:DashboardPanelVersionInUrl:8.0.0", + "index": ".kibana_1", + "source": { + "references": [ + ], + "type": "ui-metric", + "ui-metric": { + "count": 15 + }, + "updated_at": "2020-06-04T09:28:06.848Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:6847ed80-a645-11ea-b4c2-47e842e5fce5", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 2.291733333333333, + "numberOfClicks": 16, + "timestamp": "2020-06-04T09:26:02.071Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-06-04T09:26:02.072Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:7b331140-a645-11ea-b4c2-47e842e5fce5", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "management", + "minutesOnScreen": 1.2560333333333333, + "numberOfClicks": 19, + "timestamp": "2020-06-04T09:26:33.812Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-06-04T09:26:33.812Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "ui-metric:kibana-user_agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36", + "index": ".kibana_1", + "source": { + "references": [ + ], + "type": "ui-metric", + "ui-metric": { + "count": 1 + }, + "updated_at": "2020-06-04T09:28:06.848Z" + } + } +} + +{ + "type": "doc", + "value": { + "id": "application_usage_transactional:6f47f610-a646-11ea-b4c2-47e842e5fce5", + "index": ".kibana_1", + "source": { + "application_usage_transactional": { + "appId": "dashboards", + "minutesOnScreen": 6.77335, + "numberOfClicks": 5, + "timestamp": "2020-06-04T09:33:23.313Z" + }, + "references": [ + ], + "type": "application_usage_transactional", + "updated_at": "2020-06-04T09:33:23.313Z" + } + } +} \ No newline at end of file diff --git a/test/new_visualize_flow/fixtures/es_archiver/logstash_functional/data.json.gz b/test/new_visualize_flow/fixtures/es_archiver/logstash_functional/data.json.gz new file mode 100644 index 0000000000000..a4f889da61128 Binary files /dev/null and b/test/new_visualize_flow/fixtures/es_archiver/logstash_functional/data.json.gz differ diff --git a/test/new_visualize_flow/fixtures/es_archiver/logstash_functional/mappings.json b/test/new_visualize_flow/fixtures/es_archiver/logstash_functional/mappings.json new file mode 100644 index 0000000000000..010abff9cf6a9 --- /dev/null +++ b/test/new_visualize_flow/fixtures/es_archiver/logstash_functional/mappings.json @@ -0,0 +1,1118 @@ +{ + "type": "index", + "value": { + "index": "logstash-2015.09.22", + "mappings": { + "dynamic_templates": [ + { + "string_fields": { + "mapping": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "match": "*", + "match_mapping_type": "string" + } + } + ], + "properties": { + "@message": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "@tags": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "@timestamp": { + "type": "date" + }, + "agent": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "bytes": { + "type": "long" + }, + "clientip": { + "type": "ip" + }, + "extension": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "geo": { + "properties": { + "coordinates": { + "type": "geo_point" + }, + "dest": { + "type": "keyword" + }, + "src": { + "type": "keyword" + }, + "srcdest": { + "type": "keyword" + } + } + }, + "headings": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "host": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "id": { + "type": "integer" + }, + "index": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "ip": { + "type": "ip" + }, + "links": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "machine": { + "properties": { + "os": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "ram": { + "type": "long" + } + } + }, + "memory": { + "type": "double" + }, + "meta": { + "properties": { + "char": { + "type": "keyword" + }, + "related": { + "type": "text" + }, + "user": { + "properties": { + "firstname": { + "type": "text" + }, + "lastname": { + "type": "integer" + } + } + } + } + }, + "nestedField": { + "type": "nested", + "properties": { + "child": { + "type": "keyword" + } + } + }, + "phpmemory": { + "type": "long" + }, + "referer": { + "type": "keyword" + }, + "relatedContent": { + "properties": { + "article:modified_time": { + "type": "date" + }, + "article:published_time": { + "type": "date" + }, + "article:section": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "article:tag": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:description": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:image": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:image:height": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:image:width": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:site_name": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:title": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:type": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:url": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:card": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:description": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:image": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:site": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:title": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "url": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "request": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "response": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "spaces": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "type": { + "type": "keyword" + }, + "url": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "utc_time": { + "type": "date" + }, + "xss": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "settings": { + "index": { + "analysis": { + "analyzer": { + "url": { + "max_token_length": "1000", + "tokenizer": "uax_url_email", + "type": "standard" + } + } + }, + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} + +{ + "type": "index", + "value": { + "index": "logstash-2015.09.20", + "mappings": { + "dynamic_templates": [ + { + "string_fields": { + "mapping": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "match": "*", + "match_mapping_type": "string" + } + } + ], + "properties": { + "@message": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "@tags": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "@timestamp": { + "type": "date" + }, + "agent": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "bytes": { + "type": "long" + }, + "clientip": { + "type": "ip" + }, + "extension": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "geo": { + "properties": { + "coordinates": { + "type": "geo_point" + }, + "dest": { + "type": "keyword" + }, + "src": { + "type": "keyword" + }, + "srcdest": { + "type": "keyword" + } + } + }, + "headings": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "host": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "id": { + "type": "integer" + }, + "index": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "ip": { + "type": "ip" + }, + "links": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "machine": { + "properties": { + "os": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "ram": { + "type": "long" + } + } + }, + "memory": { + "type": "double" + }, + "meta": { + "properties": { + "char": { + "type": "keyword" + }, + "related": { + "type": "text" + }, + "user": { + "properties": { + "firstname": { + "type": "text" + }, + "lastname": { + "type": "integer" + } + } + } + } + }, + "nestedField": { + "type": "nested", + "properties": { + "child": { + "type": "keyword" + } + } + }, + "phpmemory": { + "type": "long" + }, + "referer": { + "type": "keyword" + }, + "relatedContent": { + "properties": { + "article:modified_time": { + "type": "date" + }, + "article:published_time": { + "type": "date" + }, + "article:section": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "article:tag": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:description": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:image": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:image:height": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:image:width": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:site_name": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:title": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:type": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:url": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:card": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:description": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:image": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:site": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:title": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "url": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "request": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "response": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "spaces": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "type": { + "type": "keyword" + }, + "url": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "utc_time": { + "type": "date" + }, + "xss": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "settings": { + "index": { + "analysis": { + "analyzer": { + "url": { + "max_token_length": "1000", + "tokenizer": "uax_url_email", + "type": "standard" + } + } + }, + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} + +{ + "type": "index", + "value": { + "index": "logstash-2015.09.21", + "mappings": { + "dynamic_templates": [ + { + "string_fields": { + "mapping": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "match": "*", + "match_mapping_type": "string" + } + } + ], + "properties": { + "@message": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "@tags": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "@timestamp": { + "type": "date" + }, + "agent": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "bytes": { + "type": "long" + }, + "clientip": { + "type": "ip" + }, + "extension": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "geo": { + "properties": { + "coordinates": { + "type": "geo_point" + }, + "dest": { + "type": "keyword" + }, + "src": { + "type": "keyword" + }, + "srcdest": { + "type": "keyword" + } + } + }, + "headings": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "host": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "id": { + "type": "integer" + }, + "index": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "ip": { + "type": "ip" + }, + "links": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "machine": { + "properties": { + "os": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "ram": { + "type": "long" + } + } + }, + "memory": { + "type": "double" + }, + "meta": { + "properties": { + "char": { + "type": "keyword" + }, + "related": { + "type": "text" + }, + "user": { + "properties": { + "firstname": { + "type": "text" + }, + "lastname": { + "type": "integer" + } + } + } + } + }, + "nestedField": { + "type": "nested", + "properties": { + "child": { + "type": "keyword" + } + } + }, + "phpmemory": { + "type": "long" + }, + "referer": { + "type": "keyword" + }, + "relatedContent": { + "properties": { + "article:modified_time": { + "type": "date" + }, + "article:published_time": { + "type": "date" + }, + "article:section": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "article:tag": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:description": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:image": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:image:height": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:image:width": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:site_name": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:title": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:type": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "og:url": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:card": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:description": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:image": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:site": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "twitter:title": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "url": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "request": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "response": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "spaces": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "type": { + "type": "keyword" + }, + "url": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + }, + "utc_time": { + "type": "date" + }, + "xss": { + "fields": { + "raw": { + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "settings": { + "index": { + "analysis": { + "analyzer": { + "url": { + "max_token_length": "1000", + "tokenizer": "uax_url_email", + "type": "standard" + } + } + }, + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} diff --git a/test/new_visualize_flow/index.ts b/test/new_visualize_flow/index.ts index e915525155990..08c00a0074bef 100644 --- a/test/new_visualize_flow/index.ts +++ b/test/new_visualize_flow/index.ts @@ -19,9 +19,14 @@ import { FtrProviderContext } from '../functional/ftr_provider_context'; // eslint-disable-next-line import/no-default-export -export default function ({ loadTestFile }: FtrProviderContext) { +export default function ({ loadTestFile, getService }: FtrProviderContext) { describe('New Visualize Flow', function () { this.tags('ciGroup2'); + const esArchiver = getService('esArchiver'); + before(async () => { + await esArchiver.loadIfNeeded('logstash_functional'); + }); + loadTestFile(require.resolve('./dashboard_embedding')); }); } diff --git a/x-pack/plugins/apm/public/components/app/service_node_metrics/index.tsx b/x-pack/plugins/apm/public/components/app/service_node_metrics/index.tsx index dd703d445cc60..59e919199be76 100644 --- a/x-pack/plugins/apm/public/components/app/service_node_metrics/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_node_metrics/index.tsx @@ -9,7 +9,7 @@ import { EuiFlexGrid, EuiFlexGroup, EuiFlexItem, - EuiHorizontalRule, + EuiPage, EuiPanel, EuiSpacer, EuiStat, @@ -31,6 +31,7 @@ import { px, truncate, unit } from '../../../style/variables'; import { ApmHeader } from '../../shared/ApmHeader'; import { MetricsChart } from '../../shared/charts/metrics_chart'; import { ElasticDocsLink } from '../../shared/Links/ElasticDocsLink'; +import { SearchBar } from '../../shared/search_bar'; const INITIAL_DATA = { host: '', @@ -42,6 +43,13 @@ const Truncate = styled.span` ${truncate(px(unit * 12))} `; +const MetadataFlexGroup = styled(EuiFlexGroup)` + border-bottom: ${({ theme }) => theme.eui.euiBorderThin}; + margin-bottom: ${({ theme }) => theme.eui.paddingSizes.m}; + padding: ${({ theme }) => + `${theme.eui.paddingSizes.m} 0 0 ${theme.eui.paddingSizes.m}`}; +`; + type ServiceNodeMetricsProps = RouteComponentProps<{ serviceName: string; serviceNodeName: string; @@ -75,11 +83,10 @@ export function ServiceNodeMetrics({ match }: ServiceNodeMetricsProps) { ); const isLoading = status === FETCH_STATUS.LOADING; - const isAggregatedData = serviceNodeName === SERVICE_NODE_NAME_MISSING; return ( -
+ <> @@ -89,7 +96,6 @@ export function ServiceNodeMetrics({ match }: ServiceNodeMetricsProps) { - {isAggregatedData ? ( ) : ( - + - + - + )} - {agentName && ( @@ -191,6 +196,28 @@ export function ServiceNodeMetrics({ match }: ServiceNodeMetricsProps) { )} -
+ + + {agentName && ( + + + {data.charts.map((chart) => ( + + + + + + ))} + + + + )} + + ); } diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_object_type_definition.test.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_object_type_definition.test.ts index f528843cf9ea3..f1e06a0cec03d 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_object_type_definition.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_object_type_definition.test.ts @@ -113,3 +113,18 @@ it('correctly determines attribute properties', () => { } } }); + +it('it correctly sets allowPredefinedID', () => { + const defaultTypeDefinition = new EncryptedSavedObjectAttributesDefinition({ + type: 'so-type', + attributesToEncrypt: new Set(['attr#1', 'attr#2']), + }); + expect(defaultTypeDefinition.allowPredefinedID).toBe(false); + + const typeDefinitionWithPredefinedIDAllowed = new EncryptedSavedObjectAttributesDefinition({ + type: 'so-type', + attributesToEncrypt: new Set(['attr#1', 'attr#2']), + allowPredefinedID: true, + }); + expect(typeDefinitionWithPredefinedIDAllowed.allowPredefinedID).toBe(true); +}); diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_object_type_definition.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_object_type_definition.ts index 849a2888b6e1a..398a64585411a 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_object_type_definition.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_object_type_definition.ts @@ -15,6 +15,7 @@ export class EncryptedSavedObjectAttributesDefinition { public readonly attributesToEncrypt: ReadonlySet; private readonly attributesToExcludeFromAAD: ReadonlySet | undefined; private readonly attributesToStrip: ReadonlySet; + public readonly allowPredefinedID: boolean; constructor(typeRegistration: EncryptedSavedObjectTypeRegistration) { const attributesToEncrypt = new Set(); @@ -34,6 +35,7 @@ export class EncryptedSavedObjectAttributesDefinition { this.attributesToEncrypt = attributesToEncrypt; this.attributesToStrip = attributesToStrip; this.attributesToExcludeFromAAD = typeRegistration.attributesToExcludeFromAAD; + this.allowPredefinedID = !!typeRegistration.allowPredefinedID; } /** diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.mocks.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.mocks.ts index c692d8698771f..0138e929ca1ca 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.mocks.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.mocks.ts @@ -13,6 +13,7 @@ import { function createEncryptedSavedObjectsServiceMock() { return ({ isRegistered: jest.fn(), + canSpecifyID: jest.fn(), stripOrDecryptAttributes: jest.fn(), encryptAttributes: jest.fn(), decryptAttributes: jest.fn(), @@ -52,6 +53,12 @@ export const encryptedSavedObjectsServiceMock = { mock.isRegistered.mockImplementation( (type) => registrations.findIndex((r) => r.type === type) >= 0 ); + mock.canSpecifyID.mockImplementation((type, version, overwrite) => { + const registration = registrations.find((r) => r.type === type); + return ( + registration === undefined || registration.allowPredefinedID || !!(version && overwrite) + ); + }); mock.encryptAttributes.mockImplementation(async (descriptor, attrs) => processAttributes( descriptor, diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts index 88d57072697fe..6bc4a392064e4 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts @@ -89,6 +89,45 @@ describe('#isRegistered', () => { }); }); +describe('#canSpecifyID', () => { + it('returns true for unknown types', () => { + expect(service.canSpecifyID('unknown-type')).toBe(true); + }); + + it('returns true for types registered setting allowPredefinedID to true', () => { + service.registerType({ + type: 'known-type-1', + attributesToEncrypt: new Set(['attr-1']), + allowPredefinedID: true, + }); + expect(service.canSpecifyID('known-type-1')).toBe(true); + }); + + it('returns true when overwriting a saved object with a version specified even when allowPredefinedID is not set', () => { + service.registerType({ + type: 'known-type-1', + attributesToEncrypt: new Set(['attr-1']), + }); + expect(service.canSpecifyID('known-type-1', '2', true)).toBe(true); + expect(service.canSpecifyID('known-type-1', '2', false)).toBe(false); + expect(service.canSpecifyID('known-type-1', undefined, true)).toBe(false); + }); + + it('returns false for types registered without setting allowPredefinedID', () => { + service.registerType({ type: 'known-type-1', attributesToEncrypt: new Set(['attr-1']) }); + expect(service.canSpecifyID('known-type-1')).toBe(false); + }); + + it('returns false for types registered setting allowPredefinedID to false', () => { + service.registerType({ + type: 'known-type-1', + attributesToEncrypt: new Set(['attr-1']), + allowPredefinedID: false, + }); + expect(service.canSpecifyID('known-type-1')).toBe(false); + }); +}); + describe('#stripOrDecryptAttributes', () => { it('does not strip attributes from unknown types', async () => { const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three' }; diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts index 1f1093a179538..8d2ebb575c35e 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts @@ -31,6 +31,7 @@ export interface EncryptedSavedObjectTypeRegistration { readonly type: string; readonly attributesToEncrypt: ReadonlySet; readonly attributesToExcludeFromAAD?: ReadonlySet; + readonly allowPredefinedID?: boolean; } /** @@ -144,6 +145,25 @@ export class EncryptedSavedObjectsService { return this.typeDefinitions.has(type); } + /** + * Checks whether ID can be specified for the provided saved object. + * + * If the type isn't registered as an encrypted saved object, or when overwriting an existing + * saved object with a version specified, this will return "true". + * + * @param type Saved object type. + * @param version Saved object version number which changes on each successful write operation. + * Can be used in conjunction with `overwrite` for implementing optimistic concurrency + * control. + * @param overwrite Overwrite existing documents. + */ + public canSpecifyID(type: string, version?: string, overwrite?: boolean) { + const typeDefinition = this.typeDefinitions.get(type); + return ( + typeDefinition === undefined || typeDefinition.allowPredefinedID || !!(version && overwrite) + ); + } + /** * Takes saved object attributes for the specified type and, depending on the type definition, * either decrypts or strips encrypted attributes (e.g. in case AAD or encryption key has changed diff --git a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts index 6346e73e6ba51..3c722ccfabae2 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.test.ts @@ -30,6 +30,11 @@ beforeEach(() => { { key: 'attrNotSoSecret', dangerouslyExposeValue: true }, ]), }, + { + type: 'known-type-predefined-id', + attributesToEncrypt: new Set(['attrSecret']), + allowPredefinedID: true, + }, ]); wrapper = new EncryptedSavedObjectsClientWrapper({ @@ -72,16 +77,36 @@ describe('#create', () => { expect(mockBaseClient.create).toHaveBeenCalledWith('unknown-type', attributes, options); }); - it('fails if type is registered and ID is specified', async () => { + it('fails if type is registered without allowPredefinedID and ID is specified', async () => { const attributes = { attrOne: 'one', attrSecret: 'secret', attrThree: 'three' }; await expect(wrapper.create('known-type', attributes, { id: 'some-id' })).rejects.toThrowError( - 'Predefined IDs are not allowed for saved objects with encrypted attributes.' + 'Predefined IDs are not allowed for encrypted saved objects of type "known-type".' ); expect(mockBaseClient.create).not.toHaveBeenCalled(); }); + it('succeeds if type is registered with allowPredefinedID and ID is specified', async () => { + const attributes = { attrOne: 'one', attrSecret: 'secret', attrThree: 'three' }; + const mockedResponse = { + id: 'some-id', + type: 'known-type-predefined-id', + attributes: { attrOne: 'one', attrSecret: '*secret*', attrThree: 'three' }, + references: [], + }; + + mockBaseClient.create.mockResolvedValue(mockedResponse); + await expect( + wrapper.create('known-type-predefined-id', attributes, { id: 'some-id' }) + ).resolves.toEqual({ + ...mockedResponse, + attributes: { attrOne: 'one', attrThree: 'three' }, + }); + + expect(mockBaseClient.create).toHaveBeenCalled(); + }); + it('allows a specified ID when overwriting an existing object', async () => { const attributes = { attrOne: 'one', @@ -299,7 +324,7 @@ describe('#bulkCreate', () => { ); }); - it('fails if ID is specified for registered type', async () => { + it('fails if ID is specified for registered type without allowPredefinedID', async () => { const attributes = { attrOne: 'one', attrSecret: 'secret', attrThree: 'three' }; const bulkCreateParams = [ @@ -308,12 +333,48 @@ describe('#bulkCreate', () => { ]; await expect(wrapper.bulkCreate(bulkCreateParams)).rejects.toThrowError( - 'Predefined IDs are not allowed for saved objects with encrypted attributes.' + 'Predefined IDs are not allowed for encrypted saved objects of type "known-type".' ); expect(mockBaseClient.bulkCreate).not.toHaveBeenCalled(); }); + it('succeeds if ID is specified for registered type with allowPredefinedID', async () => { + const attributes = { attrOne: 'one', attrSecret: 'secret', attrThree: 'three' }; + const options = { namespace: 'some-namespace' }; + const mockedResponse = { + saved_objects: [ + { + id: 'some-id', + type: 'known-type-predefined-id', + attributes, + references: [], + }, + { + id: 'some-id', + type: 'unknown-type', + attributes, + references: [], + }, + ], + }; + mockBaseClient.bulkCreate.mockResolvedValue(mockedResponse); + + const bulkCreateParams = [ + { id: 'some-id', type: 'known-type-predefined-id', attributes }, + { type: 'unknown-type', attributes }, + ]; + + await expect(wrapper.bulkCreate(bulkCreateParams, options)).resolves.toEqual({ + saved_objects: [ + { ...mockedResponse.saved_objects[0], attributes: { attrOne: 'one', attrThree: 'three' } }, + mockedResponse.saved_objects[1], + ], + }); + + expect(mockBaseClient.bulkCreate).toHaveBeenCalled(); + }); + it('allows a specified ID when overwriting an existing object', async () => { const attributes = { attrOne: 'one', diff --git a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.ts b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.ts index 59309ab67e772..ddef9f477433c 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/encrypted_saved_objects_client_wrapper.ts @@ -68,16 +68,14 @@ export class EncryptedSavedObjectsClientWrapper implements SavedObjectsClientCon } // Saved objects with encrypted attributes should have IDs that are hard to guess especially - // since IDs are part of the AAD used during encryption, that's why we control them within this - // wrapper and don't allow consumers to specify their own IDs directly. - - // only allow a specified ID if we're overwriting an existing ESO with a Version - // this helps us ensure that the document really was previously created using ESO - // and not being used to get around the specified ID limitation - const canSpecifyID = options.overwrite && options.version; - if (options.id && !canSpecifyID) { + // since IDs are part of the AAD used during encryption. Types can opt-out of this restriction, + // when necessary, but it's much safer for this wrapper to generate them. + if ( + options.id && + !this.options.service.canSpecifyID(type, options.version, options.overwrite) + ) { throw new Error( - 'Predefined IDs are not allowed for saved objects with encrypted attributes.' + `Predefined IDs are not allowed for encrypted saved objects of type "${type}".` ); } @@ -118,10 +116,12 @@ export class EncryptedSavedObjectsClientWrapper implements SavedObjectsClientCon // Saved objects with encrypted attributes should have IDs that are hard to guess especially // since IDs are part of the AAD used during encryption, that's why we control them within this // wrapper and don't allow consumers to specify their own IDs directly unless overwriting the original document. - const canSpecifyID = options?.overwrite && object.version; - if (object.id && !canSpecifyID) { + if ( + object.id && + !this.options.service.canSpecifyID(object.type, object.version, options?.overwrite) + ) { throw new Error( - 'Predefined IDs are not allowed for saved objects with encrypted attributes.' + `Predefined IDs are not allowed for encrypted saved objects of type "${object.type}".` ); } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/constants.ts new file mode 100644 index 0000000000000..54b0d47ee02d8 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/constants.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { i18n } from '@kbn/i18n'; + +export const DOCUMENTS_TITLE = i18n.translate('xpack.enterpriseSearch.appSearch.documents.title', { + defaultMessage: 'Documents', +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx new file mode 100644 index 0000000000000..a289ec78d9e80 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx @@ -0,0 +1,112 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock'; +import '../../../__mocks__/react_router_history.mock'; +import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock'; + +import React from 'react'; +import { shallow } from 'enzyme'; +import { useParams } from 'react-router-dom'; +import { EuiPageContent, EuiBasicTable } from '@elastic/eui'; + +import { Loading } from '../../../shared/loading'; +import { DocumentDetail } from '.'; +import { ResultFieldValue } from '../result_field_value'; + +describe('DocumentDetail', () => { + const values = { + dataLoading: false, + fields: [], + }; + + const actions = { + deleteDocument: jest.fn(), + getDocumentDetails: jest.fn(), + setFields: jest.fn(), + }; + + beforeEach(() => { + jest.clearAllMocks(); + setMockValues(values); + setMockActions(actions); + + (useParams as jest.Mock).mockImplementationOnce(() => ({ + documentId: '1', + })); + }); + + it('renders', () => { + const wrapper = shallow(); + expect(wrapper.find(EuiPageContent).length).toBe(1); + }); + + it('initializes data on mount', () => { + shallow(); + expect(actions.getDocumentDetails).toHaveBeenCalledWith('1'); + }); + + it('calls setFields on unmount', () => { + shallow(); + unmountHandler(); + expect(actions.setFields).toHaveBeenCalledWith([]); + }); + + it('will show a loader while data is loading', () => { + setMockValues({ + ...values, + dataLoading: true, + }); + + const wrapper = shallow(); + + expect(wrapper.find(Loading).length).toBe(1); + }); + + describe('field values list', () => { + let columns: any; + + const field = { + name: 'Foo', + value: 'Bar', + type: 'string', + }; + + beforeEach(() => { + const wrapper = shallow(); + columns = wrapper.find(EuiBasicTable).props().columns; + }); + + it('will render the field name in the first column', () => { + const column = columns[0]; + const wrapper = shallow(
{column.render(field)}
); + expect(wrapper.text()).toEqual('Foo'); + }); + + it('will render the field value in the second column', () => { + const column = columns[1]; + const wrapper = shallow(
{column.render(field)}
); + expect(wrapper.find(ResultFieldValue).props()).toEqual({ + raw: 'Bar', + type: 'string', + }); + }); + }); + + it('will delete the document when the delete button is pressed', () => { + const wrapper = shallow(); + const button = wrapper.find('[data-test-subj="DeleteDocumentButton"]'); + + button.simulate('click'); + + expect(actions.deleteDocument).toHaveBeenCalledWith('1'); + }); + + it('correctly decodes document IDs', () => { + (useParams as jest.Mock).mockReturnValueOnce({ documentId: 'hello%20world%20%26%3F!' }); + const wrapper = shallow(); + expect(wrapper.find('h1').text()).toEqual('Document: hello world &?!'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.tsx new file mode 100644 index 0000000000000..017f5a2f67ad0 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.tsx @@ -0,0 +1,107 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useEffect } from 'react'; +import { useActions, useValues } from 'kea'; +import { useParams } from 'react-router-dom'; + +import { + EuiButton, + EuiPageHeader, + EuiPageHeaderSection, + EuiTitle, + EuiPageContentBody, + EuiPageContent, + EuiBasicTable, + EuiBasicTableColumn, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { Loading } from '../../../shared/loading'; +import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; +import { FlashMessages } from '../../../shared/flash_messages'; +import { ResultFieldValue } from '../result_field_value'; + +import { DocumentDetailLogic } from './document_detail_logic'; +import { FieldDetails } from './types'; +import { DOCUMENTS_TITLE } from './constants'; + +const DOCUMENT_DETAIL_TITLE = (documentId: string) => + i18n.translate('xpack.enterpriseSearch.appSearch.documentDetail.title', { + defaultMessage: 'Document: {documentId}', + values: { documentId }, + }); +interface Props { + engineBreadcrumb: string[]; +} + +export const DocumentDetail: React.FC = ({ engineBreadcrumb }) => { + const { dataLoading, fields } = useValues(DocumentDetailLogic); + const { deleteDocument, getDocumentDetails, setFields } = useActions(DocumentDetailLogic); + + const { documentId } = useParams() as { documentId: string }; + + useEffect(() => { + getDocumentDetails(documentId); + return () => { + setFields([]); + }; + }, []); + + if (dataLoading) { + return ; + } + + const columns: Array> = [ + { + name: i18n.translate('xpack.enterpriseSearch.appSearch.documentDetail.fieldHeader', { + defaultMessage: 'Field', + }), + width: '20%', + render: (field: FieldDetails) => field.name, + }, + { + name: i18n.translate('xpack.enterpriseSearch.appSearch.documentDetail.valueHeader', { + defaultMessage: 'Value', + }), + width: '80%', + render: ({ value, type }: FieldDetails) => , + }, + ]; + + return ( + <> + + + + +

{DOCUMENT_DETAIL_TITLE(decodeURIComponent(documentId))}

+
+
+ + deleteDocument(documentId)} + data-test-subj="DeleteDocumentButton" + > + {i18n.translate('xpack.enterpriseSearch.appSearch.documentDetail.deleteButton', { + defaultMessage: 'Delete', + })} + + +
+ + + + + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts index 782b8159c94a1..4afa3f7aee5c8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts @@ -16,6 +16,11 @@ jest.mock('../engine', () => ({ EngineLogic: { values: { engineName: 'engine1' } }, })); +jest.mock('../../../shared/kibana', () => ({ + KibanaLogic: { values: { navigateToUrl: jest.fn() } }, +})); +import { KibanaLogic } from '../../../shared/kibana'; + jest.mock('../../../shared/flash_messages', () => ({ setQueuedSuccessMessage: jest.fn(), flashAPIErrors: jest.fn(), @@ -98,7 +103,8 @@ describe('DocumentDetailLogic', () => { } catch { // Do nothing } - expect(flashAPIErrors).toHaveBeenCalledWith('An error occurred'); + expect(flashAPIErrors).toHaveBeenCalledWith('An error occurred', { isQueued: true }); + expect(KibanaLogic.values.navigateToUrl).toHaveBeenCalledWith('/engines/engine1/documents'); }); }); @@ -117,7 +123,7 @@ describe('DocumentDetailLogic', () => { confirmSpy.mockRestore(); }); - it('will call an API endpoint and show a success message', async () => { + it('will call an API endpoint and show a success message on the documents page', async () => { mount(); DocumentDetailLogic.actions.deleteDocument('1'); @@ -126,6 +132,7 @@ describe('DocumentDetailLogic', () => { expect(setQueuedSuccessMessage).toHaveBeenCalledWith( 'Successfully marked document for deletion. It will be deleted momentarily.' ); + expect(KibanaLogic.values.navigateToUrl).toHaveBeenCalledWith('/engines/engine1/documents'); }); it('will do nothing if not confirmed', async () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.ts index 87bf149fb1680..62db2bf172354 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.ts @@ -11,6 +11,8 @@ import { HttpLogic } from '../../../shared/http'; import { EngineLogic } from '../engine'; import { flashAPIErrors, setQueuedSuccessMessage } from '../../../shared/flash_messages'; import { FieldDetails } from './types'; +import { KibanaLogic } from '../../../shared/kibana'; +import { ENGINE_DOCUMENTS_PATH, getEngineRoute } from '../../routes'; interface DocumentDetailLogicValues { dataLoading: boolean; @@ -65,13 +67,17 @@ export const DocumentDetailLogic = kea({ try { const { http } = HttpLogic.values; - // TODO: Handle 404s const response = await http.get( `/api/app_search/engines/${engineName}/documents/${documentId}` ); actions.setFields(response.fields); } catch (e) { - flashAPIErrors(e); + // If an error occurs trying to load this document, it will typically be a 404, or some other + // error that will prevent the page from loading, so redirect to the documents page and + // show the error + flashAPIErrors(e, { isQueued: true }); + const engineRoute = getEngineRoute(engineName); + KibanaLogic.values.navigateToUrl(engineRoute + ENGINE_DOCUMENTS_PATH); } }, deleteDocument: async ({ documentId }) => { @@ -82,7 +88,8 @@ export const DocumentDetailLogic = kea({ const { http } = HttpLogic.values; await http.delete(`/api/app_search/engines/${engineName}/documents/${documentId}`); setQueuedSuccessMessage(DELETE_SUCCESS); - // TODO Handle routing after success + const engineRoute = getEngineRoute(engineName); + KibanaLogic.values.navigateToUrl(engineRoute + ENGINE_DOCUMENTS_PATH); } catch (e) { flashAPIErrors(e); } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.tsx new file mode 100644 index 0000000000000..023ae06767abe --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.tsx @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +import { + EuiPageHeader, + EuiPageHeaderSection, + EuiTitle, + EuiPageContent, + EuiPageContentBody, +} from '@elastic/eui'; + +import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; +import { FlashMessages } from '../../../shared/flash_messages'; +import { DOCUMENTS_TITLE } from './constants'; + +interface Props { + engineBreadcrumb: string[]; +} + +export const Documents: React.FC = ({ engineBreadcrumb }) => { + return ( + <> + + + + +

{DOCUMENTS_TITLE}

+
+
+
+ + + + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/index.ts index d374098d70788..b67e444939c0e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/index.ts @@ -6,3 +6,5 @@ export { DocumentDetailLogic } from './document_detail_logic'; export { DocumentsLogic } from './documents_logic'; +export { Documents } from './documents'; +export { DocumentDetail } from './document_detail'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx index a7ac6f203b1f7..35389bbe4b3ba 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx @@ -111,8 +111,8 @@ export const EngineNav: React.FC = () => { )} {canViewEngineDocuments && ( {DOCUMENTS_TITLE} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx index f586106924f2c..9e0b043a87364 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx @@ -19,7 +19,8 @@ import { ENGINES_PATH, ENGINE_PATH, ENGINE_ANALYTICS_PATH, - // ENGINE_DOCUMENTS_PATH, + ENGINE_DOCUMENTS_PATH, + ENGINE_DOCUMENT_DETAIL_PATH, // ENGINE_SCHEMA_PATH, // ENGINE_CRAWLER_PATH, // META_ENGINE_SOURCE_ENGINES_PATH, @@ -49,6 +50,7 @@ import { Loading } from '../../../shared/loading'; import { EngineOverview } from '../engine_overview'; import { EngineLogic } from './'; +import { DocumentDetail, Documents } from '../documents'; export const EngineRouter: React.FC = () => { const { @@ -99,6 +101,12 @@ export const EngineRouter: React.FC = () => {
Just testing right now
)} + + + + + + diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/index.ts new file mode 100644 index 0000000000000..43755eaadaf81 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { ResultFieldValue } from './result_field_value'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/result_field_value.scss b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/result_field_value.scss new file mode 100644 index 0000000000000..13a771d24adc9 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/result_field_value.scss @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +.enterpriseSearchDataType { + &--number, + &--float { + color: $euiColorAccentText; + font-family: $euiCodeFontFamily; + } + + &--location { + color: $euiColorSuccessText; + font-family: $euiCodeFontFamily; + } + + &--date { + font-family: $euiCodeFontFamily; + } +} + +.enterpriseSearchResultHighlight { + color: $euiColorPrimary; + font-weight: $euiFontWeightSemiBold; +} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/result_field_value.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/result_field_value.test.tsx new file mode 100644 index 0000000000000..227700bdd0cd2 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/result_field_value.test.tsx @@ -0,0 +1,172 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { shallow, ShallowWrapper } from 'enzyme'; + +import { ResultFieldValue } from '.'; + +describe('ResultFieldValue', () => { + describe('when no raw or snippet values are provided', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + wrapper = shallow(); + }); + + it('will render a dash', () => { + expect(wrapper.text()).toEqual('—'); + }); + }); + + describe('when there is only a raw value', () => { + describe('and the value is a string', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + wrapper = shallow(); + }); + + it('will render a display value', () => { + expect(wrapper.text()).toEqual('foo'); + }); + + it('will have the appropriate type class', () => { + expect(wrapper.prop('className')).toContain('enterpriseSearchDataType--string'); + }); + }); + + describe('and the value is a string array', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + wrapper = shallow(); + }); + + it('will render a display value', () => { + expect(wrapper.text()).toEqual('["foo", "bar"]'); + }); + + it('will have the appropriate type class', () => { + expect(wrapper.prop('className')).toContain('enterpriseSearchDataType--string'); + }); + }); + + describe('and the value is a number', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + wrapper = shallow(); + }); + + it('will render a display value', () => { + expect(wrapper.text()).toEqual('1'); + }); + + it('will have the appropriate type class', () => { + expect(wrapper.prop('className')).toContain('enterpriseSearchDataType--number'); + }); + }); + + describe('and the value is an array of numbers', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + wrapper = shallow(); + }); + + it('will render a display value', () => { + expect(wrapper.text()).toEqual('[1, 2]'); + }); + + it('will have the appropriate type class', () => { + expect(wrapper.prop('className')).toContain('enterpriseSearchDataType--number'); + }); + }); + + describe('and the value is a location', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + wrapper = shallow(); + }); + + it('will render a display value', () => { + expect(wrapper.text()).toEqual('44.6, -110.5'); + }); + + it('will have the appropriate type class', () => { + expect(wrapper.prop('className')).toContain('enterpriseSearchDataType--location'); + }); + }); + + describe('and the value is an array of locations', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + wrapper = shallow( + + ); + }); + + it('will render a display value', () => { + expect(wrapper.text()).toEqual('[44.6, -110.5, 44.7, -111.0]'); + }); + + it('will have the appropriate type class', () => { + expect(wrapper.prop('className')).toContain('enterpriseSearchDataType--location'); + }); + }); + + describe('and the value is a date', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + wrapper = shallow(); + }); + + it('will render a display value', () => { + expect(wrapper.text()).toEqual('1872-03-01T06:00:00Z'); + }); + + it('will have the appropriate type class on outer div', () => { + expect(wrapper.prop('className')).toContain('enterpriseSearchDataType--date'); + }); + }); + + describe('and the value is an array of dates', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + wrapper = shallow( + + ); + }); + + it('will render a display value', () => { + expect(wrapper.text()).toEqual('[1872-03-01T06:00:00Z, 1472-04-01T06:00:00Z]'); + }); + + it('will have the appropriate type class on outer div', () => { + expect(wrapper.prop('className')).toContain('enterpriseSearchDataType--date'); + }); + }); + }); + + describe('when there is a snippet value', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + wrapper = shallow( + + ); + }); + + it('will render content as html with class names appended to em tags', () => { + expect(wrapper.find('div').html()).toContain( + 'a long description' + ); + }); + + it('will have the appropriate type class', () => { + expect(wrapper.prop('className')).toContain('enterpriseSearchDataType--string'); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/result_field_value.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/result_field_value.tsx new file mode 100644 index 0000000000000..9ee0f1e0ba043 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result_field_value/result_field_value.tsx @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +import classNames from 'classnames'; + +import { Raw, Snippet } from '../../types'; + +import './result_field_value.scss'; + +const isNotNumeric = (raw: string | number): boolean => { + if (typeof raw === 'number') return false; + return isNaN(parseFloat(raw)); +}; + +const getRawArrayDisplay = (rawArray: Array): string => { + return `[${rawArray.map((raw) => (isNotNumeric(raw) ? `"${raw}"` : raw)).join(', ')}]`; +}; + +const parseHighlights = (highlight: string): string => { + return highlight.replace( + /(.+?)<\/em>/gi, + '$1' + ); +}; + +const isFieldValueEmpty = (type?: string, raw?: Raw, snippet?: Snippet) => { + const isNumber = type === 'number'; + if (isNumber) { + return raw === null; + } + + return !snippet && !raw; +}; + +interface Props { + raw?: Raw; + snippet?: Snippet; + type?: string; + className?: string; +} + +export const ResultFieldValue: React.FC = ({ snippet, raw, type, className }) => { + const isEmpty = isFieldValueEmpty(type, raw, snippet); + if (isEmpty) return <>—; + const classes = classNames({ [`enterpriseSearchDataType--${type}`]: !!type }, className); + return ( +
+ {!!snippet ? null : Array.isArray(raw) ? getRawArrayDisplay(raw) : raw} +
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/types.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/types.ts index 7c22a45757a93..9af1ff0293fae 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/types.ts @@ -7,3 +7,5 @@ export * from '../../../common/types/app_search'; export { Role, RoleTypes, AbilityTypes } from './utils/role'; export { Engine } from './components/engine/types'; +export type Raw = string | string[] | number | number[]; +export type Snippet = string; diff --git a/x-pack/plugins/fleet/server/services/epm/archive/cache.ts b/x-pack/plugins/fleet/server/services/epm/archive/cache.ts index 04aa1767b4f14..6032159fdfcc5 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/cache.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/cache.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { ArchiveEntry } from './index'; -import { InstallSource, ArchivePackage, RegistryPackage } from '../../../../common'; +import { ArchivePackage, RegistryPackage } from '../../../../common'; const archiveEntryCache: Map = new Map(); export const getArchiveEntry = (key: string) => archiveEntryCache.get(key); @@ -16,7 +16,6 @@ export const deleteArchiveEntry = (key: string) => archiveEntryCache.delete(key) export interface SharedKey { name: string; version: string; - installSource: InstallSource; } type SharedKeyString = string; @@ -31,18 +30,10 @@ export const deleteArchiveFilelist = (keyArgs: SharedKey) => archiveFilelistCache.delete(sharedKey(keyArgs)); const packageInfoCache: Map = new Map(); -const sharedKey = ({ name, version, installSource }: SharedKey) => - `${name}-${version}-${installSource}`; +const sharedKey = ({ name, version }: SharedKey) => `${name}-${version}`; export const getPackageInfo = (args: SharedKey) => { - const packageInfo = packageInfoCache.get(sharedKey(args)); - if (args.installSource === 'registry') { - return packageInfo as RegistryPackage; - } else if (args.installSource === 'upload') { - return packageInfo as ArchivePackage; - } else { - throw new Error(`Unknown installSource: ${args.installSource}`); - } + return packageInfoCache.get(sharedKey(args)); }; export const getArchivePackage = (args: SharedKey) => { @@ -57,10 +48,9 @@ export const getArchivePackage = (args: SharedKey) => { export const setPackageInfo = ({ name, version, - installSource, packageInfo, }: SharedKey & { packageInfo: ArchivePackage | RegistryPackage }) => { - const key = sharedKey({ name, version, installSource }); + const key = sharedKey({ name, version }); return packageInfoCache.set(key, packageInfo); }; diff --git a/x-pack/plugins/fleet/server/services/epm/archive/index.ts b/x-pack/plugins/fleet/server/services/epm/archive/index.ts index ddaf9b640c86a..81d4fa6869e3b 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/index.ts @@ -49,7 +49,7 @@ export async function unpackBufferToCache({ paths.push(path); } }); - setArchiveFilelist({ name, version, installSource }, paths); + setArchiveFilelist({ name, version }, paths); return paths; } @@ -85,18 +85,18 @@ export async function unpackBufferEntries( return entries; } -export const deletePackageCache = ({ name, version, installSource }: SharedKey) => { +export const deletePackageCache = ({ name, version }: SharedKey) => { // get cached archive filelist - const paths = getArchiveFilelist({ name, version, installSource }); + const paths = getArchiveFilelist({ name, version }); // delete cached archive filelist - deleteArchiveFilelist({ name, version, installSource }); + deleteArchiveFilelist({ name, version }); // delete cached archive files // this has been populated in unpackBufferToCache() paths?.forEach(deleteArchiveEntry); - deletePackageInfo({ name, version, installSource }); + deletePackageInfo({ name, version }); }; export function getPathParts(path: string): AssetParts { diff --git a/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts b/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts index ee5257b8a3ef6..bdb6744745c97 100644 --- a/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/kibana/index_pattern/install.ts @@ -9,13 +9,12 @@ import { INDEX_PATTERN_SAVED_OBJECT_TYPE, INDEX_PATTERN_PLACEHOLDER_SUFFIX, } from '../../../../constants'; -import * as Registry from '../../registry'; import { loadFieldsFromYaml, Fields, Field } from '../../fields/field'; -import { getPackageKeysByStatus } from '../../packages/get'; import { dataTypes, installationStatuses } from '../../../../../common/constants'; -import { ValueOf } from '../../../../../common/types'; +import { ArchivePackage, InstallSource, ValueOf } from '../../../../../common/types'; import { RegistryPackage, CallESAsCurrentUser, DataType } from '../../../../types'; import { appContextService } from '../../../../services'; +import { getPackageFromSource, getPackageSavedObjects } from '../../packages/get'; interface FieldFormatMap { [key: string]: FieldFormatMapItem; @@ -73,45 +72,54 @@ export interface IndexPatternField { } export const indexPatternTypes = Object.values(dataTypes); -// TODO: use a function overload and make pkgName and pkgVersion required for install/update -// and not for an update removal. or separate out the functions export async function installIndexPatterns( savedObjectsClient: SavedObjectsClientContract, pkgName?: string, - pkgVersion?: string + pkgVersion?: string, + installSource?: InstallSource ) { // get all user installed packages - const installedPackages = await getPackageKeysByStatus( - savedObjectsClient, - installationStatuses.Installed + const installedPackagesRes = await getPackageSavedObjects(savedObjectsClient); + const installedPackagesSavedObjects = installedPackagesRes.saved_objects.filter( + (so) => so.attributes.install_status === installationStatuses.Installed ); - const packageVersionsToFetch = [...installedPackages]; - if (pkgName && pkgVersion) { - const packageToInstall = packageVersionsToFetch.find((pkg) => pkg.pkgName === pkgName); + const packagesToFetch = installedPackagesSavedObjects.reduce< + Array<{ name: string; version: string; installSource: InstallSource }> + >((acc, pkgSO) => { + acc.push({ + name: pkgSO.attributes.name, + version: pkgSO.attributes.version, + installSource: pkgSO.attributes.install_source, + }); + return acc; + }, []); + if (pkgName && pkgVersion && installSource) { + const packageToInstall = packagesToFetch.find((pkgSO) => pkgSO.name === pkgName); if (packageToInstall) { // set the version to the one we want to install - // if we're installing for the first time the number will be the same + // if we're reinstalling the number will be the same // if this is an upgrade then we'll be modifying the version number to the upgrade version - packageToInstall.pkgVersion = pkgVersion; + packageToInstall.version = pkgVersion; } else { - // this will likely not happen because the saved objects should already have the package we're trying - // install which means that it should have been found in the case above - packageVersionsToFetch.push({ pkgName, pkgVersion }); + // if we're installing for the first time, add to the list + packagesToFetch.push({ name: pkgName, version: pkgVersion, installSource }); } } // get each package's registry info - const packageVersionsFetchInfoPromise = packageVersionsToFetch.map((pkg) => - Registry.fetchInfo(pkg.pkgName, pkg.pkgVersion) + const packagesToFetchPromise = packagesToFetch.map((pkg) => + getPackageFromSource({ + pkgName: pkg.name, + pkgVersion: pkg.version, + pkgInstallSource: pkg.installSource, + }) ); - - const packageVersionsInfo = await Promise.all(packageVersionsFetchInfoPromise); - + const packages = await Promise.all(packagesToFetchPromise); // for each index pattern type, create an index pattern indexPatternTypes.forEach(async (indexPatternType) => { // if this is an update because a package is being uninstalled (no pkgkey argument passed) and no other packages are installed, remove the index pattern - if (!pkgName && installedPackages.length === 0) { + if (!pkgName && installedPackagesSavedObjects.length === 0) { try { await savedObjectsClient.delete(INDEX_PATTERN_SAVED_OBJECT_TYPE, `${indexPatternType}-*`); } catch (err) { @@ -119,9 +127,9 @@ export async function installIndexPatterns( } return; } - + const packagesWithInfo = packages.map((pkg) => pkg.packageInfo); // get all data stream fields from all installed packages - const fields = await getAllDataStreamFieldsByType(packageVersionsInfo, indexPatternType); + const fields = await getAllDataStreamFieldsByType(packagesWithInfo, indexPatternType); const kibanaIndexPattern = createIndexPattern(indexPatternType, fields); // create or overwrite the index pattern await savedObjectsClient.create(INDEX_PATTERN_SAVED_OBJECT_TYPE, kibanaIndexPattern, { @@ -134,7 +142,7 @@ export async function installIndexPatterns( // loops through all given packages and returns an array // of all fields from all data streams matching data stream type export const getAllDataStreamFieldsByType = async ( - packages: RegistryPackage[], + packages: Array, dataStreamType: ValueOf ): Promise => { const dataStreamsPromises = packages.reduce>>((acc, pkg) => { @@ -143,9 +151,9 @@ export const getAllDataStreamFieldsByType = async ( const matchingDataStreams = pkg.data_streams.filter( (dataStream) => dataStream.type === dataStreamType ); - matchingDataStreams.forEach((dataStream) => - acc.push(loadFieldsFromYaml(pkg, dataStream.path)) - ); + matchingDataStreams.forEach((dataStream) => { + acc.push(loadFieldsFromYaml(pkg, dataStream.path)); + }); } return acc; }, []); diff --git a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts index 4d36c3919198c..05f552b558205 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts @@ -82,7 +82,8 @@ export async function _installPackage({ const installIndexPatternPromise = installIndexPatterns( savedObjectsClient, pkgName, - pkgVersion + pkgVersion, + installSource ).catch((reason) => (installIndexPatternError = reason)); const kibanaAssets = await getKibanaAssets(paths); if (installedPkg) diff --git a/x-pack/plugins/fleet/server/services/epm/packages/assets.ts b/x-pack/plugins/fleet/server/services/epm/packages/assets.ts index 770f342c0a6e7..33913b7f0c14d 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/assets.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/assets.ts @@ -21,7 +21,7 @@ export function getAssets( ): string[] { const assets: string[] = []; const { name, version } = packageInfo; - const paths = getArchiveFilelist({ name, version, installSource: 'registry' }); + const paths = getArchiveFilelist({ name, version }); // TODO: might be better to throw a PackageCacheError here if (!paths || paths.length === 0) return assets; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.ts index 3df2d39419ab8..c10b26cbf0bd1 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.ts @@ -7,8 +7,8 @@ import { SavedObjectsClientContract, SavedObjectsFindOptions } from 'src/core/server'; import { isPackageLimited, installationStatuses } from '../../../../common'; import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../constants'; -import { ArchivePackage, InstallSource, RegistryPackage, ValueOf } from '../../../../common/types'; -import { Installation, InstallationStatus, PackageInfo, KibanaAssetType } from '../../../types'; +import { ArchivePackage, InstallSource, RegistryPackage } from '../../../../common/types'; +import { Installation, PackageInfo, KibanaAssetType } from '../../../types'; import * as Registry from '../registry'; import { createInstallableFrom, isRequiredPackage } from './index'; import { getArchivePackage } from '../archive'; @@ -84,26 +84,6 @@ export async function getPackageSavedObjects( }); } -export async function getPackageKeysByStatus( - savedObjectsClient: SavedObjectsClientContract, - status: ValueOf -) { - const allPackages = await getPackages({ savedObjectsClient, experimental: true }); - return allPackages.reduce>((acc, pkg) => { - if (pkg.status === status) { - if (pkg.status === installationStatuses.Installed) { - // if we're looking for installed packages grab the version from the saved object because `getPackages` will - // return the latest package information from the registry - acc.push({ pkgName: pkg.name, pkgVersion: pkg.savedObject.attributes.version }); - } else { - acc.push({ pkgName: pkg.name, pkgVersion: pkg.version }); - } - } - - return acc; - }, []); -} - export async function getPackageInfo(options: { savedObjectsClient: SavedObjectsClientContract; pkgName: string; @@ -139,7 +119,10 @@ export async function getPackageFromSource(options: { pkgName: string; pkgVersion: string; pkgInstallSource?: InstallSource; -}): Promise<{ paths: string[] | undefined; packageInfo: RegistryPackage | ArchivePackage }> { +}): Promise<{ + paths: string[] | undefined; + packageInfo: RegistryPackage | ArchivePackage; +}> { const { pkgName, pkgVersion, pkgInstallSource } = options; // TODO: Check package storage before checking registry let res; @@ -147,14 +130,16 @@ export async function getPackageFromSource(options: { res = getArchivePackage({ name: pkgName, version: pkgVersion, - installSource: pkgInstallSource, }); - if (!res.packageInfo) - throw new Error(`installed package ${pkgName}-${pkgVersion} does not exist in cache`); } else { res = await Registry.getRegistryPackage(pkgName, pkgVersion); } - return res; + if (!res.packageInfo || !res.paths) + throw new Error(`package info for ${pkgName}-${pkgVersion} does not exist`); + return { + paths: res.paths, + packageInfo: res.packageInfo, + }; } export async function getInstallationObject(options: { diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.ts index e73a5d3533828..29300818288b4 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.ts @@ -313,7 +313,6 @@ async function installPackageByUpload({ setPackageInfo({ name: packageInfo.name, version: packageInfo.version, - installSource, packageInfo, }); diff --git a/x-pack/plugins/fleet/server/services/epm/packages/remove.ts b/x-pack/plugins/fleet/server/services/epm/packages/remove.ts index ca84980107fe3..2e879be20c18b 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/remove.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/remove.ts @@ -66,7 +66,6 @@ export async function removeInstallation(options: { deletePackageCache({ name: pkgName, version: pkgVersion, - installSource: installation.install_source, }); // successful delete's in SO client return {}. return something more useful diff --git a/x-pack/plugins/fleet/server/services/epm/registry/index.ts b/x-pack/plugins/fleet/server/services/epm/registry/index.ts index 2d496055df78a..d8368f2a46d19 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/index.ts @@ -128,11 +128,10 @@ export async function fetchCategories(params?: CategoriesParams): Promise { const installSource = 'registry'; - let paths = getArchiveFilelist({ name, version, installSource }); + let paths = getArchiveFilelist({ name, version }); if (!paths || paths.length === 0) { const { archiveBuffer, archivePath } = await fetchArchiveBuffer(name, version); paths = await unpackBufferToCache({ @@ -172,7 +171,7 @@ export async function ensureCachedArchiveInfo( version: string, installSource: InstallSource = 'registry' ) { - const paths = getArchiveFilelist({ name, version, installSource }); + const paths = getArchiveFilelist({ name, version }); if (!paths || paths.length === 0) { if (installSource === 'registry') { await getRegistryPackage(name, version); diff --git a/x-pack/plugins/infra/common/http_api/log_entries/entries.ts b/x-pack/plugins/infra/common/http_api/log_entries/entries.ts index 48790c3faca52..5f35eb89774fa 100644 --- a/x-pack/plugins/infra/common/http_api/log_entries/entries.ts +++ b/x-pack/plugins/infra/common/http_api/log_entries/entries.ts @@ -7,6 +7,7 @@ import * as rt from 'io-ts'; import { jsonArrayRT } from '../../typed_json'; import { logEntriesCursorRT } from './common'; +import { logSourceColumnConfigurationRT } from '../log_sources'; export const LOG_ENTRIES_PATH = '/api/log_entries/entries'; @@ -19,6 +20,7 @@ export const logEntriesBaseRequestRT = rt.intersection([ rt.partial({ query: rt.union([rt.string, rt.null]), size: rt.number, + columns: rt.array(logSourceColumnConfigurationRT), }), ]); diff --git a/x-pack/plugins/infra/common/http_api/log_sources/log_source_configuration.ts b/x-pack/plugins/infra/common/http_api/log_sources/log_source_configuration.ts index 3fc42b661ddab..7581e29692356 100644 --- a/x-pack/plugins/infra/common/http_api/log_sources/log_source_configuration.ts +++ b/x-pack/plugins/infra/common/http_api/log_sources/log_source_configuration.ts @@ -48,7 +48,7 @@ const logSourceFieldColumnConfigurationRT = rt.strict({ ]), }); -const logSourceColumnConfigurationRT = rt.union([ +export const logSourceColumnConfigurationRT = rt.union([ logSourceTimestampColumnConfigurationRT, logSourceMessageColumnConfigurationRT, logSourceFieldColumnConfigurationRT, diff --git a/x-pack/plugins/infra/public/components/log_stream/README.md b/x-pack/plugins/infra/public/components/log_stream/README.md index 59b3edfab736c..514ffbccbff28 100644 --- a/x-pack/plugins/infra/public/components/log_stream/README.md +++ b/x-pack/plugins/infra/public/components/log_stream/README.md @@ -68,6 +68,36 @@ By default the `` uses the `"default"` source confiuration, but if ``` +### Custom columns + +It is possible to change what columns are loaded without creating a whole new source configuration. To do so the component supports the `columns` prop. The default configuration can be replicated as follows. + +```tsx + +``` + +There are three column types: + + + + + +
`type: "timestamp"` + The configured timestamp field. Defaults to `@timestamp`. +
`type: "message"` + The value of the `message` field if it exists. If it doesn't, the component will try to recompose the original log line using values of other fields. +
`type: "field"` + A specific field specified in the `field` property. +
+ ### Considerations As mentioned in the prerequisites, the component relies on `kibana-react` to access kibana's core services. If this is not the case the component will throw an exception when rendering. We advise to use an `` in your component hierarchy to catch this error if necessary. diff --git a/x-pack/plugins/infra/public/components/log_stream/index.tsx b/x-pack/plugins/infra/public/components/log_stream/index.tsx index 43d84497af9e9..c4e6bbe094642 100644 --- a/x-pack/plugins/infra/public/components/log_stream/index.tsx +++ b/x-pack/plugins/infra/public/components/log_stream/index.tsx @@ -11,13 +11,18 @@ import { euiStyled } from '../../../../observability/public'; import { LogEntriesCursor } from '../../../common/http_api'; import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; -import { useLogSource } from '../../containers/logs/log_source'; +import { LogSourceConfigurationProperties, useLogSource } from '../../containers/logs/log_source'; import { useLogStream } from '../../containers/logs/log_stream'; import { ScrollableLogTextStreamView } from '../logging/log_text_stream'; const PAGE_THRESHOLD = 2; +type LogColumnDefinition = + | { type: 'timestamp' } + | { type: 'message' } + | { type: 'field'; field: string }; + export interface LogStreamProps { sourceId?: string; startTimestamp: number; @@ -26,6 +31,7 @@ export interface LogStreamProps { center?: LogEntriesCursor; highlight?: string; height?: string | number; + columns?: LogColumnDefinition[]; } export const LogStream: React.FC = ({ @@ -36,7 +42,13 @@ export const LogStream: React.FC = ({ center, highlight, height = '400px', + columns, }) => { + const customColumns = useMemo( + () => (columns ? convertLogColumnDefinitionToLogSourceColumnDefinition(columns) : undefined), + [columns] + ); + // source boilerplate const { services } = useKibana(); if (!services?.http?.fetch) { @@ -74,6 +86,7 @@ Read more at https://github.com/elastic/kibana/blob/master/src/plugins/kibana_re endTimestamp, query, center, + columns: customColumns, }); // Derived state @@ -83,8 +96,8 @@ Read more at https://github.com/elastic/kibana/blob/master/src/plugins/kibana_re const isLoadingMore = pageLoadingState === 'loading'; const columnConfigurations = useMemo(() => { - return sourceConfiguration ? sourceConfiguration.configuration.logColumns : []; - }, [sourceConfiguration]); + return sourceConfiguration ? customColumns ?? sourceConfiguration.configuration.logColumns : []; + }, [sourceConfiguration, customColumns]); const streamItems = useMemo( () => @@ -134,7 +147,7 @@ Read more at https://github.com/elastic/kibana/blob/master/src/plugins/kibana_re columnConfigurations={columnConfigurations} items={streamItems} scale="medium" - wrap={false} + wrap={true} isReloading={isReloading} isLoadingMore={isLoadingMore} hasMoreBeforeStart={hasMoreBefore} @@ -163,6 +176,21 @@ const LogStreamContent = euiStyled.div<{ height: string }>` height: ${(props) => props.height}; `; +function convertLogColumnDefinitionToLogSourceColumnDefinition( + columns: LogColumnDefinition[] +): LogSourceConfigurationProperties['logColumns'] { + return columns.map((column) => { + switch (column.type) { + case 'timestamp': + return { timestampColumn: { id: '___#timestamp' } }; + case 'message': + return { messageColumn: { id: '___#message' } }; + case 'field': + return { fieldColumn: { id: `___#${column.field}`, field: column.field } }; + } + }); +} + // Allow for lazy loading // eslint-disable-next-line import/no-default-export export default LogStream; diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts b/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts index 566edcce91318..b0b09c76f4d85 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts @@ -12,6 +12,7 @@ import { fetchLogEntries } from '../log_entries/api/fetch_log_entries'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { LogEntry, LogEntriesCursor } from '../../../../common/http_api'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; +import { LogSourceConfigurationProperties } from '../log_source'; interface LogStreamProps { sourceId: string; @@ -19,6 +20,7 @@ interface LogStreamProps { endTimestamp: number; query?: string; center?: LogEntriesCursor; + columns?: LogSourceConfigurationProperties['logColumns']; } interface LogStreamState { @@ -60,6 +62,7 @@ export function useLogStream({ endTimestamp, query, center, + columns, }: LogStreamProps): LogStreamReturn { const { services } = useKibanaContextForPlugin(); const [state, setState] = useSetState(INITIAL_STATE); @@ -100,6 +103,7 @@ export function useLogStream({ startTimestamp, endTimestamp, query: parsedQuery, + columns, ...fetchPosition, }, services.http.fetch diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts index 1cf0afd50b80c..e10eb1d7e8aad 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts @@ -15,6 +15,7 @@ import { LogEntriesItem, LogEntriesCursor, LogColumn, + LogEntriesRequest, } from '../../../../common/http_api'; import { InfraSourceConfiguration, @@ -73,7 +74,8 @@ export class InfraLogEntriesDomain { public async getLogEntriesAround( requestContext: RequestHandlerContext, sourceId: string, - params: LogEntriesAroundParams + params: LogEntriesAroundParams, + columnOverrides?: LogEntriesRequest['columns'] ): Promise<{ entries: LogEntry[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }> { const { startTimestamp, endTimestamp, center, query, size, highlightTerm } = params; @@ -97,7 +99,8 @@ export class InfraLogEntriesDomain { cursor: { before: center }, size: Math.floor(halfSize), highlightTerm, - } + }, + columnOverrides ); /* @@ -131,13 +134,16 @@ export class InfraLogEntriesDomain { public async getLogEntries( requestContext: RequestHandlerContext, sourceId: string, - params: LogEntriesParams + params: LogEntriesParams, + columnOverrides?: LogEntriesRequest['columns'] ): Promise<{ entries: LogEntry[]; hasMoreBefore?: boolean; hasMoreAfter?: boolean }> { const { configuration } = await this.libs.sources.getSourceConfiguration( requestContext.core.savedObjects.client, sourceId ); + const columnDefinitions = columnOverrides ?? configuration.logColumns; + const messageFormattingRules = compileFormattingRules( getBuiltinRules(configuration.fields.message) ); @@ -155,7 +161,7 @@ export class InfraLogEntriesDomain { return { id: doc.id, cursor: doc.cursor, - columns: configuration.logColumns.map( + columns: columnDefinitions.map( (column): LogColumn => { if ('timestampColumn' in column) { return { diff --git a/x-pack/plugins/infra/server/routes/log_entries/entries.ts b/x-pack/plugins/infra/server/routes/log_entries/entries.ts index 2baf3fd7aa990..67083ee9d6c0d 100644 --- a/x-pack/plugins/infra/server/routes/log_entries/entries.ts +++ b/x-pack/plugins/infra/server/routes/log_entries/entries.ts @@ -31,6 +31,7 @@ export const initLogEntriesRoute = ({ framework, logEntries }: InfraBackendLibs) sourceId, query, size, + columns, } = payload; let entries; @@ -47,7 +48,8 @@ export const initLogEntriesRoute = ({ framework, logEntries }: InfraBackendLibs) query: parseFilterQuery(query), center: payload.center, size, - } + }, + columns )); } else { let cursor: LogEntriesParams['cursor']; @@ -66,7 +68,8 @@ export const initLogEntriesRoute = ({ framework, logEntries }: InfraBackendLibs) query: parseFilterQuery(query), cursor, size, - } + }, + columns )); } diff --git a/x-pack/plugins/security_solution/cypress/integration/value_lists.spec.ts b/x-pack/plugins/security_solution/cypress/integration/value_lists.spec.ts index 403538a37f523..b97e1a874da7a 100644 --- a/x-pack/plugins/security_solution/cypress/integration/value_lists.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/value_lists.spec.ts @@ -148,7 +148,7 @@ describe('value lists', () => { it('deletes a "ip_range" from an uploaded file', () => { const listName = 'cidr_list.txt'; - importValueList(listName, 'ip_range'); + importValueList(listName, 'ip_range', ['192.168.100.0']); openValueListsModal(); deleteValueListsFile(listName); cy.get(VALUE_LISTS_TABLE) @@ -209,7 +209,7 @@ describe('value lists', () => { it('exports a "ip_range" list from an uploaded file', () => { const listName = 'cidr_list.txt'; - importValueList(listName, 'ip_range'); + importValueList(listName, 'ip_range', ['192.168.100.0']); openValueListsModal(); exportValueList(); cy.wait('@exportList').then((xhr) => { diff --git a/x-pack/plugins/security_solution/cypress/tasks/lists.ts b/x-pack/plugins/security_solution/cypress/tasks/lists.ts index 1ecfeaad06d46..2ca4fa21e6650 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/lists.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/lists.ts @@ -77,27 +77,104 @@ export const deleteValueList = (list: string): Cypress.Chainable => { - return cy.fixture(file).then((data) => { - return cy.request({ - method: 'POST', - url: `api/lists/items/_import?type=${type}`, - encoding: 'binary', - headers: { - 'kbn-xsrf': 'upload-value-lists', - 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryJLrRH89J8QVArZyv', - }, - body: `------WebKitFormBoundaryJLrRH89J8QVArZyv\nContent-Disposition: form-data; name="file"; filename="${file}"\n\n${data}`, - }); + const removedEmptyLines = data + .split('\n') + .filter((line) => line.trim() !== '') + .join('\n'); + + return cy.request({ + method: 'POST', + url: `api/lists/items/_import?type=${type}`, + encoding: 'binary', + headers: { + 'kbn-xsrf': 'upload-value-lists', + 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryJLrRH89J8QVArZyv', + }, + body: `------WebKitFormBoundaryJLrRH89J8QVArZyv\nContent-Disposition: form-data; name="file"; filename="${file}"\n\n${removedEmptyLines}`, + }); +}; + +/** + * Checks a single value list file against a data set to ensure it has been uploaded. + * + * You can optionally pass in an array of test suggestions which will be useful for if you are + * using a range such as a CIDR range and need to ensure that test range has been added to the + * list but you cannot run an explicit test against that range. + * + * This also will remove any upload data such as empty strings that can happen from the fixture + * due to extra lines being added from formatters. + * @param file The file that was imported + * @param data The contents to check unless testSuggestions is given. + * @param type The type of the file import such as ip/keyword/text etc... + * @param testSuggestions The type of test to use rather than the fixture file which is useful for ranges + * Ref: https://www.elastic.co/guide/en/security/current/lists-api-import-list-items.html + */ +export const checkListItemData = ( + file: string, + data: string, + testSuggestions: string[] | undefined +): Cypress.Chainable> => { + const importCheckLines = + testSuggestions == null + ? data.split('\n').filter((line) => line.trim() !== '') + : testSuggestions; + + return cy.wrap(importCheckLines).each((line) => { + return cy + .request({ + retryOnStatusCodeFailure: true, + method: 'GET', + url: `api/lists/items?list_id=${file}&value=${line}`, + }) + .then((resp) => { + expect(resp.status).to.eq(200); + }); }); }; +/** + * Imports a single value list file this using Cypress Request and lists REST API. After it + * imports the data, it will re-check and ensure that the data is there before continuing to + * get us more deterministic. + * + * You can optionally pass in an array of test suggestions which will be useful for if you are + * using a range such as a CIDR range and need to ensure that test range has been added to the + * list but you cannot run an explicit test against that range. + * + * This also will remove any upload data such as empty strings that can happen from the fixture + * due to extra lines being added from formatters. + * @param file The file to import + * @param type The type of the file import such as ip/keyword/text etc... + * @param testSuggestions The type of test to use rather than the fixture file which is useful for ranges + * Ref: https://www.elastic.co/guide/en/security/current/lists-api-import-list-items.html + */ +export const importValueList = ( + file: string, + type: string, + testSuggestions: string[] | undefined = undefined +): Cypress.Chainable> => { + return cy + .fixture(file) + .then((data) => uploadListItemData(file, type, data)) + .fixture(file) + .then((data) => checkListItemData(file, data, testSuggestions)); +}; + /** * If you are on the value lists from the UI, this will loop over all the HTML elements * that have action-delete-value-list-${list_name} and delete all of those value lists diff --git a/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx b/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx index 18745897c594f..d8b80c07f44d8 100644 --- a/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx +++ b/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx @@ -170,8 +170,7 @@ const EndpointsEmptyState = React.memo<{ }, { title: i18n.translate('xpack.securitySolution.endpoint.list.stepTwoTitle', { - defaultMessage: - 'Enroll your agents enabled with Endpoint Security through Ingest Manager', + defaultMessage: 'Enroll your agents enabled with Endpoint Security through Fleet', }), status: actionDisabled ? 'disabled' : '', children: ( diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 04b0ef045fffe..91acad0942739 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -865,7 +865,6 @@ "data.functions.indexPatternLoad.id.help": "読み込むインデックスパターンID", "data.indexPatterns.ensureDefaultIndexPattern.bannerLabel": "Kibanaでデータの可視化と閲覧を行うには、Elasticsearchからデータを取得するためのインデックスパターンの作成が必要です。", "data.indexPatterns.fetchFieldErrorTitle": "インデックスパターンのフィールド取得中にエラーが発生 {title} (ID: {id})", - "data.indexPatterns.fetchFieldSaveErrorTitle": "インデックスパターンのフィールド取得後の保存中にエラーが発生 {title}(ID: {id})", "data.indexPatterns.unableWriteLabel": "インデックスパターンを書き込めません!このインデックスパターンへの最新の変更を取得するには、ページを更新してください。", "data.noDataPopover.content": "この時間範囲にはデータが含まれていません表示するフィールドを増やし、グラフを作成するには、時間範囲を広げるか、調整してください。", "data.noDataPopover.dismissAction": "今後表示しない", @@ -2512,11 +2511,6 @@ "indexPatternManagement.editIndexPattern.list.defaultIndexPatternListName": "デフォルト", "indexPatternManagement.editIndexPattern.mappingConflictHeader": "マッピングの矛盾", "indexPatternManagement.editIndexPattern.mappingConflictLabel": "{conflictFieldsLength, plural, one {フィールド} other {フィールド}}が、このパターンと一致するインデックスの間で異なるタイプ(文字列、整数など)に定義されています。これらの矛盾したフィールドはKibanaの一部で使用できますが、Kibanaがタイプを把握しなければならない機能には使用できません。この問題を修正するにはデータのレンダリングが必要です。", - "indexPatternManagement.editIndexPattern.refreshAria": "フィールドリストを再度読み込みます。", - "indexPatternManagement.editIndexPattern.refreshButton": "更新", - "indexPatternManagement.editIndexPattern.refreshHeader": "フィールドリストを更新しますか?", - "indexPatternManagement.editIndexPattern.refreshLabel": "この操作は各フィールドの使用頻度をリセットします。", - "indexPatternManagement.editIndexPattern.refreshTooltip": "フィールドリストを更新します。", "indexPatternManagement.editIndexPattern.removeAria": "インデックスパターンを削除します。", "indexPatternManagement.editIndexPattern.removeTooltip": "インデックスパターンを削除します。", "indexPatternManagement.editIndexPattern.scripted.addFieldButton": "スクリプトフィールドを追加", @@ -4034,7 +4028,6 @@ "visTypeTimeseries.movingAverage.windowSizeHint": "ウィンドウは、必ず、期間のサイズの 2 倍以上でなければなりません", "visTypeTimeseries.movingAverage.windowSizeLabel": "ウィンドウサイズ", "visTypeTimeseries.noButtonLabel": "いいえ", - "visTypeTimeseries.noDataDescription": "選択されたメトリックに表示するデータがありません", "visTypeTimeseries.percentile.aggregationLabel": "集約", "visTypeTimeseries.percentile.fieldLabel": "フィールド", "visTypeTimeseries.percentile.fillToLabel": "次の基準に合わせる:", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index d1ab2518c9ecd..adc448ba703ee 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -865,7 +865,6 @@ "data.functions.indexPatternLoad.id.help": "要加载的索引模式 id", "data.indexPatterns.ensureDefaultIndexPattern.bannerLabel": "要在 Kibana 中可视化和浏览数据,必须创建索引模式,以从 Elasticsearch 中检索数据。", "data.indexPatterns.fetchFieldErrorTitle": "提取索引模式 {title} (ID: {id}) 的字段时出错", - "data.indexPatterns.fetchFieldSaveErrorTitle": "在提取索引模式 {title}(ID:{id})的字段后保存出错", "data.indexPatterns.unableWriteLabel": "无法写入索引模式!请刷新页面以获取此索引模式的最新更改。", "data.noDataPopover.content": "此时间范围不包含任何数据。增大或调整时间范围,以查看更多的字段并创建图表。", "data.noDataPopover.dismissAction": "不再显示", @@ -2513,11 +2512,6 @@ "indexPatternManagement.editIndexPattern.list.defaultIndexPatternListName": "默认值", "indexPatternManagement.editIndexPattern.mappingConflictHeader": "映射冲突", "indexPatternManagement.editIndexPattern.mappingConflictLabel": "{conflictFieldsLength, plural, one {一个字段} other {# 个字段}}已在匹配此模式的各个索引中定义为多个类型(字符串、整数等)。您也许仍能够在 Kibana 的各个部分中使用这些冲突类型,但它们将无法用于需要 Kibana 知道其类型的函数。要解决此问题,需要重新索引您的数据。", - "indexPatternManagement.editIndexPattern.refreshAria": "重新加载字段列表。", - "indexPatternManagement.editIndexPattern.refreshButton": "刷新", - "indexPatternManagement.editIndexPattern.refreshHeader": "刷新字段列表?", - "indexPatternManagement.editIndexPattern.refreshLabel": "此操作重置每个字段的常见度计数器。", - "indexPatternManagement.editIndexPattern.refreshTooltip": "刷新字段列表。", "indexPatternManagement.editIndexPattern.removeAria": "移除索引模式。", "indexPatternManagement.editIndexPattern.removeTooltip": "移除索引模式。", "indexPatternManagement.editIndexPattern.scripted.addFieldButton": "添加脚本字段", @@ -4035,7 +4029,6 @@ "visTypeTimeseries.movingAverage.windowSizeHint": "窗口必须始终至少是期间大小的两倍", "visTypeTimeseries.movingAverage.windowSizeLabel": "窗口大小", "visTypeTimeseries.noButtonLabel": "否", - "visTypeTimeseries.noDataDescription": "所选指标没有可显示的数据", "visTypeTimeseries.percentile.aggregationLabel": "聚合", "visTypeTimeseries.percentile.fieldLabel": "字段", "visTypeTimeseries.percentile.fillToLabel": "填充到:", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx index 3a1f9872a96a8..53121e5249abf 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx @@ -15,6 +15,7 @@ import { EuiLoadingSpinner, EuiFlexGroup, EuiFlexItem, + EuiErrorBoundary, EuiTitle, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -179,26 +180,28 @@ export const ActionConnectorForm = ({ - - - - - - } - > - - + + + + + + + } + > + + + ) : null} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx index 5f1798d101d94..10c8498b181dc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx @@ -24,6 +24,7 @@ import { EuiSuperSelect, EuiLoadingSpinner, EuiBadge, + EuiErrorBoundary, } from '@elastic/eui'; import { AlertActionParam, ResolvedActionGroup } from '../../../../../alerts/common'; import { @@ -254,28 +255,30 @@ export const ActionTypeForm = ({ {ParamsFieldsComponent ? ( - - - - - - } - > - - + + + + + + + } + > + + + ) : null} ) : ( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/test_connector_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/test_connector_form.tsx index 315254a003e89..4d9a327f97b05 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/test_connector_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/test_connector_form.tsx @@ -14,6 +14,7 @@ import { EuiDescriptionList, EuiCallOut, EuiSpacer, + EuiErrorBoundary, } from '@elastic/eui'; import { Option, map, getOrElse } from 'fp-ts/lib/Option'; import { pipe } from 'fp-ts/lib/pipeable'; @@ -53,32 +54,34 @@ export const TestConnectorForm = ({ { title: 'Create an action', children: ParamsFieldsComponent ? ( - - - - - - } - > - - setActionParams({ - ...actionParams, - [field]: value, - }) + + + + + + } - messageVariables={[]} - docLinks={docLinks} - http={http} - toastNotifications={toastNotifications} - actionConnector={connector} - /> - + > + + setActionParams({ + ...actionParams, + [field]: value, + }) + } + messageVariables={[]} + docLinks={docLinks} + http={http} + toastNotifications={toastNotifications} + actionConnector={connector} + /> + + ) : (

This Connector does not require any Action Parameter.

diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx index b06fb3c39ea45..7fd5bdc8d8707 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx @@ -30,6 +30,7 @@ import { EuiLink, EuiText, EuiNotificationBadge, + EuiErrorBoundary, } from '@elastic/eui'; import { some, filter, map, fold } from 'fp-ts/lib/Option'; import { pipe } from 'fp-ts/lib/pipeable'; @@ -461,19 +462,21 @@ export const AlertForm = ({ defaultActionGroupId && alert.alertTypeId && alertTypesIndex?.has(alert.alertTypeId) ? ( - }> - - + + }> + + + ) : null} {canShowActions && defaultActionGroupId && diff --git a/x-pack/plugins/uptime/common/runtime_types/monitor/details.ts b/x-pack/plugins/uptime/common/runtime_types/monitor/details.ts index c622d4f19bade..89eea46edb112 100644 --- a/x-pack/plugins/uptime/common/runtime_types/monitor/details.ts +++ b/x-pack/plugins/uptime/common/runtime_types/monitor/details.ts @@ -7,17 +7,24 @@ import * as t from 'io-ts'; // IO type for validation -export const MonitorErrorType = t.partial({ - code: t.number, - message: t.string, - type: t.string, -}); +export const PingErrorType = t.intersection([ + t.partial({ + code: t.string, + id: t.string, + stack_trace: t.string, + type: t.string, + }), + t.type({ + // this is _always_ on the error field + message: t.string, + }), +]); // Typescript type for type checking -export type MonitorError = t.TypeOf; +export type PingError = t.TypeOf; export const MonitorDetailsType = t.intersection([ t.type({ monitorId: t.string }), - t.partial({ error: MonitorErrorType, timestamp: t.string, alerts: t.unknown }), + t.partial({ error: PingErrorType, timestamp: t.string, alerts: t.unknown }), ]); export type MonitorDetails = t.TypeOf; diff --git a/x-pack/plugins/uptime/common/runtime_types/ping/ping.ts b/x-pack/plugins/uptime/common/runtime_types/ping/ping.ts index 315b8f543b800..9e5cd7641b65d 100644 --- a/x-pack/plugins/uptime/common/runtime_types/ping/ping.ts +++ b/x-pack/plugins/uptime/common/runtime_types/ping/ping.ts @@ -6,6 +6,7 @@ import * as t from 'io-ts'; import { DateRangeType } from '../common'; +import { PingErrorType } from '../monitor'; export const HttpResponseBodyType = t.partial({ bytes: t.number, @@ -116,18 +117,7 @@ export const PingType = t.intersection([ ecs: t.partial({ version: t.string, }), - error: t.intersection([ - t.partial({ - code: t.string, - id: t.string, - stack_trace: t.string, - type: t.string, - }), - t.type({ - // this is _always_ on the error field - message: t.string, - }), - ]), + error: PingErrorType, http: t.partial({ request: t.partial({ body: t.partial({ diff --git a/x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap index f6cc130b39fc1..89433f8bc57c4 100644 --- a/x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap @@ -1823,7 +1823,9 @@ exports[`EmptyState component renders error message when an error occurs 1`] = `
-

+

There was an error fetching your data.

diff --git a/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx index 165b123d8884d..f2d4de9f8be6e 100644 --- a/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx +++ b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx @@ -47,7 +47,9 @@ export const EmptyStateError = ({ errors }: EmptyStateErrorProps) => { {!unauthorized && errors.map((error: IHttpFetchError) => ( -

{error.body.message || error.message}

+

+ {error.body.message || error.message} +

))}
} diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx index e0b4c0dbd78f7..8dd5ad48bc9d4 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx @@ -9,11 +9,11 @@ import React from 'react'; import moment from 'moment'; import { BrowserRouter as Router } from 'react-router-dom'; import { MostRecentError } from '../most_recent_error'; -import { MonitorDetails, MonitorError } from '../../../../../../common/runtime_types'; +import { MonitorDetails, PingError } from '../../../../../../common/runtime_types'; describe('MostRecentError component', () => { let monitorDetails: MonitorDetails; - let monitorError: MonitorError; + let monitorError: PingError; beforeAll(() => { moment.prototype.fromNow = jest.fn(() => '5 days ago'); diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/most_recent_error.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/most_recent_error.tsx index 62f2f811aad98..e7d9885680340 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/most_recent_error.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/most_recent_error.tsx @@ -10,13 +10,13 @@ import { i18n } from '@kbn/i18n'; import { MonitorPageLink } from '../../../common/monitor_page_link'; import { useGetUrlParams } from '../../../../hooks'; import { stringifyUrlParams } from '../../../../lib/helper/stringify_url_params'; -import { MonitorError } from '../../../../../common/runtime_types'; +import { PingError } from '../../../../../common/runtime_types'; interface MostRecentErrorProps { /** * error returned from API for monitor details */ - error: MonitorError | undefined; + error: PingError | undefined; /** * monitorId to be used for link to detail page diff --git a/x-pack/plugins/uptime/public/state/actions/monitor.ts b/x-pack/plugins/uptime/public/state/actions/monitor.ts index a48b68db8126d..ff3f3cca33d09 100644 --- a/x-pack/plugins/uptime/public/state/actions/monitor.ts +++ b/x-pack/plugins/uptime/public/state/actions/monitor.ts @@ -6,7 +6,7 @@ import { createAction } from 'redux-actions'; import { MonitorDetailsActionPayload } from './types'; -import { MonitorError } from '../../../common/runtime_types'; +import { PingError } from '../../../common/runtime_types'; import { MonitorLocations } from '../../../common/runtime_types'; import { QueryParams } from './types'; import { createAsyncAction } from './utils'; @@ -17,7 +17,7 @@ export interface MonitorLocationsPayload extends QueryParams { export interface MonitorDetailsState { monitorId: string; - error: MonitorError; + error: PingError; } export const getMonitorDetailsAction = createAsyncAction< diff --git a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index cd98ba1600d34..92965515f0876 100644 --- a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -10,18 +10,16 @@ import { SavedObjectsClientContract, ISavedObjectsRepository, IScopedClusterClient, - ElasticsearchClient, } from 'src/core/server'; import { UMKibanaRoute } from '../../../rest_api'; import { PluginSetupContract } from '../../../../../features/server'; -import { DynamicSettings } from '../../../../common/runtime_types'; import { MlPluginSetup as MlSetup } from '../../../../../ml/server'; +import { UptimeESClient } from '../../lib'; export type UMElasticsearchQueryFn = ( params: { - callES: ElasticsearchClient; + uptimeEsClient: UptimeESClient; esClient?: IScopedClusterClient; - dynamicSettings: DynamicSettings; } & P ) => Promise; diff --git a/x-pack/plugins/uptime/server/lib/adapters/telemetry/kibana_telemetry_adapter.ts b/x-pack/plugins/uptime/server/lib/adapters/telemetry/kibana_telemetry_adapter.ts index 2126b484b1cfd..3f6c3da2d6af0 100644 --- a/x-pack/plugins/uptime/server/lib/adapters/telemetry/kibana_telemetry_adapter.ts +++ b/x-pack/plugins/uptime/server/lib/adapters/telemetry/kibana_telemetry_adapter.ts @@ -14,6 +14,7 @@ import { import { CollectorFetchContext, UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { PageViewParams, UptimeTelemetry, Usage } from './types'; import { savedObjectsAdapter } from '../../saved_objects'; +import { UptimeESClient } from '../../lib'; interface UptimeTelemetryCollector { [key: number]: UptimeTelemetry; @@ -131,7 +132,7 @@ export class KibanaTelemetryAdapter { } public static async countNoOfUniqueMonitorAndLocations( - callCluster: ILegacyScopedClusterClient['callAsCurrentUser'] | ElasticsearchClient, + callCluster: ILegacyScopedClusterClient['callAsCurrentUser'] | UptimeESClient, savedObjectsClient: ISavedObjectsRepository | SavedObjectsClientContract ) { const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings(savedObjectsClient); diff --git a/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts b/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts index 4f795e2aaf29e..4f9fefa4188e5 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts @@ -96,13 +96,6 @@ describe('status check alert', () => { expect(mockGetter.mock.calls[0]).toMatchInlineSnapshot(` Array [ Object { - "callES": [MockFunction], - "dynamicSettings": Object { - "certAgeThreshold": 730, - "certExpirationThreshold": 30, - "defaultConnectors": Array [], - "heartbeatIndices": "heartbeat-8*", - }, "filters": undefined, "locations": Array [], "numTimes": 5, @@ -110,6 +103,12 @@ describe('status check alert', () => { "from": "now-15m", "to": "now", }, + "uptimeEsClient": Object { + "baseESClient": [MockFunction], + "count": [Function], + "getSavedObjectsClient": [Function], + "search": [Function], + }, }, ] `); @@ -152,13 +151,6 @@ describe('status check alert', () => { expect(mockGetter.mock.calls[0]).toMatchInlineSnapshot(` Array [ Object { - "callES": [MockFunction], - "dynamicSettings": Object { - "certAgeThreshold": 730, - "certExpirationThreshold": 30, - "defaultConnectors": Array [], - "heartbeatIndices": "heartbeat-8*", - }, "filters": undefined, "locations": Array [], "numTimes": 5, @@ -166,6 +158,12 @@ describe('status check alert', () => { "from": "now-15m", "to": "now", }, + "uptimeEsClient": Object { + "baseESClient": [MockFunction], + "count": [Function], + "getSavedObjectsClient": [Function], + "search": [Function], + }, }, ] `); @@ -333,13 +331,6 @@ describe('status check alert', () => { expect(mockGetter.mock.calls[0]).toMatchInlineSnapshot(` Array [ Object { - "callES": [MockFunction], - "dynamicSettings": Object { - "certAgeThreshold": 730, - "certExpirationThreshold": 30, - "defaultConnectors": Array [], - "heartbeatIndices": "heartbeat-8*", - }, "filters": Object { "bool": Object { "filter": Array [ @@ -506,6 +497,12 @@ describe('status check alert', () => { "from": "now-15m", "to": "now", }, + "uptimeEsClient": Object { + "baseESClient": [MockFunction], + "count": [Function], + "getSavedObjectsClient": [Function], + "search": [Function], + }, }, ] `); @@ -571,13 +568,6 @@ describe('status check alert', () => { expect(mockGetter.mock.calls[0]).toMatchInlineSnapshot(` Array [ Object { - "callES": [MockFunction], - "dynamicSettings": Object { - "certAgeThreshold": 730, - "certExpirationThreshold": 30, - "defaultConnectors": Array [], - "heartbeatIndices": "heartbeat-8*", - }, "filters": Object { "bool": Object { "filter": Array [ @@ -614,6 +604,12 @@ describe('status check alert', () => { "from": "now-30h", "to": "now", }, + "uptimeEsClient": Object { + "baseESClient": [MockFunction], + "count": [Function], + "getSavedObjectsClient": [Function], + "search": [Function], + }, }, ] `); @@ -758,17 +754,16 @@ describe('status check alert', () => { expect(mockAvailability.mock.calls[0]).toMatchInlineSnapshot(` Array [ Object { - "callES": [MockFunction], - "dynamicSettings": Object { - "certAgeThreshold": 730, - "certExpirationThreshold": 30, - "defaultConnectors": Array [], - "heartbeatIndices": "heartbeat-8*", - }, "filters": "{\\"bool\\":{\\"filter\\":[{\\"bool\\":{\\"should\\":[{\\"bool\\":{\\"should\\":[{\\"match\\":{\\"url.port\\":12349}}],\\"minimum_should_match\\":1}},{\\"bool\\":{\\"should\\":[{\\"bool\\":{\\"should\\":[{\\"match\\":{\\"url.port\\":5601}}],\\"minimum_should_match\\":1}},{\\"bool\\":{\\"should\\":[{\\"match\\":{\\"url.port\\":443}}],\\"minimum_should_match\\":1}}],\\"minimum_should_match\\":1}}],\\"minimum_should_match\\":1}},{\\"bool\\":{\\"filter\\":[{\\"bool\\":{\\"should\\":[{\\"match\\":{\\"observer.geo.name\\":\\"harrisburg\\"}}],\\"minimum_should_match\\":1}},{\\"bool\\":{\\"filter\\":[{\\"bool\\":{\\"should\\":[{\\"match\\":{\\"monitor.type\\":\\"http\\"}}],\\"minimum_should_match\\":1}},{\\"bool\\":{\\"should\\":[{\\"bool\\":{\\"should\\":[{\\"match\\":{\\"tags\\":\\"unsecured\\"}}],\\"minimum_should_match\\":1}},{\\"bool\\":{\\"should\\":[{\\"bool\\":{\\"should\\":[{\\"match\\":{\\"tags\\":\\"containers\\"}}],\\"minimum_should_match\\":1}},{\\"bool\\":{\\"should\\":[{\\"match_phrase\\":{\\"tags\\":\\"org:google\\"}}],\\"minimum_should_match\\":1}}],\\"minimum_should_match\\":1}}],\\"minimum_should_match\\":1}}]}}]}}]}}", "range": 35, "rangeUnit": "d", "threshold": "99.34", + "uptimeEsClient": Object { + "baseESClient": [MockFunction], + "count": [Function], + "getSavedObjectsClient": [Function], + "search": [Function], + }, }, ] `); @@ -813,17 +808,16 @@ describe('status check alert', () => { expect(mockAvailability.mock.calls[0]).toMatchInlineSnapshot(` Array [ Object { - "callES": [MockFunction], - "dynamicSettings": Object { - "certAgeThreshold": 730, - "certExpirationThreshold": 30, - "defaultConnectors": Array [], - "heartbeatIndices": "heartbeat-8*", - }, "filters": "{\\"bool\\":{\\"should\\":[{\\"exists\\":{\\"field\\":\\"ur.port\\"}}],\\"minimum_should_match\\":1}}", "range": 23, "rangeUnit": "w", "threshold": "90", + "uptimeEsClient": Object { + "baseESClient": [MockFunction], + "count": [Function], + "getSavedObjectsClient": [Function], + "search": [Function], + }, }, ] `); @@ -857,17 +851,16 @@ describe('status check alert', () => { expect(mockAvailability.mock.calls[0]).toMatchInlineSnapshot(` Array [ Object { - "callES": [MockFunction], - "dynamicSettings": Object { - "certAgeThreshold": 730, - "certExpirationThreshold": 30, - "defaultConnectors": Array [], - "heartbeatIndices": "heartbeat-8*", - }, "filters": undefined, "range": 23, "rangeUnit": "w", "threshold": "90", + "uptimeEsClient": Object { + "baseESClient": [MockFunction], + "count": [Function], + "getSavedObjectsClient": [Function], + "search": [Function], + }, }, ] `); diff --git a/x-pack/plugins/uptime/server/lib/alerts/duration_anomaly.ts b/x-pack/plugins/uptime/server/lib/alerts/duration_anomaly.ts index d4c26fe83b5fc..022ec48bad1d9 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/duration_anomaly.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/duration_anomaly.ts @@ -82,7 +82,7 @@ export const durationAnomalyAlertFactory: UptimeAlertTypeFactory = (_server, _li context: [], state: [...durationAnomalyTranslations.actionVariables, ...commonStateTranslations], }, - async executor({ options, esClient, savedObjectsClient, dynamicSettings }) { + async executor({ options, uptimeEsClient, savedObjectsClient, dynamicSettings }) { const { services: { alertInstanceFactory }, state, @@ -96,8 +96,7 @@ export const durationAnomalyAlertFactory: UptimeAlertTypeFactory = (_server, _li if (foundAnomalies) { const monitorInfo = await getLatestMonitor({ - dynamicSettings, - callES: esClient, + uptimeEsClient, dateStart: 'now-15m', dateEnd: 'now', monitorId: params.monitorId, diff --git a/x-pack/plugins/uptime/server/lib/alerts/status_check.ts b/x-pack/plugins/uptime/server/lib/alerts/status_check.ts index 577262c231977..3e45ce302bf87 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/status_check.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/status_check.ts @@ -7,13 +7,11 @@ import { schema } from '@kbn/config-schema'; import { i18n } from '@kbn/i18n'; import Mustache from 'mustache'; -import { ElasticsearchClient } from 'kibana/server'; import { UptimeAlertTypeFactory } from './types'; import { esKuery } from '../../../../../../src/plugins/data/server'; import { JsonObject } from '../../../../../../src/plugins/kibana_utils/common'; import { StatusCheckFilters, - DynamicSettings, Ping, GetMonitorAvailabilityParams, } from '../../../common/runtime_types'; @@ -27,7 +25,7 @@ import { UNNAMED_LOCATION } from '../../../common/constants'; import { uptimeAlertWrapper } from './uptime_alert_wrapper'; import { MonitorStatusTranslations } from '../../../common/translations'; import { getUptimeIndexPattern, IndexPatternTitleAndFields } from '../requests/get_index_pattern'; -import { UMServerLibs } from '../lib'; +import { UMServerLibs, UptimeESClient } from '../lib'; const { MONITOR_STATUS } = ACTION_GROUP_DEFINITIONS; @@ -89,8 +87,7 @@ export const generateFilterDSL = async ( }; export const formatFilterString = async ( - dynamicSettings: DynamicSettings, - esClient: ElasticsearchClient, + uptimeEsClient: UptimeESClient, filters: StatusCheckFilters, search: string, libs?: UMServerLibs @@ -98,10 +95,9 @@ export const formatFilterString = async ( await generateFilterDSL( () => libs?.requests?.getIndexPattern - ? libs?.requests?.getIndexPattern({ esClient, dynamicSettings }) + ? libs?.requests?.getIndexPattern({ uptimeEsClient }) : getUptimeIndexPattern({ - esClient, - dynamicSettings, + uptimeEsClient, }), filters, search @@ -265,8 +261,8 @@ export const statusCheckAlertFactory: UptimeAlertTypeFactory = (_server, libs) = state, services: { alertInstanceFactory }, }, - esClient, dynamicSettings, + uptimeEsClient, }) { const { filters, @@ -281,13 +277,7 @@ export const statusCheckAlertFactory: UptimeAlertTypeFactory = (_server, libs) = timerange: oldVersionTimeRange, } = rawParams; - const filterString = await formatFilterString( - dynamicSettings, - esClient, - filters, - search, - libs - ); + const filterString = await formatFilterString(uptimeEsClient, filters, search, libs); const timerange = oldVersionTimeRange || { from: isAutoGenerated @@ -302,8 +292,7 @@ export const statusCheckAlertFactory: UptimeAlertTypeFactory = (_server, libs) = // after that shouldCheckStatus should be explicitly false if (!(!oldVersionTimeRange && shouldCheckStatus === false)) { downMonitorsByLocation = await libs.requests.getMonitorStatus({ - callES: esClient, - dynamicSettings, + uptimeEsClient, timerange, numTimes, locations: [], @@ -337,8 +326,7 @@ export const statusCheckAlertFactory: UptimeAlertTypeFactory = (_server, libs) = let availabilityResults: GetMonitorAvailabilityResult[] = []; if (shouldCheckAvailability) { availabilityResults = await libs.requests.getMonitorAvailability({ - callES: esClient, - dynamicSettings, + uptimeEsClient, ...availability, filters: JSON.stringify(filterString) || undefined, }); diff --git a/x-pack/plugins/uptime/server/lib/alerts/tls.ts b/x-pack/plugins/uptime/server/lib/alerts/tls.ts index 11f602d10bf51..41a5101716122 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/tls.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/tls.ts @@ -100,15 +100,14 @@ export const tlsAlertFactory: UptimeAlertTypeFactory = (_server, libs) => context: [], state: [...tlsTranslations.actionVariables, ...commonStateTranslations], }, - async executor({ options, dynamicSettings, esClient }) { + async executor({ options, dynamicSettings, uptimeEsClient }) { const { services: { alertInstanceFactory }, state, } = options; const { certs, total }: CertResult = await libs.requests.getCerts({ - callES: esClient, - dynamicSettings, + uptimeEsClient, from: DEFAULT_FROM, to: DEFAULT_TO, index: 0, diff --git a/x-pack/plugins/uptime/server/lib/alerts/uptime_alert_wrapper.ts b/x-pack/plugins/uptime/server/lib/alerts/uptime_alert_wrapper.ts index 0961eb6557891..965287ffbde8e 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/uptime_alert_wrapper.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/uptime_alert_wrapper.ts @@ -4,19 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ElasticsearchClient, SavedObjectsClientContract } from 'kibana/server'; +import { SavedObjectsClientContract } from 'kibana/server'; import { AlertExecutorOptions, AlertType, AlertTypeState } from '../../../../alerts/server'; import { savedObjectsAdapter } from '../saved_objects'; import { DynamicSettings } from '../../../common/runtime_types'; +import { createUptimeESClient, UptimeESClient } from '../lib'; export interface UptimeAlertType extends Omit { executor: ({ options, - esClient, + uptimeEsClient, dynamicSettings, }: { options: AlertExecutorOptions; - esClient: ElasticsearchClient; + uptimeEsClient: UptimeESClient; dynamicSettings: DynamicSettings; savedObjectsClient: SavedObjectsClientContract; }) => Promise; @@ -34,6 +35,8 @@ export const uptimeAlertWrapper = (uptimeAlert: UptimeAlertType) => ({ options.services.savedObjectsClient ); - return uptimeAlert.executor({ options, esClient, dynamicSettings, savedObjectsClient }); + const uptimeEsClient = createUptimeESClient({ esClient, savedObjectsClient }); + + return uptimeAlert.executor({ options, dynamicSettings, uptimeEsClient, savedObjectsClient }); }, }); diff --git a/x-pack/plugins/uptime/server/lib/lib.ts b/x-pack/plugins/uptime/server/lib/lib.ts index a7121eaec6679..39dd868462525 100644 --- a/x-pack/plugins/uptime/server/lib/lib.ts +++ b/x-pack/plugins/uptime/server/lib/lib.ts @@ -3,10 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import { ElasticsearchClient, SavedObjectsClientContract } from 'kibana/server'; import { UMBackendFrameworkAdapter } from './adapters'; import { UMLicenseCheck } from './domains'; import { UptimeRequests } from './requests'; +import { savedObjectsAdapter } from './saved_objects'; +import { ESSearchResponse } from '../../../../typings/elasticsearch'; export interface UMDomainLibs { requests: UptimeRequests; @@ -16,3 +18,58 @@ export interface UMDomainLibs { export interface UMServerLibs extends UMDomainLibs { framework: UMBackendFrameworkAdapter; } + +export type UptimeESClient = ReturnType; + +export function createUptimeESClient({ + esClient, + savedObjectsClient, +}: { + esClient: ElasticsearchClient; + savedObjectsClient: SavedObjectsClientContract; +}) { + return { + baseESClient: esClient, + async search(params: TParams): Promise<{ body: ESSearchResponse }> { + const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings( + savedObjectsClient! + ); + + let res: any; + try { + res = await esClient.search({ index: dynamicSettings!.heartbeatIndices, ...params }); + } catch (e) { + throw e; + } + return res; + }, + async count( + params: TParams + ): Promise<{ + body: { + count: number; + _shards: { + total: number; + successful: number; + skipped: number; + failed: number; + }; + }; + }> { + const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings( + savedObjectsClient! + ); + + let res: any; + try { + res = await esClient.count({ index: dynamicSettings!.heartbeatIndices, ...params }); + } catch (e) { + throw e; + } + return res; + }, + getSavedObjectsClient() { + return savedObjectsClient; + }, + }; +} diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/__snapshots__/extract_filter_aggs_results.test.ts.snap b/x-pack/plugins/uptime/server/lib/requests/__tests__/__snapshots__/extract_filter_aggs_results.test.ts.snap deleted file mode 100644 index 2f6d6e06f93e1..0000000000000 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/__snapshots__/extract_filter_aggs_results.test.ts.snap +++ /dev/null @@ -1,27 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`extractFilterAggsResults extracts the bucket values of the expected filter fields 1`] = ` -Object { - "locations": Array [ - "us-east-2", - "fairbanks", - ], - "ports": Array [ - 12349, - 80, - 5601, - 8200, - 9200, - 9292, - ], - "schemes": Array [ - "http", - "tcp", - "icmp", - ], - "tags": Array [ - "api", - "dev", - ], -} -`; diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/extract_filter_aggs_results.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/extract_filter_aggs_results.test.ts deleted file mode 100644 index 19fd0fda8d83e..0000000000000 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/extract_filter_aggs_results.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { extractFilterAggsResults } from '../get_filter_bar'; - -describe('extractFilterAggsResults', () => { - it('extracts the bucket values of the expected filter fields', () => { - expect( - extractFilterAggsResults( - { - locations: { - doc_count: 8098, - term: { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 0, - buckets: [ - { key: 'us-east-2', doc_count: 4050 }, - { key: 'fairbanks', doc_count: 4048 }, - ], - }, - }, - schemes: { - doc_count: 8098, - term: { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 0, - buckets: [ - { key: 'http', doc_count: 5055 }, - { key: 'tcp', doc_count: 2685 }, - { key: 'icmp', doc_count: 358 }, - ], - }, - }, - ports: { - doc_count: 8098, - term: { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 0, - buckets: [ - { key: 12349, doc_count: 3571 }, - { key: 80, doc_count: 2985 }, - { key: 5601, doc_count: 358 }, - { key: 8200, doc_count: 358 }, - { key: 9200, doc_count: 358 }, - { key: 9292, doc_count: 110 }, - ], - }, - }, - tags: { - doc_count: 8098, - term: { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 0, - buckets: [ - { key: 'api', doc_count: 8098 }, - { key: 'dev', doc_count: 8098 }, - ], - }, - }, - }, - ['locations', 'ports', 'schemes', 'tags'] - ) - ).toMatchSnapshot(); - }); -}); diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_certs.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_certs.test.ts index c0b94b19b7582..cb37438619397 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_certs.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_certs.test.ts @@ -5,8 +5,7 @@ */ import { getCerts } from '../get_certs'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; -import { elasticsearchServiceMock } from '../../../../../../../src/core/server/mocks'; +import { getUptimeESMockClient } from './helper'; describe('getCerts', () => { let mockHits: any; @@ -82,8 +81,9 @@ describe('getCerts', () => { }); it('parses query result and returns expected values', async () => { - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); - mockEsClient.search.mockResolvedValueOnce({ + const { esClient, uptimeEsClient } = getUptimeESMockClient(); + + esClient.search.mockResolvedValueOnce({ body: { hits: { hits: mockHits, @@ -92,13 +92,7 @@ describe('getCerts', () => { } as any); const result = await getCerts({ - callES: mockEsClient, - dynamicSettings: { - heartbeatIndices: 'heartbeat*', - certAgeThreshold: DYNAMIC_SETTINGS_DEFAULTS.certAgeThreshold, - certExpirationThreshold: DYNAMIC_SETTINGS_DEFAULTS.certExpirationThreshold, - defaultConnectors: [], - }, + uptimeEsClient, index: 1, from: 'now-2d', to: 'now+1h', @@ -129,7 +123,7 @@ describe('getCerts', () => { "total": 0, } `); - expect(mockEsClient.search.mock.calls).toMatchInlineSnapshot(` + expect(esClient.search.mock.calls).toMatchInlineSnapshot(` Array [ Array [ Object { @@ -217,7 +211,7 @@ describe('getCerts', () => { }, ], }, - "index": "heartbeat*", + "index": "heartbeat-8*", }, ], ] diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts index 9503174ed104c..3e3a6878b18b9 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts @@ -6,7 +6,7 @@ import { getLatestMonitor } from '../get_latest_monitor'; import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; -import { elasticsearchServiceMock } from '../../../../../../../src/core/server/mocks'; +import { getUptimeESMockClient } from './helper'; describe('getLatestMonitor', () => { let expectedGetLatestSearchParams: any; @@ -69,12 +69,12 @@ describe('getLatestMonitor', () => { }); it('returns data in expected shape', async () => { - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); + mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); const result = await getLatestMonitor({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, dateStart: 'now-1h', dateEnd: 'now', monitorId: 'testMonitor', diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_availability.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_availability.test.ts index e8df65d410167..82256f31067c3 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_availability.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_availability.test.ts @@ -10,9 +10,9 @@ import { AvailabilityKey, getMonitorAvailability, } from '../get_monitor_availability'; -import { setupMockEsCompositeQuery } from './helper'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; +import { getUptimeESMockClient, setupMockEsCompositeQuery } from './helper'; import { GetMonitorAvailabilityParams, makePing, Ping } from '../../../../common/runtime_types'; + interface AvailabilityTopHit { _source: Ping; } @@ -108,9 +108,11 @@ describe('monitor availability', () => { "minimum_should_match": 1 } }`; + + const { uptimeEsClient } = getUptimeESMockClient(esMock); + await getMonitorAvailability({ - callES: esMock, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, filters: exampleFilter, range: 2, rangeUnit: 'w', @@ -286,9 +288,11 @@ describe('monitor availability', () => { rangeUnit: 'd', threshold: '69', }; + + const { uptimeEsClient } = getUptimeESMockClient(esMock); + const result = await getMonitorAvailability({ - callES: esMock, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, ...clientParameters, }); expect(esMock.search).toHaveBeenCalledTimes(1); @@ -509,9 +513,10 @@ describe('monitor availability', () => { ], genBucketItem ); + const { uptimeEsClient } = getUptimeESMockClient(esMock); + const result = await getMonitorAvailability({ - callES: esMock, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, range: 3, rangeUnit: 'M', threshold: '98', @@ -812,9 +817,11 @@ describe('monitor availability', () => { ], genBucketItem ); + + const { uptimeEsClient } = getUptimeESMockClient(esMock); + await getMonitorAvailability({ - callES: esMock, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, range: 3, rangeUnit: 's', threshold: '99', diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts index 9edd3e2e160d2..428f990352dfc 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts @@ -7,16 +7,16 @@ import { set } from '@elastic/safer-lodash-set'; import mockChartsData from './monitor_charts_mock.json'; import { getMonitorDurationChart } from '../get_monitor_duration'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; -import { elasticsearchServiceMock } from '../../../../../../../src/core/server/mocks'; +import { getUptimeESMockClient } from './helper'; describe('ElasticsearchMonitorsAdapter', () => { it('getMonitorChartsData will provide expected filters', async () => { expect.assertions(2); - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); + await getMonitorDurationChart({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, monitorId: 'fooID', dateStart: 'now-15m', dateEnd: 'now', @@ -33,13 +33,13 @@ describe('ElasticsearchMonitorsAdapter', () => { }); it('inserts empty buckets for missing data', async () => { - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); + mockEsClient.search.mockResolvedValueOnce(mockChartsData as any); expect( await getMonitorDurationChart({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, monitorId: 'id', dateStart: 'now-15m', dateEnd: 'now', diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts index 949bc39f07259..4978fbd6bcdbb 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts @@ -5,8 +5,7 @@ */ import { getMonitorStatus } from '../get_monitor_status'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; -import { setupMockEsCompositeQuery } from './helper'; +import { getUptimeESMockClient, setupMockEsCompositeQuery } from './helper'; export interface BucketItemCriteria { monitorId: string; @@ -77,9 +76,11 @@ describe('getMonitorStatus', () => { minimum_should_match: 1, }, }; + + const { uptimeEsClient } = getUptimeESMockClient(esMock); + await getMonitorStatus({ - callES: esMock, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, filters: exampleFilter, locations: [], numTimes: 5, @@ -193,9 +194,11 @@ describe('getMonitorStatus', () => { [], genBucketItem ); + + const { uptimeEsClient } = getUptimeESMockClient(esMock); + await getMonitorStatus({ - callES: esMock, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, locations: ['fairbanks', 'harrisburg'], numTimes: 1, timerange: { @@ -350,9 +353,11 @@ describe('getMonitorStatus', () => { }, }, }; + + const { uptimeEsClient } = getUptimeESMockClient(esMock); + await getMonitorStatus({ - callES: esMock, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, ...clientParameters, }); expect(esMock.search).toHaveBeenCalledTimes(1); @@ -495,9 +500,11 @@ describe('getMonitorStatus', () => { }, }, }; + + const { uptimeEsClient } = getUptimeESMockClient(esMock); + await getMonitorStatus({ - callES: esMock, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, ...clientParameters, }); expect(esMock.search).toHaveBeenCalledTimes(1); @@ -615,9 +622,11 @@ describe('getMonitorStatus', () => { to: 'now-2m', }, }; + + const { uptimeEsClient } = getUptimeESMockClient(esMock); + const result = await getMonitorStatus({ - callES: esMock, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, ...clientParameters, }); expect(esMock.search).toHaveBeenCalledTimes(1); @@ -793,9 +802,11 @@ describe('getMonitorStatus', () => { criteria, genBucketItem ); + + const { uptimeEsClient } = getUptimeESMockClient(esMock); + const result = await getMonitorStatus({ - callES: esMock, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, locations: [], numTimes: 5, timerange: { diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts index 427061b6c16d4..3b26adb18ae7f 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts @@ -5,9 +5,8 @@ */ import { getPingHistogram } from '../get_ping_histogram'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; -import { elasticsearchServiceMock } from '../../../../../../../src/core/server/mocks'; import * as intervalHelper from '../../helper/get_histogram_interval'; +import { getUptimeESMockClient } from './helper'; describe('getPingHistogram', () => { beforeEach(() => { @@ -43,7 +42,7 @@ describe('getPingHistogram', () => { it('returns a single bucket if array has 1', async () => { expect.assertions(2); - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); mockEsClient.search.mockResolvedValueOnce({ body: { @@ -67,8 +66,7 @@ describe('getPingHistogram', () => { } as any); const result = await getPingHistogram({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, from: 'now-15m', to: 'now', }); @@ -80,7 +78,7 @@ describe('getPingHistogram', () => { it('returns expected result for no status filter', async () => { expect.assertions(2); - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); standardMockResponse.aggregations.timeseries.interval = '1m'; @@ -89,8 +87,7 @@ describe('getPingHistogram', () => { } as any); const result = await getPingHistogram({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, from: 'now-15m', to: 'now', filters: '', @@ -103,7 +100,7 @@ describe('getPingHistogram', () => { it('handles status + additional user queries', async () => { expect.assertions(2); - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); mockEsClient.search.mockResolvedValueOnce({ body: { @@ -154,8 +151,7 @@ describe('getPingHistogram', () => { }; const result = await getPingHistogram({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, from: 'now-15m', to: 'now', filters: JSON.stringify(searchFilter), @@ -168,7 +164,7 @@ describe('getPingHistogram', () => { it('handles simple_text_query without issues', async () => { expect.assertions(2); - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); mockEsClient.search.mockResolvedValueOnce({ body: { @@ -211,8 +207,7 @@ describe('getPingHistogram', () => { const filters = `{"bool":{"must":[{"simple_query_string":{"query":"http"}}]}}`; const result = await getPingHistogram({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, from: 'now-15m', to: 'now', filters, diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts index f313cce9f758b..9b28d58c7e8c2 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts @@ -7,7 +7,7 @@ import { getPings } from '../get_pings'; import { set } from '@elastic/safer-lodash-set'; import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; -import { elasticsearchServiceMock } from '../../../../../../../src/core/server/mocks'; +import { getUptimeESMockClient } from './helper'; describe('getAll', () => { let mockEsSearchResult: any; @@ -87,12 +87,12 @@ describe('getAll', () => { }); it('returns data in the appropriate shape', async () => { - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + const result = await getPings({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, dateRange: { from: 'now-1h', to: 'now' }, sort: 'asc', size: 12, @@ -110,11 +110,12 @@ describe('getAll', () => { }); it('creates appropriate sort and size parameters', async () => { - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); + mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + await getPings({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, dateRange: { from: 'now-1h', to: 'now' }, sort: 'asc', size: 12, @@ -126,7 +127,7 @@ describe('getAll', () => { Array [ Object { "body": Object { - "aggregations": Object { + "aggs": Object { "locations": Object { "terms": Object { "field": "observer.geo.name", @@ -189,11 +190,12 @@ describe('getAll', () => { }); it('omits the sort param when no sort passed', async () => { - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); + mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + await getPings({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, dateRange: { from: 'now-1h', to: 'now' }, size: 12, }); @@ -203,7 +205,7 @@ describe('getAll', () => { Array [ Object { "body": Object { - "aggregations": Object { + "aggs": Object { "locations": Object { "terms": Object { "field": "observer.geo.name", @@ -266,11 +268,12 @@ describe('getAll', () => { }); it('omits the size param when no size passed', async () => { - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); + mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + await getPings({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, dateRange: { from: 'now-1h', to: 'now' }, sort: 'desc', }); @@ -280,7 +283,7 @@ describe('getAll', () => { Array [ Object { "body": Object { - "aggregations": Object { + "aggs": Object { "locations": Object { "terms": Object { "field": "observer.geo.name", @@ -343,11 +346,12 @@ describe('getAll', () => { }); it('adds a filter for monitor ID', async () => { - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); + mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + await getPings({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, dateRange: { from: 'now-1h', to: 'now' }, monitorId: 'testmonitorid', }); @@ -357,7 +361,7 @@ describe('getAll', () => { Array [ Object { "body": Object { - "aggregations": Object { + "aggs": Object { "locations": Object { "terms": Object { "field": "observer.geo.name", @@ -425,11 +429,12 @@ describe('getAll', () => { }); it('adds a filter for monitor status', async () => { - const mockEsClient = elasticsearchServiceMock.createElasticsearchClient(); + const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient(); + mockEsClient.search.mockResolvedValueOnce(mockEsSearchResult); + await getPings({ - callES: mockEsClient, - dynamicSettings: DYNAMIC_SETTINGS_DEFAULTS, + uptimeEsClient, dateRange: { from: 'now-1h', to: 'now' }, status: 'down', }); @@ -439,7 +444,7 @@ describe('getAll', () => { Array [ Object { "body": Object { - "aggregations": Object { + "aggs": Object { "locations": Object { "terms": Object { "field": "observer.geo.name", diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/helper.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/helper.ts index 4ebc9b2da7855..37f7583312867 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/helper.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/helper.ts @@ -4,10 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { elasticsearchServiceMock } from '../../../../../../../src/core/server/mocks'; +import { + elasticsearchServiceMock, + savedObjectsClientMock, +} from '../../../../../../../src/core/server/mocks'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ElasticsearchClientMock } from '../../../../../../../src/core/server/elasticsearch/client/mocks'; +import { createUptimeESClient } from '../../lib'; export interface MultiPageCriteria { after_key?: K; @@ -54,3 +58,17 @@ export const setupMockEsCompositeQuery = ( return esMock; }; + +export const getUptimeESMockClient = (esClientMock?: ElasticsearchClientMock) => { + const esClient = elasticsearchServiceMock.createElasticsearchClient(); + + const savedObjectsClient = savedObjectsClientMock.create(); + + return { + esClient: esClientMock || esClient, + uptimeEsClient: createUptimeESClient({ + esClient: esClientMock || esClient, + savedObjectsClient, + }), + }; +}; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_certs.ts b/x-pack/plugins/uptime/server/lib/requests/get_certs.ts index 0836cb039b215..d8b8f3733b94b 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_certs.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_certs.ts @@ -5,7 +5,7 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { CertResult, GetCertsParams } from '../../../common/runtime_types'; +import { CertResult, GetCertsParams, Ping } from '../../../common/runtime_types'; enum SortFields { 'issuer' = 'tls.server.x509.issuer.common_name', @@ -15,8 +15,7 @@ enum SortFields { } export const getCerts: UMElasticsearchQueryFn = async ({ - callES, - dynamicSettings, + uptimeEsClient, index, from, to, @@ -29,92 +28,86 @@ export const getCerts: UMElasticsearchQueryFn = asyn }) => { const sort = SortFields[sortBy as keyof typeof SortFields]; - const params: any = { - index: dynamicSettings.heartbeatIndices, - body: { - from: index * size, - size, - sort: [ - { - [sort]: { - order: direction, - }, + const searchBody = { + from: index * size, + size, + sort: [ + { + [sort]: { + order: direction as 'asc' | 'desc', }, - ], - query: { - bool: { - filter: [ - { - exists: { - field: 'tls.server', - }, - }, - { - range: { - 'monitor.timespan': { - gte: from, - lte: to, + }, + ], + query: { + bool: { + ...(search + ? { + minimum_should_match: 1, + should: [ + { + multi_match: { + query: escape(search), + type: 'phrase_prefix', + fields: [ + 'monitor.id.text', + 'monitor.name.text', + 'url.full.text', + 'tls.server.x509.subject.common_name.text', + 'tls.server.x509.issuer.common_name.text', + ], + }, }, - }, + ], + } + : {}), + filter: [ + { + exists: { + field: 'tls.server', }, - ], - }, - }, - _source: [ - 'monitor.id', - 'monitor.name', - 'tls.server.x509.issuer.common_name', - 'tls.server.x509.subject.common_name', - 'tls.server.hash.sha1', - 'tls.server.hash.sha256', - 'tls.server.x509.not_after', - 'tls.server.x509.not_before', - ], - collapse: { - field: 'tls.server.hash.sha256', - inner_hits: { - _source: { - includes: ['monitor.id', 'monitor.name', 'url.full'], }, - collapse: { - field: 'monitor.id', + { + range: { + 'monitor.timespan': { + gte: from, + lte: to, + }, + }, }, - name: 'monitors', - sort: [{ 'monitor.id': 'asc' }], - }, + ], }, - aggs: { - total: { - cardinality: { - field: 'tls.server.hash.sha256', - }, + }, + _source: [ + 'monitor.id', + 'monitor.name', + 'tls.server.x509.issuer.common_name', + 'tls.server.x509.subject.common_name', + 'tls.server.hash.sha1', + 'tls.server.hash.sha256', + 'tls.server.x509.not_after', + 'tls.server.x509.not_before', + ], + collapse: { + field: 'tls.server.hash.sha256', + inner_hits: { + _source: { + includes: ['monitor.id', 'monitor.name', 'url.full'], + }, + collapse: { + field: 'monitor.id', }, + name: 'monitors', + sort: [{ 'monitor.id': 'asc' }], }, }, - }; - - if (!params.body.query.bool.should) { - params.body.query.bool.should = []; - } - - if (search) { - params.body.query.bool.minimum_should_match = 1; - params.body.query.bool.should = [ - { - multi_match: { - query: escape(search), - type: 'phrase_prefix', - fields: [ - 'monitor.id.text', - 'monitor.name.text', - 'url.full.text', - 'tls.server.x509.subject.common_name.text', - 'tls.server.x509.issuer.common_name.text', - ], + aggs: { + total: { + cardinality: { + field: 'tls.server.hash.sha256', }, }, - ]; - } + }, + }; if (notValidBefore || notValidAfter) { const validityFilters: any = { @@ -141,18 +134,17 @@ export const getCerts: UMElasticsearchQueryFn = asyn }); } - params.body.query.bool.filter.push(validityFilters); + searchBody.query.bool.filter.push(validityFilters); } // console.log(JSON.stringify(params, null, 2)); - const { body: result } = await callES.search(params); + const { body: result } = await uptimeEsClient.search({ + body: searchBody, + }); - const certs = (result?.hits?.hits ?? []).map((hit: any) => { - const { - _source: { - tls: { server }, - }, - } = hit; + const certs = (result?.hits?.hits ?? []).map((hit) => { + const ping = hit._source as Ping; + const server = ping.tls?.server!; const notAfter = server?.x509?.not_after; const notBefore = server?.x509?.not_before; @@ -171,7 +163,7 @@ export const getCerts: UMElasticsearchQueryFn = asyn monitors, issuer, sha1, - sha256, + sha256: sha256 as string, not_after: notAfter, not_before: notBefore, common_name: commonName, diff --git a/x-pack/plugins/uptime/server/lib/requests/get_filter_bar.ts b/x-pack/plugins/uptime/server/lib/requests/get_filter_bar.ts index c3295d6dd9c8f..026ce184649cd 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_filter_bar.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_filter_bar.ts @@ -45,28 +45,8 @@ export const combineRangeWithFilters = ( return filters; }; -type SupportedFields = 'locations' | 'ports' | 'schemes' | 'tags'; - -export const extractFilterAggsResults = ( - responseAggregations: Record, - keys: SupportedFields[] -): OverviewFilters => { - const values: OverviewFilters = { - locations: [], - ports: [], - schemes: [], - tags: [], - }; - keys.forEach((key) => { - const buckets = responseAggregations?.[key]?.term?.buckets ?? []; - values[key] = buckets.map((item: { key: string | number }) => item.key); - }); - return values; -}; - export const getFilterBar: UMElasticsearchQueryFn = async ({ - callES, - dynamicSettings, + uptimeEsClient, dateRangeStart, dateRangeEnd, search, @@ -82,19 +62,24 @@ export const getFilterBar: UMElasticsearchQueryFn item.key as string), + ports: ports?.term?.buckets.map((item) => item.key as number), + schemes: schemes?.term?.buckets.map((item) => item.key as string), + tags: tags?.term?.buckets.map((item) => item.key as string), + }; }; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_index_pattern.ts b/x-pack/plugins/uptime/server/lib/requests/get_index_pattern.ts index 98d32b16b2884..ab0b9043d14e2 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_index_pattern.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_index_pattern.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ElasticsearchClient } from 'kibana/server'; import { FieldDescriptor, IndexPatternsFetcher } from '../../../../../../src/plugins/data/server'; -import { DynamicSettings } from '../../../common/runtime_types'; +import { UptimeESClient } from '../lib'; +import { savedObjectsAdapter } from '../saved_objects'; export interface IndexPatternTitleAndFields { title: string; @@ -14,14 +14,15 @@ export interface IndexPatternTitleAndFields { } export const getUptimeIndexPattern = async ({ - esClient, - dynamicSettings, + uptimeEsClient, }: { - esClient: ElasticsearchClient; - dynamicSettings: DynamicSettings; + uptimeEsClient: UptimeESClient; }): Promise => { - const indexPatternsFetcher = new IndexPatternsFetcher(esClient); + const indexPatternsFetcher = new IndexPatternsFetcher(uptimeEsClient.baseESClient); + const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings( + uptimeEsClient.getSavedObjectsClient()! + ); // Since `getDynamicIndexPattern` is called in setup_request (and thus by every endpoint) // and since `getFieldsForWildcard` will throw if the specified indices don't exist, // we have to catch errors here to avoid all endpoints returning 500 for users without APM data diff --git a/x-pack/plugins/uptime/server/lib/requests/get_index_status.ts b/x-pack/plugins/uptime/server/lib/requests/get_index_status.ts index 061d002b010de..e2baf39905bfd 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_index_status.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_index_status.ts @@ -8,15 +8,14 @@ import { UMElasticsearchQueryFn } from '../adapters'; import { StatesIndexStatus } from '../../../common/runtime_types'; export const getIndexStatus: UMElasticsearchQueryFn<{}, StatesIndexStatus> = async ({ - callES, - dynamicSettings, + uptimeEsClient, }) => { const { body: { _shards: { total }, count, }, - } = await callES.count({ index: dynamicSettings.heartbeatIndices }); + } = await uptimeEsClient.count({}); return { indexExists: total > 0, docCount: count, diff --git a/x-pack/plugins/uptime/server/lib/requests/get_journey_screenshot.ts b/x-pack/plugins/uptime/server/lib/requests/get_journey_screenshot.ts index bff3aaf1176df..dacdcaff7dfd5 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_journey_screenshot.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_journey_screenshot.ts @@ -5,6 +5,7 @@ */ import { UMElasticsearchQueryFn } from '../adapters/framework'; +import { ESSearchBody } from '../../../../../typings/elasticsearch'; interface GetJourneyScreenshotParams { checkGroup: string; @@ -14,35 +15,32 @@ interface GetJourneyScreenshotParams { export const getJourneyScreenshot: UMElasticsearchQueryFn< GetJourneyScreenshotParams, any -> = async ({ callES, dynamicSettings, checkGroup, stepIndex }) => { - const params: any = { - index: dynamicSettings.heartbeatIndices, - body: { - query: { - bool: { - filter: [ - { - term: { - 'monitor.check_group': checkGroup, - }, +> = async ({ uptimeEsClient, checkGroup, stepIndex }) => { + const params: ESSearchBody = { + query: { + bool: { + filter: [ + { + term: { + 'monitor.check_group': checkGroup, }, - { - term: { - 'synthetics.type': 'step/screenshot', - }, + }, + { + term: { + 'synthetics.type': 'step/screenshot', }, - { - term: { - 'synthetics.step.index': stepIndex, - }, + }, + { + term: { + 'synthetics.step.index': stepIndex, }, - ], - }, + }, + ], }, - _source: ['synthetics.blob'], }, + _source: ['synthetics.blob'], }; - const { body: result } = await callES.search(params); + const { body: result } = await uptimeEsClient.search({ body: params }); if (!Array.isArray(result?.hits?.hits) || result.hits.hits.length < 1) { return null; } diff --git a/x-pack/plugins/uptime/server/lib/requests/get_journey_steps.ts b/x-pack/plugins/uptime/server/lib/requests/get_journey_steps.ts index f36815a747db3..c330e1b66fe93 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_journey_steps.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_journey_steps.ts @@ -12,51 +12,50 @@ interface GetJourneyStepsParams { } export const getJourneySteps: UMElasticsearchQueryFn = async ({ - callES, - dynamicSettings, + uptimeEsClient, checkGroup, }) => { - const params: any = { - index: dynamicSettings.heartbeatIndices, - body: { - query: { - bool: { - filter: [ - { - terms: { - 'synthetics.type': ['step/end', 'stderr', 'cmd/status', 'step/screenshot'], - }, + const params = { + query: { + bool: { + filter: [ + { + terms: { + 'synthetics.type': ['step/end', 'stderr', 'cmd/status', 'step/screenshot'], }, - { - term: { - 'monitor.check_group': checkGroup, - }, + }, + { + term: { + 'monitor.check_group': checkGroup, }, - ], - }, - }, - sort: [{ 'synthetics.step.index': { order: 'asc' } }, { '@timestamp': { order: 'asc' } }], - _source: { - excludes: ['synthetics.blob'], + }, + ], }, }, + sort: [{ 'synthetics.step.index': { order: 'asc' } }, { '@timestamp': { order: 'asc' } }], + _source: { + excludes: ['synthetics.blob'], + }, size: 500, }; - const { body: result } = await callES.search(params); + const { body: result } = await uptimeEsClient.search({ body: params }); + const screenshotIndexes: number[] = result.hits.hits - .filter((h: any) => h?._source?.synthetics?.type === 'step/screenshot') - .map((h: any) => h?._source?.synthetics?.step?.index); - return result.hits.hits - .filter((h: any) => h?._source?.synthetics?.type !== 'step/screenshot') - .map( - ({ _id, _source, _source: { synthetics } }: any): Ping => ({ - ..._source, - timestamp: _source['@timestamp'], - docId: _id, + .filter((h) => (h?._source as Ping).synthetics?.type === 'step/screenshot') + .map((h) => (h?._source as Ping).synthetics?.step?.index as number); + + return (result.hits.hits + .filter((h) => (h?._source as Ping).synthetics?.type !== 'step/screenshot') + .map((h) => { + const source = h._source as Ping & { '@timestamp': string }; + return { + ...source, + timestamp: source['@timestamp'], + docId: h._id, synthetics: { - ...synthetics, - screenshotExists: screenshotIndexes.some((i) => i === synthetics?.step?.index), + ...source.synthetics, + screenshotExists: screenshotIndexes.some((i) => i === source.synthetics?.step?.index), }, - }) - ); + }; + }) as unknown) as Ping; }; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts b/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts index f6562eaa42e90..1e323b57b30dc 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts @@ -22,45 +22,42 @@ export interface GetLatestMonitorParams { // Get The monitor latest state sorted by timestamp with date range export const getLatestMonitor: UMElasticsearchQueryFn = async ({ - callES, - dynamicSettings, + uptimeEsClient, dateStart, dateEnd, monitorId, observerLocation, }) => { const params = { - index: dynamicSettings.heartbeatIndices, - body: { - query: { - bool: { - filter: [ - { exists: { field: 'summary' } }, - { - range: { - '@timestamp': { - gte: dateStart, - lte: dateEnd, - }, + query: { + bool: { + filter: [ + { exists: { field: 'summary' } }, + { + range: { + '@timestamp': { + gte: dateStart, + lte: dateEnd, }, }, - ...(monitorId ? [{ term: { 'monitor.id': monitorId } }] : []), - ...(observerLocation ? [{ term: { 'observer.geo.name': observerLocation } }] : []), - ], - }, - }, - size: 1, - _source: ['url', 'monitor', 'observer', '@timestamp', 'tls.*', 'http', 'error'], - sort: { - '@timestamp': { order: 'desc' }, + }, + ...(monitorId ? [{ term: { 'monitor.id': monitorId } }] : []), + ...(observerLocation ? [{ term: { 'observer.geo.name': observerLocation } }] : []), + ], }, }, + size: 1, + _source: ['url', 'monitor', 'observer', '@timestamp', 'tls.*', 'http', 'error'], + sort: { + '@timestamp': { order: 'desc' }, + }, }; - const { body: result } = await callES.search(params); + const { body: result } = await uptimeEsClient.search({ body: params }); + const doc = result.hits?.hits?.[0]; const docId = doc?._id ?? ''; - const { tls, ...ping } = doc?._source ?? {}; + const { tls, ...ping } = (doc?._source as Ping & { '@timestamp': string }) ?? {}; return { ...ping, diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.ts index 2f1a37095c3bc..04b4eef19d689 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_availability.ts @@ -6,6 +6,8 @@ import { UMElasticsearchQueryFn } from '../adapters'; import { GetMonitorAvailabilityParams, Ping } from '../../../common/runtime_types'; +import { AfterKey } from './get_monitor_status'; +import { SortOptions } from '../../../../../typings/elasticsearch'; export interface AvailabilityKey { monitorId: string; @@ -34,9 +36,9 @@ export const formatBuckets = async (buckets: any[]): Promise = async ({ callES, dynamicSettings, range, rangeUnit, threshold: thresholdString, filters }) => { +> = async ({ uptimeEsClient, range, rangeUnit, threshold: thresholdString, filters }) => { const queryResults: Array> = []; - let afterKey: AvailabilityKey | undefined; + let afterKey: AfterKey; const threshold = Number(thresholdString) / 100; if (threshold <= 0 || threshold > 1.0) { @@ -53,92 +55,90 @@ export const getMonitorAvailability: UMElasticsearchQueryFn< } do { - const esParams: any = { - index: dynamicSettings.heartbeatIndices, - body: { - query: { - bool: { - filter: [ + const esParams = { + query: { + bool: { + filter: [ + { + range: { + '@timestamp': { + gte, + lte: 'now', + }, + }, + }, + // append user filters, if defined + ...(parsedFilters?.bool ? [parsedFilters] : []), + ], + }, + }, + size: 0, + aggs: { + monitors: { + composite: { + size: 2000, + ...(afterKey ? { after: afterKey } : {}), + sources: [ { - range: { - '@timestamp': { - gte, - lte: 'now', + monitorId: { + terms: { + field: 'monitor.id', }, }, }, - // append user filters, if defined - ...(parsedFilters?.bool ? [parsedFilters] : []), - ], - }, - }, - size: 0, - aggs: { - monitors: { - composite: { - size: 2000, - sources: [ - { - monitorId: { - terms: { - field: 'monitor.id', - }, + { + location: { + terms: { + field: 'observer.geo.name', + missing_bucket: true, }, }, - { - location: { - terms: { - field: 'observer.geo.name', - missing_bucket: true, + }, + ], + }, + aggs: { + fields: { + top_hits: { + size: 1, + sort: [ + { + '@timestamp': { + order: 'desc', }, }, - }, - ], + ] as SortOptions, + }, }, - aggs: { - fields: { - top_hits: { - size: 1, - sort: [ - { - '@timestamp': { - order: 'desc', - }, - }, - ], - }, + up_sum: { + sum: { + field: 'summary.up', + missing: 0, }, - up_sum: { - sum: { - field: 'summary.up', - missing: 0, - }, + }, + down_sum: { + sum: { + field: 'summary.down', + missing: 0, }, - down_sum: { - sum: { - field: 'summary.down', - missing: 0, + }, + ratio: { + bucket_script: { + buckets_path: { + upTotal: 'up_sum', + downTotal: 'down_sum', }, - }, - ratio: { - bucket_script: { - buckets_path: { - upTotal: 'up_sum', - downTotal: 'down_sum', - }, - script: ` + script: ` if (params.upTotal + params.downTotal > 0) { return params.upTotal / (params.upTotal + params.downTotal); } return null;`, - }, }, - filtered: { - bucket_selector: { - buckets_path: { - threshold: 'ratio.value', - }, - script: `params.threshold < ${threshold}`, + }, + filtered: { + bucket_selector: { + buckets_path: { + threshold: 'ratio.value', }, + script: `params.threshold < ${threshold}`, }, }, }, @@ -146,12 +146,9 @@ export const getMonitorAvailability: UMElasticsearchQueryFn< }, }; - if (afterKey) { - esParams.body.aggs.monitors.composite.after = afterKey; - } + const { body: result } = await uptimeEsClient.search({ body: esParams }); - const { body: result } = await callES.search(esParams); - afterKey = result?.aggregations?.monitors?.after_key; + afterKey = result?.aggregations?.monitors?.after_key as AfterKey; queryResults.push(formatBuckets(result?.aggregations?.monitors?.buckets || [])); } while (afterKey !== undefined); diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_details.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_details.ts index 998ea3dd9df00..c4d122515d133 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_details.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_details.ts @@ -4,10 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ElasticsearchClient } from 'kibana/server'; import { UMElasticsearchQueryFn } from '../adapters'; -import { MonitorDetails, MonitorError } from '../../../common/runtime_types'; +import { MonitorDetails, Ping } from '../../../common/runtime_types'; import { formatFilterString } from '../alerts/status_check'; +import { UptimeESClient } from '../lib'; +import { ESSearchBody } from '../../../../../typings/elasticsearch'; export interface GetMonitorDetailsParams { monitorId: string; @@ -17,13 +18,11 @@ export interface GetMonitorDetailsParams { } const getMonitorAlerts = async ({ - callES, - dynamicSettings, + uptimeEsClient, alertsClient, monitorId, }: { - callES: ElasticsearchClient; - dynamicSettings: any; + uptimeEsClient: UptimeESClient; alertsClient: any; monitorId: string; }) => { @@ -44,41 +43,37 @@ const getMonitorAlerts = async ({ monitorAlerts.push(currAlert); continue; } - const esParams: any = { - index: dynamicSettings.heartbeatIndices, - body: { - query: { - bool: { - filter: [ - { - term: { - 'monitor.id': monitorId, - }, + const esParams: ESSearchBody = { + query: { + bool: { + filter: [ + { + term: { + 'monitor.id': monitorId, }, - ], - }, - }, - size: 0, - aggs: { - monitors: { - terms: { - field: 'monitor.id', - size: 1000, }, + ], + }, + }, + size: 0, + aggs: { + monitors: { + terms: { + field: 'monitor.id', + size: 1000, }, }, }, }; const parsedFilters = await formatFilterString( - dynamicSettings, - callES, + uptimeEsClient, currAlert.params.filters, currAlert.params.search ); - esParams.body.query.bool = Object.assign({}, esParams.body.query.bool, parsedFilters?.bool); + esParams.query.bool = Object.assign({}, esParams.query.bool, parsedFilters?.bool); - const { body: result } = await callES.search(esParams); + const { body: result } = await uptimeEsClient.search({ body: esParams }); if (result.hits.total.value > 0) { monitorAlerts.push(currAlert); @@ -90,7 +85,7 @@ const getMonitorAlerts = async ({ export const getMonitorDetails: UMElasticsearchQueryFn< GetMonitorDetailsParams, MonitorDetails -> = async ({ callES, dynamicSettings, monitorId, dateStart, dateEnd, alertsClient }) => { +> = async ({ uptimeEsClient, monitorId, dateStart, dateEnd, alertsClient }) => { const queryFilters: any = [ { range: { @@ -108,48 +103,43 @@ export const getMonitorDetails: UMElasticsearchQueryFn< ]; const params = { - index: dynamicSettings.heartbeatIndices, - body: { - size: 1, - _source: ['error', '@timestamp'], - query: { - bool: { - must: [ - { - exists: { - field: 'error', - }, + size: 1, + _source: ['error', '@timestamp'], + query: { + bool: { + must: [ + { + exists: { + field: 'error', }, - ], - filter: queryFilters, - }, - }, - sort: [ - { - '@timestamp': { - order: 'desc', }, - }, - ], + ], + filter: queryFilters, + }, }, + sort: [ + { + '@timestamp': { + order: 'desc', + }, + }, + ], }; - const { body: result } = await callES.search(params); + const { body: result } = await uptimeEsClient.search({ body: params }); - const data = result.hits.hits[0]?._source; + const data = result.hits.hits[0]?._source as Ping & { '@timestamp': string }; - const monitorError: MonitorError | undefined = data?.error; const errorTimestamp: string | undefined = data?.['@timestamp']; const monAlerts = await getMonitorAlerts({ - callES, - dynamicSettings, + uptimeEsClient, alertsClient, monitorId, }); return { monitorId, - error: monitorError, + error: data?.error, timestamp: errorTimestamp, alerts: monAlerts, }; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_duration.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_duration.ts index 77ae7570a96a8..cb1251eb7f9db 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_duration.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_duration.ts @@ -23,35 +23,32 @@ export interface GetMonitorChartsParams { export const getMonitorDurationChart: UMElasticsearchQueryFn< GetMonitorChartsParams, MonitorDurationResult -> = async ({ callES, dynamicSettings, dateStart, dateEnd, monitorId }) => { +> = async ({ uptimeEsClient, dateStart, dateEnd, monitorId }) => { const params = { - index: dynamicSettings.heartbeatIndices, - body: { - query: { - bool: { - filter: [ - { range: { '@timestamp': { gte: dateStart, lte: dateEnd } } }, - { term: { 'monitor.id': monitorId } }, - { range: { 'monitor.duration.us': { gt: 0 } } }, - ], - }, + query: { + bool: { + filter: [ + { range: { '@timestamp': { gte: dateStart, lte: dateEnd } } }, + { term: { 'monitor.id': monitorId } }, + { range: { 'monitor.duration.us': { gt: 0 } } }, + ], }, - size: 0, - aggs: { - timeseries: { - auto_date_histogram: { - field: '@timestamp', - buckets: QUERY.DEFAULT_BUCKET_COUNT, - }, - aggs: { - location: { - terms: { - field: 'observer.geo.name', - missing: 'N/A', - }, - aggs: { - duration: { stats: { field: 'monitor.duration.us' } }, - }, + }, + size: 0, + aggs: { + timeseries: { + auto_date_histogram: { + field: '@timestamp', + buckets: QUERY.DEFAULT_BUCKET_COUNT, + }, + aggs: { + location: { + terms: { + field: 'observer.geo.name', + missing: 'N/A', + }, + aggs: { + duration: { stats: { field: 'monitor.duration.us' } }, }, }, }, @@ -59,7 +56,7 @@ export const getMonitorDurationChart: UMElasticsearchQueryFn< }, }; - const { body: result } = await callES.search(params); + const { body: result } = await uptimeEsClient.search({ body: params }); const dateHistogramBuckets: any[] = result?.aggregations?.timeseries?.buckets ?? []; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts index b5183ca9ffb9f..af79126226e26 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts @@ -7,6 +7,7 @@ import { UMElasticsearchQueryFn } from '../adapters'; import { MonitorLocations, MonitorLocation } from '../../../common/runtime_types'; import { UNNAMED_LOCATION } from '../../../common/constants'; +import { SortOptions } from '../../../../../typings/elasticsearch'; /** * Fetch data for the monitor page title. @@ -23,64 +24,65 @@ export interface GetMonitorLocationsParams { export const getMonitorLocations: UMElasticsearchQueryFn< GetMonitorLocationsParams, MonitorLocations -> = async ({ callES, dynamicSettings, monitorId, dateStart, dateEnd }) => { +> = async ({ uptimeEsClient, monitorId, dateStart, dateEnd }) => { + const sortOptions: SortOptions = [ + { + '@timestamp': { + order: 'desc', + }, + }, + ]; + const params = { - index: dynamicSettings.heartbeatIndices, - body: { - size: 0, - query: { - bool: { - filter: [ - { - term: { - 'monitor.id': monitorId, - }, + size: 0, + query: { + bool: { + filter: [ + { + term: { + 'monitor.id': monitorId, }, - { - exists: { - field: 'summary', - }, + }, + { + exists: { + field: 'summary', }, - { - range: { - '@timestamp': { - gte: dateStart, - lte: dateEnd, - }, + }, + { + range: { + '@timestamp': { + gte: dateStart, + lte: dateEnd, }, }, - ], - }, - }, - aggs: { - location: { - terms: { - field: 'observer.geo.name', - missing: '__location_missing__', }, - aggs: { - most_recent: { - top_hits: { - size: 1, - sort: { - '@timestamp': { - order: 'desc', - }, - }, - _source: ['monitor', 'summary', 'observer', '@timestamp'], - }, + ], + }, + }, + aggs: { + location: { + terms: { + field: 'observer.geo.name', + missing: '__location_missing__', + }, + aggs: { + most_recent: { + top_hits: { + size: 1, + sort: sortOptions, + _source: ['monitor', 'summary', 'observer', '@timestamp'], }, - down_history: { - sum: { - field: 'summary.down', - missing: 0, - }, + }, + down_history: { + sum: { + field: 'summary.down', + missing: 0, }, - up_history: { - sum: { - field: 'summary.up', - missing: 0, - }, + }, + up_history: { + sum: { + field: 'summary.up', + missing: 0, }, }, }, @@ -88,7 +90,8 @@ export const getMonitorLocations: UMElasticsearchQueryFn< }, }; - const { body: result } = await callES.search(params); + const { body: result } = await uptimeEsClient.search({ body: params }); + const locations = result?.aggregations?.location?.buckets ?? []; const getGeo = (locGeo: { name: string; location?: string }) => { diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_states.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_states.ts index 2ff1043d79e84..16638f0e8cea8 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_states.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_states.ts @@ -40,8 +40,7 @@ export const getMonitorStates: UMElasticsearchQueryFn< GetMonitorStatesParams, MonitorSummariesResult > = async ({ - callES, - dynamicSettings, + uptimeEsClient, dateRangeStart, dateRangeEnd, pagination, @@ -53,8 +52,7 @@ export const getMonitorStates: UMElasticsearchQueryFn< statusFilter = statusFilter === null ? undefined : statusFilter; const queryContext = new QueryContext( - callES, - dynamicSettings.heartbeatIndices, + uptimeEsClient, dateRangeStart, dateRangeEnd, pagination, @@ -98,52 +96,49 @@ export const getHistogramForMonitors = async ( minInterval: number ): Promise<{ [key: string]: Histogram }> => { const params = { - index: queryContext.heartbeatIndices, - body: { - size: 0, - query: { - bool: { - filter: [ - { - range: { - 'summary.down': { gt: 0 }, - }, + size: 0, + query: { + bool: { + filter: [ + { + range: { + 'summary.down': { gt: 0 }, }, - { - terms: { - 'monitor.id': monitorIds, - }, + }, + { + terms: { + 'monitor.id': monitorIds, }, - { - range: { - '@timestamp': { - gte: queryContext.dateRangeStart, - lte: queryContext.dateRangeEnd, - }, + }, + { + range: { + '@timestamp': { + gte: queryContext.dateRangeStart, + lte: queryContext.dateRangeEnd, }, }, - ], - }, - }, - aggs: { - histogram: { - date_histogram: { - field: '@timestamp', - // 12 seems to be a good size for performance given - // long monitor lists of up to 100 on the overview page - fixed_interval: minInterval + 'ms', - missing: 0, }, - aggs: { - by_id: { - terms: { - field: 'monitor.id', - size: Math.max(monitorIds.length, 1), - }, - aggs: { - totalDown: { - sum: { field: 'summary.down' }, - }, + ], + }, + }, + aggs: { + histogram: { + date_histogram: { + field: '@timestamp', + // 12 seems to be a good size for performance given + // long monitor lists of up to 100 on the overview page + fixed_interval: minInterval + 'ms', + missing: 0, + }, + aggs: { + by_id: { + terms: { + field: 'monitor.id', + size: Math.max(monitorIds.length, 1), + }, + aggs: { + totalDown: { + sum: { field: 'summary.down' }, }, }, }, @@ -151,7 +146,7 @@ export const getHistogramForMonitors = async ( }, }, }; - const { body: result } = await queryContext.search(params); + const { body: result } = await queryContext.search({ body: params }); const histoBuckets: any[] = result.aggregations?.histogram.buckets ?? []; const simplified = histoBuckets.map((histoBucket: any): { timestamp: number; byId: any } => { diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts index 06648d68969c1..a5121f7a7a04f 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_status.ts @@ -23,12 +23,6 @@ export interface GetMonitorStatusResult { monitorInfo: Ping; } -interface MonitorStatusKey { - monitor_id: string; - status: string; - location: string; -} - const getLocationClause = (locations: string[]) => ({ bool: { should: [ @@ -41,76 +35,80 @@ const getLocationClause = (locations: string[]) => ({ }, }); +export type AfterKey = Record | undefined; + export const getMonitorStatus: UMElasticsearchQueryFn< GetMonitorStatusParams, GetMonitorStatusResult[] -> = async ({ callES, dynamicSettings, filters, locations, numTimes, timerange: { from, to } }) => { - let afterKey: MonitorStatusKey | undefined; +> = async ({ uptimeEsClient, filters, locations, numTimes, timerange: { from, to } }) => { + let afterKey: AfterKey; const STATUS = 'down'; let monitors: any = []; do { // today this value is hardcoded. In the future we may support // multiple status types for this alert, and this will become a parameter - const esParams: any = { - index: dynamicSettings.heartbeatIndices, - body: { - query: { - bool: { - filter: [ - { - term: { - 'monitor.status': STATUS, - }, + const esParams = { + query: { + bool: { + filter: [ + { + term: { + 'monitor.status': STATUS, }, - { - range: { - '@timestamp': { - gte: from, - lte: to, - }, + }, + { + range: { + '@timestamp': { + gte: from, + lte: to, }, }, - // append user filters, if defined - ...(filters?.bool ? [filters] : []), - ], - }, + }, + // append user filters, if defined + ...(filters?.bool ? [filters] : []), + ], }, - size: 0, - aggs: { - monitors: { - composite: { - size: 2000, - sources: [ - { - monitorId: { - terms: { - field: 'monitor.id', - }, + }, + size: 0, + aggs: { + monitors: { + composite: { + size: 2000, + /** + * We "paginate" results by utilizing the `afterKey` field + * to tell Elasticsearch where it should start on subsequent queries. + */ + ...(afterKey ? { after: afterKey } : {}), + sources: [ + { + monitorId: { + terms: { + field: 'monitor.id', }, }, - { - status: { - terms: { - field: 'monitor.status', - }, + }, + { + status: { + terms: { + field: 'monitor.status', }, }, - { - location: { - terms: { - field: 'observer.geo.name', - missing_bucket: true, - }, + }, + { + location: { + terms: { + field: 'observer.geo.name', + missing_bucket: true, }, }, - ], - }, - aggs: { - fields: { - top_hits: { - size: 1, - }, + }, + ], + }, + aggs: { + fields: { + top_hits: { + size: 1, }, }, }, @@ -122,19 +120,14 @@ export const getMonitorStatus: UMElasticsearchQueryFn< * Perform a logical `and` against the selected location filters. */ if (locations.length) { - esParams.body.query.bool.filter.push(getLocationClause(locations)); + esParams.query.bool.filter.push(getLocationClause(locations)); } - /** - * We "paginate" results by utilizing the `afterKey` field - * to tell Elasticsearch where it should start on subsequent queries. - */ - if (afterKey) { - esParams.body.aggs.monitors.composite.after = afterKey; - } + const { body: result } = await uptimeEsClient.search({ + body: esParams, + }); - const { body: result } = await callES.search(esParams); - afterKey = result?.aggregations?.monitors?.after_key; + afterKey = result?.aggregations?.monitors?.after_key as AfterKey; monitors = monitors.concat(result?.aggregations?.monitors?.buckets || []); } while (afterKey !== undefined); diff --git a/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts b/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts index 4eb2d862cb702..325c7b0e2edef 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UMElasticsearchQueryFn } from '../adapters'; import { getFilterClause } from '../helper'; import { HistogramResult, HistogramQueryResult } from '../../../common/runtime_types'; import { QUERY } from '../../../common/constants'; import { getHistogramInterval } from '../helper/get_histogram_interval'; +import { UMElasticsearchQueryFn } from '../adapters/framework'; export interface GetPingHistogramParams { /** @member dateRangeStart timestamp bounds */ @@ -26,7 +26,7 @@ export interface GetPingHistogramParams { export const getPingHistogram: UMElasticsearchQueryFn< GetPingHistogramParams, HistogramResult -> = async ({ callES, dynamicSettings, from, to, filters, monitorId, bucketSize }) => { +> = async ({ uptimeEsClient, from, to, filters, monitorId, bucketSize }) => { const boolFilters = filters ? JSON.parse(filters) : null; const additionalFilters = []; if (monitorId) { @@ -40,34 +40,31 @@ export const getPingHistogram: UMElasticsearchQueryFn< const minInterval = getHistogramInterval(from, to, QUERY.DEFAULT_BUCKET_COUNT); const params = { - index: dynamicSettings.heartbeatIndices, - body: { - query: { - bool: { - filter, - }, + query: { + bool: { + filter, }, - size: 0, - aggs: { - timeseries: { - date_histogram: { - field: '@timestamp', - fixed_interval: bucketSize || minInterval + 'ms', - missing: 0, - }, - aggs: { - down: { - filter: { - term: { - 'monitor.status': 'down', - }, + }, + size: 0, + aggs: { + timeseries: { + date_histogram: { + field: '@timestamp', + fixed_interval: bucketSize || minInterval + 'ms', + missing: 0, + }, + aggs: { + down: { + filter: { + term: { + 'monitor.status': 'down', }, }, - up: { - filter: { - term: { - 'monitor.status': 'up', - }, + }, + up: { + filter: { + term: { + 'monitor.status': 'up', }, }, }, @@ -76,7 +73,7 @@ export const getPingHistogram: UMElasticsearchQueryFn< }, }; - const { body: result } = await callES.search(params); + const { body: result } = await uptimeEsClient.search({ body: params }); const buckets: HistogramQueryResult[] = result?.aggregations?.timeseries?.buckets ?? []; const histogram = buckets.map((bucket) => { const x: number = bucket.key; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_pings.ts b/x-pack/plugins/uptime/server/lib/requests/get_pings.ts index e72b16de3d66f..3b852ad1a7381 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_pings.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_pings.ts @@ -52,8 +52,7 @@ const REMOVE_NON_SUMMARY_BROWSER_CHECKS = { }; export const getPings: UMElasticsearchQueryFn = async ({ - callES, - dynamicSettings, + uptimeEsClient, dateRange: { from, to }, index, monitorId, @@ -63,56 +62,39 @@ export const getPings: UMElasticsearchQueryFn = a location, }) => { const size = sizeParam ?? DEFAULT_PAGE_SIZE; - const sortParam = { sort: [{ '@timestamp': { order: sort ?? 'desc' } }] }; - const filter: any[] = [{ range: { '@timestamp': { gte: from, lte: to } } }]; - if (monitorId) { - filter.push({ term: { 'monitor.id': monitorId } }); - } - if (status) { - filter.push({ term: { 'monitor.status': status } }); - } - let postFilterClause = {}; - if (location) { - postFilterClause = { post_filter: { term: { 'observer.geo.name': location } } }; - } - const queryContext = { - bool: { - filter, - ...REMOVE_NON_SUMMARY_BROWSER_CHECKS, - }, - }; - const params: any = { - index: dynamicSettings.heartbeatIndices, - body: { - query: { - ...queryContext, + const searchBody = { + size, + ...(index ? { from: index * size } : {}), + query: { + bool: { + filter: [ + { range: { '@timestamp': { gte: from, lte: to } } }, + ...(monitorId ? [{ term: { 'monitor.id': monitorId } }] : []), + ...(status ? [{ term: { 'monitor.status': status } }] : []), + ], + ...REMOVE_NON_SUMMARY_BROWSER_CHECKS, }, - ...sortParam, - size, - aggregations: { - locations: { - terms: { - field: 'observer.geo.name', - missing: 'N/A', - size: 1000, - }, + }, + sort: [{ '@timestamp': { order: (sort ?? 'desc') as 'asc' | 'desc' } }], + aggs: { + locations: { + terms: { + field: 'observer.geo.name', + missing: 'N/A', + size: 1000, }, }, - ...postFilterClause, }, + ...(location ? { post_filter: { term: { 'observer.geo.name': location } } } : {}), }; - if (index) { - params.body.from = index * size; - } - const { body: { hits: { hits, total }, aggregations: aggs, }, - } = await callES.search(params); + } = await uptimeEsClient.search({ body: searchBody }); const locations = aggs?.locations ?? { buckets: [{ key: 'N/A', doc_count: 0 }] }; @@ -131,7 +113,7 @@ export const getPings: UMElasticsearchQueryFn = a return { total: total.value, - locations: locations.buckets.map((bucket: { key: string }) => bucket.key), + locations: locations.buckets.map((bucket) => bucket.key as string), pings, }; }; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_snapshot_counts.ts b/x-pack/plugins/uptime/server/lib/requests/get_snapshot_counts.ts index ac36585ff0939..9df20c79a6106 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_snapshot_counts.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_snapshot_counts.ts @@ -16,15 +16,13 @@ export interface GetSnapshotCountParams { } export const getSnapshotCount: UMElasticsearchQueryFn = async ({ - callES, - dynamicSettings: { heartbeatIndices }, + uptimeEsClient, dateRangeStart, dateRangeEnd, filters, }): Promise => { const context = new QueryContext( - callES, - heartbeatIndices, + uptimeEsClient, dateRangeStart, dateRangeEnd, CONTEXT_DEFAULTS.CURSOR_PAGINATION, @@ -40,7 +38,6 @@ export const getSnapshotCount: UMElasticsearchQueryFn => { const { body: res } = await context.search({ - index: context.heartbeatIndices, body: statusCountBody(await context.dateAndCustomFilters()), }); diff --git a/x-pack/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts index e53fff429dd8d..b4de286a5b92d 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts @@ -19,9 +19,7 @@ describe(QueryContext, () => { }; let qc: QueryContext; - beforeEach( - () => (qc = new QueryContext({}, 'indexName', rangeStart, rangeEnd, pagination, null, 10)) - ); + beforeEach(() => (qc = new QueryContext({}, rangeStart, rangeEnd, pagination, null, 10))); describe('dateRangeFilter()', () => { const expectedRange = { diff --git a/x-pack/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts index 40775bde1c7f5..205b283d40d6a 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts @@ -8,13 +8,6 @@ import { CursorPagination } from '../types'; import { CursorDirection, SortOrder } from '../../../../../common/runtime_types'; import { QueryContext } from '../query_context'; -export const prevPagination = (key: any): CursorPagination => { - return { - cursorDirection: CursorDirection.BEFORE, - sortOrder: SortOrder.ASC, - cursorKey: key, - }; -}; export const nextPagination = (key: any): CursorPagination => { return { cursorDirection: CursorDirection.AFTER, @@ -23,14 +16,5 @@ export const nextPagination = (key: any): CursorPagination => { }; }; export const simpleQueryContext = (): QueryContext => { - return new QueryContext( - undefined, - 'indexName', - '', - '', - nextPagination('something'), - undefined, - 0, - '' - ); + return new QueryContext(undefined, '', '', nextPagination('something'), undefined, 0, ''); }; diff --git a/x-pack/plugins/uptime/server/lib/requests/search/find_potential_matches.ts b/x-pack/plugins/uptime/server/lib/requests/search/find_potential_matches.ts index 38e7dabb19941..2331d991e3af3 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/find_potential_matches.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/find_potential_matches.ts @@ -36,7 +36,6 @@ const query = async (queryContext: QueryContext, searchAfter: any, size: number) const body = await queryBody(queryContext, searchAfter, size); const params = { - index: queryContext.heartbeatIndices, body, }; diff --git a/x-pack/plugins/uptime/server/lib/requests/search/query_context.ts b/x-pack/plugins/uptime/server/lib/requests/search/query_context.ts index 96df8ea651c44..bcfb3035920fb 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/query_context.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/query_context.ts @@ -12,7 +12,6 @@ import { CursorDirection, SortOrder } from '../../../../common/runtime_types'; export class QueryContext { callES: ElasticsearchClient; - heartbeatIndices: string; dateRangeStart: string; dateRangeEnd: string; pagination: CursorPagination; @@ -23,7 +22,6 @@ export class QueryContext { constructor( database: any, - heartbeatIndices: string, dateRangeStart: string, dateRangeEnd: string, pagination: CursorPagination, @@ -32,7 +30,6 @@ export class QueryContext { statusFilter?: string ) { this.callES = database; - this.heartbeatIndices = heartbeatIndices; this.dateRangeStart = dateRangeStart; this.dateRangeEnd = dateRangeEnd; this.pagination = pagination; @@ -42,12 +39,10 @@ export class QueryContext { } async search(params: any): Promise { - params.index = this.heartbeatIndices; - return this.callES.search(params); + return this.callES.search({ body: params.body }); } async count(params: any): Promise { - params.index = this.heartbeatIndices; return this.callES.count(params); } @@ -138,7 +133,6 @@ export class QueryContext { clone(): QueryContext { return new QueryContext( this.callES, - this.heartbeatIndices, this.dateRangeStart, this.dateRangeEnd, this.pagination, diff --git a/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts b/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts index 6be9f813016f8..dc3af2805d13f 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts @@ -109,7 +109,6 @@ export const query = async ( potentialMatchMonitorIDs: string[] ): Promise => { const params = { - index: queryContext.heartbeatIndices, body: { size: 0, query: { diff --git a/x-pack/plugins/uptime/server/lib/saved_objects.ts b/x-pack/plugins/uptime/server/lib/saved_objects.ts index 2eec9e233f5d2..a9191dde3df4c 100644 --- a/x-pack/plugins/uptime/server/lib/saved_objects.ts +++ b/x-pack/plugins/uptime/server/lib/saved_objects.ts @@ -48,7 +48,7 @@ export const savedObjectsAdapter: UMSavedObjectsAdapter = { getUptimeDynamicSettings: async (client): Promise => { try { const obj = await client.get(umDynamicSettings.name, settingsObjectId); - return obj.attributes; + return obj?.attributes ?? DYNAMIC_SETTINGS_DEFAULTS; } catch (getErr) { if (SavedObjectsErrorHelpers.isNotFoundError(getErr)) { return DYNAMIC_SETTINGS_DEFAULTS; diff --git a/x-pack/plugins/uptime/server/rest_api/certs/certs.ts b/x-pack/plugins/uptime/server/rest_api/certs/certs.ts index fb22d603a2d56..d377095a2a370 100644 --- a/x-pack/plugins/uptime/server/rest_api/certs/certs.ts +++ b/x-pack/plugins/uptime/server/rest_api/certs/certs.ts @@ -30,7 +30,7 @@ export const createGetCertsRoute: UMRestApiRouteFactory = (libs: UMServerLibs) = direction: schema.maybe(schema.string()), }), }, - handler: async ({ callES, dynamicSettings }, _context, request, response): Promise => { + handler: async ({ uptimeEsClient }, _context, request, response): Promise => { const index = request.query?.index ?? 0; const size = request.query?.size ?? DEFAULT_SIZE; const from = request.query?.from ?? DEFAULT_FROM; @@ -39,8 +39,7 @@ export const createGetCertsRoute: UMRestApiRouteFactory = (libs: UMServerLibs) = const direction = request.query?.direction ?? DEFAULT_DIRECTION; const { search } = request.query; const result = await libs.requests.getCerts({ - callES, - dynamicSettings, + uptimeEsClient, index, search, size, diff --git a/x-pack/plugins/uptime/server/rest_api/dynamic_settings.ts b/x-pack/plugins/uptime/server/rest_api/dynamic_settings.ts index 98e995173d811..f7be9e10d1004 100644 --- a/x-pack/plugins/uptime/server/rest_api/dynamic_settings.ts +++ b/x-pack/plugins/uptime/server/rest_api/dynamic_settings.ts @@ -20,7 +20,9 @@ export const createGetDynamicSettingsRoute: UMRestApiRouteFactory = (libs: UMSer method: 'GET', path: '/api/uptime/dynamic_settings', validate: false, - handler: async ({ dynamicSettings }, _context, _request, response): Promise => { + handler: async ({ savedObjectsClient }, _context, _request, response): Promise => { + const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings(savedObjectsClient); + return response.ok({ body: dynamicSettings, }); diff --git a/x-pack/plugins/uptime/server/rest_api/index_state/get_index_pattern.ts b/x-pack/plugins/uptime/server/rest_api/index_state/get_index_pattern.ts index 418cde9e701d5..5c1be4cdd8143 100644 --- a/x-pack/plugins/uptime/server/rest_api/index_state/get_index_pattern.ts +++ b/x-pack/plugins/uptime/server/rest_api/index_state/get_index_pattern.ts @@ -12,13 +12,12 @@ export const createGetIndexPatternRoute: UMRestApiRouteFactory = (libs: UMServer method: 'GET', path: API_URLS.INDEX_PATTERN, validate: false, - handler: async ({ callES, dynamicSettings }, _context, _request, response): Promise => { + handler: async ({ uptimeEsClient }, _context, _request, response): Promise => { try { return response.ok({ body: { ...(await libs.requests.getIndexPattern({ - esClient: callES, - dynamicSettings, + uptimeEsClient, })), }, }); diff --git a/x-pack/plugins/uptime/server/rest_api/index_state/get_index_status.ts b/x-pack/plugins/uptime/server/rest_api/index_state/get_index_status.ts index 9a4280efa98f9..e57643aed7e36 100644 --- a/x-pack/plugins/uptime/server/rest_api/index_state/get_index_status.ts +++ b/x-pack/plugins/uptime/server/rest_api/index_state/get_index_status.ts @@ -12,11 +12,13 @@ export const createGetIndexStatusRoute: UMRestApiRouteFactory = (libs: UMServerL method: 'GET', path: API_URLS.INDEX_STATUS, validate: false, - handler: async ({ callES, dynamicSettings }, _context, _request, response): Promise => { + handler: async ({ uptimeEsClient }, _context, _request, response): Promise => { try { return response.ok({ body: { - ...(await libs.requests.getIndexStatus({ callES, dynamicSettings })), + ...(await libs.requests.getIndexStatus({ + uptimeEsClient, + })), }, }); } catch (e) { diff --git a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_list.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_list.ts index 7b461060bf4bc..3eac49341b2c2 100644 --- a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_list.ts +++ b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_list.ts @@ -24,7 +24,7 @@ export const createMonitorListRoute: UMRestApiRouteFactory = (libs) => ({ options: { tags: ['access:uptime-read'], }, - handler: async ({ callES, dynamicSettings }, _context, request, response): Promise => { + handler: async ({ uptimeEsClient }, _context, request, response): Promise => { try { const { dateRangeStart, @@ -42,10 +42,9 @@ export const createMonitorListRoute: UMRestApiRouteFactory = (libs) => ({ indexStatus, { summaries, nextPagePagination, prevPagePagination }, ] = await Promise.all([ - libs.requests.getIndexStatus({ callES, dynamicSettings }), + libs.requests.getIndexStatus({ uptimeEsClient }), libs.requests.getMonitorStates({ - callES, - dynamicSettings, + uptimeEsClient, dateRangeStart, dateRangeEnd, pagination: decodedPagination, diff --git a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_locations.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_locations.ts index a110209043a7e..e2dbf7114fc91 100644 --- a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_locations.ts +++ b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_locations.ts @@ -19,14 +19,13 @@ export const createGetMonitorLocationsRoute: UMRestApiRouteFactory = (libs: UMSe dateEnd: schema.string(), }), }, - handler: async ({ callES, dynamicSettings }, _context, request, response): Promise => { + handler: async ({ uptimeEsClient }, _context, request, response): Promise => { const { monitorId, dateStart, dateEnd } = request.query; return response.ok({ body: { ...(await libs.requests.getMonitorLocations({ - callES, - dynamicSettings, + uptimeEsClient, monitorId, dateStart, dateEnd, diff --git a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_status.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_status.ts index bb002f8a8c286..3d47f0eab8640 100644 --- a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_status.ts +++ b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_status.ts @@ -20,11 +20,10 @@ export const createGetStatusBarRoute: UMRestApiRouteFactory = (libs: UMServerLib dateEnd: schema.string(), }), }, - handler: async ({ callES, dynamicSettings }, _context, request, response): Promise => { + handler: async ({ uptimeEsClient }, _context, request, response): Promise => { const { monitorId, dateStart, dateEnd } = request.query; const result = await libs.requests.getLatestMonitor({ - callES, - dynamicSettings, + uptimeEsClient, monitorId, dateStart, dateEnd, diff --git a/x-pack/plugins/uptime/server/rest_api/monitors/monitors_details.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitors_details.ts index bb54effc0d57e..0982fc1986604 100644 --- a/x-pack/plugins/uptime/server/rest_api/monitors/monitors_details.ts +++ b/x-pack/plugins/uptime/server/rest_api/monitors/monitors_details.ts @@ -19,7 +19,7 @@ export const createGetMonitorDetailsRoute: UMRestApiRouteFactory = (libs: UMServ dateEnd: schema.maybe(schema.string()), }), }, - handler: async ({ callES, dynamicSettings }, context, request, response): Promise => { + handler: async ({ uptimeEsClient }, context, request, response): Promise => { const { monitorId, dateStart, dateEnd } = request.query; const alertsClient = context.alerting?.getAlertsClient(); @@ -27,8 +27,7 @@ export const createGetMonitorDetailsRoute: UMRestApiRouteFactory = (libs: UMServ return response.ok({ body: { ...(await libs.requests.getMonitorDetails({ - callES, - dynamicSettings, + uptimeEsClient, monitorId, dateStart, dateEnd, diff --git a/x-pack/plugins/uptime/server/rest_api/monitors/monitors_durations.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitors_durations.ts index a4e024e795b46..eec3fdf9e7257 100644 --- a/x-pack/plugins/uptime/server/rest_api/monitors/monitors_durations.ts +++ b/x-pack/plugins/uptime/server/rest_api/monitors/monitors_durations.ts @@ -20,14 +20,13 @@ export const createGetMonitorDurationRoute: UMRestApiRouteFactory = (libs: UMSer dateEnd: schema.string(), }), }, - handler: async ({ callES, dynamicSettings }, _context, request, response): Promise => { + handler: async ({ uptimeEsClient }, _context, request, response): Promise => { const { monitorId, dateStart, dateEnd } = request.query; return response.ok({ body: { ...(await libs.requests.getMonitorDurationChart({ - callES, - dynamicSettings, + uptimeEsClient, monitorId, dateStart, dateEnd, diff --git a/x-pack/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts b/x-pack/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts index 00cbaf0d16723..163fbd4f8dd6e 100644 --- a/x-pack/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts +++ b/x-pack/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts @@ -28,7 +28,7 @@ export const createGetOverviewFilters: UMRestApiRouteFactory = (libs: UMServerLi tags: arrayOrStringType, }), }, - handler: async ({ callES, dynamicSettings }, _context, request, response) => { + handler: async ({ uptimeEsClient }, _context, request, response) => { const { dateRangeStart, dateRangeEnd, locations, schemes, search, ports, tags } = request.query; let parsedSearch: Record | undefined; @@ -41,8 +41,7 @@ export const createGetOverviewFilters: UMRestApiRouteFactory = (libs: UMServerLi } const filtersResponse = await libs.requests.getFilterBar({ - callES, - dynamicSettings, + uptimeEsClient, dateRangeStart, dateRangeEnd, search: parsedSearch, diff --git a/x-pack/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts b/x-pack/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts index 4ac50d0e78c4c..ba36b171793b7 100644 --- a/x-pack/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts +++ b/x-pack/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts @@ -21,12 +21,11 @@ export const createGetPingHistogramRoute: UMRestApiRouteFactory = (libs: UMServe bucketSize: schema.maybe(schema.string()), }), }, - handler: async ({ callES, dynamicSettings }, _context, request, response): Promise => { + handler: async ({ uptimeEsClient }, _context, request, response): Promise => { const { dateStart, dateEnd, monitorId, filters, bucketSize } = request.query; const result = await libs.requests.getPingHistogram({ - callES, - dynamicSettings, + uptimeEsClient, from: dateStart, to: dateEnd, monitorId, diff --git a/x-pack/plugins/uptime/server/rest_api/pings/get_pings.ts b/x-pack/plugins/uptime/server/rest_api/pings/get_pings.ts index d97195a7fe2b1..d00386d06c74c 100644 --- a/x-pack/plugins/uptime/server/rest_api/pings/get_pings.ts +++ b/x-pack/plugins/uptime/server/rest_api/pings/get_pings.ts @@ -27,7 +27,7 @@ export const createGetPingsRoute: UMRestApiRouteFactory = (libs: UMServerLibs) = status: schema.maybe(schema.string()), }), }, - handler: async ({ callES, dynamicSettings }, _context, request, response): Promise => { + handler: async ({ uptimeEsClient }, _context, request, response): Promise => { const { from, to, ...optional } = request.query; const params = GetPingsParamsType.decode({ dateRange: { from, to }, ...optional }); if (isLeft(params)) { @@ -37,8 +37,7 @@ export const createGetPingsRoute: UMRestApiRouteFactory = (libs: UMServerLibs) = } const result = await libs.requests.getPings({ - callES, - dynamicSettings, + uptimeEsClient, ...params.right, }); diff --git a/x-pack/plugins/uptime/server/rest_api/pings/journey_screenshots.ts b/x-pack/plugins/uptime/server/rest_api/pings/journey_screenshots.ts index 1fc52dd24f9d0..161d7dd558fdb 100644 --- a/x-pack/plugins/uptime/server/rest_api/pings/journey_screenshots.ts +++ b/x-pack/plugins/uptime/server/rest_api/pings/journey_screenshots.ts @@ -17,11 +17,10 @@ export const createJourneyScreenshotRoute: UMRestApiRouteFactory = (libs: UMServ stepIndex: schema.number(), }), }, - handler: async ({ callES, dynamicSettings }, _context, request, response) => { + handler: async ({ uptimeEsClient }, _context, request, response) => { const { checkGroup, stepIndex } = request.params; const result = await libs.requests.getJourneyScreenshot({ - callES, - dynamicSettings, + uptimeEsClient, checkGroup, stepIndex, }); diff --git a/x-pack/plugins/uptime/server/rest_api/pings/journeys.ts b/x-pack/plugins/uptime/server/rest_api/pings/journeys.ts index b6e06850ad3b6..5b8583ea0322f 100644 --- a/x-pack/plugins/uptime/server/rest_api/pings/journeys.ts +++ b/x-pack/plugins/uptime/server/rest_api/pings/journeys.ts @@ -16,11 +16,10 @@ export const createJourneyRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => checkGroup: schema.string(), }), }, - handler: async ({ callES, dynamicSettings }, _context, request, response) => { + handler: async ({ uptimeEsClient }, _context, request, response) => { const { checkGroup } = request.params; const result = await libs.requests.getJourneySteps({ - callES, - dynamicSettings, + uptimeEsClient, checkGroup, }); diff --git a/x-pack/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts b/x-pack/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts index 9502335e4e5a8..224ef87fd90af 100644 --- a/x-pack/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts +++ b/x-pack/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts @@ -19,11 +19,10 @@ export const createGetSnapshotCount: UMRestApiRouteFactory = (libs: UMServerLibs filters: schema.maybe(schema.string()), }), }, - handler: async ({ callES, dynamicSettings }, _context, request, response): Promise => { + handler: async ({ uptimeEsClient }, _context, request, response): Promise => { const { dateRangeStart, dateRangeEnd, filters } = request.query; const result = await libs.requests.getSnapshotCount({ - callES, - dynamicSettings, + uptimeEsClient, dateRangeStart, dateRangeEnd, filters, diff --git a/x-pack/plugins/uptime/server/rest_api/telemetry/log_page_view.ts b/x-pack/plugins/uptime/server/rest_api/telemetry/log_page_view.ts index 9881d41f3bf2b..85f274c96cf9a 100644 --- a/x-pack/plugins/uptime/server/rest_api/telemetry/log_page_view.ts +++ b/x-pack/plugins/uptime/server/rest_api/telemetry/log_page_view.ts @@ -24,7 +24,7 @@ export const createLogPageViewRoute: UMRestApiRouteFactory = () => ({ }), }, handler: async ( - { savedObjectsClient, callES, dynamicSettings }, + { savedObjectsClient, uptimeEsClient }, _context, request, response @@ -33,7 +33,10 @@ export const createLogPageViewRoute: UMRestApiRouteFactory = () => ({ if (pageView.refreshTelemetryHistory) { KibanaTelemetryAdapter.clearLocalTelemetry(); } - await KibanaTelemetryAdapter.countNoOfUniqueMonitorAndLocations(callES, savedObjectsClient); + await KibanaTelemetryAdapter.countNoOfUniqueMonitorAndLocations( + uptimeEsClient, + savedObjectsClient + ); const pageViewResult = KibanaTelemetryAdapter.countPageView(pageView as PageViewParams); return response.ok({ diff --git a/x-pack/plugins/uptime/server/rest_api/types.ts b/x-pack/plugins/uptime/server/rest_api/types.ts index 5e5f4a2a991cf..df1762a3b318d 100644 --- a/x-pack/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/plugins/uptime/server/rest_api/types.ts @@ -15,10 +15,8 @@ import { KibanaResponseFactory, IKibanaResponse, IScopedClusterClient, - ElasticsearchClient, } from 'kibana/server'; -import { DynamicSettings } from '../../common/runtime_types'; -import { UMServerLibs } from '../lib/lib'; +import { UMServerLibs, UptimeESClient } from '../lib/lib'; /** * Defines the basic properties employed by Uptime routes. @@ -64,9 +62,8 @@ export type UMKibanaRouteWrapper = (uptimeRoute: UptimeRoute) => UMKibanaRoute; * This type can store custom parameters used by the internal Uptime route handlers. */ export interface UMRouteParams { - callES: ElasticsearchClient; + uptimeEsClient: UptimeESClient; esClient: IScopedClusterClient; - dynamicSettings: DynamicSettings; savedObjectsClient: SavedObjectsClientContract; } diff --git a/x-pack/plugins/uptime/server/rest_api/uptime_route_wrapper.ts b/x-pack/plugins/uptime/server/rest_api/uptime_route_wrapper.ts index b2f1c7d6424e6..a1cf3c05e2de3 100644 --- a/x-pack/plugins/uptime/server/rest_api/uptime_route_wrapper.ts +++ b/x-pack/plugins/uptime/server/rest_api/uptime_route_wrapper.ts @@ -5,7 +5,7 @@ */ import { UMKibanaRouteWrapper } from './types'; -import { savedObjectsAdapter } from '../lib/saved_objects'; +import { createUptimeESClient } from '../lib/lib'; export const uptimeRouteWrapper: UMKibanaRouteWrapper = (uptimeRoute) => ({ ...uptimeRoute, @@ -15,9 +15,14 @@ export const uptimeRouteWrapper: UMKibanaRouteWrapper = (uptimeRoute) => ({ handler: async (context, request, response) => { const { client: esClient } = context.core.elasticsearch; const { client: savedObjectsClient } = context.core.savedObjects; - const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings(savedObjectsClient); + + const uptimeEsClient = createUptimeESClient({ + savedObjectsClient, + esClient: esClient.asCurrentUser, + }); + return uptimeRoute.handler( - { callES: esClient.asCurrentUser, esClient, savedObjectsClient, dynamicSettings }, + { uptimeEsClient, esClient, savedObjectsClient }, context, request, response diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts index 937045b6218c6..d3cd3db124ecd 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts @@ -17,7 +17,8 @@ export default function eventLogTests({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const retry = getService('retry'); - describe('eventLog', () => { + // FLAKY: https://github.com/elastic/kibana/issues/81668 + describe.skip('eventLog', () => { const objectRemover = new ObjectRemover(supertest); after(() => objectRemover.removeAll()); diff --git a/x-pack/test/api_integration/apis/metrics_ui/log_entries.ts b/x-pack/test/api_integration/apis/metrics_ui/log_entries.ts index 2928027e88f33..2d148f4c2c0f7 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/log_entries.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/log_entries.ts @@ -7,11 +7,7 @@ import expect from '@kbn/expect'; import { v4 as uuidv4 } from 'uuid'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { fold } from 'fp-ts/lib/Either'; - -import { createPlainError, throwErrors } from '../../../../plugins/infra/common/runtime_types'; +import { decodeOrThrow } from '../../../../plugins/infra/common/runtime_types'; import { LOG_ENTRIES_PATH, @@ -68,10 +64,7 @@ export default function ({ getService }: FtrProviderContext) { ) .expect(200); - const logEntriesResponse = pipe( - logEntriesResponseRT.decode(body), - fold(throwErrors(createPlainError), identity) - ); + const logEntriesResponse = decodeOrThrow(logEntriesResponseRT)(body); const entries = logEntriesResponse.data.entries; const firstEntry = entries[0]; @@ -104,10 +97,7 @@ export default function ({ getService }: FtrProviderContext) { ) .expect(200); - const logEntriesResponse = pipe( - logEntriesResponseRT.decode(body), - fold(throwErrors(createPlainError), identity) - ); + const logEntriesResponse = decodeOrThrow(logEntriesResponseRT)(body); const entries = logEntriesResponse.data.entries; const entry = entries[0]; @@ -126,6 +116,52 @@ export default function ({ getService }: FtrProviderContext) { expect(messageColumn.message.length).to.be.greaterThan(0); }); + it('Returns custom column configurations', async () => { + const customColumns = [ + { timestampColumn: { id: uuidv4() } }, + { fieldColumn: { id: uuidv4(), field: 'host.name' } }, + { fieldColumn: { id: uuidv4(), field: 'event.dataset' } }, + { messageColumn: { id: uuidv4() } }, + ]; + + const { body } = await supertest + .post(LOG_ENTRIES_PATH) + .set(COMMON_HEADERS) + .send( + logEntriesRequestRT.encode({ + sourceId: 'default', + startTimestamp: EARLIEST_KEY_WITH_DATA.time, + endTimestamp: LATEST_KEY_WITH_DATA.time, + center: KEY_WITHIN_DATA_RANGE, + columns: customColumns, + }) + ) + .expect(200); + + const logEntriesResponse = decodeOrThrow(logEntriesResponseRT)(body); + + const entries = logEntriesResponse.data.entries; + const entry = entries[0]; + expect(entry.columns).to.have.length(4); + + const timestampColumn = entry.columns[0] as LogTimestampColumn; + expect(timestampColumn).to.have.property('timestamp'); + + const hostNameColumn = entry.columns[1] as LogFieldColumn; + expect(hostNameColumn).to.have.property('field'); + expect(hostNameColumn.field).to.be('host.name'); + expect(hostNameColumn).to.have.property('value'); + + const eventDatasetColumn = entry.columns[2] as LogFieldColumn; + expect(eventDatasetColumn).to.have.property('field'); + expect(eventDatasetColumn.field).to.be('event.dataset'); + expect(eventDatasetColumn).to.have.property('value'); + + const messageColumn = entry.columns[3] as LogMessageColumn; + expect(messageColumn).to.have.property('message'); + expect(messageColumn.message.length).to.be.greaterThan(0); + }); + it('Does not build context if entry does not have all fields', async () => { const { body } = await supertest .post(LOG_ENTRIES_PATH) @@ -140,10 +176,7 @@ export default function ({ getService }: FtrProviderContext) { ) .expect(200); - const logEntriesResponse = pipe( - logEntriesResponseRT.decode(body), - fold(throwErrors(createPlainError), identity) - ); + const logEntriesResponse = decodeOrThrow(logEntriesResponseRT)(body); const entries = logEntriesResponse.data.entries; const entry = entries[0]; @@ -162,10 +195,7 @@ export default function ({ getService }: FtrProviderContext) { size: 10, }) ); - const firstPage = pipe( - logEntriesResponseRT.decode(firstPageBody), - fold(throwErrors(createPlainError), identity) - ); + const firstPage = decodeOrThrow(logEntriesResponseRT)(firstPageBody); const { body: secondPageBody } = await supertest .post(LOG_ENTRIES_PATH) @@ -179,10 +209,7 @@ export default function ({ getService }: FtrProviderContext) { size: 10, }) ); - const secondPage = pipe( - logEntriesResponseRT.decode(secondPageBody), - fold(throwErrors(createPlainError), identity) - ); + const secondPage = decodeOrThrow(logEntriesResponseRT)(secondPageBody); const { body: bothPagesBody } = await supertest .post(LOG_ENTRIES_PATH) @@ -195,10 +222,7 @@ export default function ({ getService }: FtrProviderContext) { size: 20, }) ); - const bothPages = pipe( - logEntriesResponseRT.decode(bothPagesBody), - fold(throwErrors(createPlainError), identity) - ); + const bothPages = decodeOrThrow(logEntriesResponseRT)(bothPagesBody); expect(bothPages.data.entries).to.eql([ ...firstPage.data.entries, @@ -222,10 +246,7 @@ export default function ({ getService }: FtrProviderContext) { size: 10, }) ); - const lastPage = pipe( - logEntriesResponseRT.decode(lastPageBody), - fold(throwErrors(createPlainError), identity) - ); + const lastPage = decodeOrThrow(logEntriesResponseRT)(lastPageBody); const { body: secondToLastPageBody } = await supertest .post(LOG_ENTRIES_PATH) @@ -239,10 +260,7 @@ export default function ({ getService }: FtrProviderContext) { size: 10, }) ); - const secondToLastPage = pipe( - logEntriesResponseRT.decode(secondToLastPageBody), - fold(throwErrors(createPlainError), identity) - ); + const secondToLastPage = decodeOrThrow(logEntriesResponseRT)(secondToLastPageBody); const { body: bothPagesBody } = await supertest .post(LOG_ENTRIES_PATH) @@ -256,10 +274,7 @@ export default function ({ getService }: FtrProviderContext) { size: 20, }) ); - const bothPages = pipe( - logEntriesResponseRT.decode(bothPagesBody), - fold(throwErrors(createPlainError), identity) - ); + const bothPages = decodeOrThrow(logEntriesResponseRT)(bothPagesBody); expect(bothPages.data.entries).to.eql([ ...secondToLastPage.data.entries, @@ -283,10 +298,7 @@ export default function ({ getService }: FtrProviderContext) { }) ) .expect(200); - const logEntriesResponse = pipe( - logEntriesResponseRT.decode(body), - fold(throwErrors(createPlainError), identity) - ); + const logEntriesResponse = decodeOrThrow(logEntriesResponseRT)(body); const entries = logEntriesResponse.data.entries; const firstEntry = entries[0]; @@ -313,10 +325,7 @@ export default function ({ getService }: FtrProviderContext) { ) .expect(200); - const logEntriesResponse = pipe( - logEntriesResponseRT.decode(body), - fold(throwErrors(createPlainError), identity) - ); + const logEntriesResponse = decodeOrThrow(logEntriesResponseRT)(body); expect(logEntriesResponse.data.entries).to.have.length(0); expect(logEntriesResponse.data.topCursor).to.be(null); @@ -371,10 +380,7 @@ export default function ({ getService }: FtrProviderContext) { ) .expect(200); - const logEntriesResponse = pipe( - logEntriesResponseRT.decode(body), - fold(throwErrors(createPlainError), identity) - ); + const logEntriesResponse = decodeOrThrow(logEntriesResponseRT)(body); const entries = logEntriesResponse.data.entries; const entry = entries[0]; diff --git a/x-pack/test/fleet_api_integration/apis/epm/index.js b/x-pack/test/fleet_api_integration/apis/epm/index.js index 0cb998b9b7c35..332a66d350338 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/index.js +++ b/x-pack/test/fleet_api_integration/apis/epm/index.js @@ -16,6 +16,7 @@ export default function loadTests({ loadTestFile }) { loadTestFile(require.resolve('./install_overrides')); loadTestFile(require.resolve('./install_prerelease')); loadTestFile(require.resolve('./install_remove_assets')); + loadTestFile(require.resolve('./install_remove_multiple')); loadTestFile(require.resolve('./install_update')); loadTestFile(require.resolve('./bulk_upgrade')); loadTestFile(require.resolve('./update_assets')); diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_remove_multiple.ts b/x-pack/test/fleet_api_integration/apis/epm/install_remove_multiple.ts index 82072f59a482b..1e7612455a32c 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_remove_multiple.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_remove_multiple.ts @@ -5,6 +5,8 @@ */ import expect from '@kbn/expect'; +import path from 'path'; +import fs from 'fs'; import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; import { skipIfNoDockerRegistry } from '../../helpers'; @@ -22,6 +24,23 @@ export default function (providerContext: FtrProviderContext) { const experimental2PkgName = 'experimental2'; const experimental2PkgKey = `${experimental2PkgName}-${pkgVersion}`; + const uploadPkgKey = 'apache-0.1.4'; + + const installUploadPackage = async (pkg: string) => { + const buf = fs.readFileSync(testPkgArchiveZip); + await supertest + .post(`/api/fleet/epm/packages`) + .set('kbn-xsrf', 'xxxx') + .type('application/zip') + .send(buf) + .expect(200); + }; + + const testPkgArchiveZip = path.join( + path.dirname(__filename), + '../fixtures/direct_upload_packages/apache_0.1.4.zip' + ); + const uninstallPackage = async (pkg: string) => { await supertest.delete(`/api/fleet/epm/packages/${pkg}`).set('kbn-xsrf', 'xxxx'); }; @@ -40,11 +59,7 @@ export default function (providerContext: FtrProviderContext) { const uninstallingPackagesPromise = pkgs.map((pkg) => uninstallPackage(pkg)); return Promise.all(uninstallingPackagesPromise); }; - const expectPkgFieldToExist = async ( - fields: any[], - fieldName: string, - exists: boolean = true - ) => { + const expectPkgFieldToExist = (fields: any[], fieldName: string, exists: boolean = true) => { const fieldExists = fields.find((field: { name: string }) => field.name === fieldName); if (exists) { expect(fieldExists).not.to.be(undefined); @@ -57,12 +72,13 @@ export default function (providerContext: FtrProviderContext) { before(async () => { if (!server.enabled) return; await installPackages([pkgKey, experimentalPkgKey, experimental2PkgKey]); + await installUploadPackage(uploadPkgKey); }); after(async () => { if (!server.enabled) return; - await uninstallPackages([pkgKey, experimentalPkgKey, experimental2PkgKey]); + await uninstallPackages([pkgKey, experimentalPkgKey]); }); - it('should create index patterns from all installed packages, experimental or beta', async () => { + it('should create index patterns from all installed packages: uploaded, experimental, beta', async () => { const resIndexPatternLogs = await kibanaServer.savedObjects.get({ type: 'index-pattern', id: 'logs-*', @@ -73,6 +89,7 @@ export default function (providerContext: FtrProviderContext) { expectPkgFieldToExist(fieldsLogs, 'logs_test_name'); expectPkgFieldToExist(fieldsLogs, 'logs_experimental_name'); expectPkgFieldToExist(fieldsLogs, 'logs_experimental2_name'); + expectPkgFieldToExist(fieldsLogs, 'apache.error.uploadtest'); const resIndexPatternMetrics = await kibanaServer.savedObjects.get({ type: 'index-pattern', id: 'metrics-*', @@ -81,6 +98,7 @@ export default function (providerContext: FtrProviderContext) { expectPkgFieldToExist(fieldsMetrics, 'metrics_test_name'); expectPkgFieldToExist(fieldsMetrics, 'metrics_experimental_name'); expectPkgFieldToExist(fieldsMetrics, 'metrics_experimental2_name'); + expectPkgFieldToExist(fieldsMetrics, 'apache.status.uploadtest'); }); it('should correctly recreate index patterns when a package is uninstalled', async () => { await uninstallPackage(experimental2PkgKey); @@ -88,10 +106,11 @@ export default function (providerContext: FtrProviderContext) { type: 'index-pattern', id: 'logs-*', }); - const fields = JSON.parse(resIndexPatternLogs.attributes.fields); - expectPkgFieldToExist(fields, 'logs_test_name'); - expectPkgFieldToExist(fields, 'logs_experimental_name'); - expectPkgFieldToExist(fields, 'logs_experimental2_name', false); + const fieldsLogs = JSON.parse(resIndexPatternLogs.attributes.fields); + expectPkgFieldToExist(fieldsLogs, 'logs_test_name'); + expectPkgFieldToExist(fieldsLogs, 'logs_experimental_name'); + expectPkgFieldToExist(fieldsLogs, 'logs_experimental2_name', false); + expectPkgFieldToExist(fieldsLogs, 'apache.error.uploadtest'); const resIndexPatternMetrics = await kibanaServer.savedObjects.get({ type: 'index-pattern', id: 'metrics-*', @@ -101,6 +120,27 @@ export default function (providerContext: FtrProviderContext) { expectPkgFieldToExist(fieldsMetrics, 'metrics_test_name'); expectPkgFieldToExist(fieldsMetrics, 'metrics_experimental_name'); expectPkgFieldToExist(fieldsMetrics, 'metrics_experimental2_name', false); + expectPkgFieldToExist(fieldsMetrics, 'apache.status.uploadtest'); + }); + it('should correctly recreate index patterns when an uploaded package is uninstalled', async () => { + await uninstallPackage(uploadPkgKey); + const resIndexPatternLogs = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'logs-*', + }); + const fieldsLogs = JSON.parse(resIndexPatternLogs.attributes.fields); + expectPkgFieldToExist(fieldsLogs, 'logs_test_name'); + expectPkgFieldToExist(fieldsLogs, 'logs_experimental_name'); + expectPkgFieldToExist(fieldsLogs, 'apache.error.uploadtest', false); + const resIndexPatternMetrics = await kibanaServer.savedObjects.get({ + type: 'index-pattern', + id: 'metrics-*', + }); + const fieldsMetrics = JSON.parse(resIndexPatternMetrics.attributes.fields); + + expectPkgFieldToExist(fieldsMetrics, 'metrics_test_name'); + expectPkgFieldToExist(fieldsMetrics, 'metrics_experimental_name'); + expectPkgFieldToExist(fieldsMetrics, 'apache.status.uploadtest', false); }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/direct_upload_packages/apache_0.1.4.tar.gz b/x-pack/test/fleet_api_integration/apis/fixtures/direct_upload_packages/apache_0.1.4.tar.gz index b1f2ac6797fb3..c5d3607e05cb8 100644 Binary files a/x-pack/test/fleet_api_integration/apis/fixtures/direct_upload_packages/apache_0.1.4.tar.gz and b/x-pack/test/fleet_api_integration/apis/fixtures/direct_upload_packages/apache_0.1.4.tar.gz differ diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/direct_upload_packages/apache_0.1.4.zip b/x-pack/test/fleet_api_integration/apis/fixtures/direct_upload_packages/apache_0.1.4.zip index 2095ed0dba345..6a8a12b2f2d49 100644 Binary files a/x-pack/test/fleet_api_integration/apis/fixtures/direct_upload_packages/apache_0.1.4.zip and b/x-pack/test/fleet_api_integration/apis/fixtures/direct_upload_packages/apache_0.1.4.zip differ diff --git a/x-pack/test/functional/apps/lens/persistent_context.ts b/x-pack/test/functional/apps/lens/persistent_context.ts index 467a33fb01854..1d40a0579ccd1 100644 --- a/x-pack/test/functional/apps/lens/persistent_context.ts +++ b/x-pack/test/functional/apps/lens/persistent_context.ts @@ -68,10 +68,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('keeps selected index pattern after refresh', async () => { - await PageObjects.lens.switchDataPanelIndexPattern('otherpattern'); + await PageObjects.lens.switchDataPanelIndexPattern('log*'); await browser.refresh(); await PageObjects.header.waitUntilLoadingHasFinished(); - expect(await PageObjects.lens.getDataPanelIndexPattern()).to.equal('otherpattern'); + expect(await PageObjects.lens.getDataPanelIndexPattern()).to.equal('log*'); }); it('keeps time range and pinned filters after refreshing directly after saving', async () => { diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index 2375a8acb6442..29b42230673c9 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -327,9 +327,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should allow to change index pattern', async () => { - await PageObjects.lens.switchFirstLayerIndexPattern('otherpattern'); - expect(await PageObjects.lens.getFirstLayerIndexPattern()).to.equal('otherpattern'); - expect(await PageObjects.lens.isShowingNoResults()).to.equal(true); + await PageObjects.lens.switchFirstLayerIndexPattern('log*'); + expect(await PageObjects.lens.getFirstLayerIndexPattern()).to.equal('log*'); }); }); } diff --git a/x-pack/test/functional/es_archives/lens/basic/data.json.gz b/x-pack/test/functional/es_archives/lens/basic/data.json.gz index c9ae08fe6f628..5e43aa490e1db 100644 Binary files a/x-pack/test/functional/es_archives/lens/basic/data.json.gz and b/x-pack/test/functional/es_archives/lens/basic/data.json.gz differ diff --git a/x-pack/typings/elasticsearch/aggregations.d.ts b/x-pack/typings/elasticsearch/aggregations.d.ts index 6b64ad6276f57..c63d85bd82dc0 100644 --- a/x-pack/typings/elasticsearch/aggregations.d.ts +++ b/x-pack/typings/elasticsearch/aggregations.d.ts @@ -172,6 +172,12 @@ export interface AggregationOptionsByType { field?: string; background_filter?: Record; } & AggregationSourceOptions; + bucket_selector: { + buckets_path: { + [x: string]: string; + }; + script: string; + }; } type AggregationType = keyof AggregationOptionsByType; @@ -204,14 +210,14 @@ type SubAggregationResponseOf< interface AggregationResponsePart { terms: { - doc_count_error_upper_bound: number; - sum_other_doc_count: number; buckets: Array< { doc_count: number; key: string | number; } & SubAggregationResponseOf >; + doc_count_error_upper_bound?: number; + sum_other_doc_count?: number; }; histogram: { buckets: Array< @@ -362,6 +368,7 @@ interface AggregationResponsePart; }; bucket_sort: undefined; + bucket_selector: undefined; } // Type for debugging purposes. If you see an error in AggregationResponseMap diff --git a/x-pack/typings/elasticsearch/index.d.ts b/x-pack/typings/elasticsearch/index.d.ts index f5d595edcd71e..f2c51f601a099 100644 --- a/x-pack/typings/elasticsearch/index.d.ts +++ b/x-pack/typings/elasticsearch/index.d.ts @@ -5,7 +5,7 @@ */ import { SearchParams, SearchResponse } from 'elasticsearch'; -import { AggregationResponseMap, AggregationInputMap } from './aggregations'; +import { AggregationResponseMap, AggregationInputMap, SortOptions } from './aggregations'; export { AggregationInputMap, AggregationOptionsByType, @@ -23,7 +23,13 @@ interface CollapseQuery { inner_hits: { name: string; size?: number; - sort?: [{ date: 'asc' | 'desc' }]; + sort?: SortOptions; + _source?: { + includes: string[]; + }; + collapse?: { + field: string; + }; }; max_concurrent_group_searches?: number; } @@ -31,9 +37,11 @@ interface CollapseQuery { export interface ESSearchBody { query?: any; size?: number; + from?: number; aggs?: AggregationInputMap; track_total_hits?: boolean | number; collapse?: CollapseQuery; + _source?: string | string[] | { excludes: string | string[] }; } export type ESSearchRequest = Omit & {