From 11182c8ef79cd821ac2b2284b4a3d6295e6ab75a Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Mon, 20 Jul 2020 15:51:22 +0100 Subject: [PATCH 01/77] Fix match phrase and not match phrase comparators (#71850) Co-authored-by: Elastic Machine --- .../alerting/log_threshold/register_log_threshold_alert_type.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts index fbbb38da53929..ab55601f4c475 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts @@ -56,6 +56,8 @@ const criteriaSchema = schema.object({ schema.literal(Comparator.NOT_EQ), schema.literal(Comparator.MATCH), schema.literal(Comparator.NOT_MATCH), + schema.literal(Comparator.MATCH_PHRASE), + schema.literal(Comparator.NOT_MATCH_PHRASE), ]), value: schema.oneOf([schema.number(), schema.string()]), }); From e5c7e9a4741c4472294c650dcb555a4705079abe Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Mon, 20 Jul 2020 17:02:54 +0200 Subject: [PATCH 02/77] [Ingest Pipelines] Processor Editor Move Tooltip (#72239) * first implementation of tooltip * Add processor tooltip component files * remove init position from code for now * colocate on change handler and make code a bit cleaner * removed document.body.appendChild logic because EuiPortal does that for us * use correct toggle button api * added test to check button disabled while editing * remove cursor not allowed * simplify logic * assert if against positive * remove unused variable * Remove unused actions const Co-authored-by: Elastic Machine --- .../pipeline_processors_editor.test.tsx | 8 +++ .../components/_shared.scss | 1 + .../components/index.ts | 2 + .../pipeline_processors_editor_item.tsx | 20 ++++-- .../index.ts | 7 +++ ...ipeline_processors_editor_item_toolip.scss | 7 +++ ...ipeline_processors_editor_item_tooltip.tsx | 61 +++++++++++++++++++ .../processor_information.tsx | 32 ++++++++++ .../components/drop_zone_button.tsx | 1 - .../processors_tree/processors_tree.scss | 4 -- .../pipeline_processors_editor/constants.ts | 5 -- .../pipeline_processors_editor/context.tsx | 22 +++++-- .../pipeline_processors_editor/types.ts | 2 +- 13 files changed, 151 insertions(+), 21 deletions(-) create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item_tooltip/index.ts create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item_tooltip/pipeline_processors_editor_item_toolip.scss create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item_tooltip/pipeline_processors_editor_item_tooltip.tsx create mode 100644 x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item_tooltip/processor_information.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx index acfa012990b21..df4832f9a45e0 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/pipeline_processors_editor.test.tsx @@ -178,5 +178,13 @@ describe('Pipeline Editor', () => { expect(data2.processors).toEqual(testProcessors.processors); expect(data2.on_failure).toEqual([{ test: { if: '1 == 5' } }]); }); + + it('prevents moving a processor while in edit mode', () => { + const { find, exists } = testBed; + find('processors>0.editItemButton').simulate('click'); + expect(exists('processorSettingsForm')).toBe(true); + expect(find('processors>0.moveItemButton').props().disabled).toBe(true); + expect(find('processors>1.moveItemButton').props().disabled).toBe(true); + }); }); }); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/_shared.scss b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/_shared.scss index c7c49c00bb5cf..fe9a54671a00e 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/_shared.scss +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/_shared.scss @@ -1,2 +1,3 @@ $dropZoneZIndex: $euiZLevel1; /* Prevent the next item down from obscuring the button */ $cancelButtonZIndex: $euiZLevel2; +$processorItemMouseTooltipZIndex: $euiZLevel3; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts index de0621b187230..b532b2d953e65 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/index.ts @@ -19,3 +19,5 @@ export { PipelineProcessorsEditorItem } from './pipeline_processors_editor_item' export { ProcessorRemoveModal } from './processor_remove_modal'; export { OnDoneLoadJsonHandler, LoadFromJsonButton } from './load_from_json'; + +export { PipelineProcessorsItemTooltip, Position } from './pipeline_processors_editor_item_tooltip'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx index 97b57a971ff7d..3fbef4c1b7898 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/pipeline_processors_editor_item/pipeline_processors_editor_item.tsx @@ -51,7 +51,7 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( editor, processorsDispatch, }) { - const isDisabled = editor.mode.id !== 'idle'; + const isEditorNotInIdleMode = editor.mode.id !== 'idle'; const isInMoveMode = Boolean(movingProcessor); const isMovingThisProcessor = processor.id === movingProcessor?.id; const isEditingThisProcessor = @@ -83,6 +83,7 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( 'pipelineProcessorsEditor__item__moveButton--cancel': isMovingThisProcessor, }); const icon = isMovingThisProcessor ? 'cross' : 'sortable'; + const disabled = isEditorNotInIdleMode && !isMovingThisProcessor; const moveButton = ( = memo( iconType={icon} data-test-subj={dataTestSubj} size="s" - disabled={isDisabled && !isMovingThisProcessor} + isDisabled={disabled} label={label} aria-label={label} - onChange={() => (!isMovingThisProcessor ? onMove() : onCancelMove())} + onChange={() => { + if (isMovingThisProcessor) { + onCancelMove(); + } else { + onMove(); + } + }} /> ); // Remove the tooltip from the DOM to prevent it from lingering if the mouse leave event @@ -132,7 +139,7 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( { let nextOptions: Record; if (!nextDescription) { @@ -164,7 +171,8 @@ export const PipelineProcessorsEditorItem: FunctionComponent = memo( {!isInMoveMode && ( = memo( @@ -461,7 +461,7 @@ exports[`isNewKibanaInstance 1`] = ` - Centralize security events for interactive investigation in ready-to-go visualizations. + Protect hosts, analyze security information and events, hunt threats, automate detections, and create cases. } footer={ @@ -478,7 +478,7 @@ exports[`isNewKibanaInstance 1`] = ` } textAlign="left" - title="Security" + title="SIEM + Endpoint Security" titleSize="xs" /> @@ -758,7 +758,7 @@ exports[`mlEnabled 1`] = ` - Centralize security events for interactive investigation in ready-to-go visualizations. + Protect hosts, analyze security information and events, hunt threats, automate detections, and create cases. } footer={ @@ -775,7 +775,7 @@ exports[`mlEnabled 1`] = ` } textAlign="left" - title="Security" + title="SIEM + Endpoint Security" titleSize="xs" /> @@ -1060,7 +1060,7 @@ exports[`render 1`] = ` - Centralize security events for interactive investigation in ready-to-go visualizations. + Protect hosts, analyze security information and events, hunt threats, automate detections, and create cases. } footer={ @@ -1077,7 +1077,7 @@ exports[`render 1`] = ` } textAlign="left" - title="Security" + title="SIEM + Endpoint Security" titleSize="xs" /> diff --git a/src/plugins/home/public/application/components/add_data.js b/src/plugins/home/public/application/components/add_data.js index fa1327b3fcd08..c35b7b04932fb 100644 --- a/src/plugins/home/public/application/components/add_data.js +++ b/src/plugins/home/public/application/components/add_data.js @@ -81,12 +81,12 @@ const AddDataUi = ({ apmUiEnabled, isNewKibanaInstance, intl, mlEnabled }) => { const siemData = { title: intl.formatMessage({ id: 'home.addData.securitySolution.nameTitle', - defaultMessage: 'Security', + defaultMessage: 'SIEM + Endpoint Security', }), description: intl.formatMessage({ id: 'home.addData.securitySolution.nameDescription', defaultMessage: - 'Centralize security events for interactive investigation in ready-to-go visualizations.', + 'Protect hosts, analyze security information and events, hunt threats, automate detections, and create cases.', }), ariaDescribedby: 'aria-describedby.addSiemButtonLabel', }; diff --git a/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx b/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx index 3a8f2f0c16b96..a1e7293ce974b 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx @@ -63,26 +63,19 @@ export const HeaderGlobal = React.memo(({ hideDetectionEngine - + - {indicesExist ? ( - key !== SecurityPageName.detections, navTabs) - : navTabs - } - /> - ) : ( - key === SecurityPageName.overview, navTabs)} - /> - )} + key !== SecurityPageName.detections, navTabs) + : navTabs + } + /> diff --git a/x-pack/plugins/security_solution/public/common/components/header_global/translations.ts b/x-pack/plugins/security_solution/public/common/components/header_global/translations.ts index f67f665434a96..d3205be9bd2fc 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_global/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/header_global/translations.ts @@ -6,9 +6,12 @@ import { i18n } from '@kbn/i18n'; -export const SIEM = i18n.translate('xpack.securitySolution.headerGlobal.siem', { - defaultMessage: 'SIEM', -}); +export const SECURITY_SOLUTION = i18n.translate( + 'xpack.securitySolution.headerGlobal.securitySolution', + { + defaultMessage: 'Security solution', + } +); export const BUTTON_ADD_DATA = i18n.translate('xpack.securitySolution.headerGlobal.buttonAddData', { defaultMessage: 'Add data', diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx index 03ad6ad3396f8..8ba7f7da7b8e3 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx @@ -7,6 +7,7 @@ import { act, renderHook } from '@testing-library/react-hooks'; import { useWithSource, indicesExistOrDataTemporarilyUnavailable } from '.'; +import { NO_ALERT_INDEX } from '../../../../common/constants'; import { mockBrowserFields, mockIndexFields, mocksSource } from './mock'; jest.mock('../../lib/kibana'); @@ -79,6 +80,17 @@ describe('Index Fields & Browser Fields', () => { }); }); + test('Make sure we are not querying for NO_ALERT_INDEX and it is not includes in the index pattern', async () => { + const { result, waitForNextUpdate } = renderHook(() => + useWithSource('default', [NO_ALERT_INDEX]) + ); + + await waitForNextUpdate(); + return expect(result.current.indexPattern.title).toEqual( + 'apm-*-transaction*,auditbeat-*,endgame-*,filebeat-*,logs-*,packetbeat-*,winlogbeat-*' + ); + }); + describe('indicesExistOrDataTemporarilyUnavailable', () => { test('it returns true when undefined', () => { let undefVar; diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx index cc43dd6f42772..bbd00900105e8 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx @@ -11,7 +11,7 @@ import { useEffect, useMemo, useState } from 'react'; import memoizeOne from 'memoize-one'; import { IIndexPattern } from 'src/plugins/data/public'; -import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; +import { DEFAULT_INDEX_KEY, NO_ALERT_INDEX } from '../../../../common/constants'; import { useUiSetting$ } from '../../lib/kibana'; import { IndexField, SourceQuery } from '../../../graphql/types'; @@ -126,8 +126,9 @@ export const useWithSource = ( ) => { const [configIndex] = useUiSetting$(DEFAULT_INDEX_KEY); const defaultIndex = useMemo(() => { - if (indexToAdd != null && !isEmpty(indexToAdd)) { - return onlyCheckIndexToAdd ? indexToAdd : [...configIndex, ...indexToAdd]; + const filterIndexAdd = (indexToAdd ?? []).filter((item) => item !== NO_ALERT_INDEX); + if (!isEmpty(filterIndexAdd)) { + return onlyCheckIndexToAdd ? filterIndexAdd : [...configIndex, ...filterIndexAdd]; } return configIndex; }, [configIndex, indexToAdd, onlyCheckIndexToAdd]); @@ -138,7 +139,7 @@ export const useWithSource = ( errorMessage: null, indexPattern: getIndexFields(defaultIndex.join(), []), indicesExist: indicesExistOrDataTemporarilyUnavailable(undefined), - loading: false, + loading: true, }); const apolloClient = useApolloClient(); @@ -155,7 +156,7 @@ export const useWithSource = ( try { const result = await apolloClient.query({ query: sourceQuery, - fetchPolicy: 'cache-first', + fetchPolicy: 'network-only', variables: { sourceId, defaultIndex, diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx index f93f380469622..99968cd4d9fe8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx @@ -48,7 +48,6 @@ const PrePackagedRulesPromptComponent: React.FC = ( return ( {i18n.PRE_BUILT_TITLE}} body={

{i18n.PRE_BUILT_MSG}

} actions={ diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx index 7bf151adde5cc..2b842515d0b71 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx @@ -33,7 +33,6 @@ import { useKibana } from '../../../../common/lib/kibana'; import { getSchema } from './schema'; import * as I18n from './translations'; import { APP_ID } from '../../../../../common/constants'; -import { SecurityPageName } from '../../../../app/types'; interface StepRuleActionsProps extends RuleStepProps { defaultValues?: ActionsStepRule | null; @@ -86,16 +85,13 @@ const StepRuleActionsComponent: FC = ({ }); const { submit } = form; - // TO DO need to make sure that logic is still valid - const kibanaAbsoluteUrl = useMemo(() => { - const url = application.getUrlForApp(`${APP_ID}:${SecurityPageName.detections}`, { - absolute: true, - }); - if (url != null && url.includes('app/security/alerts')) { - return url.replace('app/security/alerts', 'app/security'); - } - return url; - }, [application]); + const kibanaAbsoluteUrl = useMemo( + () => + application.getUrlForApp(`${APP_ID}`, { + absolute: true, + }), + [application] + ); const onSubmit = useCallback( async (enabled: boolean) => { diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx index 9a2f43bb475b1..6257a9980e00c 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx @@ -70,7 +70,7 @@ export const useFetchIndexPatterns = (defaultIndices: string[] = []): Return => apolloClient .query({ query: sourceQuery, - fetchPolicy: 'cache-first', + fetchPolicy: 'network-only', variables: { sourceId: 'default', defaultIndex: indices, diff --git a/x-pack/plugins/security_solution/public/timelines/components/fields_browser/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/fields_browser/index.tsx index 7b843b4f69447..f4e39ff8227c7 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/fields_browser/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/fields_browser/index.tsx @@ -138,10 +138,9 @@ export const StatefulFieldsBrowserComponent: React.FC = ({ setShow(false); }, []); // only merge in the default category if the field browser is visible - const browserFieldsWithDefaultCategory = useMemo( - () => (show ? mergeBrowserFieldsWithDefaultCategory(browserFields) : {}), - [show, browserFields] - ); + const browserFieldsWithDefaultCategory = useMemo(() => { + return show ? mergeBrowserFieldsWithDefaultCategory(browserFields) : {}; + }, [show, browserFields]); return ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/index.tsx index 5f35bc5212d37..7ee7e12c0ef62 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/index.tsx @@ -78,8 +78,7 @@ const StatefulSearchOrFilterComponent = React.memo( serializedQuery: convertKueryToElasticSearchQuery(expression, indexPattern), }, }), - // eslint-disable-next-line react-hooks/exhaustive-deps - [indexPattern, timelineId] + [applyKqlFilterQuery, indexPattern, timelineId] ); const setFilterQueryDraftFromKueryExpression = useCallback( @@ -91,8 +90,7 @@ const StatefulSearchOrFilterComponent = React.memo( expression, }, }), - // eslint-disable-next-line react-hooks/exhaustive-deps - [timelineId] + [timelineId, setKqlFilterQueryDraft] ); const setFiltersInTimeline = useCallback( @@ -101,8 +99,7 @@ const StatefulSearchOrFilterComponent = React.memo( id: timelineId, filters: newFilters, }), - // eslint-disable-next-line react-hooks/exhaustive-deps - [timelineId] + [timelineId, setFilters] ); const setSavedQueryInTimeline = useCallback( @@ -111,8 +108,7 @@ const StatefulSearchOrFilterComponent = React.memo( id: timelineId, savedQueryId: newSavedQueryId, }), - // eslint-disable-next-line react-hooks/exhaustive-deps - [timelineId] + [timelineId, setSavedQueryId] ); const handleUpdateEventType = useCallback( @@ -121,8 +117,7 @@ const StatefulSearchOrFilterComponent = React.memo( id: timelineId, eventType: newEventType, }), - // eslint-disable-next-line react-hooks/exhaustive-deps - [timelineId] + [timelineId, updateEventType] ); return ( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.test.ts index 0d363e1f6f3c2..95e6071e4defc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.test.ts @@ -9,13 +9,13 @@ import { getNotificationResultsLink } from './utils'; describe('utils', () => { it('getNotificationResultsLink', () => { const resultLink = getNotificationResultsLink({ - kibanaSiemAppUrl: 'http://localhost:5601/app/siem', + kibanaSiemAppUrl: 'http://localhost:5601/app/security', id: 'notification-id', from: '00000', to: '1111', }); expect(resultLink).toEqual( - `http://localhost:5601/app/siem#/detections/rules/id/notification-id?timerange=(global:(linkTo:!(timeline),timerange:(from:00000,kind:absolute,to:1111)),timeline:(linkTo:!(global),timerange:(from:00000,kind:absolute,to:1111)))` + `http://localhost:5601/app/security/detections/rules/id/notification-id?timerange=(global:(linkTo:!(timeline),timerange:(from:00000,kind:absolute,to:1111)),timeline:(linkTo:!(global),timerange:(from:00000,kind:absolute,to:1111)))` ); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.ts index c91c4490e8eba..983ee86598fa1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.ts @@ -4,8 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ +import { APP_PATH } from '../../../../common/constants'; + export const getNotificationResultsLink = ({ - kibanaSiemAppUrl = '/app/siem', + kibanaSiemAppUrl = APP_PATH, id, from, to, @@ -17,5 +19,5 @@ export const getNotificationResultsLink = ({ }) => { if (from == null || to == null) return ''; - return `${kibanaSiemAppUrl}#/detections/rules/id/${id}?timerange=(global:(linkTo:!(timeline),timerange:(from:${from},kind:absolute,to:${to})),timeline:(linkTo:!(global),timerange:(from:${from},kind:absolute,to:${to})))`; + return `${kibanaSiemAppUrl}/detections/rules/id/${id}?timerange=(global:(linkTo:!(timeline),timerange:(from:${from},kind:absolute,to:${to})),timeline:(linkTo:!(global),timerange:(from:${from},kind:absolute,to:${to})))`; }; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index b87957ae45289..c1f0dc4c0c60c 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -14067,7 +14067,6 @@ "xpack.securitySolution.header.editableTitle.editButtonAria": "クリックすると {title} を編集できます", "xpack.securitySolution.header.editableTitle.save": "保存", "xpack.securitySolution.headerGlobal.buttonAddData": "データの追加", - "xpack.securitySolution.headerGlobal.siem": "Security", "xpack.securitySolution.headerPage.pageSubtitle": "前回のイベント: {beat}", "xpack.securitySolution.hooks.useAddToTimeline.addedFieldMessage": "{fieldOrValue}をタイムラインに追加しました", "xpack.securitySolution.host.details.architectureLabel": "アーキテクチャー", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 01ffa4833a3bb..0f2a51c8ff889 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -14073,7 +14073,6 @@ "xpack.securitySolution.header.editableTitle.editButtonAria": "通过单击,可以编辑 {title}", "xpack.securitySolution.header.editableTitle.save": "保存", "xpack.securitySolution.headerGlobal.buttonAddData": "添加数据", - "xpack.securitySolution.headerGlobal.siem": "Security", "xpack.securitySolution.headerPage.pageSubtitle": "最后事件:{beat}", "xpack.securitySolution.hooks.useAddToTimeline.addedFieldMessage": "已将 {fieldOrValue} 添加到时间线", "xpack.securitySolution.host.details.architectureLabel": "架构", From 54c3644757d5622f9e516aa3c99cf2ec87d6591e Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Mon, 20 Jul 2020 18:35:42 +0300 Subject: [PATCH 05/77] [Alerting][Connectors] Increase the size of the logos (#72419) --- .../sections/action_connector_form/action_type_menu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.tsx index bc36c41664e57..7ecb833fdfc9e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.tsx @@ -81,7 +81,7 @@ export const ActionTypeMenu = ({ } + icon={} title={item.name} description={item.selectMessage} isDisabled={!checkEnabledResult.isEnabled} From d744d18b1921655c12b82bb6760f9bc8348e2a3c Mon Sep 17 00:00:00 2001 From: Bohdan Tsymbala Date: Mon, 20 Jul 2020 17:44:17 +0200 Subject: [PATCH 06/77] [ENDPOINT] Added unerolling status for host. (#72303) * Added unerolling status for host. * Added unenrolling status to frontend tests. --- .../common/endpoint/types.ts | 5 ++++ .../endpoint_hosts/view/host_constants.ts | 1 + .../pages/endpoint_hosts/view/index.test.tsx | 25 ++++++++++++------- .../pages/endpoint_hosts/view/index.tsx | 2 +- .../server/endpoint/routes/metadata/index.ts | 1 + .../endpoint/routes/metadata/metadata.test.ts | 4 +-- 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/security_solution/common/endpoint/types.ts b/x-pack/plugins/security_solution/common/endpoint/types.ts index 5e7e4d22f8c3c..a982f9ffe8f21 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types.ts @@ -419,6 +419,11 @@ export enum HostStatus { * Host is offline as indicated by its checkin status during the last checkin window */ OFFLINE = 'offline', + + /** + * Host is unenrolling as indicated by its checkin status during the last checkin window + */ + UNENROLLING = 'unenrolling', } export type HostInfo = Immutable<{ diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/host_constants.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/host_constants.ts index 790bbd3cb98da..4204d4f79f19c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/host_constants.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/host_constants.ts @@ -15,6 +15,7 @@ export const HOST_STATUS_TO_HEALTH_COLOR = Object.freeze< [HostStatus.ERROR]: 'danger', [HostStatus.ONLINE]: 'success', [HostStatus.OFFLINE]: 'subdued', + [HostStatus.UNENROLLING]: 'warning', }); export const POLICY_STATUS_TO_HEALTH_COLOR = Object.freeze< diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index a61088e2edd29..47227244b7066 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -112,14 +112,16 @@ describe('when on the hosts page', () => { let firstPolicyID: string; beforeEach(() => { reactTestingLibrary.act(() => { - const hostListData = mockHostResultList({ total: 3 }); + const hostListData = mockHostResultList({ total: 4 }); firstPolicyID = hostListData.hosts[0].metadata.Endpoint.policy.applied.id; - [HostStatus.ERROR, HostStatus.ONLINE, HostStatus.OFFLINE].forEach((status, index) => { - hostListData.hosts[index] = { - metadata: hostListData.hosts[index].metadata, - host_status: status, - }; - }); + [HostStatus.ERROR, HostStatus.ONLINE, HostStatus.OFFLINE, HostStatus.UNENROLLING].forEach( + (status, index) => { + hostListData.hosts[index] = { + metadata: hostListData.hosts[index].metadata, + host_status: status, + }; + } + ); hostListData.hosts.forEach((item, index) => { generatedPolicyStatuses[index] = item.metadata.Endpoint.policy.applied.status; }); @@ -134,12 +136,12 @@ describe('when on the hosts page', () => { it('should display rows in the table', async () => { const renderResult = render(); const rows = await renderResult.findAllByRole('row'); - expect(rows).toHaveLength(4); + expect(rows).toHaveLength(5); }); it('should show total', async () => { const renderResult = render(); const total = await renderResult.findByTestId('hostListTableTotal'); - expect(total.textContent).toEqual('3 Hosts'); + expect(total.textContent).toEqual('4 Hosts'); }); it('should display correct status', async () => { const renderResult = render(); @@ -157,6 +159,11 @@ describe('when on the hosts page', () => { expect( hostStatuses[2].querySelector('[data-euiicon-type][color="subdued"]') ).not.toBeNull(); + + expect(hostStatuses[3].textContent).toEqual('Unenrolling'); + expect( + hostStatuses[3].querySelector('[data-euiicon-type][color="warning"]') + ).not.toBeNull(); }); it('should display correct policy status', async () => { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx index 4c8d2c5a6df4e..c5ed71cba46d9 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx @@ -226,7 +226,7 @@ export const HostList = () => { > diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/index.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/index.ts index cb9889ca0cb76..fe7a8296608d2 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/index.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/index.ts @@ -35,6 +35,7 @@ interface MetadataRequestContext { const HOST_STATUS_MAPPING = new Map([ ['online', HostStatus.ONLINE], ['offline', HostStatus.OFFLINE], + ['unenrolling', HostStatus.UNENROLLING], ]); /** diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts index 321eb0195aac3..8d967656065d1 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts @@ -335,7 +335,7 @@ describe('test endpoint route', () => { expect(result.host_status).toEqual(HostStatus.ERROR); }); - it('should return a single endpoint with status error when status is not offline or online', async () => { + it('should return a single endpoint with status error when status is not offline, online or enrolling', async () => { const response = createSearchResponse(new EndpointDocGenerator().generateHostMetadata()); const mockRequest = httpServerMock.createKibanaRequest({ @@ -368,7 +368,7 @@ describe('test endpoint route', () => { expect(result.host_status).toEqual(HostStatus.ERROR); }); - it('should throw error when endpoint egent is not active', async () => { + it('should throw error when endpoint agent is not active', async () => { const response = createSearchResponse(new EndpointDocGenerator().generateHostMetadata()); const mockRequest = httpServerMock.createKibanaRequest({ From 96d965d4e305e7891500b7ad6cb83f4356d6117c Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Mon, 20 Jul 2020 17:55:27 +0200 Subject: [PATCH 07/77] Unskip dashboard embeddable rendering tests (#71824) --- test/functional/apps/dashboard/embeddable_rendering.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/functional/apps/dashboard/embeddable_rendering.js b/test/functional/apps/dashboard/embeddable_rendering.js index 9ba0c07c744fc..c00f01d060f4a 100644 --- a/test/functional/apps/dashboard/embeddable_rendering.js +++ b/test/functional/apps/dashboard/embeddable_rendering.js @@ -98,8 +98,7 @@ export default function ({ getService, getPageObjects }) { await dashboardExpect.vegaTextsDoNotExist(['5,000']); }; - // FLAKY: https://github.com/elastic/kibana/issues/46305 - describe.skip('dashboard embeddable rendering', function describeIndexTests() { + describe('dashboard embeddable rendering', function describeIndexTests() { before(async () => { await esArchiver.load('dashboard/current/kibana'); await kibanaServer.uiSettings.replace({ From 2094f33537df6185ec0894316f8af107110bd071 Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Mon, 20 Jul 2020 12:28:46 -0400 Subject: [PATCH 08/77] [Security Solution] Cleanup endpoint telemetry (#71950) Co-authored-by: Elastic Machine --- .../server/usage/collector.ts | 2 +- .../server/usage/endpoints/endpoint.mocks.ts | 60 +++- .../server/usage/endpoints/endpoint.test.ts | 332 +++++++++++++++--- .../usage/endpoints/fleet_saved_objects.ts | 16 +- .../server/usage/endpoints/index.ts | 239 +++++++------ 5 files changed, 480 insertions(+), 169 deletions(-) diff --git a/x-pack/plugins/security_solution/server/usage/collector.ts b/x-pack/plugins/security_solution/server/usage/collector.ts index 9740f57450e80..9a7ad6fc2db74 100644 --- a/x-pack/plugins/security_solution/server/usage/collector.ts +++ b/x-pack/plugins/security_solution/server/usage/collector.ts @@ -12,7 +12,7 @@ import { EndpointUsage, getEndpointTelemetryFromFleet } from './endpoints'; export type RegisterCollector = (deps: CollectorDependencies) => void; export interface UsageData { detections: DetectionsUsage; - endpoints: EndpointUsage; + endpoints: EndpointUsage | {}; } export async function getInternalSavedObjectsClient(core: CoreSetup) { diff --git a/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.mocks.ts b/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.mocks.ts index 1369a3d398265..e3f0f7bde2fed 100644 --- a/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.mocks.ts +++ b/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.mocks.ts @@ -14,6 +14,7 @@ import { FLEET_ENDPOINT_PACKAGE_CONSTANT } from './fleet_saved_objects'; const testAgentId = 'testAgentId'; const testConfigId = 'testConfigId'; +const testHostId = 'randoHostId'; /** Mock OS Platform for endpoint telemetry */ export const MockOSPlatform = 'somePlatform'; @@ -30,6 +31,7 @@ export const MockOSFullName = 'somePlatformFullName'; * @description We request the install and OS related telemetry information from the 'fleet-agents' saved objects in ingest_manager. This mocks that response */ export const mockFleetObjectsResponse = ( + hasDuplicates = true, lastCheckIn = new Date().toISOString() ): SavedObjectsFindResponse => ({ page: 1, @@ -56,7 +58,44 @@ export const mockFleetObjectsResponse = ( host: { hostname: 'testDesktop', name: 'testDesktop', - id: 'randoHostId', + id: testHostId, + }, + os: { + platform: MockOSPlatform, + version: MockOSVersion, + name: MockOSName, + full: MockOSFullName, + }, + }, + packages: [FLEET_ENDPOINT_PACKAGE_CONSTANT, 'system'], + last_checkin: lastCheckIn, + }, + references: [], + updated_at: lastCheckIn, + version: 'WzI4MSwxXQ==', + score: 0, + }, + { + type: AGENT_SAVED_OBJECT_TYPE, + id: testAgentId, + attributes: { + active: true, + id: 'oldTestAgentId', + config_id: 'randoConfigId', + type: 'PERMANENT', + user_provided_metadata: {}, + enrolled_at: lastCheckIn, + current_error_events: [], + local_metadata: { + elastic: { + agent: { + id: 'oldTestAgentId', + }, + }, + host: { + hostname: 'testDesktop', + name: 'testDesktop', + id: hasDuplicates ? testHostId : 'oldRandoHostId', }, os: { platform: MockOSPlatform, @@ -76,7 +115,10 @@ export const mockFleetObjectsResponse = ( ], }); -const mockPolicyPayload = (malwareStatus: 'success' | 'warning' | 'failure') => +const mockPolicyPayload = ( + policyStatus: 'success' | 'warning' | 'failure', + policyMode: 'prevent' | 'detect' | 'off' = 'prevent' +) => JSON.stringify({ 'endpoint-security': { Endpoint: { @@ -105,7 +147,7 @@ const mockPolicyPayload = (malwareStatus: 'success' | 'warning' | 'failure') => file: 'info', }, malware: { - mode: 'prevent', + mode: policyMode, }, }, windows: { @@ -122,7 +164,7 @@ const mockPolicyPayload = (malwareStatus: 'success' | 'warning' | 'failure') => file: 'info', }, malware: { - mode: 'prevent', + mode: policyMode, }, }, }, @@ -151,11 +193,11 @@ const mockPolicyPayload = (malwareStatus: 'success' | 'warning' | 'failure') => 'detect_file_open_events', 'detect_sync_image_load_events', ], - status: `${malwareStatus}`, + status: `${policyStatus}`, }, }, }, - status: `${malwareStatus}`, + status: `${policyStatus}`, }, }, }, @@ -186,7 +228,9 @@ const mockPolicyPayload = (malwareStatus: 'success' | 'warning' | 'failure') => */ export const mockFleetEventsObjectsResponse = ( running?: boolean, - updatedDate = new Date().toISOString() + updatedDate = new Date().toISOString(), + policyStatus: 'success' | 'failure' = running ? 'success' : 'failure', + policyMode: 'prevent' | 'detect' | 'off' = 'prevent' ): SavedObjectsFindResponse => { return { page: 1, @@ -204,7 +248,7 @@ export const mockFleetEventsObjectsResponse = ( message: `Application: endpoint-security--8.0.0[d8f7f6e8-9375-483c-b456-b479f1d7a4f2]: State changed to ${ running ? 'RUNNING' : 'FAILED' }: `, - payload: mockPolicyPayload(running ? 'success' : 'failure'), + payload: running ? mockPolicyPayload(policyStatus, policyMode) : undefined, config_id: testConfigId, }, references: [], diff --git a/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.test.ts b/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.test.ts index 06755192bd818..e2f7a3be6d80a 100644 --- a/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.test.ts +++ b/x-pack/plugins/security_solution/server/usage/endpoints/endpoint.test.ts @@ -51,17 +51,31 @@ describe('test security solution endpoint telemetry', () => { `); }); + describe('when a request for endpoint agents fails', () => { + it('should return an empty object', async () => { + getFleetSavedObjectsMetadataSpy.mockImplementation(() => + Promise.reject(Error('No agents for you')) + ); + + const endpointUsage = await endpointTelemetry.getEndpointTelemetryFromFleet( + mockSavedObjectsRepository + ); + expect(getFleetSavedObjectsMetadataSpy).toHaveBeenCalled(); + expect(endpointUsage).toEqual({}); + }); + }); + describe('when an agent has not been installed', () => { it('should return the default shape if no agents are found', async () => { getFleetSavedObjectsMetadataSpy.mockImplementation(() => Promise.resolve({ saved_objects: [], total: 0, per_page: 0, page: 0 }) ); - const emptyEndpointTelemetryData = await endpointTelemetry.getEndpointTelemetryFromFleet( + const endpointUsage = await endpointTelemetry.getEndpointTelemetryFromFleet( mockSavedObjectsRepository ); expect(getFleetSavedObjectsMetadataSpy).toHaveBeenCalled(); - expect(emptyEndpointTelemetryData).toEqual({ + expect(endpointUsage).toEqual({ total_installed: 0, active_within_last_24_hours: 0, os: [], @@ -76,68 +90,274 @@ describe('test security solution endpoint telemetry', () => { }); }); - describe('when an agent has been installed', () => { - it('should show one enpoint installed but it is inactive', async () => { - getFleetSavedObjectsMetadataSpy.mockImplementation(() => - Promise.resolve(mockFleetObjectsResponse()) - ); - getLatestFleetEndpointEventSpy.mockImplementation(() => - Promise.resolve(mockFleetEventsObjectsResponse()) - ); + describe('when agent(s) have been installed', () => { + describe('when a request for events has failed', () => { + it('should show only one endpoint installed but it is inactive', async () => { + getFleetSavedObjectsMetadataSpy.mockImplementation(() => + Promise.resolve(mockFleetObjectsResponse()) + ); + getLatestFleetEndpointEventSpy.mockImplementation(() => + Promise.reject(Error('No events for you')) + ); - const emptyEndpointTelemetryData = await endpointTelemetry.getEndpointTelemetryFromFleet( - mockSavedObjectsRepository - ); - expect(emptyEndpointTelemetryData).toEqual({ - total_installed: 1, - active_within_last_24_hours: 0, - os: [ - { - full_name: MockOSFullName, - platform: MockOSPlatform, - version: MockOSVersion, - count: 1, - }, - ], - policies: { - malware: { - failure: 1, - active: 0, - inactive: 0, + const endpointUsage = await endpointTelemetry.getEndpointTelemetryFromFleet( + mockSavedObjectsRepository + ); + expect(endpointUsage).toEqual({ + total_installed: 1, + active_within_last_24_hours: 0, + os: [ + { + full_name: MockOSFullName, + platform: MockOSPlatform, + version: MockOSVersion, + count: 1, + }, + ], + policies: { + malware: { + failure: 0, + active: 0, + inactive: 0, + }, }, - }, + }); }); }); - it('should show one endpoint installed and it is active', async () => { - getFleetSavedObjectsMetadataSpy.mockImplementation(() => - Promise.resolve(mockFleetObjectsResponse()) - ); - getLatestFleetEndpointEventSpy.mockImplementation(() => - Promise.resolve(mockFleetEventsObjectsResponse(true)) - ); + describe('when a request for events is successful', () => { + it('should show one endpoint installed but endpoint has failed to run', async () => { + getFleetSavedObjectsMetadataSpy.mockImplementation(() => + Promise.resolve(mockFleetObjectsResponse()) + ); + getLatestFleetEndpointEventSpy.mockImplementation(() => + Promise.resolve(mockFleetEventsObjectsResponse()) + ); - const emptyEndpointTelemetryData = await endpointTelemetry.getEndpointTelemetryFromFleet( - mockSavedObjectsRepository - ); - expect(emptyEndpointTelemetryData).toEqual({ - total_installed: 1, - active_within_last_24_hours: 1, - os: [ - { - full_name: MockOSFullName, - platform: MockOSPlatform, - version: MockOSVersion, - count: 1, + const endpointUsage = await endpointTelemetry.getEndpointTelemetryFromFleet( + mockSavedObjectsRepository + ); + expect(endpointUsage).toEqual({ + total_installed: 1, + active_within_last_24_hours: 0, + os: [ + { + full_name: MockOSFullName, + platform: MockOSPlatform, + version: MockOSVersion, + count: 1, + }, + ], + policies: { + malware: { + failure: 0, + active: 0, + inactive: 0, + }, }, - ], - policies: { - malware: { - failure: 0, - active: 1, - inactive: 0, + }); + }); + + it('should show two endpoints installed but both endpoints have failed to run', async () => { + getFleetSavedObjectsMetadataSpy.mockImplementation(() => + Promise.resolve(mockFleetObjectsResponse(false)) + ); + getLatestFleetEndpointEventSpy.mockImplementation(() => + Promise.resolve(mockFleetEventsObjectsResponse()) + ); + + const endpointUsage = await endpointTelemetry.getEndpointTelemetryFromFleet( + mockSavedObjectsRepository + ); + expect(endpointUsage).toEqual({ + total_installed: 2, + active_within_last_24_hours: 0, + os: [ + { + full_name: MockOSFullName, + platform: MockOSPlatform, + version: MockOSVersion, + count: 2, + }, + ], + policies: { + malware: { + failure: 0, + active: 0, + inactive: 0, + }, }, - }, + }); + }); + + it('should show two endpoints installed but agents have not checked in within past day', async () => { + const twoDaysAgo = new Date(); + twoDaysAgo.setDate(twoDaysAgo.getDate() - 2); + const twoDaysAgoISOString = twoDaysAgo.toISOString(); + + getFleetSavedObjectsMetadataSpy.mockImplementation(() => + Promise.resolve(mockFleetObjectsResponse(false, twoDaysAgoISOString)) + ); + getLatestFleetEndpointEventSpy.mockImplementation( + () => Promise.resolve(mockFleetEventsObjectsResponse(true, twoDaysAgoISOString)) // agent_id doesn't matter for mock here + ); + + const endpointUsage = await endpointTelemetry.getEndpointTelemetryFromFleet( + mockSavedObjectsRepository + ); + expect(endpointUsage).toEqual({ + total_installed: 2, + active_within_last_24_hours: 0, + os: [ + { + full_name: MockOSFullName, + platform: MockOSPlatform, + version: MockOSVersion, + count: 2, + }, + ], + policies: { + malware: { + failure: 0, + active: 2, + inactive: 0, + }, + }, + }); + }); + + it('should show one endpoint installed and endpoint is running', async () => { + getFleetSavedObjectsMetadataSpy.mockImplementation(() => + Promise.resolve(mockFleetObjectsResponse()) + ); + getLatestFleetEndpointEventSpy.mockImplementation(() => + Promise.resolve(mockFleetEventsObjectsResponse(true)) + ); + + const endpointUsage = await endpointTelemetry.getEndpointTelemetryFromFleet( + mockSavedObjectsRepository + ); + expect(endpointUsage).toEqual({ + total_installed: 1, + active_within_last_24_hours: 1, + os: [ + { + full_name: MockOSFullName, + platform: MockOSPlatform, + version: MockOSVersion, + count: 1, + }, + ], + policies: { + malware: { + failure: 0, + active: 1, + inactive: 0, + }, + }, + }); + }); + + describe('malware policy', () => { + it('should have failed to enable', async () => { + getFleetSavedObjectsMetadataSpy.mockImplementation(() => + Promise.resolve(mockFleetObjectsResponse()) + ); + getLatestFleetEndpointEventSpy.mockImplementation(() => + Promise.resolve( + mockFleetEventsObjectsResponse(true, new Date().toISOString(), 'failure') + ) + ); + + const endpointUsage = await endpointTelemetry.getEndpointTelemetryFromFleet( + mockSavedObjectsRepository + ); + expect(endpointUsage).toEqual({ + total_installed: 1, + active_within_last_24_hours: 1, + os: [ + { + full_name: MockOSFullName, + platform: MockOSPlatform, + version: MockOSVersion, + count: 1, + }, + ], + policies: { + malware: { + failure: 1, + active: 0, + inactive: 0, + }, + }, + }); + }); + + it('should be enabled successfully', async () => { + getFleetSavedObjectsMetadataSpy.mockImplementation(() => + Promise.resolve(mockFleetObjectsResponse()) + ); + getLatestFleetEndpointEventSpy.mockImplementation(() => + Promise.resolve(mockFleetEventsObjectsResponse(true)) + ); + + const endpointUsage = await endpointTelemetry.getEndpointTelemetryFromFleet( + mockSavedObjectsRepository + ); + expect(endpointUsage).toEqual({ + total_installed: 1, + active_within_last_24_hours: 1, + os: [ + { + full_name: MockOSFullName, + platform: MockOSPlatform, + version: MockOSVersion, + count: 1, + }, + ], + policies: { + malware: { + failure: 0, + active: 1, + inactive: 0, + }, + }, + }); + }); + + it('should be disabled successfully', async () => { + getFleetSavedObjectsMetadataSpy.mockImplementation(() => + Promise.resolve(mockFleetObjectsResponse()) + ); + getLatestFleetEndpointEventSpy.mockImplementation(() => + Promise.resolve( + mockFleetEventsObjectsResponse(true, new Date().toISOString(), 'success', 'off') + ) + ); + + const endpointUsage = await endpointTelemetry.getEndpointTelemetryFromFleet( + mockSavedObjectsRepository + ); + expect(endpointUsage).toEqual({ + total_installed: 1, + active_within_last_24_hours: 1, + os: [ + { + full_name: MockOSFullName, + platform: MockOSPlatform, + version: MockOSVersion, + count: 1, + }, + ], + policies: { + malware: { + failure: 0, + active: 0, + inactive: 1, + }, + }, + }); + }); }); }); }); diff --git a/x-pack/plugins/security_solution/server/usage/endpoints/fleet_saved_objects.ts b/x-pack/plugins/security_solution/server/usage/endpoints/fleet_saved_objects.ts index 7e05fdec36169..42c1ec0e2eed2 100644 --- a/x-pack/plugins/security_solution/server/usage/endpoints/fleet_saved_objects.ts +++ b/x-pack/plugins/security_solution/server/usage/endpoints/fleet_saved_objects.ts @@ -16,8 +16,16 @@ export const FLEET_ENDPOINT_PACKAGE_CONSTANT = FleetDefaultPackages.endpoint; export const getFleetSavedObjectsMetadata = async (savedObjectsClient: ISavedObjectsRepository) => savedObjectsClient.find({ + // Get up to 10000 agents with endpoint installed type: AGENT_SAVED_OBJECT_TYPE, - fields: ['packages', 'last_checkin', 'local_metadata'], + fields: [ + 'packages', + 'last_checkin', + 'local_metadata.agent.id', + 'local_metadata.host.id', + 'local_metadata.elastic.agent.id', + 'local_metadata.os', + ], filter: `${AGENT_SAVED_OBJECT_TYPE}.attributes.packages: ${FLEET_ENDPOINT_PACKAGE_CONSTANT}`, perPage: 10000, sortField: 'enrolled_at', @@ -29,9 +37,11 @@ export const getLatestFleetEndpointEvent = async ( agentId: string ) => savedObjectsClient.find({ + // Get the most recent endpoint event. type: AGENT_EVENT_SAVED_OBJECT_TYPE, - filter: `${AGENT_EVENT_SAVED_OBJECT_TYPE}.attributes.agent_id: ${agentId} and ${AGENT_EVENT_SAVED_OBJECT_TYPE}.attributes.message: "${FLEET_ENDPOINT_PACKAGE_CONSTANT}"`, - perPage: 1, // Get the most recent endpoint event. + fields: ['agent_id', 'subtype', 'payload'], + filter: `${AGENT_EVENT_SAVED_OBJECT_TYPE}.attributes.message: "${FLEET_ENDPOINT_PACKAGE_CONSTANT}"`, + perPage: 1, sortField: 'timestamp', sortOrder: 'desc', search: agentId, diff --git a/x-pack/plugins/security_solution/server/usage/endpoints/index.ts b/x-pack/plugins/security_solution/server/usage/endpoints/index.ts index ab5669d503275..9e071f4adff25 100644 --- a/x-pack/plugins/security_solution/server/usage/endpoints/index.ts +++ b/x-pack/plugins/security_solution/server/usage/endpoints/index.ts @@ -3,8 +3,10 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import { cloneDeep } from 'lodash'; import { ISavedObjectsRepository } from 'src/core/server'; +import { SavedObject } from './../../../../../../src/core/types/saved_objects'; +import { Agent, NewAgentEvent } from './../../../../ingest_manager/common/types/models/agent'; import { AgentMetadata } from '../../../../ingest_manager/common/types/models/agent'; import { getFleetSavedObjectsMetadata, getLatestFleetEndpointEvent } from './fleet_saved_objects'; @@ -51,7 +53,7 @@ export interface AgentLocalMetadata extends AgentMetadata { } type OSTracker = Record; -type AgentDailyActiveTracker = Map; + /** * @description returns an empty telemetry object to be incrmented and updated within the `getEndpointTelemetryFromFleet` fn */ @@ -69,13 +71,14 @@ export const getDefaultEndpointTelemetry = (): EndpointUsage => ({ }); /** - * @description this fun + * @description this function updates the os telemetry. We use the fullName field as the key as it contains the name and version details. + * If it has already been tracked, the count will be updated, otherwise a tracker will be initialized for that fullName. */ -export const trackEndpointOSTelemetry = ( +export const updateEndpointOSTelemetry = ( os: AgentLocalMetadata['os'], osTracker: OSTracker ): OSTracker => { - const updatedOSTracker = { ...osTracker }; + const updatedOSTracker = cloneDeep(osTracker); const { version: osVersion, platform: osPlatform, full: osFullName } = os; if (osFullName && osVersion) { if (updatedOSTracker[osFullName]) updatedOSTracker[osFullName].count += 1; @@ -93,18 +96,32 @@ export const trackEndpointOSTelemetry = ( }; /** - * @description This iterates over all unique agents that currently track an endpoint package. It takes a list of agents who have checked in in the last 24 hours - * and then checks whether those agents have endpoints whose latest status is 'RUNNING' to determine an active_within_last_24_hours. Since the policy information is also tracked in these events - * we pull out the status of the current protection (malware) type. This must be done in a compound manner as the desired status is reflected in the config, and the successful application of that policy - * is tracked in the policy.applied.response.configurations[protectionsType].status. Using these two we can determine whether the policy is toggled on, off, or failed to turn on. + * @description we take the latest endpoint specific agent event, get the status of the endpoint, and if it is running + * and the agent itself has been active within the last 24 hours, we can safely assume the endpoint has been active within + * the same time span. */ -export const addEndpointDailyActivityAndPolicyDetailsToTelemetry = async ( - agentDailyActiveTracker: AgentDailyActiveTracker, - savedObjectsClient: ISavedObjectsRepository, - endpointTelemetry: EndpointUsage -): Promise => { - const updatedEndpointTelemetry = { ...endpointTelemetry }; +export const updateEndpointDailyActiveCount = ( + latestEndpointEvent: SavedObject, + lastAgentCheckin: Agent['last_checkin'], + currentCount: number +) => { + const aDayAgo = new Date(); + aDayAgo.setDate(aDayAgo.getDate() - 1); + + const agentWasActiveOverLastDay = !!lastAgentCheckin && new Date(lastAgentCheckin) > aDayAgo; + return agentWasActiveOverLastDay && latestEndpointEvent.attributes.subtype === 'RUNNING' + ? currentCount + 1 + : currentCount; +}; +/** + * @description We take the latest endpoint specific agent event, and as long as it provides the payload with policy details, we will parse that policy + * to populate the success of it's application. The policy is provided in the agent health checks. + */ +export const updateEndpointPolicyTelemetry = ( + latestEndpointEvent: SavedObject, + policiesTracker: PoliciesTelemetry +): PoliciesTelemetry => { const policyHostTypeToPolicyType = { Linux: 'linux', macOs: 'mac', @@ -112,58 +129,60 @@ export const addEndpointDailyActivityAndPolicyDetailsToTelemetry = async ( }; const enabledMalwarePolicyTypes = ['prevent', 'detect']; - for (const agentId of agentDailyActiveTracker.keys()) { - const { saved_objects: agentEvents } = await getLatestFleetEndpointEvent( - savedObjectsClient, - agentId - ); - - const latestEndpointEvent = agentEvents[0]; - if (latestEndpointEvent) { - /* - We can assume that if the last status of the endpoint is RUNNING and the agent has checked in within the last 24 hours - then the endpoint has still been running within the last 24 hours. - */ - const { subtype, payload } = latestEndpointEvent.attributes; - const endpointIsActive = - subtype === 'RUNNING' && agentDailyActiveTracker.get(agentId) === true; - - if (endpointIsActive) { - updatedEndpointTelemetry.active_within_last_24_hours += 1; - } + // The policy details are sent as a string on the 'payload' attribute of the agent event + const { payload } = latestEndpointEvent.attributes; - // The policy details are sent as a string on the 'payload' attribute of the agent event - const endpointPolicyDetails = payload ? JSON.parse(payload) : null; - if (endpointPolicyDetails) { - // We get the setting the user desired to enable (treating prevent and detect as 'active' states) and then see if it succeded or failed. - const hostType = - policyHostTypeToPolicyType[ - endpointPolicyDetails['endpoint-security']?.host?.os?.name as EndpointOSNames - ]; - const userDesiredMalwareState = - endpointPolicyDetails['endpoint-security'].Endpoint?.configuration?.inputs[0]?.policy[ - hostType - ]?.malware?.mode; - - const isAnActiveMalwareState = enabledMalwarePolicyTypes.includes(userDesiredMalwareState); - const malwareStatus = - endpointPolicyDetails['endpoint-security'].Endpoint?.policy?.applied?.response - ?.configurations?.malware?.status; - - if (isAnActiveMalwareState && malwareStatus !== 'failure') { - updatedEndpointTelemetry.policies.malware.active += 1; - } - if (!isAnActiveMalwareState) { - updatedEndpointTelemetry.policies.malware.inactive += 1; - } - if (isAnActiveMalwareState && malwareStatus === 'failure') { - updatedEndpointTelemetry.policies.malware.failure += 1; - } - } - } + if (!payload) { + // This payload may not always be provided depending on the state of the endpoint. Guard again situations where it is not sent + return policiesTracker; + } + + let endpointPolicyPayload; + try { + endpointPolicyPayload = JSON.parse(latestEndpointEvent.attributes.payload); + } catch (error) { + return policiesTracker; + } + + // Get the platform: windows, mac, or linux + const hostType = + policyHostTypeToPolicyType[ + endpointPolicyPayload['endpoint-security']?.host?.os?.name as EndpointOSNames + ]; + // Get whether the malware setting for the platform on the most recently provided config is active (prevent or detect is on) or off + const userDesiredMalwareState = + endpointPolicyPayload['endpoint-security'].Endpoint?.configuration?.inputs[0]?.policy[hostType] + ?.malware?.mode; + + // Get the status of the application of the malware protection + const malwareStatus = + endpointPolicyPayload['endpoint-security'].Endpoint?.policy?.applied?.response?.configurations + ?.malware?.status; + + if (!userDesiredMalwareState || !malwareStatus) { + // If we get policy information without the mode or status, then nothing to track or update + return policiesTracker; } - return updatedEndpointTelemetry; + const updatedPoliciesTracker = { + malware: { ...policiesTracker.malware }, + }; + + const isAnActiveMalwareState = enabledMalwarePolicyTypes.includes(userDesiredMalwareState); + + // we only check for 'not failure' as the 'warning' state for malware is still technically actively enabled (with warnings) + const successfullyEnabled = !!malwareStatus && malwareStatus !== 'failure'; + const failedToEnable = !!malwareStatus && malwareStatus === 'failure'; + + if (isAnActiveMalwareState && successfullyEnabled) { + updatedPoliciesTracker.malware.active += 1; + } else if (!isAnActiveMalwareState && successfullyEnabled) { + updatedPoliciesTracker.malware.inactive += 1; + } else if (isAnActiveMalwareState && failedToEnable) { + updatedPoliciesTracker.malware.failure += 1; + } + + return updatedPoliciesTracker; }; /** @@ -173,53 +192,71 @@ export const addEndpointDailyActivityAndPolicyDetailsToTelemetry = async ( * to confirm whether or not the endpoint is still active */ export const getEndpointTelemetryFromFleet = async ( - savedObjectsClient: ISavedObjectsRepository -): Promise => { - // Retrieve every agent that references the endpoint as an installed package. It will not be listed if it was never installed - const { saved_objects: endpointAgents } = await getFleetSavedObjectsMetadata(savedObjectsClient); + soClient: ISavedObjectsRepository +): Promise => { + // Retrieve every agent (max 10000) that references the endpoint as an installed package. It will not be listed if it was never installed + let endpointAgents; + try { + const response = await getFleetSavedObjectsMetadata(soClient); + endpointAgents = response.saved_objects; + } catch (error) { + // Better to provide an empty object rather than default telemetry as this better informs us of an error + return {}; + } + + const endpointAgentsCount = endpointAgents.length; const endpointTelemetry = getDefaultEndpointTelemetry(); // If there are no installed endpoints return the default telemetry object - if (!endpointAgents || endpointAgents.length < 1) return endpointTelemetry; + if (!endpointAgents || endpointAgentsCount < 1) return endpointTelemetry; // Use unique hosts to prevent any potential duplicates const uniqueHostIds: Set = new Set(); - // Need agents to get events data for those that have run in last 24 hours as well as policy details - const agentDailyActiveTracker: AgentDailyActiveTracker = new Map(); - - const aDayAgo = new Date(); - aDayAgo.setDate(aDayAgo.getDate() - 1); let osTracker: OSTracker = {}; + let dailyActiveCount = 0; + let policyTracker: PoliciesTelemetry = { malware: { active: 0, inactive: 0, failure: 0 } }; + + for (let i = 0; i < endpointAgentsCount; i += 1) { + const { attributes: metadataAttributes } = endpointAgents[i]; + const { last_checkin: lastCheckin, local_metadata: localMetadata } = metadataAttributes; + const { host, os, elastic } = localMetadata as AgentLocalMetadata; // AgentMetadata is just an empty blob, casting for our use case + + if (!uniqueHostIds.has(host.id)) { + uniqueHostIds.add(host.id); + const agentId = elastic?.agent?.id; + osTracker = updateEndpointOSTelemetry(os, osTracker); + + if (agentId) { + let agentEvents; + try { + const response = await getLatestFleetEndpointEvent(soClient, agentId); + agentEvents = response.saved_objects; + } catch (error) { + // If the request fails we do not obtain `active within last 24 hours for this agent` or policy specifics + } - const endpointMetadataTelemetry = endpointAgents.reduce( - (metadataTelemetry, { attributes: metadataAttributes }) => { - const { last_checkin: lastCheckin, local_metadata: localMetadata } = metadataAttributes; - const { host, os, elastic } = localMetadata as AgentLocalMetadata; // AgentMetadata is just an empty blob, casting for our use case - - if (host && uniqueHostIds.has(host.id)) { - // use hosts since new agents could potentially be re-installed on existing hosts - return metadataTelemetry; - } else { - uniqueHostIds.add(host.id); - const isActiveWithinLastDay = !!lastCheckin && new Date(lastCheckin) > aDayAgo; - agentDailyActiveTracker.set(elastic.agent.id, isActiveWithinLastDay); - osTracker = trackEndpointOSTelemetry(os, osTracker); - return metadataTelemetry; + // AgentEvents will have a max length of 1 + if (agentEvents && agentEvents.length > 0) { + const latestEndpointEvent = agentEvents[0]; + dailyActiveCount = updateEndpointDailyActiveCount( + latestEndpointEvent, + lastCheckin, + dailyActiveCount + ); + policyTracker = updateEndpointPolicyTelemetry(latestEndpointEvent, policyTracker); + } } - }, - endpointTelemetry - ); + } + } - // All unique hosts with an endpoint installed. + // All unique hosts with an endpoint installed, thus all unique endpoint installs endpointTelemetry.total_installed = uniqueHostIds.size; + // Set the daily active count for the endpoints + endpointTelemetry.active_within_last_24_hours = dailyActiveCount; // Get the objects to populate our OS Telemetry - endpointMetadataTelemetry.os = Object.values(osTracker); - // Populate endpoint telemetry with the finalized 24 hour count and policy details - const finalizedEndpointTelemetryData = await addEndpointDailyActivityAndPolicyDetailsToTelemetry( - agentDailyActiveTracker, - savedObjectsClient, - endpointMetadataTelemetry - ); - - return finalizedEndpointTelemetryData; + endpointTelemetry.os = Object.values(osTracker); + // Provide the updated policy information + endpointTelemetry.policies = policyTracker; + + return endpointTelemetry; }; From 5741a868bc524dbb8363b85f4a0f37fd8ab321f8 Mon Sep 17 00:00:00 2001 From: spalger Date: Mon, 20 Jul 2020 09:32:41 -0700 Subject: [PATCH 09/77] Revert "skip flaky suite (#72146)" This reverts commit 45a4393459e0400171564f1d096784ebc97cc8ed. --- test/functional/apps/dashboard/dashboard_error_handling.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/functional/apps/dashboard/dashboard_error_handling.ts b/test/functional/apps/dashboard/dashboard_error_handling.ts index 38803739ff129..6bd8327a110b9 100644 --- a/test/functional/apps/dashboard/dashboard_error_handling.ts +++ b/test/functional/apps/dashboard/dashboard_error_handling.ts @@ -28,8 +28,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { /** * Common test suite for testing exception scenarious within dashboard */ - // Flaky: https://github.com/elastic/kibana/issues/72146 - describe.skip('dashboard error handling', () => { + describe('dashboard error handling', () => { before(async () => { await esArchiver.loadIfNeeded('dashboard/current/kibana'); await PageObjects.common.navigateToApp('dashboard'); From 75e4c7a2b73c5e0606e11cb3fecf08337a0ea81e Mon Sep 17 00:00:00 2001 From: Robert Austin Date: Mon, 20 Jul 2020 12:40:59 -0400 Subject: [PATCH 10/77] [Resolver] no longer pass related event stats to process node component (#72435) --- .../public/resolver/store/data/selectors.ts | 38 ++++--------------- .../public/resolver/store/selectors.ts | 6 ++- .../public/resolver/view/map.tsx | 4 -- .../public/resolver/view/panel.tsx | 5 ++- .../resolver/view/process_event_dot.tsx | 20 +++------- 5 files changed, 20 insertions(+), 53 deletions(-) diff --git a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts index 109b3abddcc77..4098c6fc6c5dd 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts @@ -116,13 +116,14 @@ export const tree = createSelector(graphableProcesses, function indexedTree( */ export const relatedEventsStats: ( state: DataState -) => Map | null = createSelector( +) => (nodeID: string) => ResolverNodeStats | undefined = createSelector( resolverTreeResponse, (resolverTree?: ResolverTree) => { if (resolverTree) { - return resolverTreeModel.relatedEventsStats(resolverTree); + const map = resolverTreeModel.relatedEventsStats(resolverTree); + return (nodeID: string) => map.get(nodeID); } else { - return null; + return () => undefined; } } ); @@ -213,12 +214,8 @@ export const relatedEventInfoByEntityId: ( relatedEventsStats /* eslint-enable no-shadow */ ) { - if (!relatedEventsStats) { - // If there are no related event stats, there are no related event info objects - return () => null; - } return (entityId) => { - const stats = relatedEventsStats.get(entityId); + const stats = relatedEventsStats(entityId); if (!stats) { return null; } @@ -524,37 +521,16 @@ export function databaseDocumentIDToAbort(state: DataState): string | null { } } -/** - * `ResolverNodeStats` for a process (`ResolverEvent`) - */ -const relatedEventStatsForProcess: ( - state: DataState -) => (event: ResolverEvent) => ResolverNodeStats | null = createSelector( - relatedEventsStats, - (statsMap) => { - if (!statsMap) { - return () => null; - } - return (event: ResolverEvent) => { - const nodeStats = statsMap.get(uniquePidForProcess(event)); - if (!nodeStats) { - return null; - } - return nodeStats; - }; - } -); - /** * The sum of all related event categories for a process. */ export const relatedEventTotalForProcess: ( state: DataState ) => (event: ResolverEvent) => number | null = createSelector( - relatedEventStatsForProcess, + relatedEventsStats, (statsForProcess) => { return (event: ResolverEvent) => { - const stats = statsForProcess(event); + const stats = statsForProcess(uniquePidForProcess(event)); if (!stats) { return null; } diff --git a/x-pack/plugins/security_solution/public/resolver/store/selectors.ts b/x-pack/plugins/security_solution/public/resolver/store/selectors.ts index 040e2920ce554..09293d0b3b683 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/selectors.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/selectors.ts @@ -10,7 +10,7 @@ import * as dataSelectors from './data/selectors'; import * as uiSelectors from './ui/selectors'; import { ResolverState, IsometricTaxiLayout } from '../types'; import { uniquePidForProcess } from '../models/process_event'; -import { ResolverEvent } from '../../../common/endpoint/types'; +import { ResolverEvent, ResolverNodeStats } from '../../../common/endpoint/types'; /** * A matrix that when applied to a Vector2 will convert it from world coordinates to screen coordinates. @@ -99,7 +99,9 @@ export const terminatedProcesses = composeSelectors( /** * Returns a map of `ResolverEvent` entity_id to their related event and alert statistics */ -export const relatedEventsStats = composeSelectors( +export const relatedEventsStats: ( + state: ResolverState +) => (nodeID: string) => ResolverNodeStats | undefined = composeSelectors( dataStateSelector, dataSelectors.relatedEventsStats ); diff --git a/x-pack/plugins/security_solution/public/resolver/view/map.tsx b/x-pack/plugins/security_solution/public/resolver/view/map.tsx index b366e2f220652..930e96c3f3e40 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/map.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/map.tsx @@ -60,7 +60,6 @@ export const ResolverMap = React.memo(function ({ const { processNodePositions, connectingEdgeLineSegments } = useSelector( selectors.visibleNodesAndEdgeLines )(timeAtRender); - const relatedEventsStats = useSelector(selectors.relatedEventsStats); const terminatedProcesses = useSelector(selectors.terminatedProcesses); const { projectionMatrix, ref, onMouseDown } = useCamera(); const isLoading = useSelector(selectors.isLoading); @@ -110,9 +109,6 @@ export const ResolverMap = React.memo(function ({ position={position} projectionMatrix={projectionMatrix} event={processEvent} - relatedEventsStatsForProcess={ - relatedEventsStats ? relatedEventsStats.get(entityId(processEvent)) : undefined - } isProcessTerminated={terminatedProcesses.has(processEntityId)} isProcessOrigin={false} timeAtRender={timeAtRender} diff --git a/x-pack/plugins/security_solution/public/resolver/view/panel.tsx b/x-pack/plugins/security_solution/public/resolver/view/panel.tsx index 47ce9b949fa59..efb2d95396ef5 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panel.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panel.tsx @@ -99,8 +99,9 @@ const PanelContent = memo(function PanelContent() { const relatedEventStats = useSelector(selectors.relatedEventsStats); const { crumbId, crumbEvent } = queryParams; - const relatedStatsForIdFromParams: ResolverNodeStats | undefined = - idFromParams && relatedEventStats ? relatedEventStats.get(idFromParams) : undefined; + const relatedStatsForIdFromParams: ResolverNodeStats | undefined = idFromParams + ? relatedEventStats(idFromParams) + : undefined; /** * Determine which set of breadcrumbs to display based on the query parameters diff --git a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx index 7666d1ac7c88a..aab4193bf031d 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx @@ -14,7 +14,7 @@ import { NodeSubMenu, subMenuAssets } from './submenu'; import { applyMatrix3 } from '../models/vector2'; import { Vector2, Matrix3 } from '../types'; import { SymbolIds, useResolverTheme, calculateResolverFontSize } from './assets'; -import { ResolverEvent, ResolverNodeStats } from '../../../common/endpoint/types'; +import { ResolverEvent } from '../../../common/endpoint/types'; import { useResolverDispatch } from './use_resolver_dispatch'; import * as eventModel from '../../../common/endpoint/models/event'; import * as processEventModel from '../models/process_event'; @@ -73,7 +73,6 @@ const UnstyledProcessEventDot = React.memo( projectionMatrix, isProcessTerminated, isProcessOrigin, - relatedEventsStatsForProcess, timeAtRender, }: { /** @@ -100,12 +99,6 @@ const UnstyledProcessEventDot = React.memo( * Whether or not to show the process as the originating event. */ isProcessOrigin: boolean; - /** - * A collection of events related to the current node and statistics (e.g. counts indexed by event type) - * to provide the user some visibility regarding the contents thereof. - * Statistics for the number of related events and alerts for this process node - */ - relatedEventsStatsForProcess?: ResolverNodeStats; /** * The time (unix epoch) at render. @@ -127,6 +120,7 @@ const UnstyledProcessEventDot = React.memo( const activeDescendantId = useSelector(selectors.uiActiveDescendantId); const selectedDescendantId = useSelector(selectors.uiSelectedDescendantId); const nodeID = processEventModel.uniquePidForProcess(event); + const relatedEventStats = useSelector(selectors.relatedEventsStats)(nodeID); // define a standard way of giving HTML IDs to nodes based on their entity_id/nodeID. // this is used to link nodes via aria attributes @@ -270,15 +264,13 @@ const UnstyledProcessEventDot = React.memo( const relatedEventOptions = useMemo(() => { const relatedStatsList = []; - if (!relatedEventsStatsForProcess) { + if (!relatedEventStats) { // Return an empty set of options if there are no stats to report return []; } // If we have entries to show, map them into options to display in the selectable list - for (const [category, total] of Object.entries( - relatedEventsStatsForProcess.events.byCategory - )) { + for (const [category, total] of Object.entries(relatedEventStats.events.byCategory)) { relatedStatsList.push({ prefix: , optionTitle: category, @@ -296,9 +288,9 @@ const UnstyledProcessEventDot = React.memo( }); } return relatedStatsList; - }, [relatedEventsStatsForProcess, dispatch, event, pushToQueryParams, nodeID]); + }, [relatedEventStats, dispatch, event, pushToQueryParams, nodeID]); - const relatedEventStatusOrOptions = !relatedEventsStatsForProcess + const relatedEventStatusOrOptions = !relatedEventStats ? subMenuAssets.initialMenuStatus : relatedEventOptions; From afae94a85ec8d58221f673c23f76aa664fe0cea0 Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Mon, 20 Jul 2020 11:00:06 -0600 Subject: [PATCH 11/77] [SIEM][Detection Engine][Lists] Adds conflict versioning and io-ts improvements to lists (#72337) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary * Adds conflict versioning by exposing the "_version" from the saved object system. It renames "version" to "_version" so that we can use regular "version" later for versioning things for pre-packaged lists abilities. * Utilizes `t.OutputOf` in the requests and the data types to give us more correctly types * Removes the `Identity` utility as that is adding confusion and can confuse vs code rather than improves things * Removes extra types that were causing confusion which was an idiom from io-ts * Changes the wording of `Partial` by removing that and instead focuses the request types on either client side or server side at this point. NOTE: The UI can migrate to holding onto the `_version` and then push it back down when it wants to migrate to using the conflict resolution. If the UI does not push it down, then a value of undefined will be used which is indicating that no conflict errors are wanted. Output example of posting an exception list: ❯ ./post_exception_list.sh ```ts { "_tags": [ "endpoint", "process", "malware", "os:linux" ], "_version": "Wzk4NiwxXQ==", "created_at": "2020-07-17T18:59:22.872Z", "created_by": "yo", "description": "This is a sample endpoint type exception", "id": "a08795b0-c85f-11ea-b1a6-c155df988a92", "list_id": "simple_list", "name": "Sample Endpoint Exception List", "namespace_type": "single", "tags": [ "user added string for a tag", "malware" ], "tie_breaker_id": "b789ec05-3e0f-4344-a156-0c0f5b6e2f9c", "type": "detection", "updated_at": "2020-07-17T18:59:22.891Z", "updated_by": "yo" } ``` Output example of posting an exception list item ❯ ./post_exception_list_item.sh ```ts { "_tags": [ "endpoint", "process", "malware", "os:linux" ], "_version": "Wzk4NywxXQ==", "comments": [], "created_at": "2020-07-17T18:59:30.286Z", "created_by": "yo", "description": "This is a sample endpoint type exception", "entries": [ { "field": "actingProcess.file.signer", "operator": "excluded", "type": "exists" }, { "field": "host.name", "operator": "included", "type": "match_any", "value": [ "some host", "another host" ] } ], "id": "a4f2b800-c85f-11ea-b1a6-c155df988a92", "item_id": "simple_list_item", "list_id": "simple_list", "name": "Sample Endpoint Exception List", "namespace_type": "single", "tags": [ "user added string for a tag", "malware" ], "tie_breaker_id": "1dc456bc-7aa9-44b4-bca3-131689cf729f", "type": "simple", "updated_at": "2020-07-17T18:59:30.304Z", "updated_by": "yo" } ``` Output example of when you get an exception list: ❯ ./get_exception_list.sh simple_list ```ts { "_tags": [ "endpoint", "process", "malware", "os:linux" ], "_version": "WzEwNzcsMV0=", "created_at": "2020-07-17T18:59:22.872Z", "created_by": "yo", "description": "Different description", "id": "a08795b0-c85f-11ea-b1a6-c155df988a92", "list_id": "simple_list", "name": "Sample Endpoint Exception List", "namespace_type": "single", "tags": [ "user added string for a tag", "malware" ], "tie_breaker_id": "b789ec05-3e0f-4344-a156-0c0f5b6e2f9c", "type": "endpoint", "updated_at": "2020-07-17T20:01:24.958Z", "updated_by": "yo" } ``` Example of the error you get if you do an update of an exception list and someone else has changed it: ```ts { "message": "[exception-list:a08795b0-c85f-11ea-b1a6-c155df988a92]: version conflict, required seqNo [1074], primary term [1]. current document has seqNo [1077] and primary term [1]: [version_conflict_engine_exception] [exception-list:a08795b0-c85f-11ea-b1a6-c155df988a92]: version conflict, required seqNo [1074], primary term [1]. current document has seqNo [1077] and primary term [1], with { index_uuid=\"a2mgXBO6Tl2ULDq-MTs1Tw\" & shard=\"0\" & index=\".kibana-hassanabad_1\" }", "status_code": 409 } ``` Lists are the same way and flavor, they encode the _version the same way that saved objects do. To see those work you run these scripts: ```ts ./post_list.sh ./post_list_item.sh ./find_list.sh ./find_list_item.sh ``` ### Checklist - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios --- x-pack/plugins/lists/common/constants.mock.ts | 1 + .../lists/common/schemas/common/schemas.ts | 4 ++ .../elastic_query/create_es_bulk_type.ts | 2 +- .../index_es_list_item_schema.ts | 2 +- .../elastic_query/index_es_list_schema.ts | 2 +- .../update_es_list_item_schema.ts | 2 +- .../elastic_query/update_es_list_schema.ts | 2 +- .../create_endpoint_list_item_schema.ts | 28 ++++++-------- .../create_exception_list_item_schema.ts | 33 +++++++---------- .../request/create_exception_list_schema.ts | 24 ++++++------ .../request/create_list_item_schema.ts | 8 ++-- .../schemas/request/create_list_schema.ts | 6 +-- .../delete_endpoint_list_item_schema.ts | 7 +++- .../delete_exception_list_item_schema.ts | 5 ++- .../request/delete_exception_list_schema.ts | 8 +++- .../request/delete_list_item_schema.ts | 8 ++-- .../schemas/request/delete_list_schema.ts | 3 +- .../request/export_list_item_query_schema.ts | 5 ++- .../find_endpoint_list_item_schema.mock.ts | 8 ++-- .../find_endpoint_list_item_schema.test.ts | 6 +-- .../request/find_endpoint_list_item_schema.ts | 9 +---- .../find_exception_list_item_schema.mock.ts | 12 +++--- .../find_exception_list_item_schema.test.ts | 16 +++++--- .../find_exception_list_item_schema.ts | 15 ++------ .../find_exception_list_schema.mock.ts | 8 ++-- .../find_exception_list_schema.test.ts | 15 +++++--- .../request/find_exception_list_schema.ts | 15 ++------ .../request/find_list_item_schema.mock.ts | 9 ++--- .../request/find_list_item_schema.test.ts | 10 ++--- .../schemas/request/find_list_item_schema.ts | 8 ++-- .../schemas/request/find_list_schema.mock.ts | 1 + .../schemas/request/find_list_schema.test.ts | 5 +-- .../schemas/request/find_list_schema.ts | 3 +- .../request/import_list_item_query_schema.ts | 8 ++-- .../request/import_list_item_schema.ts | 3 +- .../schemas/request/patch_list_item_schema.ts | 12 +++--- .../schemas/request/patch_list_schema.ts | 10 ++--- .../request/read_endpoint_list_item_schema.ts | 9 +---- .../read_exception_list_item_schema.ts | 13 ++----- .../request/read_exception_list_schema.ts | 13 ++----- .../schemas/request/read_list_item_schema.ts | 6 +-- .../schemas/request/read_list_schema.ts | 2 +- .../update_endpoint_list_item_schema.mock.ts | 1 + .../update_endpoint_list_item_schema.ts | 28 +++++++------- .../update_exception_list_item_schema.mock.ts | 1 + .../update_exception_list_item_schema.ts | 33 +++++++---------- .../update_exception_list_schema.mock.ts | 1 + .../request/update_exception_list_schema.ts | 30 ++++++++------- .../request/update_list_item_schema.ts | 11 ++++-- .../schemas/request/update_list_schema.ts | 9 +++-- .../create_endpoint_list_schema.test.ts | 2 +- .../exception_list_item_schema.mock.ts | 36 ++++++++++++------ .../response/exception_list_item_schema.ts | 2 + .../response/exception_list_schema.mock.ts | 25 +++++++++---- .../schemas/response/exception_list_schema.ts | 2 + .../schemas/response/list_item_schema.mock.ts | 1 + .../schemas/response/list_item_schema.ts | 2 + .../schemas/response/list_schema.mock.ts | 1 + .../common/schemas/response/list_schema.ts | 2 + .../schemas/types/default_comments_array.ts | 8 +--- .../types/default_create_comments_array.ts | 4 +- .../schemas/types/default_entries_array.ts | 8 +--- .../common/schemas/types/default_namespace.ts | 4 +- .../types/default_namespace_array.test.ts | 18 ++++----- .../schemas/types/default_namespace_array.ts | 4 +- .../types/default_update_comments_array.ts | 4 +- .../schemas/types/empty_string_array.ts | 2 - .../types/non_empty_string_array.test.ts | 16 ++++---- .../schemas/types/non_empty_string_array.ts | 4 +- x-pack/plugins/lists/common/types.ts | 8 ---- .../server/routes/find_list_item_route.ts | 4 +- .../server/routes/patch_list_item_route.ts | 3 +- .../lists/server/routes/patch_list_route.ts | 4 +- .../routes/update_endpoint_list_item_route.ts | 2 + .../update_exception_list_item_route.ts | 2 + .../routes/update_exception_list_route.ts | 2 + .../server/routes/update_list_item_route.ts | 3 +- .../lists/server/routes/update_list_route.ts | 4 +- .../updates/simple_update.json | 2 +- .../exception_lists/exception_list_client.ts | 6 +++ .../exception_list_client_types.ts | 4 ++ .../exception_lists/update_exception_list.ts | 6 +++ .../update_exception_list_item.ts | 6 +++ .../server/services/exception_lists/utils.ts | 8 ++++ .../server/services/items/create_list_item.ts | 2 + .../server/services/items/find_list_item.ts | 7 +++- .../server/services/items/get_list_item.ts | 7 +++- .../services/items/update_list_item.mock.ts | 1 + .../server/services/items/update_list_item.ts | 7 ++++ .../server/services/lists/create_list.ts | 2 + .../lists/server/services/lists/find_list.ts | 7 +++- .../lists/server/services/lists/get_list.ts | 7 +++- .../server/services/lists/list_client.ts | 4 ++ .../services/lists/list_client_types.ts | 3 ++ .../server/services/lists/update_list.mock.ts | 1 + .../server/services/lists/update_list.ts | 7 ++++ .../server/services/utils/decode_version.ts | 37 +++++++++++++++++++ .../services/utils/encode_hit_version.ts | 27 ++++++++++++++ .../utils/transform_elastic_to_list.ts | 3 ++ .../utils/transform_elastic_to_list_item.ts | 2 + .../schemas/types/default_actions_array.ts | 6 +-- .../schemas/types/default_boolean_false.ts | 4 +- .../schemas/types/default_boolean_true.ts | 4 +- .../schemas/types/default_empty_string.ts | 4 +- .../schemas/types/default_export_file_name.ts | 4 +- .../schemas/types/default_from_string.ts | 4 +- .../schemas/types/default_interval_string.ts | 4 +- .../schemas/types/default_language_string.ts | 4 +- .../types/default_max_signals_number.ts | 8 +--- .../schemas/types/default_page.ts | 4 +- .../schemas/types/default_per_page.ts | 4 +- .../types/default_risk_score_mapping_array.ts | 8 ++-- .../types/default_severity_mapping_array.ts | 8 ++-- .../schemas/types/default_string_array.ts | 7 ++-- .../types/default_string_boolean_false.ts | 2 +- .../schemas/types/default_threat_array.ts | 4 +- .../schemas/types/default_throttle_null.ts | 4 +- .../schemas/types/default_to_string.ts | 4 +- .../schemas/types/default_uuid.ts | 4 +- .../schemas/types/default_version_number.ts | 4 +- .../schemas/types/lists_default_array.test.ts | 4 +- .../schemas/types/lists_default_array.ts | 4 +- .../schemas/types/only_false_allowed.ts | 4 +- .../schemas/types/positive_integer.ts | 2 - .../positive_integer_greater_than_zero.ts | 2 - .../schemas/types/references_default_array.ts | 4 +- .../components/exceptions/helpers.test.tsx | 16 ++++---- .../exception_item/exception_details.test.tsx | 8 ++-- 128 files changed, 517 insertions(+), 435 deletions(-) create mode 100644 x-pack/plugins/lists/server/services/utils/decode_version.ts create mode 100644 x-pack/plugins/lists/server/services/utils/encode_hit_version.ts diff --git a/x-pack/plugins/lists/common/constants.mock.ts b/x-pack/plugins/lists/common/constants.mock.ts index 4924ba24426af..6ed1d19611c68 100644 --- a/x-pack/plugins/lists/common/constants.mock.ts +++ b/x-pack/plugins/lists/common/constants.mock.ts @@ -60,3 +60,4 @@ export const TAGS = []; export const COMMENTS = []; export const FILTER = 'name:Nicolas Bourbaki'; export const CURSOR = 'c29tZXN0cmluZ2ZvcnlvdQ=='; +export const _VERSION = 'WzI5NywxXQ=='; diff --git a/x-pack/plugins/lists/common/schemas/common/schemas.ts b/x-pack/plugins/lists/common/schemas/common/schemas.ts index 6199a5f16f109..8f1666bb542d9 100644 --- a/x-pack/plugins/lists/common/schemas/common/schemas.ts +++ b/x-pack/plugins/lists/common/schemas/common/schemas.ts @@ -307,3 +307,7 @@ export type Deserializer = t.TypeOf; export const deserializerOrUndefined = t.union([deserializer, t.undefined]); export type DeserializerOrUndefined = t.TypeOf; + +export const _version = t.string; +export const _versionOrUndefined = t.union([_version, t.undefined]); +export type _VersionOrUndefined = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/elastic_query/create_es_bulk_type.ts b/x-pack/plugins/lists/common/schemas/elastic_query/create_es_bulk_type.ts index 4a825382c06e4..3104ee27c57de 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_query/create_es_bulk_type.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_query/create_es_bulk_type.ts @@ -14,4 +14,4 @@ export const createEsBulkTypeSchema = t.exact( }) ); -export type CreateEsBulkTypeSchema = t.TypeOf; +export type CreateEsBulkTypeSchema = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_item_schema.ts index 006600ee5b7fd..8dc5a376d1495 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_item_schema.ts @@ -38,4 +38,4 @@ export const indexEsListItemSchema = t.intersection([ esDataTypeUnion, ]); -export type IndexEsListItemSchema = t.TypeOf; +export type IndexEsListItemSchema = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts index fd1018bc46a8d..3ee598291149f 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts @@ -38,4 +38,4 @@ export const indexEsListSchema = t.exact( }) ); -export type IndexEsListSchema = t.TypeOf; +export type IndexEsListSchema = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_item_schema.ts index e4cf46bc39429..20187de535a8e 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_item_schema.ts @@ -21,4 +21,4 @@ export const updateEsListItemSchema = t.intersection([ esDataTypeUnion, ]); -export type UpdateEsListItemSchema = t.TypeOf; +export type UpdateEsListItemSchema = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_schema.ts index 8f23f3744e563..80b9733908d39 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_query/update_es_list_schema.ts @@ -26,4 +26,4 @@ export const updateEsListSchema = t.exact( }) ); -export type UpdateEsListSchema = t.TypeOf; +export type UpdateEsListSchema = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts index 5311c7a43cdb5..3f0e1a12894d4 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts @@ -19,7 +19,7 @@ import { name, tags, } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { RequiredKeepUndefined } from '../../types'; import { CreateCommentsArray, DefaultCreateCommentsArray, DefaultEntryArray } from '../types'; import { EntriesArray } from '../types/entries'; import { DefaultUuid } from '../../siem_common_deps'; @@ -44,20 +44,16 @@ export const createEndpointListItemSchema = t.intersection([ ), ]); -export type CreateEndpointListItemSchemaPartial = Identity< - t.TypeOf ->; -export type CreateEndpointListItemSchema = RequiredKeepUndefined< - t.TypeOf ->; +export type CreateEndpointListItemSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type CreateEndpointListItemSchemaDecoded = Identity< - Omit & { - _tags: _Tags; - comments: CreateCommentsArray; - tags: Tags; - item_id: ItemId; - entries: EntriesArray; - } ->; +export type CreateEndpointListItemSchemaDecoded = Omit< + RequiredKeepUndefined>, + '_tags' | 'tags' | 'item_id' | 'entries' | 'comments' +> & { + _tags: _Tags; + comments: CreateCommentsArray; + tags: Tags; + item_id: ItemId; + entries: EntriesArray; +}; diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts index 4b7db3eee35bc..c2ccf18ed8720 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts @@ -21,7 +21,7 @@ import { namespace_type, tags, } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { RequiredKeepUndefined } from '../../types'; import { CreateCommentsArray, DefaultCreateCommentsArray, @@ -53,24 +53,17 @@ export const createExceptionListItemSchema = t.intersection([ ), ]); -export type CreateExceptionListItemSchemaPartial = Identity< - t.TypeOf ->; -export type CreateExceptionListItemSchema = RequiredKeepUndefined< - t.TypeOf ->; +export type CreateExceptionListItemSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type CreateExceptionListItemSchemaDecoded = Identity< - Omit< - CreateExceptionListItemSchema, - '_tags' | 'tags' | 'item_id' | 'entries' | 'namespace_type' | 'comments' - > & { - _tags: _Tags; - comments: CreateCommentsArray; - tags: Tags; - item_id: ItemId; - entries: EntriesArray; - namespace_type: NamespaceType; - } ->; +export type CreateExceptionListItemSchemaDecoded = Omit< + RequiredKeepUndefined>, + '_tags' | 'tags' | 'item_id' | 'entries' | 'namespace_type' | 'comments' +> & { + _tags: _Tags; + comments: CreateCommentsArray; + tags: Tags; + item_id: ItemId; + entries: EntriesArray; + namespace_type: NamespaceType; +}; diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts index 66cca4ab9ca53..8f714760621ff 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts @@ -20,7 +20,7 @@ import { namespace_type, tags, } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { RequiredKeepUndefined } from '../../types'; import { DefaultUuid } from '../../siem_common_deps'; import { NamespaceType } from '../types'; @@ -43,17 +43,15 @@ export const createExceptionListSchema = t.intersection([ ), ]); -export type CreateExceptionListSchemaPartial = Identity>; -export type CreateExceptionListSchema = RequiredKeepUndefined< - t.TypeOf ->; +export type CreateExceptionListSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type CreateExceptionListSchemaDecoded = Identity< - Omit & { - _tags: _Tags; - tags: Tags; - list_id: ListId; - namespace_type: NamespaceType; - } ->; +export type CreateExceptionListSchemaDecoded = Omit< + RequiredKeepUndefined>, + '_tags' | 'tags' | 'list_id' | 'namespace_type' +> & { + _tags: _Tags; + tags: Tags; + list_id: ListId; + namespace_type: NamespaceType; +}; diff --git a/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.ts index 6d16f2074864c..351eae48a638d 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_list_item_schema.ts @@ -9,7 +9,7 @@ import * as t from 'io-ts'; import { id, list_id, meta, value } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { RequiredKeepUndefined } from '../../types'; export const createListItemSchema = t.intersection([ t.exact( @@ -21,5 +21,7 @@ export const createListItemSchema = t.intersection([ t.exact(t.partial({ id, meta })), ]); -export type CreateListItemSchemaPartial = Identity>; -export type CreateListItemSchema = RequiredKeepUndefined>; +export type CreateListItemSchema = t.OutputOf; +export type CreateListItemSchemaDecoded = RequiredKeepUndefined< + t.TypeOf +>; diff --git a/x-pack/plugins/lists/common/schemas/request/create_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_list_schema.ts index fcf4465f88c8d..38d6167ea63f3 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_list_schema.ts @@ -7,7 +7,7 @@ import * as t from 'io-ts'; import { description, deserializer, id, meta, name, serializer, type } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { RequiredKeepUndefined } from '../../types'; export const createListSchema = t.intersection([ t.exact( @@ -20,5 +20,5 @@ export const createListSchema = t.intersection([ t.exact(t.partial({ deserializer, id, meta, serializer })), ]); -export type CreateListSchemaPartial = Identity>; -export type CreateListSchema = RequiredKeepUndefined>; +export type CreateListSchema = t.OutputOf; +export type CreateListSchemaDecoded = RequiredKeepUndefined>; diff --git a/x-pack/plugins/lists/common/schemas/request/delete_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/delete_endpoint_list_item_schema.ts index 311af3a4c0437..5af5bcd17e744 100644 --- a/x-pack/plugins/lists/common/schemas/request/delete_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/delete_endpoint_list_item_schema.ts @@ -9,6 +9,7 @@ import * as t from 'io-ts'; import { id, item_id } from '../common/schemas'; +import { RequiredKeepUndefined } from '../../types'; export const deleteEndpointListItemSchema = t.exact( t.partial({ @@ -17,7 +18,9 @@ export const deleteEndpointListItemSchema = t.exact( }) ); -export type DeleteEndpointListItemSchema = t.TypeOf; +export type DeleteEndpointListItemSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type DeleteEndpointListItemSchemaDecoded = DeleteEndpointListItemSchema; +export type DeleteEndpointListItemSchemaDecoded = RequiredKeepUndefined< + t.TypeOf +>; diff --git a/x-pack/plugins/lists/common/schemas/request/delete_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/delete_exception_list_item_schema.ts index 909960c9fffc0..da6516f4b6fe4 100644 --- a/x-pack/plugins/lists/common/schemas/request/delete_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/delete_exception_list_item_schema.ts @@ -10,6 +10,7 @@ import * as t from 'io-ts'; import { id, item_id, namespace_type } from '../common/schemas'; import { NamespaceType } from '../types'; +import { RequiredKeepUndefined } from '../../types'; export const deleteExceptionListItemSchema = t.exact( t.partial({ @@ -19,11 +20,11 @@ export const deleteExceptionListItemSchema = t.exact( }) ); -export type DeleteExceptionListItemSchema = t.TypeOf; +export type DeleteExceptionListItemSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. export type DeleteExceptionListItemSchemaDecoded = Omit< - DeleteExceptionListItemSchema, + RequiredKeepUndefined>, 'namespace_type' > & { namespace_type: NamespaceType; diff --git a/x-pack/plugins/lists/common/schemas/request/delete_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/delete_exception_list_schema.ts index 3bf5e7a4d0782..0911a9342f7a9 100644 --- a/x-pack/plugins/lists/common/schemas/request/delete_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/delete_exception_list_schema.ts @@ -10,6 +10,7 @@ import * as t from 'io-ts'; import { id, list_id, namespace_type } from '../common/schemas'; import { NamespaceType } from '../types'; +import { RequiredKeepUndefined } from '../../types'; export const deleteExceptionListSchema = t.exact( t.partial({ @@ -19,9 +20,12 @@ export const deleteExceptionListSchema = t.exact( }) ); -export type DeleteExceptionListSchema = t.TypeOf; +export type DeleteExceptionListSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type DeleteExceptionListSchemaDecoded = Omit & { +export type DeleteExceptionListSchemaDecoded = Omit< + RequiredKeepUndefined>, + 'namespace_type' +> & { namespace_type: NamespaceType; }; diff --git a/x-pack/plugins/lists/common/schemas/request/delete_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/delete_list_item_schema.ts index 91887395e747d..5e2425271c463 100644 --- a/x-pack/plugins/lists/common/schemas/request/delete_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/delete_list_item_schema.ts @@ -9,7 +9,7 @@ import * as t from 'io-ts'; import { id, list_id, valueOrUndefined } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { RequiredKeepUndefined } from '../../types'; export const deleteListItemSchema = t.intersection([ t.exact( @@ -20,5 +20,7 @@ export const deleteListItemSchema = t.intersection([ t.exact(t.partial({ id, list_id })), ]); -export type DeleteListItemSchemaPartial = Identity>; -export type DeleteListItemSchema = RequiredKeepUndefined>; +export type DeleteListItemSchema = t.OutputOf; +export type DeleteListItemSchemaDecoded = RequiredKeepUndefined< + t.TypeOf +>; diff --git a/x-pack/plugins/lists/common/schemas/request/delete_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/delete_list_schema.ts index 6f6fc7a9ea33c..830e7fe695d1d 100644 --- a/x-pack/plugins/lists/common/schemas/request/delete_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/delete_list_schema.ts @@ -9,6 +9,7 @@ import * as t from 'io-ts'; import { id } from '../common/schemas'; +import { RequiredKeepUndefined } from '../../types'; export const deleteListSchema = t.exact( t.type({ @@ -16,5 +17,5 @@ export const deleteListSchema = t.exact( }) ); -export type DeleteListSchema = t.TypeOf; +export type DeleteListSchema = RequiredKeepUndefined>; export type DeleteListSchemaEncoded = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/request/export_list_item_query_schema.ts b/x-pack/plugins/lists/common/schemas/request/export_list_item_query_schema.ts index 58092ffc563b1..8d14f015d3805 100644 --- a/x-pack/plugins/lists/common/schemas/request/export_list_item_query_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/export_list_item_query_schema.ts @@ -9,6 +9,7 @@ import * as t from 'io-ts'; import { list_id } from '../common/schemas'; +import { RequiredKeepUndefined } from '../../types'; export const exportListItemQuerySchema = t.exact( t.type({ @@ -17,5 +18,7 @@ export const exportListItemQuerySchema = t.exact( }) ); -export type ExportListItemQuerySchema = t.TypeOf; +export type ExportListItemQuerySchema = RequiredKeepUndefined< + t.TypeOf +>; export type ExportListItemQuerySchemaEncoded = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.mock.ts index bff55dedf3064..469936eae96c9 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.mock.ts @@ -7,11 +7,11 @@ import { FILTER } from '../../constants.mock'; import { - FindEndpointListItemSchemaPartial, - FindEndpointListItemSchemaPartialDecoded, + FindEndpointListItemSchema, + FindEndpointListItemSchemaDecoded, } from './find_endpoint_list_item_schema'; -export const getFindEndpointListItemSchemaMock = (): FindEndpointListItemSchemaPartial => ({ +export const getFindEndpointListItemSchemaMock = (): FindEndpointListItemSchema => ({ filter: FILTER, page: '1', per_page: '25', @@ -19,7 +19,7 @@ export const getFindEndpointListItemSchemaMock = (): FindEndpointListItemSchemaP sort_order: undefined, }); -export const getFindEndpointListItemSchemaDecodedMock = (): FindEndpointListItemSchemaPartialDecoded => ({ +export const getFindEndpointListItemSchemaDecodedMock = (): FindEndpointListItemSchemaDecoded => ({ filter: FILTER, page: 1, per_page: 25, diff --git a/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.test.ts index f9eeaa33230f9..8249b1e2d49c2 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.test.ts @@ -14,7 +14,7 @@ import { getFindEndpointListItemSchemaMock, } from './find_endpoint_list_item_schema.mock'; import { - FindEndpointListItemSchemaPartial, + FindEndpointListItemSchema, findEndpointListItemSchema, } from './find_endpoint_list_item_schema'; @@ -29,7 +29,7 @@ describe('find_endpoint_list_item_schema', () => { }); test('it should validate and empty object since everything is optional and has defaults', () => { - const payload: FindEndpointListItemSchemaPartial = {}; + const payload: FindEndpointListItemSchema = {}; const decoded = findEndpointListItemSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -98,7 +98,7 @@ describe('find_endpoint_list_item_schema', () => { }); test('it should not allow an extra key to be sent in', () => { - const payload: FindEndpointListItemSchemaPartial & { + const payload: FindEndpointListItemSchema & { extraKey: string; } = { ...getFindEndpointListItemSchemaMock(), extraKey: 'some new value' }; const decoded = findEndpointListItemSchema.decode(payload); diff --git a/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.ts index c9ee46994d720..bc839ce1346f3 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_endpoint_list_item_schema.ts @@ -22,16 +22,9 @@ export const findEndpointListItemSchema = t.exact( }) ); -export type FindEndpointListItemSchemaPartial = t.OutputOf; - -// This type is used after a decode since some things are defaults after a decode. -export type FindEndpointListItemSchemaPartialDecoded = t.TypeOf; +export type FindEndpointListItemSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. export type FindEndpointListItemSchemaDecoded = RequiredKeepUndefined< - FindEndpointListItemSchemaPartialDecoded ->; - -export type FindEndpointListItemSchema = RequiredKeepUndefined< t.TypeOf >; diff --git a/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.mock.ts index f22e6685fe0ac..d2733531eada4 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.mock.ts @@ -7,11 +7,11 @@ import { FILTER, LIST_ID, NAMESPACE_TYPE } from '../../constants.mock'; import { - FindExceptionListItemSchemaPartial, - FindExceptionListItemSchemaPartialDecoded, + FindExceptionListItemSchema, + FindExceptionListItemSchemaDecoded, } from './find_exception_list_item_schema'; -export const getFindExceptionListItemSchemaMock = (): FindExceptionListItemSchemaPartial => ({ +export const getFindExceptionListItemSchemaMock = (): FindExceptionListItemSchema => ({ filter: FILTER, list_id: LIST_ID, namespace_type: NAMESPACE_TYPE, @@ -21,7 +21,7 @@ export const getFindExceptionListItemSchemaMock = (): FindExceptionListItemSchem sort_order: undefined, }); -export const getFindExceptionListItemSchemaMultipleMock = (): FindExceptionListItemSchemaPartial => ({ +export const getFindExceptionListItemSchemaMultipleMock = (): FindExceptionListItemSchema => ({ filter: 'name:Sofia Kovalevskaya,name:Hypatia,name:Sophie Germain', list_id: 'list-1,list-2,list-3', namespace_type: 'single,single,agnostic', @@ -31,7 +31,7 @@ export const getFindExceptionListItemSchemaMultipleMock = (): FindExceptionListI sort_order: undefined, }); -export const getFindExceptionListItemSchemaDecodedMock = (): FindExceptionListItemSchemaPartialDecoded => ({ +export const getFindExceptionListItemSchemaDecodedMock = (): FindExceptionListItemSchemaDecoded => ({ filter: [FILTER], list_id: [LIST_ID], namespace_type: [NAMESPACE_TYPE], @@ -41,7 +41,7 @@ export const getFindExceptionListItemSchemaDecodedMock = (): FindExceptionListIt sort_order: undefined, }); -export const getFindExceptionListItemSchemaDecodedMultipleMock = (): FindExceptionListItemSchemaPartialDecoded => ({ +export const getFindExceptionListItemSchemaDecodedMultipleMock = (): FindExceptionListItemSchemaDecoded => ({ filter: ['name:Sofia Kovalevskaya', 'name:Hypatia', 'name:Sophie Germain'], list_id: ['list-1', 'list-2', 'list-3'], namespace_type: ['single', 'single', 'agnostic'], diff --git a/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.test.ts index ba64bb434d50b..f402f22b093ad 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.test.ts @@ -17,8 +17,8 @@ import { getFindExceptionListItemSchemaMultipleMock, } from './find_exception_list_item_schema.mock'; import { - FindExceptionListItemSchemaPartial, - FindExceptionListItemSchemaPartialDecoded, + FindExceptionListItemSchema, + FindExceptionListItemSchemaDecoded, findExceptionListItemSchema, } from './find_exception_list_item_schema'; @@ -42,15 +42,19 @@ describe('find_list_item_schema', () => { }); test('it should validate just a list_id where it decodes into an array for list_id and adds a namespace_type of "single" as an array', () => { - const payload: FindExceptionListItemSchemaPartial = { list_id: LIST_ID }; + const payload: FindExceptionListItemSchema = { list_id: LIST_ID }; const decoded = findExceptionListItemSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: FindExceptionListItemSchemaPartialDecoded = { + const expected: FindExceptionListItemSchemaDecoded = { filter: [], list_id: [LIST_ID], namespace_type: ['single'], + page: undefined, + per_page: undefined, + sort_field: undefined, + sort_order: undefined, }; expect(message.schema).toEqual(expected); }); @@ -86,7 +90,7 @@ describe('find_list_item_schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: FindExceptionListItemSchemaPartialDecoded = { + const expected: FindExceptionListItemSchemaDecoded = { ...getFindExceptionListItemSchemaDecodedMock(), filter: [], }; @@ -118,7 +122,7 @@ describe('find_list_item_schema', () => { }); test('it should not allow an extra key to be sent in', () => { - const payload: FindExceptionListItemSchemaPartial & { + const payload: FindExceptionListItemSchema & { extraKey: string; } = { ...getFindExceptionListItemSchemaMock(), extraKey: 'some new value' }; const decoded = findExceptionListItemSchema.decode(payload); diff --git a/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.ts index aa53fa0fd912c..634c080d70b75 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_exception_list_item_schema.ts @@ -36,22 +36,13 @@ export const findExceptionListItemSchema = t.intersection([ ), ]); -export type FindExceptionListItemSchemaPartial = t.OutputOf; +export type FindExceptionListItemSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type FindExceptionListItemSchemaPartialDecoded = Omit< - t.TypeOf, +export type FindExceptionListItemSchemaDecoded = Omit< + RequiredKeepUndefined>, 'namespace_type' | 'filter' > & { filter: EmptyStringArrayDecoded; namespace_type: DefaultNamespaceArrayTypeDecoded; }; - -// This type is used after a decode since some things are defaults after a decode. -export type FindExceptionListItemSchemaDecoded = RequiredKeepUndefined< - FindExceptionListItemSchemaPartialDecoded ->; - -export type FindExceptionListItemSchema = RequiredKeepUndefined< - t.TypeOf ->; diff --git a/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.mock.ts index 8080d10ca451c..96f4b7e1cbd63 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.mock.ts @@ -7,11 +7,11 @@ import { FILTER, NAMESPACE_TYPE } from '../../constants.mock'; import { - FindExceptionListSchemaPartial, - FindExceptionListSchemaPartialDecoded, + FindExceptionListSchema, + FindExceptionListSchemaDecoded, } from './find_exception_list_schema'; -export const getFindExceptionListSchemaMock = (): FindExceptionListSchemaPartial => ({ +export const getFindExceptionListSchemaMock = (): FindExceptionListSchema => ({ filter: FILTER, namespace_type: NAMESPACE_TYPE, page: '1', @@ -20,7 +20,7 @@ export const getFindExceptionListSchemaMock = (): FindExceptionListSchemaPartial sort_order: undefined, }); -export const getFindExceptionListSchemaDecodedMock = (): FindExceptionListSchemaPartialDecoded => ({ +export const getFindExceptionListSchemaDecodedMock = (): FindExceptionListSchemaDecoded => ({ filter: FILTER, namespace_type: NAMESPACE_TYPE, page: 1, diff --git a/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.test.ts index 42356066176d5..ef96346c732b8 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.test.ts @@ -14,8 +14,8 @@ import { getFindExceptionListSchemaMock, } from './find_exception_list_schema.mock'; import { - FindExceptionListSchemaPartial, - FindExceptionListSchemaPartialDecoded, + FindExceptionListSchema, + FindExceptionListSchemaDecoded, findExceptionListSchema, } from './find_exception_list_schema'; @@ -30,13 +30,18 @@ describe('find_exception_list_schema', () => { }); test('it should validate and empty object since everything is optional and will respond only with namespace_type filled out to be "single"', () => { - const payload: FindExceptionListSchemaPartial = {}; + const payload: FindExceptionListSchema = {}; const decoded = findExceptionListSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: FindExceptionListSchemaPartialDecoded = { + const expected: FindExceptionListSchemaDecoded = { + filter: undefined, namespace_type: 'single', + page: undefined, + per_page: undefined, + sort_field: undefined, + sort_order: undefined, }; expect(message.schema).toEqual(expected); }); @@ -102,7 +107,7 @@ describe('find_exception_list_schema', () => { }); test('it should not allow an extra key to be sent in', () => { - const payload: FindExceptionListSchemaPartial & { + const payload: FindExceptionListSchema & { extraKey: string; } = { ...getFindExceptionListSchemaMock(), extraKey: 'some new value' }; const decoded = findExceptionListSchema.decode(payload); diff --git a/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.ts index 4fa9d2e42c5d1..7ce01c79bbe42 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_exception_list_schema.ts @@ -24,21 +24,12 @@ export const findExceptionListSchema = t.exact( }) ); -export type FindExceptionListSchemaPartial = t.OutputOf; +export type FindExceptionListSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type FindExceptionListSchemaPartialDecoded = Omit< - t.TypeOf, +export type FindExceptionListSchemaDecoded = Omit< + RequiredKeepUndefined>, 'namespace_type' > & { namespace_type: NamespaceType; }; - -// This type is used after a decode since some things are defaults after a decode. -export type FindExceptionListSchemaDecoded = RequiredKeepUndefined< - FindExceptionListSchemaPartialDecoded ->; - -export type FindExceptionListSchema = RequiredKeepUndefined< - t.TypeOf ->; diff --git a/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.mock.ts index a1e91f6acd264..ccde93eec4580 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.mock.ts @@ -6,12 +6,9 @@ import { CURSOR, FILTER, LIST_ID } from '../../constants.mock'; -import { - FindListItemSchemaPartial, - FindListItemSchemaPartialDecoded, -} from './find_list_item_schema'; +import { FindListItemSchema, FindListItemSchemaDecoded } from './find_list_item_schema'; -export const getFindListItemSchemaMock = (): FindListItemSchemaPartial => ({ +export const getFindListItemSchemaMock = (): FindListItemSchema => ({ cursor: CURSOR, filter: FILTER, list_id: LIST_ID, @@ -21,7 +18,7 @@ export const getFindListItemSchemaMock = (): FindListItemSchemaPartial => ({ sort_order: undefined, }); -export const getFindListItemSchemaDecodedMock = (): FindListItemSchemaPartialDecoded => ({ +export const getFindListItemSchemaDecodedMock = (): FindListItemSchemaDecoded => ({ cursor: CURSOR, filter: FILTER, list_id: LIST_ID, diff --git a/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.test.ts index 42803fffc53c2..59d4b4485b578 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.test.ts @@ -15,8 +15,8 @@ import { getFindListItemSchemaMock, } from './find_list_item_schema.mock'; import { - FindListItemSchemaPartial, - FindListItemSchemaPartialDecoded, + FindListItemSchema, + FindListItemSchemaDecoded, findListItemSchema, } from './find_list_item_schema'; @@ -31,12 +31,12 @@ describe('find_list_item_schema', () => { }); test('it should validate just a list_id where it decodes into an array for list_id and adds a namespace_type of "single"', () => { - const payload: FindListItemSchemaPartial = { list_id: LIST_ID }; + const payload: FindListItemSchema = { list_id: LIST_ID }; const decoded = findListItemSchema.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: FindListItemSchemaPartialDecoded = { + const expected: FindListItemSchemaDecoded = { cursor: undefined, filter: undefined, list_id: LIST_ID, @@ -97,7 +97,7 @@ describe('find_list_item_schema', () => { }); test('it should not allow an extra key to be sent in', () => { - const payload: FindListItemSchemaPartial & { + const payload: FindListItemSchema & { extraKey: string; } = { ...getFindListItemSchemaMock(), extraKey: 'some new value' }; const decoded = findListItemSchema.decode(payload); diff --git a/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.ts index bbd3c7b5ec642..ba3dfc6ee33ec 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_list_item_schema.ts @@ -9,7 +9,7 @@ import * as t from 'io-ts'; import { cursor, filter, list_id, sort_field, sort_order } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { RequiredKeepUndefined } from '../../types'; import { StringToPositiveNumber } from '../types/string_to_positive_number'; export const findListItemSchema = t.intersection([ @@ -26,9 +26,7 @@ export const findListItemSchema = t.intersection([ ), ]); -export type FindListItemSchemaPartial = Identity>; +export type FindListItemSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type FindListItemSchemaPartialDecoded = RequiredKeepUndefined< - t.TypeOf ->; +export type FindListItemSchemaDecoded = RequiredKeepUndefined>; diff --git a/x-pack/plugins/lists/common/schemas/request/find_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/find_list_schema.mock.ts index dcb18dac8cfb6..bb9e15a439b3b 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_list_schema.mock.ts @@ -17,6 +17,7 @@ export const getFindListSchemaMock = (): FindListSchemaEncoded => ({ }); export const getFindListSchemaDecodedMock = (): FindListSchema => ({ + cursor: undefined, filter: FILTER, page: 1, per_page: 25, diff --git a/x-pack/plugins/lists/common/schemas/request/find_list_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/find_list_schema.test.ts index a343fb4b08bfc..63f29a64b4bf9 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_list_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_list_schema.test.ts @@ -10,7 +10,7 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { exactCheck, foldLeftRight, getPaths } from '../../siem_common_deps'; import { getFindListSchemaDecodedMock, getFindListSchemaMock } from './find_list_schema.mock'; -import { FindListSchema, FindListSchemaEncoded, findListSchema } from './find_list_schema'; +import { FindListSchemaEncoded, findListSchema } from './find_list_schema'; describe('find_list_schema', () => { test('it should validate a typical find item request', () => { @@ -28,8 +28,7 @@ describe('find_list_schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: FindListSchema = {}; - expect(message.schema).toEqual(expected); + expect(message.schema).toEqual(payload); }); test('it should validate with page missing', () => { diff --git a/x-pack/plugins/lists/common/schemas/request/find_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/find_list_schema.ts index 212232f6bc9c1..e5020cc8eff84 100644 --- a/x-pack/plugins/lists/common/schemas/request/find_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/find_list_schema.ts @@ -10,6 +10,7 @@ import * as t from 'io-ts'; import { cursor, filter, sort_field, sort_order } from '../common/schemas'; import { StringToPositiveNumber } from '../types/string_to_positive_number'; +import { RequiredKeepUndefined } from '../../types'; export const findListSchema = t.exact( t.partial({ @@ -22,5 +23,5 @@ export const findListSchema = t.exact( }) ); -export type FindListSchema = t.TypeOf; +export type FindListSchema = RequiredKeepUndefined>; export type FindListSchemaEncoded = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/request/import_list_item_query_schema.ts b/x-pack/plugins/lists/common/schemas/request/import_list_item_query_schema.ts index 2c671466702e0..e45f77ca18ae1 100644 --- a/x-pack/plugins/lists/common/schemas/request/import_list_item_query_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/import_list_item_query_schema.ts @@ -8,14 +8,14 @@ import * as t from 'io-ts'; +import { RequiredKeepUndefined } from '../../types'; import { deserializer, list_id, serializer, type } from '../common/schemas'; -import { Identity } from '../../types'; export const importListItemQuerySchema = t.exact( t.partial({ deserializer, list_id, serializer, type }) ); -export type ImportListItemQuerySchemaPartial = Identity>; - -export type ImportListItemQuerySchema = t.TypeOf; +export type ImportListItemQuerySchema = RequiredKeepUndefined< + t.TypeOf +>; export type ImportListItemQuerySchemaEncoded = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts index 7370eecf690c7..671aeda757eff 100644 --- a/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts @@ -9,6 +9,7 @@ import * as t from 'io-ts'; import { file } from '../common/schemas'; +import { RequiredKeepUndefined } from '../../types'; export const importListItemSchema = t.exact( t.type({ @@ -16,5 +17,5 @@ export const importListItemSchema = t.exact( }) ); -export type ImportListItemSchema = t.TypeOf; +export type ImportListItemSchema = RequiredKeepUndefined>; export type ImportListItemSchemaEncoded = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/request/patch_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/patch_list_item_schema.ts index 2016069f32fb3..9c5284c15ca99 100644 --- a/x-pack/plugins/lists/common/schemas/request/patch_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/patch_list_item_schema.ts @@ -8,8 +8,8 @@ import * as t from 'io-ts'; -import { id, meta, value } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { _version, id, meta, value } from '../common/schemas'; +import { RequiredKeepUndefined } from '../../types'; export const patchListItemSchema = t.intersection([ t.exact( @@ -17,8 +17,10 @@ export const patchListItemSchema = t.intersection([ id, }) ), - t.exact(t.partial({ meta, value })), + t.exact(t.partial({ _version, meta, value })), ]); -export type PatchListItemSchemaPartial = Identity>; -export type PatchListItemSchema = RequiredKeepUndefined>; +export type PatchListItemSchema = t.OutputOf; +export type PatchListItemSchemaDecoded = RequiredKeepUndefined< + t.TypeOf +>; diff --git a/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts index 653a42dc91653..e0cd1571afc81 100644 --- a/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts @@ -8,8 +8,8 @@ import * as t from 'io-ts'; -import { description, id, meta, name } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { _version, description, id, meta, name } from '../common/schemas'; +import { RequiredKeepUndefined } from '../../types'; export const patchListSchema = t.intersection([ t.exact( @@ -17,8 +17,8 @@ export const patchListSchema = t.intersection([ id, }) ), - t.exact(t.partial({ description, meta, name })), + t.exact(t.partial({ _version, description, meta, name })), ]); -export type PatchListSchemaPartial = Identity>; -export type PatchListSchema = RequiredKeepUndefined>>; +export type PatchListSchema = t.OutputOf; +export type PatchListSchemaDecoded = RequiredKeepUndefined>; diff --git a/x-pack/plugins/lists/common/schemas/request/read_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/read_endpoint_list_item_schema.ts index 22750f5db6a1d..d6c54e289effe 100644 --- a/x-pack/plugins/lists/common/schemas/request/read_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/read_endpoint_list_item_schema.ts @@ -18,14 +18,9 @@ export const readEndpointListItemSchema = t.exact( }) ); -export type ReadEndpointListItemSchemaPartial = t.TypeOf; - -// This type is used after a decode since some things are defaults after a decode. -export type ReadEndpointListItemSchemaPartialDecoded = ReadEndpointListItemSchemaPartial; +export type ReadEndpointListItemSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. export type ReadEndpointListItemSchemaDecoded = RequiredKeepUndefined< - ReadEndpointListItemSchemaPartialDecoded + t.TypeOf >; - -export type ReadEndpointListItemSchema = RequiredKeepUndefined; diff --git a/x-pack/plugins/lists/common/schemas/request/read_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/read_exception_list_item_schema.ts index d8864a6fc66e5..a2ba8126c7788 100644 --- a/x-pack/plugins/lists/common/schemas/request/read_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/read_exception_list_item_schema.ts @@ -20,19 +20,12 @@ export const readExceptionListItemSchema = t.exact( }) ); -export type ReadExceptionListItemSchemaPartial = t.TypeOf; +export type ReadExceptionListItemSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type ReadExceptionListItemSchemaPartialDecoded = Omit< - ReadExceptionListItemSchemaPartial, +export type ReadExceptionListItemSchemaDecoded = Omit< + RequiredKeepUndefined>, 'namespace_type' > & { namespace_type: NamespaceType; }; - -// This type is used after a decode since some things are defaults after a decode. -export type ReadExceptionListItemSchemaDecoded = RequiredKeepUndefined< - ReadExceptionListItemSchemaPartialDecoded ->; - -export type ReadExceptionListItemSchema = RequiredKeepUndefined; diff --git a/x-pack/plugins/lists/common/schemas/request/read_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/read_exception_list_schema.ts index 613fb22a99d61..f22eca6a8ab15 100644 --- a/x-pack/plugins/lists/common/schemas/request/read_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/read_exception_list_schema.ts @@ -20,19 +20,12 @@ export const readExceptionListSchema = t.exact( }) ); -export type ReadExceptionListSchemaPartial = t.TypeOf; +export type ReadExceptionListSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type ReadExceptionListSchemaPartialDecoded = Omit< - ReadExceptionListSchemaPartial, +export type ReadExceptionListSchemaDecoded = Omit< + RequiredKeepUndefined>, 'namespace_type' > & { namespace_type: NamespaceType; }; - -// This type is used after a decode since some things are defaults after a decode. -export type ReadExceptionListSchemaDecoded = RequiredKeepUndefined< - ReadExceptionListSchemaPartialDecoded ->; - -export type ReadExceptionListSchema = RequiredKeepUndefined; diff --git a/x-pack/plugins/lists/common/schemas/request/read_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/read_list_item_schema.ts index 394c1f1e2289a..063f430aa9cea 100644 --- a/x-pack/plugins/lists/common/schemas/request/read_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/read_list_item_schema.ts @@ -9,9 +9,9 @@ import * as t from 'io-ts'; import { id, list_id, value } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { RequiredKeepUndefined } from '../../types'; export const readListItemSchema = t.exact(t.partial({ id, list_id, value })); -export type ReadListItemSchemaPartial = Identity>; -export type ReadListItemSchema = RequiredKeepUndefined>; +export type ReadListItemSchema = t.OutputOf; +export type ReadListItemSchemaDecoded = RequiredKeepUndefined>; diff --git a/x-pack/plugins/lists/common/schemas/request/read_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/read_list_schema.ts index 8803346709c31..e395875462cb4 100644 --- a/x-pack/plugins/lists/common/schemas/request/read_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/read_list_schema.ts @@ -16,4 +16,4 @@ export const readListSchema = t.exact( }) ); -export type ReadListSchema = t.TypeOf; +export type ReadListSchema = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.mock.ts index 30bbbe2d22ea4..0847389dac922 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.mock.ts @@ -21,6 +21,7 @@ import { UpdateEndpointListItemSchema } from './update_endpoint_list_item_schema export const getUpdateEndpointListItemSchemaMock = (): UpdateEndpointListItemSchema => ({ _tags: _TAGS, + _version: undefined, comments: COMMENTS, description: DESCRIPTION, entries: ENTRIES, diff --git a/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts index dbe38f6d468e2..4430aa98b8e3d 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts @@ -12,6 +12,7 @@ import { Tags, _Tags, _tags, + _version, description, exceptionListItemType, id, @@ -19,7 +20,7 @@ import { name, tags, } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { RequiredKeepUndefined } from '../../types'; import { DefaultEntryArray, DefaultUpdateCommentsArray, @@ -38,6 +39,7 @@ export const updateEndpointListItemSchema = t.intersection([ t.exact( t.partial({ _tags, // defaults to empty array if not set during decode + _version, // defaults to undefined if not set during decode comments: DefaultUpdateCommentsArray, // defaults to empty array if not set during decode entries: DefaultEntryArray, // defaults to empty array if not set during decode id, // defaults to undefined if not set during decode @@ -48,19 +50,15 @@ export const updateEndpointListItemSchema = t.intersection([ ), ]); -export type UpdateEndpointListItemSchemaPartial = Identity< - t.TypeOf ->; -export type UpdateEndpointListItemSchema = RequiredKeepUndefined< - t.TypeOf ->; +export type UpdateEndpointListItemSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type UpdateEndpointListItemSchemaDecoded = Identity< - Omit & { - _tags: _Tags; - comments: UpdateCommentsArray; - tags: Tags; - entries: EntriesArray; - } ->; +export type UpdateEndpointListItemSchemaDecoded = Omit< + RequiredKeepUndefined>, + '_tags' | 'tags' | 'entries' | 'comments' +> & { + _tags: _Tags; + comments: UpdateCommentsArray; + tags: Tags; + entries: EntriesArray; +}; diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.mock.ts index e8936f0bdc6d4..90d70c273f490 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.mock.ts @@ -22,6 +22,7 @@ import { UpdateExceptionListItemSchema } from './update_exception_list_item_sche export const getUpdateExceptionListItemSchemaMock = (): UpdateExceptionListItemSchema => ({ _tags: _TAGS, + _version: undefined, comments: COMMENTS, description: DESCRIPTION, entries: ENTRIES, diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts index 20a63e0fc7dac..9e0a1759fc9f4 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts @@ -12,6 +12,7 @@ import { Tags, _Tags, _tags, + _version, description, exceptionListItemType, id, @@ -20,7 +21,7 @@ import { namespace_type, tags, } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { RequiredKeepUndefined } from '../../types'; import { DefaultEntryArray, DefaultUpdateCommentsArray, @@ -40,6 +41,7 @@ export const updateExceptionListItemSchema = t.intersection([ t.exact( t.partial({ _tags, // defaults to empty array if not set during decode + _version, // defaults to undefined if not set during decode comments: DefaultUpdateCommentsArray, // defaults to empty array if not set during decode entries: DefaultEntryArray, // defaults to empty array if not set during decode id, // defaults to undefined if not set during decode @@ -51,23 +53,16 @@ export const updateExceptionListItemSchema = t.intersection([ ), ]); -export type UpdateExceptionListItemSchemaPartial = Identity< - t.TypeOf ->; -export type UpdateExceptionListItemSchema = RequiredKeepUndefined< - t.TypeOf ->; +export type UpdateExceptionListItemSchema = t.OutputOf; // This type is used after a decode since some things are defaults after a decode. -export type UpdateExceptionListItemSchemaDecoded = Identity< - Omit< - UpdateExceptionListItemSchema, - '_tags' | 'tags' | 'entries' | 'namespace_type' | 'comments' - > & { - _tags: _Tags; - comments: UpdateCommentsArray; - tags: Tags; - entries: EntriesArray; - namespace_type: NamespaceType; - } ->; +export type UpdateExceptionListItemSchemaDecoded = Omit< + RequiredKeepUndefined>, + '_tags' | 'tags' | 'entries' | 'namespace_type' | 'comments' +> & { + _tags: _Tags; + comments: UpdateCommentsArray; + tags: Tags; + entries: EntriesArray; + namespace_type: NamespaceType; +}; diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.mock.ts index 48a8baf9aea16..22af29e6af0b7 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.mock.ts @@ -10,6 +10,7 @@ import { UpdateExceptionListSchema } from './update_exception_list_schema'; export const getUpdateExceptionListSchemaMock = (): UpdateExceptionListSchema => ({ _tags: _TAGS, + _version: undefined, description: DESCRIPTION, id: ID, list_id: LIST_ID, diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts index 0b5f3a8a01794..5d7294ae27af2 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts @@ -12,14 +12,17 @@ import { Tags, _Tags, _tags, + _version, description, exceptionListType, + id, + list_id, meta, name, namespace_type, tags, } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { RequiredKeepUndefined } from '../../types'; import { NamespaceType } from '../types'; export const updateExceptionListSchema = t.intersection([ @@ -33,8 +36,9 @@ export const updateExceptionListSchema = t.intersection([ t.exact( t.partial({ _tags, // defaults to empty array if not set during decode - id: t.union([t.string, t.undefined]), // defaults to undefined if not set during decode - list_id: t.union([t.string, t.undefined]), // defaults to undefined if not set during decode + _version, // defaults to undefined if not set during decode + id, // defaults to undefined if not set during decode + list_id, // defaults to undefined if not set during decode meta, // defaults to undefined if not set during decode namespace_type, // defaults to 'single' if not set during decode tags, // defaults to empty array if not set during decode @@ -42,16 +46,14 @@ export const updateExceptionListSchema = t.intersection([ ), ]); -export type UpdateExceptionListSchemaPartial = Identity>; -export type UpdateExceptionListSchema = RequiredKeepUndefined< - t.TypeOf ->; +export type UpdateExceptionListSchema = t.OutputOf; // This type is used after a decode since the arrays turn into defaults of empty arrays. -export type UpdateExceptionListSchemaDecoded = Identity< - Omit & { - _tags: _Tags; - tags: Tags; - namespace_type: NamespaceType; - } ->; +export type UpdateExceptionListSchemaDecoded = Omit< + RequiredKeepUndefined>, + '_tags | tags | namespace_type' +> & { + _tags: _Tags; + tags: Tags; + namespace_type: NamespaceType; +}; diff --git a/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.ts index 3a42cf28665f5..c6ed5ef0e9517 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_list_item_schema.ts @@ -8,8 +8,8 @@ import * as t from 'io-ts'; -import { id, meta, value } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { _version, id, meta, value } from '../common/schemas'; +import { RequiredKeepUndefined } from '../../types'; export const updateListItemSchema = t.intersection([ t.exact( @@ -20,10 +20,13 @@ export const updateListItemSchema = t.intersection([ ), t.exact( t.partial({ + _version, // defaults to undefined if not set during decode meta, // defaults to undefined if not set during decode }) ), ]); -export type UpdateListItemSchemaPartial = Identity>; -export type UpdateListItemSchema = RequiredKeepUndefined>; +export type UpdateListItemSchema = t.OutputOf; +export type UpdateListItemSchemaDecoded = RequiredKeepUndefined< + t.TypeOf +>; diff --git a/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts index 4c5c8c429a14c..19a39d362c241 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts @@ -8,8 +8,8 @@ import * as t from 'io-ts'; -import { description, id, meta, name } from '../common/schemas'; -import { Identity, RequiredKeepUndefined } from '../../types'; +import { _version, description, id, meta, name } from '../common/schemas'; +import { RequiredKeepUndefined } from '../../types'; export const updateListSchema = t.intersection([ t.exact( @@ -21,10 +21,11 @@ export const updateListSchema = t.intersection([ ), t.exact( t.partial({ + _version, // defaults to undefined if not set during decode meta, // defaults to undefined if not set during decode }) ), ]); -export type UpdateListSchemaPartial = Identity>; -export type UpdateListSchema = RequiredKeepUndefined>; +export type UpdateListSchema = t.OutputOf; +export type UpdateListSchemaDecoded = RequiredKeepUndefined>; diff --git a/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.test.ts b/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.test.ts index d346ea72ca310..646cc3d97f8ee 100644 --- a/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.test.ts @@ -41,7 +41,7 @@ describe('create_endpoint_list_schema', () => { const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'invalid keys "_tags,["endpoint","process","malware","os:linux"],created_at,created_by,description,id,meta,{},name,namespace_type,tags,["user added string for a tag","malware"],tie_breaker_id,type,updated_at,updated_by"', + 'invalid keys "_tags,["endpoint","process","malware","os:linux"],_version,created_at,created_by,description,id,meta,{},name,namespace_type,tags,["user added string for a tag","malware"],tie_breaker_id,type,updated_at,updated_by"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.mock.ts index 9e1a88ceb28bd..c0d04c9823ca3 100644 --- a/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.mock.ts @@ -3,26 +3,38 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { ENTRIES } from '../../constants.mock'; +import { + COMMENTS, + DATE_NOW, + DESCRIPTION, + ENTRIES, + ITEM_TYPE, + META, + NAME, + NAMESPACE_TYPE, + TIE_BREAKER, + USER, +} from '../../constants.mock'; import { ExceptionListItemSchema } from './exception_list_item_schema'; export const getExceptionListItemSchemaMock = (): ExceptionListItemSchema => ({ _tags: ['endpoint', 'process', 'malware', 'os:linux'], - comments: [], - created_at: '2020-04-23T00:19:13.289Z', - created_by: 'user_name', - description: 'This is a sample endpoint type exception', + _version: undefined, + comments: COMMENTS, + created_at: DATE_NOW, + created_by: USER, + description: DESCRIPTION, entries: ENTRIES, id: '1', item_id: 'endpoint_list_item', list_id: 'endpoint_list_id', - meta: {}, - name: 'Sample Endpoint Exception List', - namespace_type: 'single', + meta: META, + name: NAME, + namespace_type: NAMESPACE_TYPE, tags: ['user added string for a tag', 'malware'], - tie_breaker_id: '77fd1909-6786-428a-a671-30229a719c1f', - type: 'simple', - updated_at: '2020-04-23T00:19:13.289Z', - updated_by: 'user_name', + tie_breaker_id: TIE_BREAKER, + type: ITEM_TYPE, + updated_at: DATE_NOW, + updated_by: USER, }); diff --git a/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.ts index c8440e9d3f3d0..54907f3f8a854 100644 --- a/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/exception_list_item_schema.ts @@ -10,6 +10,7 @@ import * as t from 'io-ts'; import { _tags, + _versionOrUndefined, created_at, created_by, description, @@ -30,6 +31,7 @@ import { commentsArray, entriesArray } from '../types'; export const exceptionListItemSchema = t.exact( t.type({ _tags, + _version: _versionOrUndefined, comments: commentsArray, created_at, created_by, diff --git a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts index 906dcf6560ee5..f790ad9544d53 100644 --- a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts @@ -4,23 +4,32 @@ * you may not use this file except in compliance with the Elastic License. */ +import { + DATE_NOW, + DESCRIPTION, + ENDPOINT_TYPE, + META, + TIE_BREAKER, + USER, + _VERSION, +} from '../../constants.mock'; import { ENDPOINT_LIST_ID } from '../..'; import { ExceptionListSchema } from './exception_list_schema'; - export const getExceptionListSchemaMock = (): ExceptionListSchema => ({ _tags: ['endpoint', 'process', 'malware', 'os:linux'], - created_at: '2020-04-23T00:19:13.289Z', - created_by: 'user_name', - description: 'This is a sample endpoint type exception', + _version: _VERSION, + created_at: DATE_NOW, + created_by: USER, + description: DESCRIPTION, id: '1', list_id: ENDPOINT_LIST_ID, - meta: {}, + meta: META, name: 'Sample Endpoint Exception List', namespace_type: 'agnostic', tags: ['user added string for a tag', 'malware'], - tie_breaker_id: '77fd1909-6786-428a-a671-30229a719c1f', - type: 'endpoint', - updated_at: '2020-04-23T00:19:13.289Z', + tie_breaker_id: TIE_BREAKER, + type: ENDPOINT_TYPE, + updated_at: DATE_NOW, updated_by: 'user_name', }); diff --git a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts index 0fb2bfca4a48f..11c23bc2ff354 100644 --- a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts @@ -10,6 +10,7 @@ import * as t from 'io-ts'; import { _tags, + _versionOrUndefined, created_at, created_by, description, @@ -28,6 +29,7 @@ import { export const exceptionListSchema = t.exact( t.type({ _tags, + _version: _versionOrUndefined, created_at, created_by, description, diff --git a/x-pack/plugins/lists/common/schemas/response/list_item_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/list_item_schema.mock.ts index 16e8057974917..e122f6a2bbe3b 100644 --- a/x-pack/plugins/lists/common/schemas/response/list_item_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/response/list_item_schema.mock.ts @@ -17,6 +17,7 @@ import { } from '../../../common/constants.mock'; export const getListItemResponseMock = (): ListItemSchema => ({ + _version: undefined, created_at: DATE_NOW, created_by: USER, deserializer: undefined, diff --git a/x-pack/plugins/lists/common/schemas/response/list_item_schema.ts b/x-pack/plugins/lists/common/schemas/response/list_item_schema.ts index c2104aaf18b53..9ee801298f950 100644 --- a/x-pack/plugins/lists/common/schemas/response/list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/list_item_schema.ts @@ -9,6 +9,7 @@ import * as t from 'io-ts'; /* eslint-disable @typescript-eslint/camelcase */ import { + _versionOrUndefined, created_at, created_by, deserializerOrUndefined, @@ -25,6 +26,7 @@ import { export const listItemSchema = t.exact( t.type({ + _version: _versionOrUndefined, created_at, created_by, deserializer: deserializerOrUndefined, diff --git a/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts index c165c4ed8e745..339beddb00f8e 100644 --- a/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts @@ -17,6 +17,7 @@ import { } from '../../../common/constants.mock'; export const getListResponseMock = (): ListSchema => ({ + _version: undefined, created_at: DATE_NOW, created_by: USER, description: DESCRIPTION, diff --git a/x-pack/plugins/lists/common/schemas/response/list_schema.ts b/x-pack/plugins/lists/common/schemas/response/list_schema.ts index 1950831bee694..7e2bc202a6520 100644 --- a/x-pack/plugins/lists/common/schemas/response/list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/list_schema.ts @@ -9,6 +9,7 @@ import * as t from 'io-ts'; import { + _versionOrUndefined, created_at, created_by, description, @@ -25,6 +26,7 @@ import { export const listSchema = t.exact( t.type({ + _version: _versionOrUndefined, created_at, created_by, description, diff --git a/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts b/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts index e8be299246ab8..342cf8b0d7091 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts @@ -9,17 +9,11 @@ import { Either } from 'fp-ts/lib/Either'; import { CommentsArray, comments } from './comments'; -export type DefaultCommentsArrayC = t.Type; - /** * Types the DefaultCommentsArray as: * - If null or undefined, then a default array of type entry will be set */ -export const DefaultCommentsArray: DefaultCommentsArrayC = new t.Type< - CommentsArray, - CommentsArray, - unknown ->( +export const DefaultCommentsArray = new t.Type( 'DefaultCommentsArray', t.array(comments).is, (input): Either => diff --git a/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.ts b/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.ts index 51431b9c39850..7fd79782836e3 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.ts @@ -9,13 +9,11 @@ import { Either } from 'fp-ts/lib/Either'; import { CreateCommentsArray, createComments } from './create_comments'; -export type DefaultCreateCommentsArrayC = t.Type; - /** * Types the DefaultCreateComments as: * - If null or undefined, then a default array of type entry will be set */ -export const DefaultCreateCommentsArray: DefaultCreateCommentsArrayC = new t.Type< +export const DefaultCreateCommentsArray = new t.Type< CreateCommentsArray, CreateCommentsArray, unknown diff --git a/x-pack/plugins/lists/common/schemas/types/default_entries_array.ts b/x-pack/plugins/lists/common/schemas/types/default_entries_array.ts index da67fb286affa..a85fdf8537f39 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_entries_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_entries_array.ts @@ -9,17 +9,11 @@ import { Either } from 'fp-ts/lib/Either'; import { EntriesArray, entriesArray } from './entries'; -export type DefaultEntriesArrayC = t.Type; - /** * Types the DefaultEntriesArray as: * - If null or undefined, then a default array of type entry will be set */ -export const DefaultEntryArray: DefaultEntriesArrayC = new t.Type< - EntriesArray, - EntriesArray, - unknown ->( +export const DefaultEntryArray = new t.Type( 'DefaultEntryArray', entriesArray.is, (input): Either => diff --git a/x-pack/plugins/lists/common/schemas/types/default_namespace.ts b/x-pack/plugins/lists/common/schemas/types/default_namespace.ts index ecc45d3c84313..b61497a78aff0 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_namespace.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_namespace.ts @@ -14,12 +14,10 @@ export type NamespaceType = t.TypeOf; * Types the DefaultNamespace as: * - If null or undefined, then a default string/enumeration of "single" will be used. */ -export const DefaultNamespace = new t.Type( +export const DefaultNamespace = new t.Type( 'DefaultNamespace', namespaceType.is, (input, context): Either => input == null ? t.success('single') : namespaceType.validate(input, context), t.identity ); - -export type DefaultNamespaceC = typeof DefaultNamespace; diff --git a/x-pack/plugins/lists/common/schemas/types/default_namespace_array.test.ts b/x-pack/plugins/lists/common/schemas/types/default_namespace_array.test.ts index 055f93069950e..255c89959b610 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_namespace_array.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_namespace_array.test.ts @@ -9,11 +9,11 @@ import { left } from 'fp-ts/lib/Either'; import { foldLeftRight, getPaths } from '../../siem_common_deps'; -import { DefaultNamespaceArray, DefaultNamespaceArrayTypeEncoded } from './default_namespace_array'; +import { DefaultNamespaceArray, DefaultNamespaceArrayType } from './default_namespace_array'; describe('default_namespace_array', () => { test('it should validate "null" single item as an array with a "single" value', () => { - const payload: DefaultNamespaceArrayTypeEncoded = null; + const payload: DefaultNamespaceArrayType = null; const decoded = DefaultNamespaceArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -33,7 +33,7 @@ describe('default_namespace_array', () => { }); test('it should validate "undefined" item as an array with a "single" value', () => { - const payload: DefaultNamespaceArrayTypeEncoded = undefined; + const payload: DefaultNamespaceArrayType = undefined; const decoded = DefaultNamespaceArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -42,7 +42,7 @@ describe('default_namespace_array', () => { }); test('it should validate "single" as an array of a "single" value', () => { - const payload: DefaultNamespaceArrayTypeEncoded = 'single'; + const payload: DefaultNamespaceArrayType = 'single'; const decoded = DefaultNamespaceArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -51,7 +51,7 @@ describe('default_namespace_array', () => { }); test('it should validate "agnostic" as an array of a "agnostic" value', () => { - const payload: DefaultNamespaceArrayTypeEncoded = 'agnostic'; + const payload: DefaultNamespaceArrayType = 'agnostic'; const decoded = DefaultNamespaceArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -60,7 +60,7 @@ describe('default_namespace_array', () => { }); test('it should validate "single,agnostic" as an array of 2 values of ["single", "agnostic"] values', () => { - const payload: DefaultNamespaceArrayTypeEncoded = 'agnostic,single'; + const payload: DefaultNamespaceArrayType = 'agnostic,single'; const decoded = DefaultNamespaceArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -69,7 +69,7 @@ describe('default_namespace_array', () => { }); test('it should validate 3 elements of "single,agnostic,single" as an array of 3 values of ["single", "agnostic", "single"] values', () => { - const payload: DefaultNamespaceArrayTypeEncoded = 'single,agnostic,single'; + const payload: DefaultNamespaceArrayType = 'single,agnostic,single'; const decoded = DefaultNamespaceArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -78,7 +78,7 @@ describe('default_namespace_array', () => { }); test('it should validate 3 elements of "single,agnostic, single" as an array of 3 values of ["single", "agnostic", "single"] values when there are spaces', () => { - const payload: DefaultNamespaceArrayTypeEncoded = ' single, agnostic, single '; + const payload: DefaultNamespaceArrayType = ' single, agnostic, single '; const decoded = DefaultNamespaceArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -87,7 +87,7 @@ describe('default_namespace_array', () => { }); test('it should not validate 3 elements of "single,agnostic,junk" since the 3rd value is junk', () => { - const payload: DefaultNamespaceArrayTypeEncoded = 'single,agnostic,junk'; + const payload: DefaultNamespaceArrayType = 'single,agnostic,junk'; const decoded = DefaultNamespaceArray.decode(payload); const message = pipe(decoded, foldLeftRight); diff --git a/x-pack/plugins/lists/common/schemas/types/default_namespace_array.ts b/x-pack/plugins/lists/common/schemas/types/default_namespace_array.ts index c4099a48ffbcc..b0ae85e65b22a 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_namespace_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_namespace_array.ts @@ -39,7 +39,5 @@ export const DefaultNamespaceArray = new t.Type< String ); -export type DefaultNamespaceC = typeof DefaultNamespaceArray; - -export type DefaultNamespaceArrayTypeEncoded = t.OutputOf; +export type DefaultNamespaceArrayType = t.OutputOf; export type DefaultNamespaceArrayTypeDecoded = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.ts b/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.ts index c2593826a6358..854b7cf7ada7e 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.ts @@ -9,13 +9,11 @@ import { Either } from 'fp-ts/lib/Either'; import { UpdateCommentsArray, updateCommentsArray } from './update_comments'; -export type DefaultUpdateCommentsArrayC = t.Type; - /** * Types the DefaultCommentsUpdate as: * - If null or undefined, then a default array of type entry will be set */ -export const DefaultUpdateCommentsArray: DefaultUpdateCommentsArrayC = new t.Type< +export const DefaultUpdateCommentsArray = new t.Type< UpdateCommentsArray, UpdateCommentsArray, unknown diff --git a/x-pack/plugins/lists/common/schemas/types/empty_string_array.ts b/x-pack/plugins/lists/common/schemas/types/empty_string_array.ts index 389dc4a410cc9..bbaa66260e76e 100644 --- a/x-pack/plugins/lists/common/schemas/types/empty_string_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/empty_string_array.ts @@ -39,7 +39,5 @@ export const EmptyStringArray = new t.Type; export type EmptyStringArrayDecoded = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_string_array.test.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_string_array.test.ts index 6124487cdd7fb..fac088568f85e 100644 --- a/x-pack/plugins/lists/common/schemas/types/non_empty_string_array.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_string_array.test.ts @@ -9,11 +9,11 @@ import { left } from 'fp-ts/lib/Either'; import { foldLeftRight, getPaths } from '../../siem_common_deps'; -import { NonEmptyStringArray, NonEmptyStringArrayEncoded } from './non_empty_string_array'; +import { NonEmptyStringArray } from './non_empty_string_array'; describe('non_empty_string_array', () => { test('it should NOT validate "null"', () => { - const payload: NonEmptyStringArrayEncoded | null = null; + const payload: NonEmptyStringArray | null = null; const decoded = NonEmptyStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -24,7 +24,7 @@ describe('non_empty_string_array', () => { }); test('it should NOT validate "undefined"', () => { - const payload: NonEmptyStringArrayEncoded | undefined = undefined; + const payload: NonEmptyStringArray | undefined = undefined; const decoded = NonEmptyStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -35,7 +35,7 @@ describe('non_empty_string_array', () => { }); test('it should NOT validate a single value of an empty string ""', () => { - const payload: NonEmptyStringArrayEncoded = ''; + const payload: NonEmptyStringArray = ''; const decoded = NonEmptyStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -46,7 +46,7 @@ describe('non_empty_string_array', () => { }); test('it should validate a single value of "a" into an array of size 1 of ["a"]', () => { - const payload: NonEmptyStringArrayEncoded = 'a'; + const payload: NonEmptyStringArray = 'a'; const decoded = NonEmptyStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -55,7 +55,7 @@ describe('non_empty_string_array', () => { }); test('it should validate 2 values of "a,b" into an array of size 2 of ["a", "b"]', () => { - const payload: NonEmptyStringArrayEncoded = 'a,b'; + const payload: NonEmptyStringArray = 'a,b'; const decoded = NonEmptyStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -64,7 +64,7 @@ describe('non_empty_string_array', () => { }); test('it should validate 3 values of "a,b,c" into an array of size 3 of ["a", "b", "c"]', () => { - const payload: NonEmptyStringArrayEncoded = 'a,b,c'; + const payload: NonEmptyStringArray = 'a,b,c'; const decoded = NonEmptyStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -84,7 +84,7 @@ describe('non_empty_string_array', () => { }); test('it should validate 3 values of " a, b, c " into an array of size 3 of ["a", "b", "c"] even though they have spaces', () => { - const payload: NonEmptyStringArrayEncoded = ' a, b, c '; + const payload: NonEmptyStringArray = ' a, b, c '; const decoded = NonEmptyStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_string_array.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_string_array.ts index c4a640e7cdbad..90475f7935875 100644 --- a/x-pack/plugins/lists/common/schemas/types/non_empty_string_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_string_array.ts @@ -35,7 +35,5 @@ export const NonEmptyStringArray = new t.Type( String ); -export type NonEmptyStringArrayC = typeof NonEmptyStringArray; - -export type NonEmptyStringArrayEncoded = t.OutputOf; +export type NonEmptyStringArray = t.OutputOf; export type NonEmptyStringArrayDecoded = t.TypeOf; diff --git a/x-pack/plugins/lists/common/types.ts b/x-pack/plugins/lists/common/types.ts index 1539c5ae01ff5..cee5567a55a6c 100644 --- a/x-pack/plugins/lists/common/types.ts +++ b/x-pack/plugins/lists/common/types.ts @@ -20,11 +20,3 @@ export type RequiredKeepUndefined = { [K in keyof T]-?: [T[K]] } extends infe ? { [K in keyof U]: U[K][0] } : never : never; - -/** - * This is just a helper to cleanup nasty intersections and unions to make them - * readable from io.ts, it's an identity that strips away the uglyness of them. - */ -export type Identity = { - [P in keyof T]: T[P]; -}; diff --git a/x-pack/plugins/lists/server/routes/find_list_item_route.ts b/x-pack/plugins/lists/server/routes/find_list_item_route.ts index 52d534b08df2b..8a0e06aa0c7d8 100644 --- a/x-pack/plugins/lists/server/routes/find_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/find_list_item_route.ts @@ -10,7 +10,7 @@ import { LIST_ITEM_URL } from '../../common/constants'; import { buildRouteValidation, buildSiemResponse, transformError } from '../siem_server_deps'; import { validate } from '../../common/siem_common_deps'; import { - FindListItemSchemaPartialDecoded, + FindListItemSchemaDecoded, findListItemSchema, foundListItemSchema, } from '../../common/schemas'; @@ -26,7 +26,7 @@ export const findListItemRoute = (router: IRouter): void => { }, path: `${LIST_ITEM_URL}/_find`, validate: { - query: buildRouteValidation( + query: buildRouteValidation( findListItemSchema ), }, diff --git a/x-pack/plugins/lists/server/routes/patch_list_item_route.ts b/x-pack/plugins/lists/server/routes/patch_list_item_route.ts index f706559dffdbd..9a74beb45bafd 100644 --- a/x-pack/plugins/lists/server/routes/patch_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/patch_list_item_route.ts @@ -27,9 +27,10 @@ export const patchListItemRoute = (router: IRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const { value, id, meta } = request.body; + const { value, id, meta, _version } = request.body; const lists = getListClient(context); const listItem = await lists.updateListItem({ + _version, id, meta, value, diff --git a/x-pack/plugins/lists/server/routes/patch_list_route.ts b/x-pack/plugins/lists/server/routes/patch_list_route.ts index 3a0d8714a14cd..06a76559dee9a 100644 --- a/x-pack/plugins/lists/server/routes/patch_list_route.ts +++ b/x-pack/plugins/lists/server/routes/patch_list_route.ts @@ -27,9 +27,9 @@ export const patchListRoute = (router: IRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const { name, description, id, meta } = request.body; + const { name, description, id, meta, _version } = request.body; const lists = getListClient(context); - const list = await lists.updateList({ description, id, meta, name }); + const list = await lists.updateList({ _version, description, id, meta, name }); if (list == null) { return siemResponse.error({ body: `list id: "${id}" found found`, diff --git a/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts index 1ecf4e8a9765d..8415c64633a06 100644 --- a/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts @@ -41,6 +41,7 @@ export const updateEndpointListItemRoute = (router: IRouter): void => { meta, type, _tags, + _version, comments, entries, item_id: itemId, @@ -49,6 +50,7 @@ export const updateEndpointListItemRoute = (router: IRouter): void => { const exceptionLists = getExceptionListClient(context); const exceptionListItem = await exceptionLists.updateEndpointListItem({ _tags, + _version, comments, description, entries, diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts index f6c7bcebedc13..2aa1e016d51ed 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts @@ -41,6 +41,7 @@ export const updateExceptionListItemRoute = (router: IRouter): void => { meta, type, _tags, + _version, comments, entries, item_id: itemId, @@ -50,6 +51,7 @@ export const updateExceptionListItemRoute = (router: IRouter): void => { const exceptionLists = getExceptionListClient(context); const exceptionListItem = await exceptionLists.updateExceptionListItem({ _tags, + _version, comments, description, entries, diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts index cff78614d05ba..331ec064fa663 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts @@ -36,6 +36,7 @@ export const updateExceptionListRoute = (router: IRouter): void => { try { const { _tags, + _version, tags, name, description, @@ -54,6 +55,7 @@ export const updateExceptionListRoute = (router: IRouter): void => { } else { const list = await exceptionLists.updateExceptionList({ _tags, + _version, description, id, listId, diff --git a/x-pack/plugins/lists/server/routes/update_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_list_item_route.ts index 3e231e319104b..0f5d11afcda09 100644 --- a/x-pack/plugins/lists/server/routes/update_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_list_item_route.ts @@ -27,9 +27,10 @@ export const updateListItemRoute = (router: IRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const { value, id, meta } = request.body; + const { value, id, meta, _version } = request.body; const lists = getListClient(context); const listItem = await lists.updateListItem({ + _version, id, meta, value, diff --git a/x-pack/plugins/lists/server/routes/update_list_route.ts b/x-pack/plugins/lists/server/routes/update_list_route.ts index a6d9f8329c7c8..2fae910c1b398 100644 --- a/x-pack/plugins/lists/server/routes/update_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_list_route.ts @@ -27,9 +27,9 @@ export const updateListRoute = (router: IRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const { name, description, id, meta } = request.body; + const { name, description, id, meta, _version } = request.body; const lists = getListClient(context); - const list = await lists.updateList({ description, id, meta, name }); + const list = await lists.updateList({ _version, description, id, meta, name }); if (list == null) { return siemResponse.error({ body: `list id: "${id}" found found`, diff --git a/x-pack/plugins/lists/server/scripts/exception_lists/updates/simple_update.json b/x-pack/plugins/lists/server/scripts/exception_lists/updates/simple_update.json index a7fbe1ea48c02..8d07b29d7b428 100644 --- a/x-pack/plugins/lists/server/scripts/exception_lists/updates/simple_update.json +++ b/x-pack/plugins/lists/server/scripts/exception_lists/updates/simple_update.json @@ -1,5 +1,5 @@ { - "list_id": "endpoint_list", + "list_id": "simple_list", "_tags": ["endpoint", "process", "malware", "os:linux"], "tags": ["user added string for a tag", "malware"], "type": "endpoint", diff --git a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts index 5c9607e2d956d..08b1f517036a9 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts @@ -131,6 +131,7 @@ export class ExceptionListClient { */ public updateEndpointListItem = async ({ _tags, + _version, comments, description, entries, @@ -145,6 +146,7 @@ export class ExceptionListClient { await this.createEndpointList(); return updateExceptionListItem({ _tags, + _version, comments, description, entries, @@ -198,6 +200,7 @@ export class ExceptionListClient { public updateExceptionList = async ({ _tags, + _version, id, description, listId, @@ -210,6 +213,7 @@ export class ExceptionListClient { const { savedObjectsClient, user } = this; return updateExceptionList({ _tags, + _version, description, id, listId, @@ -270,6 +274,7 @@ export class ExceptionListClient { public updateExceptionListItem = async ({ _tags, + _version, comments, description, entries, @@ -284,6 +289,7 @@ export class ExceptionListClient { const { savedObjectsClient, user } = this; return updateExceptionListItem({ _tags, + _version, comments, description, entries, diff --git a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts index 89f8310281648..b972b6564bb8a 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts @@ -38,6 +38,7 @@ import { UpdateCommentsArray, _Tags, _TagsOrUndefined, + _VersionOrUndefined, } from '../../../common/schemas'; export interface ConstructorOptions { @@ -64,6 +65,7 @@ export interface CreateExceptionListOptions { export interface UpdateExceptionListOptions { _tags: _TagsOrUndefined; + _version: _VersionOrUndefined; id: IdOrUndefined; listId: ListIdOrUndefined; namespaceType: NamespaceType; @@ -130,6 +132,7 @@ export interface CreateEndpointListItemOptions { export interface UpdateExceptionListItemOptions { _tags: _TagsOrUndefined; + _version: _VersionOrUndefined; comments: UpdateCommentsArray; entries: EntriesArrayOrUndefined; id: IdOrUndefined; @@ -144,6 +147,7 @@ export interface UpdateExceptionListItemOptions { export interface UpdateEndpointListItemOptions { _tags: _TagsOrUndefined; + _version: _VersionOrUndefined; comments: UpdateCommentsArray; entries: EntriesArrayOrUndefined; id: IdOrUndefined; diff --git a/x-pack/plugins/lists/server/services/exception_lists/update_exception_list.ts b/x-pack/plugins/lists/server/services/exception_lists/update_exception_list.ts index a739366c67331..99c42e56f4888 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/update_exception_list.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/update_exception_list.ts @@ -18,6 +18,7 @@ import { NamespaceType, TagsOrUndefined, _TagsOrUndefined, + _VersionOrUndefined, } from '../../../common/schemas'; import { getSavedObjectType, transformSavedObjectUpdateToExceptionList } from './utils'; @@ -26,6 +27,7 @@ import { getExceptionList } from './get_exception_list'; interface UpdateExceptionListOptions { id: IdOrUndefined; _tags: _TagsOrUndefined; + _version: _VersionOrUndefined; name: NameOrUndefined; description: DescriptionOrUndefined; savedObjectsClient: SavedObjectsClientContract; @@ -40,6 +42,7 @@ interface UpdateExceptionListOptions { export const updateExceptionList = async ({ _tags, + _version, id, savedObjectsClient, namespaceType, @@ -67,6 +70,9 @@ export const updateExceptionList = async ({ tags, type, updated_by: user, + }, + { + version: _version, } ); return transformSavedObjectUpdateToExceptionList({ exceptionList, savedObject }); diff --git a/x-pack/plugins/lists/server/services/exception_lists/update_exception_list_item.ts b/x-pack/plugins/lists/server/services/exception_lists/update_exception_list_item.ts index a5ed1e38df374..f26dd7e18dd5c 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/update_exception_list_item.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/update_exception_list_item.ts @@ -20,6 +20,7 @@ import { TagsOrUndefined, UpdateCommentsArrayOrUndefined, _TagsOrUndefined, + _VersionOrUndefined, } from '../../../common/schemas'; import { @@ -33,6 +34,7 @@ interface UpdateExceptionListItemOptions { id: IdOrUndefined; comments: UpdateCommentsArrayOrUndefined; _tags: _TagsOrUndefined; + _version: _VersionOrUndefined; name: NameOrUndefined; description: DescriptionOrUndefined; entries: EntriesArrayOrUndefined; @@ -48,6 +50,7 @@ interface UpdateExceptionListItemOptions { export const updateExceptionListItem = async ({ _tags, + _version, comments, entries, id, @@ -89,6 +92,9 @@ export const updateExceptionListItem = async ({ tags, type, updated_by: user, + }, + { + version: _version, } ); return transformSavedObjectUpdateToExceptionListItem({ diff --git a/x-pack/plugins/lists/server/services/exception_lists/utils.ts b/x-pack/plugins/lists/server/services/exception_lists/utils.ts index ded39933fe9d8..d5e1965efcc89 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/utils.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/utils.ts @@ -72,6 +72,7 @@ export const transformSavedObjectToExceptionList = ({ }): ExceptionListSchema => { const dateNow = new Date().toISOString(); const { + version: _version, attributes: { _tags, created_at, @@ -93,6 +94,7 @@ export const transformSavedObjectToExceptionList = ({ // TODO: Do a throw if after the decode this is not the correct "list_type: list" return { _tags, + _version, created_at, created_by, description, @@ -118,6 +120,7 @@ export const transformSavedObjectUpdateToExceptionList = ({ }): ExceptionListSchema => { const dateNow = new Date().toISOString(); const { + version: _version, attributes: { _tags, description, meta, name, tags, type, updated_by: updatedBy }, id, updated_at: updatedAt, @@ -127,6 +130,7 @@ export const transformSavedObjectUpdateToExceptionList = ({ // TODO: Do a throw if after the decode this is not the correct "list_type: list" return { _tags: _tags ?? exceptionList._tags, + _version, created_at: exceptionList.created_at, created_by: exceptionList.created_by, description: description ?? exceptionList.description, @@ -150,6 +154,7 @@ export const transformSavedObjectToExceptionListItem = ({ }): ExceptionListItemSchema => { const dateNow = new Date().toISOString(); const { + version: _version, attributes: { _tags, comments, @@ -174,6 +179,7 @@ export const transformSavedObjectToExceptionListItem = ({ // TODO: Do a throw if item_id or entries is not defined. return { _tags, + _version, comments: comments ?? [], created_at, created_by, @@ -202,6 +208,7 @@ export const transformSavedObjectUpdateToExceptionListItem = ({ }): ExceptionListItemSchema => { const dateNow = new Date().toISOString(); const { + version: _version, attributes: { _tags, comments, @@ -223,6 +230,7 @@ export const transformSavedObjectUpdateToExceptionListItem = ({ // defaulting return { _tags: _tags ?? exceptionListItem._tags, + _version, comments: comments ?? exceptionListItem.comments, created_at: exceptionListItem.created_at, created_by: exceptionListItem.created_by, diff --git a/x-pack/plugins/lists/server/services/items/create_list_item.ts b/x-pack/plugins/lists/server/services/items/create_list_item.ts index aa17fc00b25c6..5332e2f6c7f4e 100644 --- a/x-pack/plugins/lists/server/services/items/create_list_item.ts +++ b/x-pack/plugins/lists/server/services/items/create_list_item.ts @@ -18,6 +18,7 @@ import { Type, } from '../../../common/schemas'; import { transformListItemToElasticQuery } from '../utils'; +import { encodeHitVersion } from '../utils/encode_hit_version'; export interface CreateListItemOptions { deserializer: DeserializerOrUndefined; @@ -75,6 +76,7 @@ export const createListItem = async ({ }); return { + _version: encodeHitVersion(response), id: response._id, type, value, diff --git a/x-pack/plugins/lists/server/services/items/find_list_item.ts b/x-pack/plugins/lists/server/services/items/find_list_item.ts index 93fa682631b06..a997b10004e76 100644 --- a/x-pack/plugins/lists/server/services/items/find_list_item.ts +++ b/x-pack/plugins/lists/server/services/items/find_list_item.ts @@ -5,6 +5,7 @@ */ import { LegacyAPICaller } from 'kibana/server'; +import { SearchResponse } from 'elasticsearch'; import { Filter, @@ -82,7 +83,10 @@ export const findListItem = async ({ }); if (scroll.validSearchAfterFound) { - const response = await callCluster('search', { + // Note: This typing of response = await callCluster> + // is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have + // to explicitly define the type . + const response = await callCluster>('search', { body: { query, search_after: scroll.searchAfter, @@ -90,6 +94,7 @@ export const findListItem = async ({ }, ignoreUnavailable: true, index: listItemIndex, + seq_no_primary_term: true, size: perPage, }); return { diff --git a/x-pack/plugins/lists/server/services/items/get_list_item.ts b/x-pack/plugins/lists/server/services/items/get_list_item.ts index 6f2a7ad63a973..ad9ae8763fe94 100644 --- a/x-pack/plugins/lists/server/services/items/get_list_item.ts +++ b/x-pack/plugins/lists/server/services/items/get_list_item.ts @@ -5,6 +5,7 @@ */ import { LegacyAPICaller } from 'kibana/server'; +import { SearchResponse } from 'elasticsearch'; import { Id, ListItemSchema, SearchEsListItemSchema } from '../../../common/schemas'; import { transformElasticToListItem } from '../utils'; @@ -21,7 +22,10 @@ export const getListItem = async ({ callCluster, listItemIndex, }: GetListItemOptions): Promise => { - const listItemES = await callCluster('search', { + // Note: This typing of response = await callCluster> + // is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have + // to explicitly define the type . + const listItemES = await callCluster>('search', { body: { query: { term: { @@ -31,6 +35,7 @@ export const getListItem = async ({ }, ignoreUnavailable: true, index: listItemIndex, + seq_no_primary_term: true, }); if (listItemES.hits.hits.length) { diff --git a/x-pack/plugins/lists/server/services/items/update_list_item.mock.ts b/x-pack/plugins/lists/server/services/items/update_list_item.mock.ts index 7ee8664b04d6b..8fc4b55338344 100644 --- a/x-pack/plugins/lists/server/services/items/update_list_item.mock.ts +++ b/x-pack/plugins/lists/server/services/items/update_list_item.mock.ts @@ -15,6 +15,7 @@ import { } from '../../../common/constants.mock'; export const getUpdateListItemOptionsMock = (): UpdateListItemOptions => ({ + _version: undefined, callCluster: getCallClusterMock(), dateNow: DATE_NOW, id: LIST_ITEM_ID, diff --git a/x-pack/plugins/lists/server/services/items/update_list_item.ts b/x-pack/plugins/lists/server/services/items/update_list_item.ts index eb20f1cfe3b30..8387d916b12f2 100644 --- a/x-pack/plugins/lists/server/services/items/update_list_item.ts +++ b/x-pack/plugins/lists/server/services/items/update_list_item.ts @@ -12,12 +12,16 @@ import { ListItemSchema, MetaOrUndefined, UpdateEsListItemSchema, + _VersionOrUndefined, } from '../../../common/schemas'; import { transformListItemToElasticQuery } from '../utils'; +import { decodeVersion } from '../utils/decode_version'; +import { encodeHitVersion } from '../utils/encode_hit_version'; import { getListItem } from './get_list_item'; export interface UpdateListItemOptions { + _version: _VersionOrUndefined; id: Id; value: string | null | undefined; callCluster: LegacyAPICaller; @@ -28,6 +32,7 @@ export interface UpdateListItemOptions { } export const updateListItem = async ({ + _version, id, value, callCluster, @@ -57,6 +62,7 @@ export const updateListItem = async ({ }; const response = await callCluster('update', { + ...decodeVersion(_version), body: { doc, }, @@ -65,6 +71,7 @@ export const updateListItem = async ({ refresh: 'wait_for', }); return { + _version: encodeHitVersion(response), created_at: listItem.created_at, created_by: listItem.created_by, deserializer: listItem.deserializer, diff --git a/x-pack/plugins/lists/server/services/lists/create_list.ts b/x-pack/plugins/lists/server/services/lists/create_list.ts index 3d396cf4d5af9..f97399e6dc131 100644 --- a/x-pack/plugins/lists/server/services/lists/create_list.ts +++ b/x-pack/plugins/lists/server/services/lists/create_list.ts @@ -8,6 +8,7 @@ import uuid from 'uuid'; import { CreateDocumentResponse } from 'elasticsearch'; import { LegacyAPICaller } from 'kibana/server'; +import { encodeHitVersion } from '../utils/encode_hit_version'; import { Description, DeserializerOrUndefined, @@ -70,6 +71,7 @@ export const createList = async ({ refresh: 'wait_for', }); return { + _version: encodeHitVersion(response), id: response._id, ...body, }; diff --git a/x-pack/plugins/lists/server/services/lists/find_list.ts b/x-pack/plugins/lists/server/services/lists/find_list.ts index 86cead9e868d6..363794b6affe4 100644 --- a/x-pack/plugins/lists/server/services/lists/find_list.ts +++ b/x-pack/plugins/lists/server/services/lists/find_list.ts @@ -5,6 +5,7 @@ */ import { LegacyAPICaller } from 'kibana/server'; +import { SearchResponse } from 'elasticsearch'; import { Filter, @@ -71,7 +72,10 @@ export const findList = async ({ }); if (scroll.validSearchAfterFound) { - const response = await callCluster('search', { + // Note: This typing of response = await callCluster> + // is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have + // to explicitly define the type . + const response = await callCluster>('search', { body: { query, search_after: scroll.searchAfter, @@ -79,6 +83,7 @@ export const findList = async ({ }, ignoreUnavailable: true, index: listIndex, + seq_no_primary_term: true, size: perPage, }); return { diff --git a/x-pack/plugins/lists/server/services/lists/get_list.ts b/x-pack/plugins/lists/server/services/lists/get_list.ts index 13550eb7d30dd..860e8e9f97f87 100644 --- a/x-pack/plugins/lists/server/services/lists/get_list.ts +++ b/x-pack/plugins/lists/server/services/lists/get_list.ts @@ -5,6 +5,7 @@ */ import { LegacyAPICaller } from 'kibana/server'; +import { SearchResponse } from 'elasticsearch'; import { Id, ListSchema, SearchEsListSchema } from '../../../common/schemas'; import { transformElasticToList } from '../utils/transform_elastic_to_list'; @@ -20,7 +21,10 @@ export const getList = async ({ callCluster, listIndex, }: GetListOptions): Promise => { - const response = await callCluster('search', { + // Note: This typing of response = await callCluster> + // is because when you pass in seq_no_primary_term: true it does a "fall through" type and you have + // to explicitly define the type . + const response = await callCluster>('search', { body: { query: { term: { @@ -30,6 +34,7 @@ export const getList = async ({ }, ignoreUnavailable: true, index: listIndex, + seq_no_primary_term: true, }); const list = transformElasticToList({ response }); return list[0] ?? null; diff --git a/x-pack/plugins/lists/server/services/lists/list_client.ts b/x-pack/plugins/lists/server/services/lists/list_client.ts index 4acc2e7092491..9bece64fa943f 100644 --- a/x-pack/plugins/lists/server/services/lists/list_client.ts +++ b/x-pack/plugins/lists/server/services/lists/list_client.ts @@ -395,6 +395,7 @@ export class ListClient { }; public updateListItem = async ({ + _version, id, value, meta, @@ -402,6 +403,7 @@ export class ListClient { const { callCluster, user } = this; const listItemIndex = this.getListItemIndex(); return updateListItem({ + _version, callCluster, id, listItemIndex, @@ -412,6 +414,7 @@ export class ListClient { }; public updateList = async ({ + _version, id, name, description, @@ -420,6 +423,7 @@ export class ListClient { const { callCluster, user } = this; const listIndex = this.getListIndex(); return updateList({ + _version, callCluster, description, id, diff --git a/x-pack/plugins/lists/server/services/lists/list_client_types.ts b/x-pack/plugins/lists/server/services/lists/list_client_types.ts index 68a018fa2fc16..7fa1727be118b 100644 --- a/x-pack/plugins/lists/server/services/lists/list_client_types.ts +++ b/x-pack/plugins/lists/server/services/lists/list_client_types.ts @@ -26,6 +26,7 @@ import { SortFieldOrUndefined, SortOrderOrUndefined, Type, + _VersionOrUndefined, } from '../../../common/schemas'; import { ConfigType } from '../../config'; @@ -106,12 +107,14 @@ export interface CreateListItemOptions { } export interface UpdateListItemOptions { + _version: _VersionOrUndefined; id: Id; value: string | null | undefined; meta: MetaOrUndefined; } export interface UpdateListOptions { + _version: _VersionOrUndefined; id: Id; name: NameOrUndefined; description: DescriptionOrUndefined; diff --git a/x-pack/plugins/lists/server/services/lists/update_list.mock.ts b/x-pack/plugins/lists/server/services/lists/update_list.mock.ts index ff974b6e7352b..fc3d63277c5b5 100644 --- a/x-pack/plugins/lists/server/services/lists/update_list.mock.ts +++ b/x-pack/plugins/lists/server/services/lists/update_list.mock.ts @@ -16,6 +16,7 @@ import { } from '../../../common/constants.mock'; export const getUpdateListOptionsMock = (): UpdateListOptions => ({ + _version: undefined, callCluster: getCallClusterMock(), dateNow: DATE_NOW, description: DESCRIPTION, diff --git a/x-pack/plugins/lists/server/services/lists/update_list.ts b/x-pack/plugins/lists/server/services/lists/update_list.ts index f84ca787eaa7c..fba57ca744f9d 100644 --- a/x-pack/plugins/lists/server/services/lists/update_list.ts +++ b/x-pack/plugins/lists/server/services/lists/update_list.ts @@ -7,6 +7,8 @@ import { CreateDocumentResponse } from 'elasticsearch'; import { LegacyAPICaller } from 'kibana/server'; +import { decodeVersion } from '../utils/decode_version'; +import { encodeHitVersion } from '../utils/encode_hit_version'; import { DescriptionOrUndefined, Id, @@ -14,11 +16,13 @@ import { MetaOrUndefined, NameOrUndefined, UpdateEsListSchema, + _VersionOrUndefined, } from '../../../common/schemas'; import { getList } from '.'; export interface UpdateListOptions { + _version: _VersionOrUndefined; id: Id; callCluster: LegacyAPICaller; listIndex: string; @@ -30,6 +34,7 @@ export interface UpdateListOptions { } export const updateList = async ({ + _version, id, name, description, @@ -52,12 +57,14 @@ export const updateList = async ({ updated_by: user, }; const response = await callCluster('update', { + ...decodeVersion(_version), body: { doc }, id, index: listIndex, refresh: 'wait_for', }); return { + _version: encodeHitVersion(response), created_at: list.created_at, created_by: list.created_by, description: description ?? list.description, diff --git a/x-pack/plugins/lists/server/services/utils/decode_version.ts b/x-pack/plugins/lists/server/services/utils/decode_version.ts new file mode 100644 index 0000000000000..e5fb9b54bcf97 --- /dev/null +++ b/x-pack/plugins/lists/server/services/utils/decode_version.ts @@ -0,0 +1,37 @@ +/* + * 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. + */ + +// Similar to the src/core/server/saved_objects/version/decode_version.ts +// with the notable differences in that it is more tolerant and does not throw saved object specific errors +// but rather just returns an empty object if it cannot parse the version or cannot find one. +export const decodeVersion = ( + version: string | undefined +): + | { + ifSeqNo: number; + ifPrimaryTerm: number; + } + | {} => { + if (version != null) { + try { + const decoded = Buffer.from(version, 'base64').toString('utf8'); + const parsed = JSON.parse(decoded); + if (Array.isArray(parsed) && Number.isInteger(parsed[0]) && Number.isInteger(parsed[1])) { + return { + ifPrimaryTerm: parsed[1], + ifSeqNo: parsed[0], + }; + } else { + return {}; + } + } catch (err) { + // do nothing here, this is on purpose and we want to return any empty object when we can't parse. + return {}; + } + } else { + return {}; + } +}; diff --git a/x-pack/plugins/lists/server/services/utils/encode_hit_version.ts b/x-pack/plugins/lists/server/services/utils/encode_hit_version.ts new file mode 100644 index 0000000000000..42dccfbac7340 --- /dev/null +++ b/x-pack/plugins/lists/server/services/utils/encode_hit_version.ts @@ -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. + */ + +/** + * Very similar to the encode_hit_version from saved object system from here: + * src/core/server/saved_objects/version/encode_hit_version.ts + * + * with the most notably change is that it doesn't do any throws but rather just returns undefined + * if _seq_no or _primary_term does not exist. + * @param response The response to encode into a version by using _seq_no and _primary_term + */ +export const encodeHitVersion = (hit: T): string | undefined => { + // Have to do this "as cast" here as these two types aren't included in the SearchResponse hit type + const { _seq_no: seqNo, _primary_term: primaryTerm } = (hit as unknown) as { + _seq_no: number; + _primary_term: number; + }; + + if (seqNo == null || primaryTerm == null) { + return undefined; + } else { + return Buffer.from(JSON.stringify([seqNo, primaryTerm]), 'utf8').toString('base64'); + } +}; diff --git a/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list.ts b/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list.ts index bb1ae1d4b9ff3..fb226d91fe395 100644 --- a/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list.ts +++ b/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list.ts @@ -8,6 +8,8 @@ import { SearchResponse } from 'elasticsearch'; import { ListArraySchema, SearchEsListSchema } from '../../../common/schemas'; +import { encodeHitVersion } from './encode_hit_version'; + export interface TransformElasticToListOptions { response: SearchResponse; } @@ -17,6 +19,7 @@ export const transformElasticToList = ({ }: TransformElasticToListOptions): ListArraySchema => { return response.hits.hits.map((hit) => { return { + _version: encodeHitVersion(hit), id: hit._id, ...hit._source, }; diff --git a/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list_item.ts b/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list_item.ts index a59b3b383cd2a..26fe15e9106fe 100644 --- a/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list_item.ts +++ b/x-pack/plugins/lists/server/services/utils/transform_elastic_to_list_item.ts @@ -9,6 +9,7 @@ import { SearchResponse } from 'elasticsearch'; import { ListItemArraySchema, SearchEsListItemSchema, Type } from '../../../common/schemas'; import { ErrorWithStatusCode } from '../../error_with_status_code'; +import { encodeHitVersion } from './encode_hit_version'; import { findSourceValue } from './find_source_value'; export interface TransformElasticToListItemOptions { @@ -40,6 +41,7 @@ export const transformElasticToListItem = ({ throw new ErrorWithStatusCode(`Was expected ${type} to not be null/undefined`, 400); } else { return { + _version: encodeHitVersion(hit), created_at, created_by, deserializer, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.ts index c69ae591f5ddc..e6b00aeac0d9c 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.ts @@ -10,14 +10,12 @@ import { actions, Actions } from '../common/schemas'; /** * Types the DefaultStringArray as: - * - If null or undefined, then a default action array will be set + * - If undefined, then a default action array will be set */ -export const DefaultActionsArray = new t.Type( +export const DefaultActionsArray = new t.Type( 'DefaultActionsArray', actions.is, (input, context): Either => input == null ? t.success([]) : actions.validate(input, context), t.identity ); - -export type DefaultActionsArrayC = typeof DefaultActionsArray; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.ts index 0cab6525779a6..5ace191c5f86f 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.ts @@ -11,12 +11,10 @@ import { Either } from 'fp-ts/lib/Either'; * Types the DefaultBooleanFalse as: * - If null or undefined, then a default false will be set */ -export const DefaultBooleanFalse = new t.Type( +export const DefaultBooleanFalse = new t.Type( 'DefaultBooleanFalse', t.boolean.is, (input, context): Either => input == null ? t.success(false) : t.boolean.validate(input, context), t.identity ); - -export type DefaultBooleanFalseC = typeof DefaultBooleanFalse; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_true.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_true.ts index 6997652b72636..92167287d23f5 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_true.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_true.ts @@ -11,12 +11,10 @@ import { Either } from 'fp-ts/lib/Either'; * Types the DefaultBooleanTrue as: * - If null or undefined, then a default true will be set */ -export const DefaultBooleanTrue = new t.Type( +export const DefaultBooleanTrue = new t.Type( 'DefaultBooleanTrue', t.boolean.is, (input, context): Either => input == null ? t.success(true) : t.boolean.validate(input, context), t.identity ); - -export type DefaultBooleanTrueC = typeof DefaultBooleanTrue; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.ts index a1103c4aa8d0e..185cccd86313e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.ts @@ -11,12 +11,10 @@ import { Either } from 'fp-ts/lib/Either'; * Types the DefaultEmptyString as: * - If null or undefined, then a default of an empty string "" will be used */ -export const DefaultEmptyString = new t.Type( +export const DefaultEmptyString = new t.Type( 'DefaultEmptyString', t.string.is, (input, context): Either => input == null ? t.success('') : t.string.validate(input, context), t.identity ); - -export type DefaultEmptyStringC = typeof DefaultEmptyString; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.ts index 4c7f663e7f46d..12efda77e5435 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.ts @@ -11,12 +11,10 @@ import { Either } from 'fp-ts/lib/Either'; * Types the DefaultExportFileName as: * - If null or undefined, then a default of "export.ndjson" will be used */ -export const DefaultExportFileName = new t.Type( +export const DefaultExportFileName = new t.Type( 'DefaultExportFileName', t.string.is, (input, context): Either => input == null ? t.success('export.ndjson') : t.string.validate(input, context), t.identity ); - -export type DefaultExportFileNameC = typeof DefaultExportFileName; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_from_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_from_string.ts index b6b432858eb92..a85ea58b26478 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_from_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_from_string.ts @@ -11,12 +11,10 @@ import { Either } from 'fp-ts/lib/Either'; * Types the DefaultFromString as: * - If null or undefined, then a default of the string "now-6m" will be used */ -export const DefaultFromString = new t.Type( +export const DefaultFromString = new t.Type( 'DefaultFromString', t.string.is, (input, context): Either => input == null ? t.success('now-6m') : t.string.validate(input, context), t.identity ); - -export type DefaultFromStringC = typeof DefaultFromString; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.ts index 9492374ffe91e..4001af46e7ddf 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.ts @@ -11,12 +11,10 @@ import { Either } from 'fp-ts/lib/Either'; * Types the DefaultIntervalString as: * - If null or undefined, then a default of the string "5m" will be used */ -export const DefaultIntervalString = new t.Type( +export const DefaultIntervalString = new t.Type( 'DefaultIntervalString', t.string.is, (input, context): Either => input == null ? t.success('5m') : t.string.validate(input, context), t.identity ); - -export type DefaultIntervalStringC = typeof DefaultIntervalString; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.ts index 1e05a46d7273c..afa83c484698f 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.ts @@ -12,12 +12,10 @@ import { language } from '../common/schemas'; * Types the DefaultLanguageString as: * - If null or undefined, then a default of the string "kuery" will be used */ -export const DefaultLanguageString = new t.Type( +export const DefaultLanguageString = new t.Type( 'DefaultLanguageString', t.string.is, (input, context): Either => input == null ? t.success('kuery') : language.validate(input, context), t.identity ); - -export type DefaultLanguageStringC = typeof DefaultLanguageString; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts index d3c48b5522f57..518af32dcf2b4 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts @@ -16,11 +16,7 @@ import { DEFAULT_MAX_SIGNALS } from '../../../constants'; * - greater than 1 * - If undefined then it will use DEFAULT_MAX_SIGNALS (100) as the default */ -export const DefaultMaxSignalsNumber: DefaultMaxSignalsNumberC = new t.Type< - number, - number, - unknown ->( +export const DefaultMaxSignalsNumber = new t.Type( 'DefaultMaxSignals', t.number.is, (input, context): Either => { @@ -28,5 +24,3 @@ export const DefaultMaxSignalsNumber: DefaultMaxSignalsNumberC = new t.Type< }, t.identity ); - -export type DefaultMaxSignalsNumberC = t.Type; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.ts index 96e01d381e34b..f3a997e3cc897 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.ts @@ -14,7 +14,7 @@ import { PositiveIntegerGreaterThanZero } from './positive_integer_greater_than_ * - If null or undefined, then a default of 1 will be used * - If the number is 0 or less this will not validate as it has to be a positive number greater than zero */ -export const DefaultPage = new t.Type( +export const DefaultPage = new t.Type( 'DefaultPerPage', t.number.is, (input, context): Either => { @@ -28,5 +28,3 @@ export const DefaultPage = new t.Type( }, t.identity ); - -export type DefaultPageC = typeof DefaultPage; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.ts index b78de8b35cede..72e817b10a600 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.ts @@ -14,7 +14,7 @@ import { PositiveIntegerGreaterThanZero } from './positive_integer_greater_than_ * - If null or undefined, then a default of 20 will be used * - If the number is 0 or less this will not validate as it has to be a positive number greater than zero */ -export const DefaultPerPage = new t.Type( +export const DefaultPerPage = new t.Type( 'DefaultPerPage', t.number.is, (input, context): Either => { @@ -28,5 +28,3 @@ export const DefaultPerPage = new t.Type( }, t.identity ); - -export type DefaultPerPageC = typeof DefaultPerPage; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_risk_score_mapping_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_risk_score_mapping_array.ts index ba74045b4e32c..bf88ece913767 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_risk_score_mapping_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_risk_score_mapping_array.ts @@ -13,12 +13,14 @@ import { risk_score_mapping, RiskScoreMapping } from '../common/schemas'; * Types the DefaultStringArray as: * - If null or undefined, then a default risk_score_mapping array will be set */ -export const DefaultRiskScoreMappingArray = new t.Type( +export const DefaultRiskScoreMappingArray = new t.Type< + RiskScoreMapping, + RiskScoreMapping | undefined, + unknown +>( 'DefaultRiskScoreMappingArray', risk_score_mapping.is, (input, context): Either => input == null ? t.success([]) : risk_score_mapping.validate(input, context), t.identity ); - -export type DefaultRiskScoreMappingArrayC = typeof DefaultRiskScoreMappingArray; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_severity_mapping_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_severity_mapping_array.ts index 8e68b73148af1..56b0ac1b75982 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_severity_mapping_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_severity_mapping_array.ts @@ -13,12 +13,14 @@ import { severity_mapping, SeverityMapping } from '../common/schemas'; * Types the DefaultStringArray as: * - If null or undefined, then a default severity_mapping array will be set */ -export const DefaultSeverityMappingArray = new t.Type( +export const DefaultSeverityMappingArray = new t.Type< + SeverityMapping, + SeverityMapping | undefined, + unknown +>( 'DefaultSeverityMappingArray', severity_mapping.is, (input, context): Either => input == null ? t.success([]) : severity_mapping.validate(input, context), t.identity ); - -export type DefaultSeverityMappingArrayC = typeof DefaultSeverityMappingArray; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.ts index a8c53c230acd9..a973bbb37cac7 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.ts @@ -9,14 +9,13 @@ import { Either } from 'fp-ts/lib/Either'; /** * Types the DefaultStringArray as: - * - If null or undefined, then a default array will be set + * - If undefined, then a default array will be set + * - If an array is sent in, then the array will be validated to ensure all elements are a string */ -export const DefaultStringArray = new t.Type( +export const DefaultStringArray = new t.Type( 'DefaultStringArray', t.array(t.string).is, (input, context): Either => input == null ? t.success([]) : t.array(t.string).validate(input, context), t.identity ); - -export type DefaultStringArrayC = typeof DefaultStringArray; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.ts index aa070c171d7ea..eba805048fe3a 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.ts @@ -12,7 +12,7 @@ import { Either } from 'fp-ts/lib/Either'; * - If a string this will convert the string to a boolean * - If null or undefined, then a default false will be set */ -export const DefaultStringBooleanFalse = new t.Type( +export const DefaultStringBooleanFalse = new t.Type( 'DefaultStringBooleanFalse', t.boolean.is, (input, context): Either => { diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.ts index 5499a3c1e3064..3b3c20f003e6e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.ts @@ -12,12 +12,10 @@ import { Threat, threat } from '../common/schemas'; * Types the DefaultThreatArray as: * - If null or undefined, then an empty array will be set */ -export const DefaultThreatArray = new t.Type( +export const DefaultThreatArray = new t.Type( 'DefaultThreatArray', threat.is, (input, context): Either => input == null ? t.success([]) : threat.validate(input, context), t.identity ); - -export type DefaultThreatArrayC = typeof DefaultThreatArray; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.ts index b76a35c0265a0..c4cf9a07ed359 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.ts @@ -12,12 +12,10 @@ import { ThrottleOrNull, throttle } from '../common/schemas'; * Types the DefaultThrottleNull as: * - If null or undefined, then a null will be set */ -export const DefaultThrottleNull = new t.Type( +export const DefaultThrottleNull = new t.Type( 'DefaultThreatNull', throttle.is, (input, context): Either => input == null ? t.success(null) : throttle.validate(input, context), t.identity ); - -export type DefaultThrottleNullC = typeof DefaultThrottleNull; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.ts index 158eedc121c53..6fe247f05e7e6 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.ts @@ -11,12 +11,10 @@ import { Either } from 'fp-ts/lib/Either'; * Types the DefaultToString as: * - If null or undefined, then a default of the string "now" will be used */ -export const DefaultToString = new t.Type( +export const DefaultToString = new t.Type( 'DefaultToString', t.string.is, (input, context): Either => input == null ? t.success('now') : t.string.validate(input, context), t.identity ); - -export type DefaultToStringC = typeof DefaultToString; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.ts index 74e32e083cc44..5f1d51ba84369 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.ts @@ -15,12 +15,10 @@ import { NonEmptyString } from './non_empty_string'; * - If null or undefined, then a default string uuid.v4() will be * created otherwise it will be checked just against an empty string */ -export const DefaultUuid = new t.Type( +export const DefaultUuid = new t.Type( 'DefaultUuid', t.string.is, (input, context): Either => input == null ? t.success(uuid.v4()) : NonEmptyString.validate(input, context), t.identity ); - -export type DefaultUuidC = typeof DefaultUuid; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts index 832c942291c32..bbba7c5b8f3bb 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts @@ -12,12 +12,10 @@ import { version, Version } from '../common/schemas'; * Types the DefaultVersionNumber as: * - If null or undefined, then a default of the number 1 will be used */ -export const DefaultVersionNumber = new t.Type( +export const DefaultVersionNumber = new t.Type( 'DefaultVersionNumber', version.is, (input, context): Either => input == null ? t.success(1) : version.validate(input, context), t.identity ); - -export type DefaultVersionNumberC = typeof DefaultVersionNumber; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.test.ts index 2268e47bd1149..59819947ddddf 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.test.ts @@ -9,7 +9,7 @@ import { left } from 'fp-ts/lib/Either'; import { foldLeftRight, getPaths } from '../../../test_utils'; -import { DefaultListArray, DefaultListArrayC } from './lists_default_array'; +import { DefaultListArray } from './lists_default_array'; import { getListArrayMock } from './lists.mock'; describe('lists_default_array', () => { @@ -51,7 +51,7 @@ describe('lists_default_array', () => { test('it should not validate an array of non accepted types', () => { // Terrible casting for purpose of tests - const payload = ([1] as unknown) as DefaultListArrayC; + const payload = [1] as unknown; const decoded = DefaultListArray.decode(payload); const message = pipe(decoded, foldLeftRight); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.ts index ac5666cad23a7..9260d7cbdb2a8 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.ts @@ -9,13 +9,11 @@ import { Either } from 'fp-ts/lib/Either'; import { ListArray, list } from './lists'; -export type DefaultListArrayC = t.Type; - /** * Types the DefaultListArray as: * - If null or undefined, then a default array of type list will be set */ -export const DefaultListArray: DefaultListArrayC = new t.Type( +export const DefaultListArray = new t.Type( 'DefaultListArray', t.array(list).is, (input, context): Either => diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/only_false_allowed.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/only_false_allowed.ts index b22562e2ab9dc..add926598a137 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/only_false_allowed.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/only_false_allowed.ts @@ -13,7 +13,7 @@ import { Either } from 'fp-ts/lib/Either'; * - If true is sent in then this will return an error * - If false is sent in then this will allow it only false */ -export const OnlyFalseAllowed = new t.Type( +export const OnlyFalseAllowed = new t.Type( 'DefaultBooleanTrue', t.boolean.is, (input, context): Either => { @@ -29,5 +29,3 @@ export const OnlyFalseAllowed = new t.Type( }, t.identity ); - -export type OnlyFalseAllowedC = typeof OnlyFalseAllowed; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer.ts index 298487a3fae98..0dc6e2c700395 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer.ts @@ -22,5 +22,3 @@ export const PositiveInteger = new t.Type( }, t.identity ); - -export type PositiveIntegerC = typeof PositiveInteger; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer_greater_than_zero.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer_greater_than_zero.ts index 8aeaf99a19eb1..2aa17c6c68955 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer_greater_than_zero.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer_greater_than_zero.ts @@ -22,5 +22,3 @@ export const PositiveIntegerGreaterThanZero = new t.Type( +export const ReferencesDefaultArray = new t.Type( 'referencesWithDefaultArray', t.array(t.string).is, (input, context): Either => input == null ? t.success([]) : t.array(t.string).validate(input, context), t.identity ); - -export type ReferencesDefaultArrayC = typeof ReferencesDefaultArray; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx index daa8589613daa..7171d3c6b815e 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx @@ -398,11 +398,11 @@ describe('Exception helpers', () => { title: 'OS', }, { - description: 'April 23rd 2020 @ 00:19:13', + description: 'April 20th 2020 @ 15:25:31', title: 'Date created', }, { - description: 'user_name', + description: 'some user', title: 'Created by', }, ]; @@ -417,11 +417,11 @@ describe('Exception helpers', () => { const result = getDescriptionListContent(payload); const expected: DescriptionListItem[] = [ { - description: 'April 23rd 2020 @ 00:19:13', + description: 'April 20th 2020 @ 15:25:31', title: 'Date created', }, { - description: 'user_name', + description: 'some user', title: 'Created by', }, { @@ -440,11 +440,11 @@ describe('Exception helpers', () => { const result = getDescriptionListContent(payload); const expected: DescriptionListItem[] = [ { - description: 'April 23rd 2020 @ 00:19:13', + description: 'April 20th 2020 @ 15:25:31', title: 'Date created', }, { - description: 'user_name', + description: 'some user', title: 'Created by', }, ]; @@ -520,12 +520,12 @@ describe('Exception helpers', () => { const expected = { _tags: ['endpoint', 'process', 'malware', 'os:linux'], comments: [], - description: 'This is a sample endpoint type exception', + description: 'some description', entries: ENTRIES, id: '1', item_id: 'endpoint_list_item', meta: {}, - name: 'Sample Endpoint Exception List', + name: 'some name', namespace_type: 'single', tags: ['user added string for a tag', 'malware'], type: 'simple', diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/exception_details.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/exception_details.test.tsx index f5b34b7838d25..4fc744c2c9d01 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/exception_details.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/exception_details.test.tsx @@ -179,7 +179,7 @@ describe('ExceptionDetails', () => { expect(wrapper.find('EuiDescriptionListTitle').at(1).text()).toEqual('Date created'); expect(wrapper.find('EuiDescriptionListDescription').at(1).text()).toEqual( - 'April 23rd 2020 @ 00:19:13' + 'April 20th 2020 @ 15:25:31' ); }); @@ -196,7 +196,7 @@ describe('ExceptionDetails', () => { ); expect(wrapper.find('EuiDescriptionListTitle').at(2).text()).toEqual('Created by'); - expect(wrapper.find('EuiDescriptionListDescription').at(2).text()).toEqual('user_name'); + expect(wrapper.find('EuiDescriptionListDescription').at(2).text()).toEqual('some user'); }); test('it renders the description if one is included on the exception item', () => { @@ -212,8 +212,6 @@ describe('ExceptionDetails', () => { ); expect(wrapper.find('EuiDescriptionListTitle').at(3).text()).toEqual('Comment'); - expect(wrapper.find('EuiDescriptionListDescription').at(3).text()).toEqual( - 'This is a sample endpoint type exception' - ); + expect(wrapper.find('EuiDescriptionListDescription').at(3).text()).toEqual('some description'); }); }); From 8a4daffcfdb90b8ff776ea051266516441c6fda2 Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Mon, 20 Jul 2020 11:00:59 -0600 Subject: [PATCH 12/77] [SIEM][Detection Engine][Lists] Adds list permissions (#72335) ## Summary * Adds list permissions as a feature control to SIEM. * Separates the controls between two, one of which is `access:lists-all` and the other is `access:lists-read` * Grants SIEM the ability to utilize both depending on which feature mode the space is in. --- .../routes/create_endpoint_list_item_route.ts | 2 +- .../routes/create_endpoint_list_route.ts | 2 +- .../routes/create_exception_list_item_route.ts | 2 +- .../routes/create_exception_list_route.ts | 2 +- .../server/routes/create_list_index_route.ts | 2 +- .../server/routes/create_list_item_route.ts | 2 +- .../lists/server/routes/create_list_route.ts | 2 +- .../routes/delete_endpoint_list_item_route.ts | 2 +- .../routes/delete_exception_list_item_route.ts | 2 +- .../routes/delete_exception_list_route.ts | 2 +- .../server/routes/delete_list_index_route.ts | 2 +- .../server/routes/delete_list_item_route.ts | 2 +- .../lists/server/routes/delete_list_route.ts | 2 +- .../server/routes/export_list_item_route.ts | 2 +- .../routes/find_endpoint_list_item_route.ts | 2 +- .../routes/find_exception_list_item_route.ts | 2 +- .../server/routes/find_exception_list_route.ts | 2 +- .../server/routes/find_list_item_route.ts | 2 +- .../lists/server/routes/find_list_route.ts | 2 +- .../server/routes/import_list_item_route.ts | 2 +- .../server/routes/patch_list_item_route.ts | 2 +- .../lists/server/routes/patch_list_route.ts | 2 +- .../routes/read_endpoint_list_item_route.ts | 2 +- .../routes/read_exception_list_item_route.ts | 2 +- .../server/routes/read_exception_list_route.ts | 2 +- .../server/routes/read_list_index_route.ts | 2 +- .../server/routes/read_list_item_route.ts | 2 +- .../lists/server/routes/read_list_route.ts | 2 +- .../server/routes/read_privileges_route.ts | 2 +- .../routes/update_endpoint_list_item_route.ts | 2 +- .../routes/update_exception_list_item_route.ts | 2 +- .../routes/update_exception_list_route.ts | 2 +- .../server/routes/update_list_item_route.ts | 2 +- .../lists/server/routes/update_list_route.ts | 2 +- .../plugins/security_solution/server/plugin.ts | 18 ++++++++++++++++-- 35 files changed, 50 insertions(+), 36 deletions(-) diff --git a/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts index b6eacc3b7dd04..5ff2a9d9df9f4 100644 --- a/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts @@ -21,7 +21,7 @@ export const createEndpointListItemRoute = (router: IRouter): void => { router.post( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: ENDPOINT_LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts b/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts index cac69ce65623f..b1e589be67cd1 100644 --- a/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts +++ b/x-pack/plugins/lists/server/routes/create_endpoint_list_route.ts @@ -26,7 +26,7 @@ export const createEndpointListRoute = (router: IRouter): void => { router.post( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: ENDPOINT_LIST_URL, validate: false, diff --git a/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts index c331eeb4bd2d0..e4885c7393bd4 100644 --- a/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts @@ -22,7 +22,7 @@ export const createExceptionListItemRoute = (router: IRouter): void => { router.post( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: EXCEPTION_LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/create_exception_list_route.ts b/x-pack/plugins/lists/server/routes/create_exception_list_route.ts index bd29a65c9450a..897d82d6a9ba0 100644 --- a/x-pack/plugins/lists/server/routes/create_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/create_exception_list_route.ts @@ -21,7 +21,7 @@ export const createExceptionListRoute = (router: IRouter): void => { router.post( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: EXCEPTION_LIST_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/create_list_index_route.ts b/x-pack/plugins/lists/server/routes/create_list_index_route.ts index 5ec2b36da61b0..1bffdd6bd5b5f 100644 --- a/x-pack/plugins/lists/server/routes/create_list_index_route.ts +++ b/x-pack/plugins/lists/server/routes/create_list_index_route.ts @@ -17,7 +17,7 @@ export const createListIndexRoute = (router: IRouter): void => { router.post( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: LIST_INDEX, validate: false, diff --git a/x-pack/plugins/lists/server/routes/create_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_list_item_route.ts index 8ac5db3c7fd1c..656d6af2c6c9a 100644 --- a/x-pack/plugins/lists/server/routes/create_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_list_item_route.ts @@ -17,7 +17,7 @@ export const createListItemRoute = (router: IRouter): void => { router.post( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/create_list_route.ts b/x-pack/plugins/lists/server/routes/create_list_route.ts index eee7517523b0f..ff041699054c9 100644 --- a/x-pack/plugins/lists/server/routes/create_list_route.ts +++ b/x-pack/plugins/lists/server/routes/create_list_route.ts @@ -17,7 +17,7 @@ export const createListRoute = (router: IRouter): void => { router.post( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: LIST_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts index b8946c542b27e..2d5028bd9525a 100644 --- a/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_endpoint_list_item_route.ts @@ -21,7 +21,7 @@ export const deleteEndpointListItemRoute = (router: IRouter): void => { router.delete( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: ENDPOINT_LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts index f363252dada50..06ff051925407 100644 --- a/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_exception_list_item_route.ts @@ -21,7 +21,7 @@ export const deleteExceptionListItemRoute = (router: IRouter): void => { router.delete( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: EXCEPTION_LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts b/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts index b1bf705dcc5f6..f2bf517f55ae3 100644 --- a/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_exception_list_route.ts @@ -21,7 +21,7 @@ export const deleteExceptionListRoute = (router: IRouter): void => { router.delete( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: EXCEPTION_LIST_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/delete_list_index_route.ts b/x-pack/plugins/lists/server/routes/delete_list_index_route.ts index cb2e16b3602a7..be58d8aeed17d 100644 --- a/x-pack/plugins/lists/server/routes/delete_list_index_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_list_index_route.ts @@ -33,7 +33,7 @@ export const deleteListIndexRoute = (router: IRouter): void => { router.delete( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: LIST_INDEX, validate: false, diff --git a/x-pack/plugins/lists/server/routes/delete_list_item_route.ts b/x-pack/plugins/lists/server/routes/delete_list_item_route.ts index bb278ba436725..50313cd1294ae 100644 --- a/x-pack/plugins/lists/server/routes/delete_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_list_item_route.ts @@ -17,7 +17,7 @@ export const deleteListItemRoute = (router: IRouter): void => { router.delete( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/delete_list_route.ts b/x-pack/plugins/lists/server/routes/delete_list_route.ts index 600e4b00c29ca..4eeb6d8f126ad 100644 --- a/x-pack/plugins/lists/server/routes/delete_list_route.ts +++ b/x-pack/plugins/lists/server/routes/delete_list_route.ts @@ -17,7 +17,7 @@ export const deleteListRoute = (router: IRouter): void => { router.delete( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: LIST_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/export_list_item_route.ts b/x-pack/plugins/lists/server/routes/export_list_item_route.ts index 8148c9b1ed824..98167931c4346 100644 --- a/x-pack/plugins/lists/server/routes/export_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/export_list_item_route.ts @@ -18,7 +18,7 @@ export const exportListItemRoute = (router: IRouter): void => { router.post( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: `${LIST_ITEM_URL}/_export`, validate: { diff --git a/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts index 7374ff7dc92ea..9f83761cc501a 100644 --- a/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/find_endpoint_list_item_route.ts @@ -21,7 +21,7 @@ export const findEndpointListItemRoute = (router: IRouter): void => { router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: `${ENDPOINT_LIST_ITEM_URL}/_find`, validate: { diff --git a/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts index a318d653450c7..270aad85796b2 100644 --- a/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/find_exception_list_item_route.ts @@ -21,7 +21,7 @@ export const findExceptionListItemRoute = (router: IRouter): void => { router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: `${EXCEPTION_LIST_ITEM_URL}/_find`, validate: { diff --git a/x-pack/plugins/lists/server/routes/find_exception_list_route.ts b/x-pack/plugins/lists/server/routes/find_exception_list_route.ts index 97e1de834cd37..c5cae7a1e0bb8 100644 --- a/x-pack/plugins/lists/server/routes/find_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/find_exception_list_route.ts @@ -21,7 +21,7 @@ export const findExceptionListRoute = (router: IRouter): void => { router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: `${EXCEPTION_LIST_URL}/_find`, validate: { diff --git a/x-pack/plugins/lists/server/routes/find_list_item_route.ts b/x-pack/plugins/lists/server/routes/find_list_item_route.ts index 8a0e06aa0c7d8..533dc74aa3694 100644 --- a/x-pack/plugins/lists/server/routes/find_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/find_list_item_route.ts @@ -22,7 +22,7 @@ export const findListItemRoute = (router: IRouter): void => { router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: `${LIST_ITEM_URL}/_find`, validate: { diff --git a/x-pack/plugins/lists/server/routes/find_list_route.ts b/x-pack/plugins/lists/server/routes/find_list_route.ts index 2fa43c6368b5c..268eb36a5e26e 100644 --- a/x-pack/plugins/lists/server/routes/find_list_route.ts +++ b/x-pack/plugins/lists/server/routes/find_list_route.ts @@ -18,7 +18,7 @@ export const findListRoute = (router: IRouter): void => { router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: `${LIST_URL}/_find`, validate: { diff --git a/x-pack/plugins/lists/server/routes/import_list_item_route.ts b/x-pack/plugins/lists/server/routes/import_list_item_route.ts index 2e629d7516dd1..5e88ca0f2569a 100644 --- a/x-pack/plugins/lists/server/routes/import_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/import_list_item_route.ts @@ -26,7 +26,7 @@ export const importListItemRoute = (router: IRouter, config: ConfigType): void = maxBytes: config.maxImportPayloadBytes, parse: false, }, - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: `${LIST_ITEM_URL}/_import`, validate: { diff --git a/x-pack/plugins/lists/server/routes/patch_list_item_route.ts b/x-pack/plugins/lists/server/routes/patch_list_item_route.ts index 9a74beb45bafd..d975e80079ab7 100644 --- a/x-pack/plugins/lists/server/routes/patch_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/patch_list_item_route.ts @@ -17,7 +17,7 @@ export const patchListItemRoute = (router: IRouter): void => { router.patch( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/patch_list_route.ts b/x-pack/plugins/lists/server/routes/patch_list_route.ts index 06a76559dee9a..681581c6ff6bd 100644 --- a/x-pack/plugins/lists/server/routes/patch_list_route.ts +++ b/x-pack/plugins/lists/server/routes/patch_list_route.ts @@ -17,7 +17,7 @@ export const patchListRoute = (router: IRouter): void => { router.patch( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: LIST_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts index 5e7ed901bf0cb..fd932746ce990 100644 --- a/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/read_endpoint_list_item_route.ts @@ -21,7 +21,7 @@ export const readEndpointListItemRoute = (router: IRouter): void => { router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: ENDPOINT_LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts index c4e969b27fcf4..fe8256fbda5cd 100644 --- a/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/read_exception_list_item_route.ts @@ -21,7 +21,7 @@ export const readExceptionListItemRoute = (router: IRouter): void => { router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: EXCEPTION_LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/read_exception_list_route.ts b/x-pack/plugins/lists/server/routes/read_exception_list_route.ts index 6cb91c10aea55..0512876d298d4 100644 --- a/x-pack/plugins/lists/server/routes/read_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/read_exception_list_route.ts @@ -21,7 +21,7 @@ export const readExceptionListRoute = (router: IRouter): void => { router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: EXCEPTION_LIST_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/read_list_index_route.ts b/x-pack/plugins/lists/server/routes/read_list_index_route.ts index 4664bed3e7a8b..87a4d85e0d254 100644 --- a/x-pack/plugins/lists/server/routes/read_list_index_route.ts +++ b/x-pack/plugins/lists/server/routes/read_list_index_route.ts @@ -17,7 +17,7 @@ export const readListIndexRoute = (router: IRouter): void => { router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: LIST_INDEX, validate: false, diff --git a/x-pack/plugins/lists/server/routes/read_list_item_route.ts b/x-pack/plugins/lists/server/routes/read_list_item_route.ts index 24011d3b50d27..b7cf2b9f7123b 100644 --- a/x-pack/plugins/lists/server/routes/read_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/read_list_item_route.ts @@ -17,7 +17,7 @@ export const readListItemRoute = (router: IRouter): void => { router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/read_list_route.ts b/x-pack/plugins/lists/server/routes/read_list_route.ts index 34924b70fd4df..4bce09ecd3bde 100644 --- a/x-pack/plugins/lists/server/routes/read_list_route.ts +++ b/x-pack/plugins/lists/server/routes/read_list_route.ts @@ -17,7 +17,7 @@ export const readListRoute = (router: IRouter): void => { router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: LIST_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/read_privileges_route.ts b/x-pack/plugins/lists/server/routes/read_privileges_route.ts index 892b6406a28ec..a4ec878613608 100644 --- a/x-pack/plugins/lists/server/routes/read_privileges_route.ts +++ b/x-pack/plugins/lists/server/routes/read_privileges_route.ts @@ -20,7 +20,7 @@ export const readPrivilegesRoute = ( router.get( { options: { - tags: ['access:lists'], + tags: ['access:lists-read'], }, path: LIST_PRIVILEGES_URL, validate: false, diff --git a/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts index 8415c64633a06..f717dc0fb3392 100644 --- a/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_endpoint_list_item_route.ts @@ -21,7 +21,7 @@ export const updateEndpointListItemRoute = (router: IRouter): void => { router.put( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: ENDPOINT_LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts index 2aa1e016d51ed..293435b3f6202 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts @@ -21,7 +21,7 @@ export const updateExceptionListItemRoute = (router: IRouter): void => { router.put( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: EXCEPTION_LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts index 331ec064fa663..403a9f6db934f 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts @@ -21,7 +21,7 @@ export const updateExceptionListRoute = (router: IRouter): void => { router.put( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: EXCEPTION_LIST_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/update_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_list_item_route.ts index 0f5d11afcda09..d479bc63b64bd 100644 --- a/x-pack/plugins/lists/server/routes/update_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_list_item_route.ts @@ -17,7 +17,7 @@ export const updateListItemRoute = (router: IRouter): void => { router.put( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: LIST_ITEM_URL, validate: { diff --git a/x-pack/plugins/lists/server/routes/update_list_route.ts b/x-pack/plugins/lists/server/routes/update_list_route.ts index 2fae910c1b398..78aed23db13fc 100644 --- a/x-pack/plugins/lists/server/routes/update_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_list_route.ts @@ -17,7 +17,7 @@ export const updateListRoute = (router: IRouter): void => { router.put( { options: { - tags: ['access:lists'], + tags: ['access:lists-all'], }, path: LIST_URL, validate: { diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index 17192057d2ad3..22b55c64a1657 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -167,7 +167,14 @@ export class Plugin implements IPlugin Date: Mon, 20 Jul 2020 13:47:04 -0400 Subject: [PATCH 13/77] add index-pattern link when error contains 'click here' text (#72470) --- .../job_config_error_callout.tsx | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx index 945d6654067c0..9b9e1258db503 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx @@ -6,7 +6,7 @@ import React, { FC } from 'react'; -import { EuiCallOut, EuiPanel, EuiSpacer } from '@elastic/eui'; +import { EuiCallOut, EuiLink, EuiPanel, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -31,6 +31,23 @@ export const JobConfigErrorCallout: FC = ({ jobConfigErrorMessage, title, }) => { + const containsIndexPatternLink = + typeof jobCapsServiceErrorMessage === 'string' && + jobCapsServiceErrorMessage.includes('locate that index-pattern') && + jobCapsServiceErrorMessage.includes('click here to re-create'); + + const message = ( +

{jobConfigErrorMessage ? jobConfigErrorMessage : jobCapsServiceErrorMessage}

+ ); + + const calloutBody = containsIndexPatternLink ? ( + + {message} + + ) : ( + message + ); + return ( @@ -40,7 +57,7 @@ export const JobConfigErrorCallout: FC = ({ color="danger" iconType="cross" > -

{jobConfigErrorMessage ? jobConfigErrorMessage : jobCapsServiceErrorMessage}

+ {calloutBody}
); From 85d8ec8905856d2eb0f0bb22454d8ca3801e3b98 Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Mon, 20 Jul 2020 13:18:43 -0500 Subject: [PATCH 14/77] [Metrics UI] Fix Alert Preview Error design (#71005) Co-authored-by: Elastic Machine --- .../common/components/alert_preview.tsx | 58 ++++++++----------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/x-pack/plugins/infra/public/alerting/common/components/alert_preview.tsx b/x-pack/plugins/infra/public/alerting/common/components/alert_preview.tsx index 0e0e23ef73a3a..f3136ca155c78 100644 --- a/x-pack/plugins/infra/public/alerting/common/components/alert_preview.tsx +++ b/x-pack/plugins/infra/public/alerting/common/components/alert_preview.tsx @@ -14,13 +14,9 @@ import { EuiFlexGroup, EuiFlexItem, EuiCallOut, - EuiOverlayMask, - EuiModal, - EuiModalHeader, - EuiModalHeaderTitle, - EuiModalBody, + EuiAccordion, EuiCodeBlock, - EuiLink, + EuiText, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; @@ -61,9 +57,6 @@ export const AlertPreview: React.FC = (props) => { const [previewResult, setPreviewResult] = useState< (AlertPreviewSuccessResponsePayload & Record) | null >(null); - const [isErrorModalVisible, setIsErrorModalVisible] = useState(false); - const onOpenModal = useCallback(() => setIsErrorModalVisible(true), [setIsErrorModalVisible]); - const onCloseModal = useCallback(() => setIsErrorModalVisible(false), [setIsErrorModalVisible]); const onSelectPreviewLookbackInterval = useCallback((e) => { setPreviewLookbackInterval(e.target.value); @@ -271,33 +264,32 @@ export const AlertPreview: React.FC = (props) => { iconType="alert" > {previewError.body && ( - view the error, - }} - /> + <> + + + + + + + + } + > + + {previewError.body.message} + + )} )} - {isErrorModalVisible && ( - - - - - - - - - {previewError.body.message} - - - - )} )} From 88e8c30e61daf0a982a9944469a901dad8fa4118 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Mon, 20 Jul 2020 11:21:03 -0700 Subject: [PATCH 15/77] Convert ILM remove_lifecycle_confirm_modal component to TS. (#70382) - Also convert api and api_errors services, and improve typing of http service. - Fix bug where fatalErrors service was improperly consumed in api_errors. - Improve typing in Rollup api_errors service, for consistency. --- .../helpers/setup_environment.ts | 2 ++ .../public/application/services/api.ts | 12 ++++++++---- .../services/{api_errors.js => api_errors.ts} | 10 ++++++---- .../public/application/services/http.ts | 15 ++++++++++----- ...odal.js => remove_lifecycle_confirm_modal.tsx} | 15 ++++++--------- .../rollup/public/crud_app/services/api_errors.ts | 10 ++++++---- 6 files changed, 38 insertions(+), 26 deletions(-) rename x-pack/plugins/index_lifecycle_management/public/application/services/{api_errors.js => api_errors.ts} (73%) rename x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/{remove_lifecycle_confirm_modal.js => remove_lifecycle_confirm_modal.tsx} (95%) diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.ts index b3205a9523c62..325d8193de5fd 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.ts @@ -29,6 +29,8 @@ export const setupEnvironment = () => { ); mockHttpClient.interceptors.response.use(({ data }) => data); + // This expects HttpSetup but we're giving it AxiosInstance. + // @ts-ignore initHttp(mockHttpClient); const { server, httpRequestsMockHelpers } = initHttpRequests(); diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/api.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/api.ts index 065fb3bcebca7..30c341baa6194 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/api.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/api.ts @@ -5,7 +5,6 @@ */ import { METRIC_TYPE } from '@kbn/analytics'; -import { trackUiMetric } from './ui_metric'; import { UIM_POLICY_DELETE, @@ -15,8 +14,13 @@ import { UIM_INDEX_RETRY_STEP, } from '../constants'; +import { trackUiMetric } from './ui_metric'; import { sendGet, sendPost, sendDelete, useRequest } from './http'; +interface GenericObject { + [key: string]: any; +} + export async function loadNodes() { return await sendGet(`nodes/list`); } @@ -33,7 +37,7 @@ export async function loadPolicies(withIndices: boolean) { return await sendGet('policies', { withIndices }); } -export async function savePolicy(policy: any) { +export async function savePolicy(policy: GenericObject) { return await sendPost(`policies`, policy); } @@ -58,14 +62,14 @@ export const removeLifecycleForIndex = async (indexNames: string[]) => { return response; }; -export const addLifecyclePolicyToIndex = async (body: any) => { +export const addLifecyclePolicyToIndex = async (body: GenericObject) => { const response = await sendPost(`index/add`, body); // Only track successful actions. trackUiMetric(METRIC_TYPE.COUNT, UIM_POLICY_ATTACH_INDEX); return response; }; -export const addLifecyclePolicyToTemplate = async (body: any) => { +export const addLifecyclePolicyToTemplate = async (body: GenericObject) => { const response = await sendPost(`template`, body); // Only track successful actions. trackUiMetric(METRIC_TYPE.COUNT, UIM_POLICY_ATTACH_INDEX_TEMPLATE); diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/api_errors.js b/x-pack/plugins/index_lifecycle_management/public/application/services/api_errors.ts similarity index 73% rename from x-pack/plugins/index_lifecycle_management/public/application/services/api_errors.js rename to x-pack/plugins/index_lifecycle_management/public/application/services/api_errors.ts index af107b5cff4b1..7b8d48acced33 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/api_errors.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/api_errors.ts @@ -4,10 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ +import { IHttpFetchError } from 'src/core/public'; import { fatalErrors, toasts } from './notification'; -function createToastConfig(error, errorTitle) { +function createToastConfig(error: IHttpFetchError, errorTitle: string) { if (error && error.body) { + // Error body shape is defined by the API. const { error: errorString, statusCode, message } = error.body; return { @@ -17,7 +19,7 @@ function createToastConfig(error, errorTitle) { } } -export function showApiWarning(error, errorTitle) { +export function showApiWarning(error: IHttpFetchError, errorTitle: string) { const toastConfig = createToastConfig(error, errorTitle); if (toastConfig) { @@ -26,10 +28,10 @@ export function showApiWarning(error, errorTitle) { // This error isn't an HTTP error, so let the fatal error screen tell the user something // unexpected happened. - return fatalErrors(error, errorTitle); + return fatalErrors.add(error, errorTitle); } -export function showApiError(error, errorTitle) { +export function showApiError(error: IHttpFetchError, errorTitle: string) { const toastConfig = createToastConfig(error, errorTitle); if (toastConfig) { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/http.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/http.ts index c54ee15fd69bf..0b5f39a52c13f 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/http.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/http.ts @@ -4,15 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ +import { HttpSetup } from 'src/core/public'; import { UseRequestConfig, useRequest as _useRequest, Error, } from '../../../../../../src/plugins/es_ui_shared/public'; -let _httpClient: any; +interface GenericObject { + [key: string]: any; +} + +let _httpClient: HttpSetup; -export function init(httpClient: any): void { +export function init(httpClient: HttpSetup): void { _httpClient = httpClient; } @@ -26,15 +31,15 @@ function getFullPath(path: string): string { return apiPrefix; } -export function sendPost(path: string, payload: any): any { +export function sendPost(path: string, payload: GenericObject) { return _httpClient.post(getFullPath(path), { body: JSON.stringify(payload) }); } -export function sendGet(path: string, query?: any): any { +export function sendGet(path: string, query?: GenericObject): any { return _httpClient.get(getFullPath(path), { query }); } -export function sendDelete(path: string): any { +export function sendDelete(path: string) { return _httpClient.delete(getFullPath(path)); } diff --git a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.js b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.tsx similarity index 95% rename from x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.js rename to x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.tsx index 048ed44bd58b2..6057522885b1d 100644 --- a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.js +++ b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/components/remove_lifecycle_confirm_modal.tsx @@ -13,16 +13,13 @@ import { removeLifecycleForIndex } from '../../application/services/api'; import { showApiError } from '../../application/services/api_errors'; import { toasts } from '../../application/services/notification'; -export class RemoveLifecyclePolicyConfirmModal extends Component { - constructor(props) { - super(props); - this.state = { - policies: [], - selectedPolicyName: null, - selectedAlias: null, - }; - } +interface Props { + indexNames: string[]; + closeModal: () => void; + reloadIndices: () => void; +} +export class RemoveLifecyclePolicyConfirmModal extends Component { removePolicy = async () => { const { indexNames, closeModal, reloadIndices } = this.props; diff --git a/x-pack/plugins/rollup/public/crud_app/services/api_errors.ts b/x-pack/plugins/rollup/public/crud_app/services/api_errors.ts index af9e1a16e4cc5..bea21d119e7fd 100644 --- a/x-pack/plugins/rollup/public/crud_app/services/api_errors.ts +++ b/x-pack/plugins/rollup/public/crud_app/services/api_errors.ts @@ -4,12 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ +import { IHttpFetchError } from 'src/core/public'; import { getNotifications, getFatalErrors } from '../../kibana_services'; -function createToastConfig(error: any, errorTitle: string) { - // Expect an error in the shape provided by http service. +function createToastConfig(error: IHttpFetchError, errorTitle: string) { if (error && error.body) { + // Error body shape is defined by the API. const { error: errorString, statusCode, message } = error.body; + return { title: errorTitle, text: `${statusCode}: ${errorString}. ${message}`, @@ -17,7 +19,7 @@ function createToastConfig(error: any, errorTitle: string) { } } -export function showApiWarning(error: any, errorTitle: string) { +export function showApiWarning(error: IHttpFetchError, errorTitle: string) { const toastConfig = createToastConfig(error, errorTitle); if (toastConfig) { @@ -29,7 +31,7 @@ export function showApiWarning(error: any, errorTitle: string) { return getFatalErrors().add(error, errorTitle); } -export function showApiError(error: any, errorTitle: string) { +export function showApiError(error: IHttpFetchError, errorTitle: string) { const toastConfig = createToastConfig(error, errorTitle); if (toastConfig) { From 2771d69c96330465b56f5b7c18530d04d5e00cb8 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Mon, 20 Jul 2020 21:32:46 +0300 Subject: [PATCH 16/77] [KP] bump es client to rc2 (#72448) * bump es client to rc2 * update code for new typings --- package.json | 2 +- .../security_solution/common/endpoint/index_data.ts | 2 +- x-pack/test/api_integration/apis/fleet/agents/acks.ts | 2 +- .../test/api_integration/apis/fleet/agents/checkin.ts | 2 +- .../test/api_integration/apis/fleet/agents/enroll.ts | 2 +- .../test/api_integration/apis/fleet/unenroll_agent.ts | 2 +- x-pack/test/api_integration/services/resolver.ts | 2 +- yarn.lock | 11 +++++++++++ 8 files changed, 18 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index ceb3ac4cca937..2f3f95854df04 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "@elastic/apm-rum": "^5.2.0", "@elastic/charts": "19.8.1", "@elastic/datemath": "5.0.3", - "@elastic/elasticsearch": "7.9.0-rc.1", + "@elastic/elasticsearch": "7.9.0-rc.2", "@elastic/ems-client": "7.9.3", "@elastic/eui": "26.3.1", "@elastic/filesaver": "1.1.2", diff --git a/x-pack/plugins/security_solution/common/endpoint/index_data.ts b/x-pack/plugins/security_solution/common/endpoint/index_data.ts index 00b8f0b057afd..9a61738cd84b4 100644 --- a/x-pack/plugins/security_solution/common/endpoint/index_data.ts +++ b/x-pack/plugins/security_solution/common/endpoint/index_data.ts @@ -94,6 +94,6 @@ async function indexAlerts( }, [] ); - await client.bulk({ body, refresh: 'true' }); + await client.bulk({ body, refresh: true }); } } diff --git a/x-pack/test/api_integration/apis/fleet/agents/acks.ts b/x-pack/test/api_integration/apis/fleet/agents/acks.ts index e8381aa9d59ea..a040ef20081a8 100644 --- a/x-pack/test/api_integration/apis/fleet/agents/acks.ts +++ b/x-pack/test/api_integration/apis/fleet/agents/acks.ts @@ -38,7 +38,7 @@ export default function (providerContext: FtrProviderContext) { await esClient.update({ index: '.kibana', id: 'fleet-agents:agent1', - refresh: 'true', + refresh: true, body: { doc: agentDoc, }, diff --git a/x-pack/test/api_integration/apis/fleet/agents/checkin.ts b/x-pack/test/api_integration/apis/fleet/agents/checkin.ts index 8942deafdd83c..70147f602e9c7 100644 --- a/x-pack/test/api_integration/apis/fleet/agents/checkin.ts +++ b/x-pack/test/api_integration/apis/fleet/agents/checkin.ts @@ -38,7 +38,7 @@ export default function (providerContext: FtrProviderContext) { await esClient.update({ index: '.kibana', id: 'fleet-agents:agent1', - refresh: 'true', + refresh: true, body: { doc: agentDoc, }, diff --git a/x-pack/test/api_integration/apis/fleet/agents/enroll.ts b/x-pack/test/api_integration/apis/fleet/agents/enroll.ts index 8a21fbcf24c7d..58440a34457d0 100644 --- a/x-pack/test/api_integration/apis/fleet/agents/enroll.ts +++ b/x-pack/test/api_integration/apis/fleet/agents/enroll.ts @@ -43,7 +43,7 @@ export default function (providerContext: FtrProviderContext) { await esClient.update({ index: '.kibana', id: 'fleet-enrollment-api-keys:ed22ca17-e178-4cfe-8b02-54ea29fbd6d0', - refresh: 'true', + refresh: true, body: { doc: enrollmentApiKeyDoc, }, diff --git a/x-pack/test/api_integration/apis/fleet/unenroll_agent.ts b/x-pack/test/api_integration/apis/fleet/unenroll_agent.ts index bc6c44e590cc4..bbbce3314e4cc 100644 --- a/x-pack/test/api_integration/apis/fleet/unenroll_agent.ts +++ b/x-pack/test/api_integration/apis/fleet/unenroll_agent.ts @@ -52,7 +52,7 @@ export default function (providerContext: FtrProviderContext) { await esClient.update({ index: '.kibana', id: 'fleet-agents:agent1', - refresh: 'true', + refresh: true, body: { doc: agentDoc, }, diff --git a/x-pack/test/api_integration/services/resolver.ts b/x-pack/test/api_integration/services/resolver.ts index 750d2f702fb84..7f568a2b00314 100644 --- a/x-pack/test/api_integration/services/resolver.ts +++ b/x-pack/test/api_integration/services/resolver.ts @@ -57,7 +57,7 @@ export function ResolverGeneratorProvider({ getService }: FtrProviderContext) { return array; }, []); // force a refresh here otherwise the documents might not be available when the tests search for them - await client.bulk({ body, refresh: 'true' }); + await client.bulk({ body, refresh: true }); allTrees.push(tree); } return { trees: allTrees, eventsIndex, alertsIndex }; diff --git a/yarn.lock b/yarn.lock index 3924655b5e43e..4cc802e328ab8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2183,6 +2183,17 @@ pump "^3.0.0" secure-json-parse "^2.1.0" +"@elastic/elasticsearch@7.9.0-rc.2": + version "7.9.0-rc.2" + resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-7.9.0-rc.2.tgz#cbc935f30940a15484b5ec3758c9b1ef119a5e5c" + integrity sha512-1FKCQJVr7s/LasKq6VbrmbWCI0LjoPcnjgmh2vKPzC+yyEEHVoYlmEfR5wBRchK1meATTXZtDhCVF95+Q9kVbA== + dependencies: + debug "^4.1.1" + decompress-response "^4.2.0" + ms "^2.1.1" + pump "^3.0.0" + secure-json-parse "^2.1.0" + "@elastic/ems-client@7.9.3": version "7.9.3" resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-7.9.3.tgz#71b79914f76e347f050ead8474ad65d761e94a8a" From 3ccdd79aa7ff6f03b08de2a21590a92c1a7e759e Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Mon, 20 Jul 2020 12:55:52 -0600 Subject: [PATCH 17/77] [SIEM][Detection Engine] Reduces flakiness within the tests using waitFor() and un-skips the tests (#72479) ## Summary * Utilizes the `waitFor` so that the tests are less flaky and more resilient * Unskips a test that was due to a regression within Elastic Search that should be fixed now * https://github.com/elastic/kibana/issues/71867 * https://github.com/elastic/kibana/issues/71814 * https://github.com/elastic/kibana/issues/71612 ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios --- .../basic/tests/add_prepackaged_rules.ts | 14 ++++++++++++-- .../tests/add_prepackaged_rules.ts | 14 ++++++++++++-- .../security_and_spaces/tests/create_rules_bulk.ts | 3 +-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/add_prepackaged_rules.ts b/x-pack/test/detection_engine_api_integration/basic/tests/add_prepackaged_rules.ts index 3340ac49b2d2d..a022b7c79c079 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/add_prepackaged_rules.ts +++ b/x-pack/test/detection_engine_api_integration/basic/tests/add_prepackaged_rules.ts @@ -13,6 +13,7 @@ import { deleteAllAlerts, deleteAllTimelines, deleteSignalsIndex, + waitFor, } from '../../utils'; // eslint-disable-next-line import/no-default-export @@ -20,8 +21,7 @@ export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const es = getService('es'); - // FLAKY: https://github.com/elastic/kibana/issues/71867 - describe.skip('add_prepackaged_rules', () => { + describe('add_prepackaged_rules', () => { describe('validation errors', () => { it('should give an error that the index must exist first if it does not exist before adding prepackaged rules', async () => { const { body } = await supertest @@ -91,6 +91,16 @@ export default ({ getService }: FtrProviderContext): void => { .send() .expect(200); + // NOTE: I call the GET call until eventually it becomes consistent and that the number of rules to install are zero. + // This is to reduce flakiness where it can for a short period of time try to install the same rule twice. + await waitFor(async () => { + const { body } = await supertest + .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .set('kbn-xsrf', 'true') + .expect(200); + return body.rules_not_installed === 0; + }); + const { body } = await supertest .put(DETECTION_ENGINE_PREPACKAGED_URL) .set('kbn-xsrf', 'true') diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/add_prepackaged_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/add_prepackaged_rules.ts index 7671b1bd49744..40456737b8761 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/add_prepackaged_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/add_prepackaged_rules.ts @@ -13,6 +13,7 @@ import { deleteAllAlerts, deleteAllTimelines, deleteSignalsIndex, + waitFor, } from '../../utils'; // eslint-disable-next-line import/no-default-export @@ -20,8 +21,7 @@ export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const es = getService('es'); - // FLAKY: https://github.com/elastic/kibana/issues/71814 - describe.skip('add_prepackaged_rules', () => { + describe('add_prepackaged_rules', () => { describe('validation errors', () => { it('should give an error that the index must exist first if it does not exist before adding prepackaged rules', async () => { const { body } = await supertest @@ -91,6 +91,16 @@ export default ({ getService }: FtrProviderContext): void => { .send() .expect(200); + // NOTE: I call the GET call until eventually it becomes consistent and that the number of rules to install are zero. + // This is to reduce flakiness where it can for a short period of time try to install the same rule the same rule twice. + await waitFor(async () => { + const { body } = await supertest + .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .set('kbn-xsrf', 'true') + .expect(200); + return body.rules_not_installed === 0; + }); + const { body } = await supertest .put(DETECTION_ENGINE_PREPACKAGED_URL) .set('kbn-xsrf', 'true') diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_rules_bulk.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_rules_bulk.ts index b59fd1b744e97..52865e43be750 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_rules_bulk.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/create_rules_bulk.ts @@ -29,8 +29,7 @@ export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const es = getService('es'); - // Failing ES promotion: https://github.com/elastic/kibana/issues/71612 - describe.skip('create_rules_bulk', () => { + describe('create_rules_bulk', () => { describe('validation errors', () => { it('should give a 200 even if the index does not exist as all bulks return a 200 but have an error of 409 bad request in the body', async () => { const { body } = await supertest From 0f964f66916480f2de1f4b633e5afafc08cf62a0 Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Mon, 20 Jul 2020 12:14:33 -0700 Subject: [PATCH 18/77] [Ingest Manager] Disable asset facet links (#72158) * Disable asset facets * Fix prop name Co-authored-by: Elastic Machine --- .../epm/components/assets_facet_group.tsx | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/assets_facet_group.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/assets_facet_group.tsx index 24b4baeaa092b..b8fab92e40da8 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/assets_facet_group.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/assets_facet_group.tsx @@ -3,7 +3,7 @@ * 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, { Fragment } from 'react'; import { EuiFacetButton, EuiFacetGroup, @@ -14,8 +14,8 @@ import { EuiTextColor, EuiTitle, } from '@elastic/eui'; -import React, { Fragment } from 'react'; import styled from 'styled-components'; +import { FormattedMessage } from '@kbn/i18n/react'; import { AssetsGroupedByServiceByType, AssetTypeToParts, @@ -43,8 +43,15 @@ const FacetGroup = styled(EuiFacetGroup)` `; const FacetButton = styled(EuiFacetButton)` - padding: '${(props) => props.theme.eui.paddingSizes.xs} 0'; - height: 'unset'; + &&& { + .euiFacetButton__icon, + .euiFacetButton__quantity { + opacity: 1; + } + .euiFacetButton__text { + color: ${(props) => props.theme.eui.euiTextColor}; + } + } `; export function AssetsFacetGroup({ assets }: { assets: AssetsGroupedByServiceByType }) { @@ -70,7 +77,15 @@ export function AssetsFacetGroup({ assets }: { assets: AssetsGroupedByServiceByT -

{ServiceTitleMap[service]} Assets

+

+ +

@@ -83,13 +98,7 @@ export function AssetsFacetGroup({ assets }: { assets: AssetsGroupedByServiceByT const iconType = type in AssetIcons && AssetIcons[type]; const iconNode = iconType ? : ''; return ( - {}} - > + {AssetTitleMap[type]} ); From 4ccf1aed96600382f2ba60bdf631a0d8c7f5e257 Mon Sep 17 00:00:00 2001 From: Davis Plumlee <56367316+dplumlee@users.noreply.github.com> Date: Mon, 20 Jul 2020 15:34:26 -0400 Subject: [PATCH 19/77] [Security Solution][Detections]Exceptions modal bugs (#72471) --- .../exceptions/add_exception_modal/index.tsx | 8 ++++++-- .../exceptions/edit_exception_modal/index.tsx | 10 ++++++++-- .../detections/components/alerts_table/index.tsx | 1 + 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx index 79383676266f5..53c53f48f076b 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx @@ -21,6 +21,7 @@ import { EuiCallOut, EuiText, } from '@elastic/eui'; +import { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; import { alertsIndexPattern } from '../../../../../common/endpoint/constants'; import { ExceptionListItemSchema, @@ -67,6 +68,7 @@ interface AddExceptionModalProps { }; onCancel: () => void; onConfirm: (didCloseAlert: boolean) => void; + alertStatus?: Status; } const Modal = styled(EuiModal)` @@ -105,6 +107,7 @@ export const AddExceptionModal = memo(function AddExceptionModal({ alertData, onCancel, onConfirm, + alertStatus, }: AddExceptionModalProps) { const { http } = useKibana().services; const [comment, setComment] = useState(''); @@ -183,7 +186,8 @@ export const AddExceptionModal = memo(function AddExceptionModal({ if (indexPatternLoading === false && isSignalIndexLoading === false) { setShouldDisableBulkClose( entryHasListType(exceptionItemsToAdd) || - entryHasNonEcsType(exceptionItemsToAdd, indexPatterns) + entryHasNonEcsType(exceptionItemsToAdd, indexPatterns) || + exceptionItemsToAdd.length === 0 ); } }, [ @@ -335,7 +339,7 @@ export const AddExceptionModal = memo(function AddExceptionModal({ - {alertData !== undefined && ( + {alertData !== undefined && alertStatus !== 'closed' && ( - {!isSignalIndexLoading && ( + {(addExceptionIsLoading || indexPatternLoading || isSignalIndexLoading) && ( + + )} + + {!isSignalIndexLoading && !addExceptionIsLoading && !indexPatternLoading && ( <> {i18n.EXCEPTION_BUILDER_INFO} diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index 30cfe2d02354f..1d4c97d85443f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -458,6 +458,7 @@ export const AlertsTableComponent: React.FC = ({ alertData={addExceptionModalState.alertData} onCancel={onAddExceptionCancel} onConfirm={onAddExceptionConfirm} + alertStatus={filterGroup} /> )} From b9413cf3c816d65c53d5b7fb5f2d0e1300729f3c Mon Sep 17 00:00:00 2001 From: "Devin W. Hurley" Date: Mon, 20 Jul 2020 15:55:26 -0400 Subject: [PATCH 20/77] [SIEM] [Detections] Fixes faulty circuit breaker (#71999) * removes useSortIds which was leftover from a previous attempt at implementing gap detection mitigation code. This only showed up because I modified the count variable used to determine when we hit maxSignals from utilizing the searchResult hits length to using the count of bulk created items (signals indexed) in this commit 56de45d156be23069815fec17440cf978710451f * removes logs and fixes if statement ordering * adds tests, increases code coverage for search after and bulk create function, updates log statements * update tests after rebase onto master * clean up if statements * fix test data * merge conflicts are hard --- .../signals/__mocks__/es_results.ts | 42 +++- .../signals/build_bulk_body.test.ts | 7 +- .../signals/search_after_bulk_create.test.ts | 207 ++++++++++++++++++ .../signals/search_after_bulk_create.ts | 171 +++++++++------ 4 files changed, 351 insertions(+), 76 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts index 17e05109b9a87..19fcf65ec0c5e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/__mocks__/es_results.ts @@ -56,11 +56,10 @@ export const sampleRuleAlertParams = ( exceptionsList: getListArrayMock(), }); -export const sampleDocNoSortId = (someUuid: string = sampleIdGuid): SignalSourceHit => ({ +export const sampleDocNoSortIdNoVersion = (someUuid: string = sampleIdGuid): SignalSourceHit => ({ _index: 'myFakeSignalIndex', _type: 'doc', _score: 100, - _version: 1, _id: someUuid, _source: { someKey: 'someValue', @@ -68,18 +67,26 @@ export const sampleDocNoSortId = (someUuid: string = sampleIdGuid): SignalSource }, }); -export const sampleDocNoSortIdNoVersion = (someUuid: string = sampleIdGuid): SignalSourceHit => ({ +export const sampleDocWithSortId = ( + someUuid: string = sampleIdGuid, + ip?: string +): SignalSourceHit => ({ _index: 'myFakeSignalIndex', _type: 'doc', _score: 100, + _version: 1, _id: someUuid, _source: { someKey: 'someValue', '@timestamp': '2020-04-20T21:27:45+0000', + source: { + ip: ip ?? '127.0.0.1', + }, }, + sort: ['1234567891111'], }); -export const sampleDocWithSortId = ( +export const sampleDocNoSortId = ( someUuid: string = sampleIdGuid, ip?: string ): SignalSourceHit => ({ @@ -95,7 +102,7 @@ export const sampleDocWithSortId = ( ip: ip ?? '127.0.0.1', }, }, - sort: ['1234567891111'], + sort: [], }); export const sampleEmptyDocSearchResults = (): SignalSearchResponse => ({ @@ -116,6 +123,8 @@ export const sampleEmptyDocSearchResults = (): SignalSearchResponse => ({ export const sampleDocWithAncestors = (): SignalSearchResponse => { const sampleDoc = sampleDocNoSortId(); + delete sampleDoc.sort; + delete sampleDoc._source.source; sampleDoc._source.signal = { parent: { rule: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', @@ -317,6 +326,29 @@ export const repeatedSearchResultsWithSortId = ( }, }); +export const repeatedSearchResultsWithNoSortId = ( + total: number, + pageSize: number, + guids: string[], + ips?: string[] +) => ({ + took: 10, + timed_out: false, + _shards: { + total: 10, + successful: 10, + failed: 0, + skipped: 0, + }, + hits: { + total, + max_score: 100, + hits: Array.from({ length: pageSize }).map((x, index) => ({ + ...sampleDocNoSortId(guids[index], ips ? ips[index] : '127.0.0.1'), + })), + }, +}); + export const sampleDocSearchResultsWithSortId = ( someUuid: string = sampleIdGuid ): SignalSearchResponse => ({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts index e840ae96cf3c1..fe2e0f2d96fd8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.test.ts @@ -21,8 +21,10 @@ describe('buildBulkBody', () => { test('bulk body builds well-defined body', () => { const sampleParams = sampleRuleAlertParams(); + const doc = sampleDocNoSortId(); + delete doc._source.source; const fakeSignalSourceHit = buildBulkBody({ - doc: sampleDocNoSortId(), + doc, ruleParams: sampleParams, id: sampleRuleGuid, name: 'rule-name', @@ -107,6 +109,7 @@ describe('buildBulkBody', () => { test('bulk body builds original_event if it exists on the event to begin with', () => { const sampleParams = sampleRuleAlertParams(); const doc = sampleDocNoSortId(); + delete doc._source.source; doc._source.event = { action: 'socket_opened', module: 'system', @@ -208,6 +211,7 @@ describe('buildBulkBody', () => { test('bulk body builds original_event if it exists on the event to begin with but no kind information', () => { const sampleParams = sampleRuleAlertParams(); const doc = sampleDocNoSortId(); + delete doc._source.source; doc._source.event = { action: 'socket_opened', module: 'system', @@ -307,6 +311,7 @@ describe('buildBulkBody', () => { test('bulk body builds original_event if it exists on the event to begin with with only kind information', () => { const sampleParams = sampleRuleAlertParams(); const doc = sampleDocNoSortId(); + delete doc._source.source; doc._source.event = { kind: 'event', }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts index 17935f64d5e14..3312191c3b41b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts @@ -11,6 +11,7 @@ import { sampleRuleGuid, mockLogger, repeatedSearchResultsWithSortId, + repeatedSearchResultsWithNoSortId, sampleDocSearchResultsNoSortIdNoHits, } from './__mocks__/es_results'; import { searchAfterAndBulkCreate } from './search_after_bulk_create'; @@ -356,6 +357,212 @@ describe('searchAfterAndBulkCreate', () => { expect(lastLookBackDate).toEqual(new Date('2020-04-20T21:27:45+0000')); }); + test('should return success when all search results are in the allowlist and with sortId present', async () => { + listClient.getListItemByValues = jest + .fn() + .mockResolvedValue([{ value: '1.1.1.1' }, { value: '2.2.2.2' }, { value: '3.3.3.3' }]); + const sampleParams = sampleRuleAlertParams(30); + mockService.callCluster + .mockResolvedValueOnce( + repeatedSearchResultsWithSortId(4, 4, someGuids.slice(0, 3), [ + '1.1.1.1', + '2.2.2.2', + '2.2.2.2', + '2.2.2.2', + ]) + ) + .mockResolvedValueOnce(sampleDocSearchResultsNoSortIdNoHits()); + + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [ + { + field: 'source.ip', + operator: 'included', + type: 'list', + list: { + id: 'ci-badguys.txt', + type: 'ip', + }, + }, + ]; + const { success, createdSignalsCount, lastLookBackDate } = await searchAfterAndBulkCreate({ + ruleParams: sampleParams, + gap: null, + previousStartedAt: new Date(), + listClient, + exceptionsList: [exceptionItem], + services: mockService, + logger: mockLogger, + id: sampleRuleGuid, + inputIndexPattern, + signalsIndex: DEFAULT_SIGNALS_INDEX, + name: 'rule-name', + actions: [], + createdAt: '2020-01-28T15:58:34.810Z', + updatedAt: '2020-01-28T15:59:14.004Z', + createdBy: 'elastic', + updatedBy: 'elastic', + interval: '5m', + enabled: true, + pageSize: 1, + filter: undefined, + refresh: false, + tags: ['some fake tag 1', 'some fake tag 2'], + throttle: 'no_actions', + buildRuleMessage, + }); + expect(success).toEqual(true); + expect(mockService.callCluster).toHaveBeenCalledTimes(2); + expect(createdSignalsCount).toEqual(0); // should not create any signals because all events were in the allowlist + expect(lastLookBackDate).toEqual(new Date('2020-04-20T21:27:45+0000')); + }); + + test('should return success when all search results are in the allowlist and no sortId present', async () => { + listClient.getListItemByValues = jest + .fn() + .mockResolvedValue([{ value: '1.1.1.1' }, { value: '2.2.2.2' }, { value: '3.3.3.3' }]); + const sampleParams = sampleRuleAlertParams(30); + mockService.callCluster.mockResolvedValueOnce( + repeatedSearchResultsWithNoSortId(4, 4, someGuids.slice(0, 3), [ + '1.1.1.1', + '2.2.2.2', + '2.2.2.2', + '2.2.2.2', + ]) + ); + + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [ + { + field: 'source.ip', + operator: 'included', + type: 'list', + list: { + id: 'ci-badguys.txt', + type: 'ip', + }, + }, + ]; + const { success, createdSignalsCount, lastLookBackDate } = await searchAfterAndBulkCreate({ + ruleParams: sampleParams, + gap: null, + previousStartedAt: new Date(), + listClient, + exceptionsList: [exceptionItem], + services: mockService, + logger: mockLogger, + id: sampleRuleGuid, + inputIndexPattern, + signalsIndex: DEFAULT_SIGNALS_INDEX, + name: 'rule-name', + actions: [], + createdAt: '2020-01-28T15:58:34.810Z', + updatedAt: '2020-01-28T15:59:14.004Z', + createdBy: 'elastic', + updatedBy: 'elastic', + interval: '5m', + enabled: true, + pageSize: 1, + filter: undefined, + refresh: false, + tags: ['some fake tag 1', 'some fake tag 2'], + throttle: 'no_actions', + buildRuleMessage, + }); + expect(success).toEqual(true); + expect(mockService.callCluster).toHaveBeenCalledTimes(1); + expect(createdSignalsCount).toEqual(0); // should not create any signals because all events were in the allowlist + expect(lastLookBackDate).toEqual(new Date('2020-04-20T21:27:45+0000')); + // I don't like testing log statements since logs change but this is the best + // way I can think of to ensure this section is getting hit with this test case. + expect(((mockLogger.debug as unknown) as jest.Mock).mock.calls[7][0]).toContain( + 'sortIds was empty on searchResult' + ); + }); + + test('should return success when no sortId present but search results are in the allowlist', async () => { + const sampleParams = sampleRuleAlertParams(30); + mockService.callCluster + .mockResolvedValueOnce(repeatedSearchResultsWithNoSortId(4, 4, someGuids.slice(0, 3))) + .mockResolvedValueOnce({ + took: 100, + errors: false, + items: [ + { + fakeItemValue: 'fakeItemKey', + }, + { + create: { + status: 201, + }, + }, + { + create: { + status: 201, + }, + }, + { + create: { + status: 201, + }, + }, + { + create: { + status: 201, + }, + }, + ], + }); + + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [ + { + field: 'source.ip', + operator: 'included', + type: 'list', + list: { + id: 'ci-badguys.txt', + type: 'ip', + }, + }, + ]; + const { success, createdSignalsCount, lastLookBackDate } = await searchAfterAndBulkCreate({ + ruleParams: sampleParams, + gap: null, + previousStartedAt: new Date(), + listClient, + exceptionsList: [exceptionItem], + services: mockService, + logger: mockLogger, + id: sampleRuleGuid, + inputIndexPattern, + signalsIndex: DEFAULT_SIGNALS_INDEX, + name: 'rule-name', + actions: [], + createdAt: '2020-01-28T15:58:34.810Z', + updatedAt: '2020-01-28T15:59:14.004Z', + createdBy: 'elastic', + updatedBy: 'elastic', + interval: '5m', + enabled: true, + pageSize: 1, + filter: undefined, + refresh: false, + tags: ['some fake tag 1', 'some fake tag 2'], + throttle: 'no_actions', + buildRuleMessage, + }); + expect(success).toEqual(true); + expect(mockService.callCluster).toHaveBeenCalledTimes(2); + expect(createdSignalsCount).toEqual(4); // should not create any signals because all events were in the allowlist + expect(lastLookBackDate).toEqual(new Date('2020-04-20T21:27:45+0000')); + // I don't like testing log statements since logs change but this is the best + // way I can think of to ensure this section is getting hit with this test case. + expect(((mockLogger.debug as unknown) as jest.Mock).mock.calls[12][0]).toContain( + 'sortIds was empty on filteredEvents' + ); + }); + test('should return success when no exceptions list provided', async () => { const sampleParams = sampleRuleAlertParams(30); mockService.callCluster diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.ts index 2a0e39cbbf237..e90e5996877f8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.ts @@ -90,23 +90,12 @@ export const searchAfterAndBulkCreate = async ({ createdSignalsCount: 0, }; - let sortId; // tells us where to start our next search_after query - let searchResultSize = 0; + // sortId tells us where to start our next consecutive search_after query + let sortId; - /* - The purpose of `maxResults` is to ensure we do not perform - extra search_after's. This will be reset on each - iteration, although it really only matters for the first - iteration of the loop. - e.g. if maxSignals = 100 but our search result only yields - 27 documents, there is no point in performing another search - since we know there are no more events that match our rule, - and thus, no more signals we could possibly generate. - However, if maxSignals = 500 and our search yields a total - of 3050 results we don't want to make 3050 signals, - we only want 500. So maxResults will help us control how - many times we perform a search_after - */ + // signalsCreatedCount keeps track of how many signals we have created, + // to ensure we don't exceed maxSignals + let signalsCreatedCount = 0; const totalToFromTuples = getSignalTimeTuples({ logger, @@ -118,7 +107,6 @@ export const searchAfterAndBulkCreate = async ({ interval, buildRuleMessage, }); - const useSortIds = totalToFromTuples.length <= 1; logger.debug(buildRuleMessage(`totalToFromTuples: ${totalToFromTuples.length}`)); while (totalToFromTuples.length > 0) { const tuple = totalToFromTuples.pop(); @@ -127,16 +115,18 @@ export const searchAfterAndBulkCreate = async ({ toReturn.success = false; return toReturn; } - searchResultSize = 0; - while (searchResultSize < tuple.maxSignals) { + signalsCreatedCount = 0; + while (signalsCreatedCount < tuple.maxSignals) { try { logger.debug(buildRuleMessage(`sortIds: ${sortId}`)); + + // perform search_after with optionally undefined sortId const { searchResult, searchDuration, }: { searchResult: SignalSearchResponse; searchDuration: string } = await singleSearchAfter( { - searchAfterSortId: useSortIds ? sortId : undefined, + searchAfterSortId: sortId, index: inputIndexPattern, from: tuple.from.toISOString(), to: tuple.to.toISOString(), @@ -149,6 +139,7 @@ export const searchAfterAndBulkCreate = async ({ ); toReturn.searchAfterTimes.push(searchDuration); + // determine if there are any candidate signals to be processed const totalHits = typeof searchResult.hits.total === 'number' ? searchResult.hits.total @@ -157,7 +148,23 @@ export const searchAfterAndBulkCreate = async ({ logger.debug( buildRuleMessage(`searchResult.hit.hits.length: ${searchResult.hits.hits.length}`) ); - if (totalHits === 0) { + + // search results yielded zero hits so exit + // with search_after, these two values can be different when + // searching with the last sortId of a consecutive search_after + // yields zero hits, but there were hits using the previous + // sortIds. + // e.g. totalHits was 156, index 50 of 100 results, do another search-after + // this time with a new sortId, index 22 of the remainding 56, get another sortId + // search with that sortId, total is still 156 but the hits.hits array is empty. + if (totalHits === 0 || searchResult.hits.hits.length === 0) { + logger.debug( + buildRuleMessage( + `${ + totalHits === 0 ? 'totalHits' : 'searchResult.hits.hits.length' + } was 0, exiting and moving on to next tuple` + ) + ); toReturn.success = true; break; } @@ -167,10 +174,10 @@ export const searchAfterAndBulkCreate = async ({ searchResult.hits.hits[searchResult.hits.hits.length - 1]?._source['@timestamp'] ) : null; - searchResultSize += searchResult.hits.hits.length; // filter out the search results that match with the values found in the list. - // the resulting set are valid signals that are not on the allowlist. + // the resulting set are signals to be indexed, given they are not duplicates + // of signals already present in the signals index. const filteredEvents: SignalSearchResponse = listClient != null ? await filterEventsAgainstList({ @@ -181,55 +188,79 @@ export const searchAfterAndBulkCreate = async ({ buildRuleMessage, }) : searchResult; - if (filteredEvents.hits.total === 0 || filteredEvents.hits.hits.length === 0) { - // everything in the events were allowed, so no need to generate signals - toReturn.success = true; - break; - } - const { - bulkCreateDuration: bulkDuration, - createdItemsCount: createdCount, - } = await singleBulkCreate({ - filteredEvents, - ruleParams, - services, - logger, - id, - signalsIndex, - actions, - name, - createdAt, - createdBy, - updatedAt, - updatedBy, - interval, - enabled, - refresh, - tags, - throttle, - }); - logger.debug(buildRuleMessage(`created ${createdCount} signals`)); - toReturn.createdSignalsCount += createdCount; - if (bulkDuration) { - toReturn.bulkCreateTimes.push(bulkDuration); - } + // only bulk create if there are filteredEvents leftover + // if there isn't anything after going through the value list filter + // skip the call to bulk create and proceed to the next search_after, + // if there is a sort id to continue the search_after with. + if (filteredEvents.hits.hits.length !== 0) { + // make sure we are not going to create more signals than maxSignals allows + if (signalsCreatedCount + filteredEvents.hits.hits.length > tuple.maxSignals) { + filteredEvents.hits.hits = filteredEvents.hits.hits.slice( + 0, + tuple.maxSignals - signalsCreatedCount + ); + } + const { + bulkCreateDuration: bulkDuration, + createdItemsCount: createdCount, + } = await singleBulkCreate({ + filteredEvents, + ruleParams, + services, + logger, + id, + signalsIndex, + actions, + name, + createdAt, + createdBy, + updatedAt, + updatedBy, + interval, + enabled, + refresh, + tags, + throttle, + }); + logger.debug(buildRuleMessage(`created ${createdCount} signals`)); + toReturn.createdSignalsCount += createdCount; + signalsCreatedCount += createdCount; + logger.debug(buildRuleMessage(`signalsCreatedCount: ${signalsCreatedCount}`)); + if (bulkDuration) { + toReturn.bulkCreateTimes.push(bulkDuration); + } - logger.debug( - buildRuleMessage(`filteredEvents.hits.hits: ${filteredEvents.hits.hits.length}`) - ); - if (useSortIds && filteredEvents.hits.hits[0].sort == null) { - logger.debug(buildRuleMessage('sortIds was empty on search')); - toReturn.success = true; - break; - } else if ( - useSortIds && - filteredEvents.hits.hits !== null && - filteredEvents.hits.hits[0].sort !== null - ) { - sortId = filteredEvents.hits.hits[0].sort - ? filteredEvents.hits.hits[0].sort[0] - : undefined; + logger.debug( + buildRuleMessage(`filteredEvents.hits.hits: ${filteredEvents.hits.hits.length}`) + ); + + if ( + filteredEvents.hits.hits[0].sort != null && + filteredEvents.hits.hits[0].sort.length !== 0 + ) { + sortId = filteredEvents.hits.hits[0].sort + ? filteredEvents.hits.hits[0].sort[0] + : undefined; + } else { + logger.debug(buildRuleMessage('sortIds was empty on filteredEvents')); + toReturn.success = true; + break; + } + } else { + // we are guaranteed to have searchResult hits at this point + // because we check before if the totalHits or + // searchResult.hits.hits.length is 0 + if ( + searchResult.hits.hits[0].sort != null && + searchResult.hits.hits[0].sort.length !== 0 + ) { + sortId = searchResult.hits.hits[0].sort ? searchResult.hits.hits[0].sort[0] : undefined; + } else { + logger.debug(buildRuleMessage('sortIds was empty on searchResult')); + toReturn.success = true; + break; + } } } catch (exc) { logger.error(buildRuleMessage(`[-] search_after and bulk threw an error ${exc}`)); From 9947c671ecf87eb04dfdf46eecf9d4cf19559534 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Mon, 20 Jul 2020 15:24:32 -0600 Subject: [PATCH 21/77] [Maps] auto-fit to data bounds (#72129) * [Maps] auto-fit to data bounds * update jest snapshot * add buffer to fit to bounds * sync join layers prior to fitting to bounds * clean-up comment * better names * fix tslint errors * update functional test expect * add functional tests * clean-up * change test run location * fix test expect Co-authored-by: Elastic Machine --- .../public/actions/data_request_actions.ts | 23 ++++++- .../maps/public/actions/map_actions.ts | 37 +++++++---- .../blended_vector_layer.ts | 4 ++ .../layers/vector_layer/vector_layer.d.ts | 2 + .../layers/vector_layer/vector_layer.js | 22 +++++-- .../navigation_panel.test.tsx.snap | 66 +++++++++++++++++++ .../map_settings_panel/map_settings_panel.tsx | 1 + .../map_settings_panel/navigation_panel.tsx | 20 ++++++ .../maps/public/elasticsearch_geo_utils.d.ts | 9 +++ .../maps/public/elasticsearch_geo_utils.js | 11 ++++ .../public/elasticsearch_geo_utils.test.js | 18 +++++ .../public/reducers/default_map_settings.ts | 1 + x-pack/plugins/maps/public/reducers/map.d.ts | 1 + .../apps/maps/auto_fit_to_bounds.js | 35 ++++++++++ .../apps/maps/documents_source/search_hits.js | 2 +- x-pack/test/functional/apps/maps/index.js | 1 + .../test/functional/page_objects/gis_page.js | 18 +++++ 17 files changed, 249 insertions(+), 22 deletions(-) create mode 100644 x-pack/plugins/maps/public/elasticsearch_geo_utils.d.ts create mode 100644 x-pack/test/functional/apps/maps/auto_fit_to_bounds.js diff --git a/x-pack/plugins/maps/public/actions/data_request_actions.ts b/x-pack/plugins/maps/public/actions/data_request_actions.ts index a0c484a82e530..5919feadfcc2a 100644 --- a/x-pack/plugins/maps/public/actions/data_request_actions.ts +++ b/x-pack/plugins/maps/public/actions/data_request_actions.ts @@ -37,8 +37,12 @@ import { UPDATE_SOURCE_DATA_REQUEST, } from './map_action_constants'; import { ILayer } from '../classes/layers/layer'; +import { IVectorLayer } from '../classes/layers/vector_layer/vector_layer'; import { DataMeta, MapExtent, MapFilters } from '../../common/descriptor_types'; import { DataRequestAbortError } from '../classes/util/data_request'; +import { scaleBounds } from '../elasticsearch_geo_utils'; + +const FIT_TO_BOUNDS_SCALE_FACTOR = 0.1; export type DataRequestContext = { startLoading(dataId: string, requestToken: symbol, meta: DataMeta): void; @@ -122,13 +126,26 @@ function getDataRequestContext( export function syncDataForAllLayers() { return async (dispatch: Dispatch, getState: () => MapStoreState) => { - const syncPromises = getLayerList(getState()).map(async (layer) => { + const syncPromises = getLayerList(getState()).map((layer) => { return dispatch(syncDataForLayer(layer)); }); await Promise.all(syncPromises); }; } +export function syncDataForAllJoinLayers() { + return async (dispatch: Dispatch, getState: () => MapStoreState) => { + const syncPromises = getLayerList(getState()) + .filter((layer) => { + return 'hasJoins' in layer ? (layer as IVectorLayer).hasJoins() : false; + }) + .map((layer) => { + return dispatch(syncDataForLayer(layer)); + }); + await Promise.all(syncPromises); + }; +} + export function syncDataForLayer(layer: ILayer) { return async (dispatch: Dispatch, getState: () => MapStoreState) => { const dataRequestContext = getDataRequestContext(dispatch, getState, layer.getId()); @@ -284,7 +301,7 @@ export function fitToLayerExtent(layerId: string) { getDataRequestContext(dispatch, getState, layerId) ); if (bounds) { - await dispatch(setGotoWithBounds(bounds)); + await dispatch(setGotoWithBounds(scaleBounds(bounds, FIT_TO_BOUNDS_SCALE_FACTOR))); } } catch (error) { if (!(error instanceof DataRequestAbortError)) { @@ -359,7 +376,7 @@ export function fitToDataBounds() { maxLat: turfUnionBbox[3], }; - dispatch(setGotoWithBounds(dataBounds)); + dispatch(setGotoWithBounds(scaleBounds(dataBounds, FIT_TO_BOUNDS_SCALE_FACTOR))); }; } diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index 75df8689a670e..ef0cfdf0b4742 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -8,11 +8,13 @@ import { Dispatch } from 'redux'; // @ts-ignore import turf from 'turf'; +import uuid from 'uuid/v4'; import turfBooleanContains from '@turf/boolean-contains'; import { Filter, Query, TimeRange } from 'src/plugins/data/public'; import { MapStoreState } from '../reducers/store'; import { getDataFilters, + getMapSettings, getWaitingForMapReadyLayerListRaw, getQuery, } from '../selectors/map_selectors'; @@ -42,7 +44,11 @@ import { UPDATE_DRAW_STATE, UPDATE_MAP_SETTING, } from './map_action_constants'; -import { syncDataForAllLayers } from './data_request_actions'; +import { + fitToDataBounds, + syncDataForAllJoinLayers, + syncDataForAllLayers, +} from './data_request_actions'; import { addLayer } from './layer_actions'; import { MapSettings } from '../reducers/map'; import { @@ -51,6 +57,7 @@ import { MapExtent, MapRefreshConfig, } from '../../common/descriptor_types'; +import { scaleBounds } from '../elasticsearch_geo_utils'; export function setMapInitError(errorMessage: string) { return { @@ -134,15 +141,7 @@ export function mapExtentChanged(newMapConstants: { zoom: number; extent: MapExt } if (!doesBufferContainExtent || currentZoom !== newZoom) { - const scaleFactor = 0.5; // TODO put scale factor in store and fetch with selector - const width = extent.maxLon - extent.minLon; - const height = extent.maxLat - extent.minLat; - dataFilters.buffer = { - minLon: extent.minLon - width * scaleFactor, - minLat: extent.minLat - height * scaleFactor, - maxLon: extent.maxLon + width * scaleFactor, - maxLat: extent.maxLat + height * scaleFactor, - }; + dataFilters.buffer = scaleBounds(extent, 0.5); } } @@ -197,6 +196,7 @@ function generateQueryTimestamp() { return new Date().toISOString(); } +let lastSetQueryCallId: string = ''; export function setQuery({ query, timeFilters, @@ -226,7 +226,22 @@ export function setQuery({ filters, }); - await dispatch(syncDataForAllLayers()); + if (getMapSettings(getState()).autoFitToDataBounds) { + // Joins are performed on the client. + // As a result, bounds for join layers must also be performed on the client. + // Therefore join layers need to fetch data prior to auto fitting bounds. + const localSetQueryCallId = uuid(); + lastSetQueryCallId = localSetQueryCallId; + await dispatch(syncDataForAllJoinLayers()); + + // setQuery can be triggered before async data fetching completes + // Only continue execution path if setQuery has not been re-triggered. + if (localSetQueryCallId === lastSetQueryCallId) { + dispatch(fitToDataBounds()); + } + } else { + await dispatch(syncDataForAllLayers()); + } }; } diff --git a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts index aefa2beede7d1..c0b9c4553d01e 100644 --- a/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts +++ b/x-pack/plugins/maps/public/classes/layers/blended_vector_layer/blended_vector_layer.ts @@ -237,6 +237,10 @@ export class BlendedVectorLayer extends VectorLayer implements IVectorLayer { return []; } + hasJoins() { + return false; + } + getSource() { return this._isClustered ? this._clusterSource : this._documentSource; } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts index 77daf9c9af570..e6cb212daddae 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts @@ -35,6 +35,7 @@ export interface IVectorLayer extends ILayer { getStyle(): IVectorStyle; getFeatureById(id: string | number): Feature | null; getPropertiesForTooltip(properties: GeoJsonProperties): Promise; + hasJoins(): boolean; } export class VectorLayer extends AbstractLayer implements IVectorLayer { @@ -81,4 +82,5 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { getStyle(): IVectorStyle; getFeatureById(id: string | number): Feature | null; getPropertiesForTooltip(properties: GeoJsonProperties): Promise; + hasJoins(): boolean; } diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js index 0a4fcfc23060c..23889bdca2dd7 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.js @@ -85,7 +85,7 @@ export class VectorLayer extends AbstractLayer { }); } - _hasJoins() { + hasJoins() { return this.getValidJoins().length > 0; } @@ -159,7 +159,7 @@ export class VectorLayer extends AbstractLayer { async getBounds({ startLoading, stopLoading, registerCancelCallback, dataFilters }) { const isStaticLayer = !this.getSource().isBoundsAware(); if (isStaticLayer) { - return getFeatureCollectionBounds(this._getSourceFeatureCollection(), this._hasJoins()); + return getFeatureCollectionBounds(this._getSourceFeatureCollection(), this.hasJoins()); } const requestToken = Symbol(`${SOURCE_BOUNDS_DATA_REQUEST_ID}-${this.getId()}`); @@ -193,6 +193,11 @@ export class VectorLayer extends AbstractLayer { return bounds; } + isLoadingBounds() { + const boundsDataRequest = this.getDataRequest(SOURCE_BOUNDS_DATA_REQUEST_ID); + return !!boundsDataRequest && boundsDataRequest.isLoading(); + } + async getLeftJoinFields() { return await this.getSource().getLeftJoinFields(); } @@ -583,7 +588,7 @@ export class VectorLayer extends AbstractLayer { } async syncData(syncContext) { - this._syncData(syncContext, this.getSource(), this.getCurrentStyle()); + await this._syncData(syncContext, this.getSource(), this.getCurrentStyle()); } // TLDR: Do not call getSource or getCurrentStyle in syncData flow. Use 'source' and 'style' arguments instead. @@ -597,13 +602,16 @@ export class VectorLayer extends AbstractLayer { // Given 2 above, which source/style to use can not be pulled from data request state. // Therefore, source and style are provided as arugments and must be used instead of calling getSource or getCurrentStyle. async _syncData(syncContext, source, style) { + if (this.isLoadingBounds()) { + return; + } await this._syncSourceStyleMeta(syncContext, source, style); await this._syncSourceFormatters(syncContext, source, style); const sourceResult = await this._syncSource(syncContext, source, style); if ( !sourceResult.featureCollection || !sourceResult.featureCollection.features.length || - !this._hasJoins() + !this.hasJoins() ) { return; } @@ -711,7 +719,7 @@ export class VectorLayer extends AbstractLayer { mbMap.addLayer(mbLayer); } - const filterExpr = getPointFilterExpression(this._hasJoins()); + const filterExpr = getPointFilterExpression(this.hasJoins()); if (filterExpr !== mbMap.getFilter(pointLayerId)) { mbMap.setFilter(pointLayerId, filterExpr); mbMap.setFilter(textLayerId, filterExpr); @@ -747,7 +755,7 @@ export class VectorLayer extends AbstractLayer { mbMap.addLayer(mbLayer); } - const filterExpr = getPointFilterExpression(this._hasJoins()); + const filterExpr = getPointFilterExpression(this.hasJoins()); if (filterExpr !== mbMap.getFilter(symbolLayerId)) { mbMap.setFilter(symbolLayerId, filterExpr); } @@ -769,7 +777,7 @@ export class VectorLayer extends AbstractLayer { const sourceId = this.getId(); const fillLayerId = this._getMbPolygonLayerId(); const lineLayerId = this._getMbLineLayerId(); - const hasJoins = this._hasJoins(); + const hasJoins = this.hasJoins(); if (!mbMap.getLayer(fillLayerId)) { const mbLayer = { id: fillLayerId, diff --git a/x-pack/plugins/maps/public/connected_components/map_settings_panel/__snapshots__/navigation_panel.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/map_settings_panel/__snapshots__/navigation_panel.test.tsx.snap index 641dd20a1a44a..18e30d9446e05 100644 --- a/x-pack/plugins/maps/public/connected_components/map_settings_panel/__snapshots__/navigation_panel.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/map_settings_panel/__snapshots__/navigation_panel.test.tsx.snap @@ -16,6 +16,25 @@ exports[`should render 1`] = ` + + + + + + + + + + + + + + + { + updateMapSetting('autoFitToDataBounds', event.target.checked); + }; + const onZoomChange = (value: Value) => { const minZoom = Math.max(MIN_ZOOM, parseInt(value[0] as string, 10)); const maxZoom = Math.min(MAX_ZOOM, parseInt(value[1] as string, 10)); @@ -207,6 +213,19 @@ export function NavigationPanel({ center, settings, updateMapSetting, zoom }: Pr + + + + + + { expect(bbox).toEqual({ bottom_right: [-170, -89], top_left: [-175, 89] }); }); }); + +describe('scaleBounds', () => { + it('Should scale bounds', () => { + const bounds = { + maxLat: 10, + maxLon: 100, + minLat: 5, + minLon: 95, + }; + expect(scaleBounds(bounds, 0.5)).toEqual({ + maxLat: 12.5, + maxLon: 102.5, + minLat: 2.5, + minLon: 92.5, + }); + }); +}); diff --git a/x-pack/plugins/maps/public/reducers/default_map_settings.ts b/x-pack/plugins/maps/public/reducers/default_map_settings.ts index 9c9b814ae6add..896ac11e36782 100644 --- a/x-pack/plugins/maps/public/reducers/default_map_settings.ts +++ b/x-pack/plugins/maps/public/reducers/default_map_settings.ts @@ -9,6 +9,7 @@ import { MapSettings } from './map'; export function getDefaultMapSettings(): MapSettings { return { + autoFitToDataBounds: false, initialLocation: INITIAL_LOCATION.LAST_SAVED_LOCATION, fixedLocation: { lat: 0, lon: 0, zoom: 2 }, browserLocation: { zoom: 2 }, diff --git a/x-pack/plugins/maps/public/reducers/map.d.ts b/x-pack/plugins/maps/public/reducers/map.d.ts index 33794fcf8657d..aca75334032d9 100644 --- a/x-pack/plugins/maps/public/reducers/map.d.ts +++ b/x-pack/plugins/maps/public/reducers/map.d.ts @@ -42,6 +42,7 @@ export type MapContext = { }; export type MapSettings = { + autoFitToDataBounds: boolean; initialLocation: INITIAL_LOCATION; fixedLocation: { lat: number; diff --git a/x-pack/test/functional/apps/maps/auto_fit_to_bounds.js b/x-pack/test/functional/apps/maps/auto_fit_to_bounds.js new file mode 100644 index 0000000000000..64c07273c9ccf --- /dev/null +++ b/x-pack/test/functional/apps/maps/auto_fit_to_bounds.js @@ -0,0 +1,35 @@ +/* + * 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 expect from '@kbn/expect'; + +export default function ({ getPageObjects }) { + const PageObjects = getPageObjects(['maps']); + + describe('auto fit map to bounds', () => { + describe('without joins', () => { + before(async () => { + await PageObjects.maps.loadSavedMap('document example'); + await PageObjects.maps.enableAutoFitToBounds(); + }); + + it('should automatically fit to bounds when query is applied', async () => { + // Set view to other side of world so no matching results + await PageObjects.maps.setView(-15, -100, 6); + + // Setting query should trigger fit to bounds and move map + const origView = await PageObjects.maps.getView(); + await PageObjects.maps.setAndSubmitQuery('machine.os.raw : "ios"'); + await PageObjects.maps.waitForMapPanAndZoom(origView); + + const { lat, lon, zoom } = await PageObjects.maps.getView(); + expect(Math.round(lat)).to.equal(43); + expect(Math.round(lon)).to.equal(-102); + expect(Math.round(zoom)).to.equal(5); + }); + }); + }); +} diff --git a/x-pack/test/functional/apps/maps/documents_source/search_hits.js b/x-pack/test/functional/apps/maps/documents_source/search_hits.js index 5d75679432c97..cc0f3a7df32de 100644 --- a/x-pack/test/functional/apps/maps/documents_source/search_hits.js +++ b/x-pack/test/functional/apps/maps/documents_source/search_hits.js @@ -103,7 +103,7 @@ export default function ({ getPageObjects, getService }) { await PageObjects.maps.setView(-15, -100, 6); await PageObjects.maps.clickFitToBounds('logstash'); const { lat, lon, zoom } = await PageObjects.maps.getView(); - expect(Math.round(lat)).to.equal(42); + expect(Math.round(lat)).to.equal(43); expect(Math.round(lon)).to.equal(-102); expect(Math.round(zoom)).to.equal(5); }); diff --git a/x-pack/test/functional/apps/maps/index.js b/x-pack/test/functional/apps/maps/index.js index 15928170972d9..d0735aecda78b 100644 --- a/x-pack/test/functional/apps/maps/index.js +++ b/x-pack/test/functional/apps/maps/index.js @@ -34,6 +34,7 @@ export default function ({ loadTestFile, getService }) { loadTestFile(require.resolve('./vector_styling')); loadTestFile(require.resolve('./saved_object_management')); loadTestFile(require.resolve('./sample_data')); + loadTestFile(require.resolve('./auto_fit_to_bounds')); loadTestFile(require.resolve('./feature_controls/maps_security')); loadTestFile(require.resolve('./feature_controls/maps_spaces')); loadTestFile(require.resolve('./full_screen_mode')); diff --git a/x-pack/test/functional/page_objects/gis_page.js b/x-pack/test/functional/page_objects/gis_page.js index ff50415d3066e..8a0b4aaefa888 100644 --- a/x-pack/test/functional/page_objects/gis_page.js +++ b/x-pack/test/functional/page_objects/gis_page.js @@ -656,6 +656,24 @@ export function GisPageProvider({ getService, getPageObjects }) { async getCategorySuggestions() { return await comboBox.getOptionsList(`colorStopInput1`); } + + async enableAutoFitToBounds() { + await testSubjects.click('openSettingsButton'); + const isEnabled = await testSubjects.getAttribute('autoFitToDataBoundsSwitch', 'checked'); + if (!isEnabled) { + await retry.try(async () => { + await testSubjects.click('autoFitToDataBoundsSwitch'); + const ensureEnabled = await testSubjects.getAttribute( + 'autoFitToDataBoundsSwitch', + 'checked' + ); + if (!ensureEnabled) { + throw new Error('autoFitToDataBoundsSwitch is not enabled'); + } + }); + } + await testSubjects.click('mapSettingSubmitButton'); + } } return new GisPage(); } From c3263aa9a2d046ba23edf8cbd9fdc86420d5faeb Mon Sep 17 00:00:00 2001 From: Kevin Qualters <56408403+kqualters-elastic@users.noreply.github.com> Date: Mon, 20 Jul 2020 17:41:25 -0400 Subject: [PATCH 22/77] [Security Solution][Resolver] Update the resolver element ref on scroll events if the position of the element has changed within the page (#72461) --- .../public/resolver/view/use_camera.ts | 54 +++++++++++++++++-- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/resolver/view/use_camera.ts b/x-pack/plugins/security_solution/public/resolver/view/use_camera.ts index 6a1c35be57000..661e038d04e32 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/use_camera.ts +++ b/x-pack/plugins/security_solution/public/resolver/view/use_camera.ts @@ -281,17 +281,61 @@ export function useCamera(): { * handle that. */ export function useAutoUpdatingClientRect(): [DOMRect | null, (node: Element | null) => void] { + // This hooks returns `rect`. const [rect, setRect] = useState(null); - // Using state as ref.current update does not trigger effect hook when reset + + const { ResizeObserver, requestAnimationFrame } = useContext(SideEffectContext); + + // Keep the current DOM node in state so that we can create a ResizeObserver for it via `useEffect`. const [currentNode, setCurrentNode] = useState(null); + // `ref` will be used with a react element. When the element is available, this function will be called. const ref = useCallback((node: Element | null) => { + // track the node in state setCurrentNode(node); - if (node !== null) { - setRect(node.getBoundingClientRect()); - } }, []); - const { ResizeObserver } = useContext(SideEffectContext); + + /** + * Any time the DOM node changes (to something other than `null`) recalculate the DOMRect and set it (which will cause it to be returned from the hook. + * This effect re-runs when the DOM node has changed. + */ + useEffect(() => { + if (currentNode !== null) { + // When the DOM node is received, immedaiately calculate its DOM Rect and return that + setRect(currentNode.getBoundingClientRect()); + } + }, [currentNode]); + + /** + * When scroll events occur, recalculate the DOMRect. DOMRect represents the position of an element relative to the viewport, so that may change during scroll (depending on the layout.) + * This effect re-runs when the DOM node has changed. + */ + useEffect(() => { + // the last scrollX and scrollY values that we handled + let previousX: number = window.scrollX; + let previousY: number = window.scrollY; + + const handleScroll = () => { + requestAnimationFrame(() => { + // synchronously read from the DOM + const currentX = window.scrollX; + const currentY = window.scrollY; + + if (currentNode !== null && (previousX !== currentX || previousY !== currentY)) { + setRect(currentNode.getBoundingClientRect()); + } + + previousX = currentX; + previousY = currentY; + }); + }; + + window.addEventListener('scroll', handleScroll, { passive: true }); + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, [currentNode, requestAnimationFrame]); + useEffect(() => { if (currentNode !== null) { const resizeObserver = new ResizeObserver((entries) => { From a221e04b3caa161cccef45985032c403f74fb974 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 20 Jul 2020 15:06:02 -0700 Subject: [PATCH 23/77] [pipeline/commitStatus] update commit status in baseline-capture job (#72366) Co-authored-by: spalger --- .ci/Jenkinsfile_baseline_capture | 36 ++++++++++--------- .../src/test/githubCommitStatus.groovy | 2 ++ vars/githubCommitStatus.groovy | 34 +++++++++++------- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/.ci/Jenkinsfile_baseline_capture b/.ci/Jenkinsfile_baseline_capture index 3f90a6bc05af0..b0d3591821642 100644 --- a/.ci/Jenkinsfile_baseline_capture +++ b/.ci/Jenkinsfile_baseline_capture @@ -4,23 +4,25 @@ library 'kibana-pipeline-library' kibanaLibrary.load() kibanaPipeline(timeoutMinutes: 120) { - ciStats.trackBuild { - catchError { - parallel([ - 'oss-visualRegression': { - workers.ci(name: 'oss-visualRegression', size: 's-highmem', ramDisk: true) { - kibanaPipeline.functionalTestProcess('oss-visualRegression', './test/scripts/jenkins_visual_regression.sh')(1) - } - }, - 'xpack-visualRegression': { - workers.ci(name: 'xpack-visualRegression', size: 's-highmem', ramDisk: true) { - kibanaPipeline.functionalTestProcess('xpack-visualRegression', './test/scripts/jenkins_xpack_visual_regression.sh')(1) - } - }, - ]) - } + githubCommitStatus.trackBuild(params.commit, 'kibana-ci-baseline') { + ciStats.trackBuild { + catchError { + parallel([ + 'oss-visualRegression': { + workers.ci(name: 'oss-visualRegression', size: 's-highmem', ramDisk: true) { + kibanaPipeline.functionalTestProcess('oss-visualRegression', './test/scripts/jenkins_visual_regression.sh')(1) + } + }, + 'xpack-visualRegression': { + workers.ci(name: 'xpack-visualRegression', size: 's-highmem', ramDisk: true) { + kibanaPipeline.functionalTestProcess('xpack-visualRegression', './test/scripts/jenkins_xpack_visual_regression.sh')(1) + } + }, + ]) + } - kibanaPipeline.sendMail() - slackNotifications.onFailure() + kibanaPipeline.sendMail() + slackNotifications.onFailure() + } } } diff --git a/.ci/pipeline-library/src/test/githubCommitStatus.groovy b/.ci/pipeline-library/src/test/githubCommitStatus.groovy index 17878624b73cf..c770d5596f9cb 100644 --- a/.ci/pipeline-library/src/test/githubCommitStatus.groovy +++ b/.ci/pipeline-library/src/test/githubCommitStatus.groovy @@ -12,6 +12,7 @@ class GithubCommitStatusTest extends KibanaBasePipelineTest { interface BuildState { Object get(String key) + Object has(String key) } interface GithubApi { @@ -25,6 +26,7 @@ class GithubCommitStatusTest extends KibanaBasePipelineTest { buildStateMock = mock(BuildState) githubApiMock = mock(GithubApi) + when(buildStateMock.has('checkoutInfo')).thenReturn(true) when(buildStateMock.get('checkoutInfo')).thenReturn([ commit: 'COMMIT_HASH', ]) when(githubApiMock.post(any(), any())).thenReturn(null) diff --git a/vars/githubCommitStatus.groovy b/vars/githubCommitStatus.groovy index 17d3c234f6928..248d226169a61 100644 --- a/vars/githubCommitStatus.groovy +++ b/vars/githubCommitStatus.groovy @@ -1,39 +1,47 @@ -def shouldCreateStatuses() { - return !githubPr.isPr() && buildState.get('checkoutInfo') +def defaultCommit() { + if (buildState.has('checkoutInfo')) { + return buildState.get('checkoutInfo').commit + } } -def onStart() { +def onStart(commit = defaultCommit(), context = 'kibana-ci') { catchError { - if (!shouldCreateStatuses()) { + if (githubPr.isPr() || !commit) { return } - def checkoutInfo = buildState.get('checkoutInfo') - create(checkoutInfo.commit, 'pending', 'Build started.') + create(commit, 'pending', 'Build started.', context) } } -def onFinish() { +def onFinish(commit = defaultCommit(), context = 'kibana-ci') { catchError { - if (!shouldCreateStatuses()) { + if (githubPr.isPr() || !commit) { return } - def checkoutInfo = buildState.get('checkoutInfo') def status = buildUtils.getBuildStatus() if (status == 'SUCCESS' || status == 'UNSTABLE') { - create(checkoutInfo.commit, 'success', 'Build completed successfully.') + create(commit, 'success', 'Build completed successfully.', context) } else if(status == 'ABORTED') { - create(checkoutInfo.commit, 'error', 'Build aborted or timed out.') + create(commit, 'error', 'Build aborted or timed out.', context) } else { - create(checkoutInfo.commit, 'error', 'Build failed.') + create(commit, 'error', 'Build failed.', context) } } } +def trackBuild(commit, context, Closure closure) { + onStart(commit, context) + catchError { + closure() + } + onFinish(commit, context) +} + // state: error|failure|pending|success -def create(sha, state, description, context = 'kibana-ci') { +def create(sha, state, description, context) { withGithubCredentials { return githubApi.post("repos/elastic/kibana/statuses/${sha}", [ state: state, From 709e0a0a11fa5c87106c0d1ebc06cebc81b9caea Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Mon, 20 Jul 2020 15:16:46 -0700 Subject: [PATCH 24/77] Fix long combo box items breaking out of flex item width (#72512) --- .../components/package_config_input_stream.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/components/package_config_input_stream.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/components/package_config_input_stream.tsx index 11a9df276485b..04a0f4e6dbb74 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/components/package_config_input_stream.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/components/package_config_input_stream.tsx @@ -5,6 +5,7 @@ */ import React, { useState, Fragment, memo, useMemo } from 'react'; import ReactMarkdown from 'react-markdown'; +import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFlexGrid, @@ -23,6 +24,10 @@ import { } from '../services'; import { PackageConfigInputVarField } from './package_config_input_var_field'; +const FlexItemWithMaxWidth = styled(EuiFlexItem)` + max-width: calc(50% - ${(props) => props.theme.eui.euiSizeL}); +`; + export const PackageConfigInputStreamConfig: React.FunctionComponent<{ packageInputStream: RegistryStream; packageConfigInputStream: PackageConfigInputStream; @@ -91,7 +96,7 @@ export const PackageConfigInputStreamConfig: React.FunctionComponent<{ - + {requiredVars.map((varDef) => { const { name: varName, type: varType } = varDef; @@ -178,7 +183,7 @@ export const PackageConfigInputStreamConfig: React.FunctionComponent<{ ) : null} - + ); } From 03fe8c3e89b273d0c1b1d82b6951d6a682969242 Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Mon, 20 Jul 2020 16:23:38 -0600 Subject: [PATCH 25/77] [SIEM] Uses faster wait from testing-library and removes duplicate older wait idiom (#72509) ## Summary * Removes the older wait pattern that does a block no matter what * Utilizes the improved and better pattern for test-library's waitFor which will test immediately and then poll for results * Changes everything to put their expect statement within the waitFor * Once the waitFor is in TypeScript/JS we can change the import statement to use that If you get a timeout or error this is what it looks like now which improves the developer experience in some ways but does degrade things in others as it suggests that everything is timeout related. However, developers should inspect the values and remove the waitFor() and re-run their tests if they think that they have a real problem during development. Screen Shot 2020-07-20 at 12 40 39 PM See the API for more information: https://testing-library.com/docs/dom-testing-library/api-async#waitfor But in short we should be using: ```ts await waitFor(() => expect(...)); ``` throughout our code at this point and the waitFor will loop quickly and efficiently until it either times out or gets the condition expected. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios --- .../components/add_comment/index.test.tsx | 13 +- .../cases/components/case_view/index.test.tsx | 125 +++---- .../cases/components/create/index.test.tsx | 7 +- .../components/edit_connector/index.test.tsx | 26 +- .../cases/components/tag_list/index.test.tsx | 13 +- .../user_action_tree/index.test.tsx | 55 ++-- .../events_viewer/events_viewer.test.tsx | 70 ++-- .../components/events_viewer/index.test.tsx | 17 +- .../components/url_state/index.test.tsx | 42 +-- .../public/common/lib/helpers/index.tsx | 6 - .../rules/step_about_rule/index.test.tsx | 105 +++--- .../detection_engine/rules/all/index.test.tsx | 21 +- .../first_last_seen_host/index.test.tsx | 58 ++-- .../alerts_by_category/index.test.tsx | 63 ++-- .../components/overview_host/index.test.tsx | 14 +- .../overview_network/index.test.tsx | 14 +- .../components/open_timeline/index.test.tsx | 304 +++++++++--------- .../open_timeline_modal/index.test.tsx | 18 +- .../open_timeline_modal_button.test.tsx | 25 +- .../components/timeline/body/index.test.tsx | 24 +- .../components/timeline/index.test.tsx | 25 +- .../timeline/epic_local_storage.test.tsx | 24 +- 22 files changed, 578 insertions(+), 491 deletions(-) diff --git a/x-pack/plugins/security_solution/public/cases/components/add_comment/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/add_comment/index.test.tsx index 5da75033d17fa..88969c3ae5fb3 100644 --- a/x-pack/plugins/security_solution/public/cases/components/add_comment/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/add_comment/index.test.tsx @@ -15,7 +15,9 @@ import { Router, routeData, mockHistory, mockLocation } from '../__mock__/router import { useInsertTimeline } from '../../../timelines/components/timeline/insert_timeline_popover/use_insert_timeline'; import { usePostComment } from '../../containers/use_post_comment'; import { useForm } from '../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form'; -import { wait } from '../../../common/lib/helpers'; + +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; jest.mock( '../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form' @@ -84,10 +86,11 @@ describe('AddComment ', () => { expect(wrapper.find(`[data-test-subj="loading-spinner"]`).exists()).toBeFalsy(); wrapper.find(`[data-test-subj="submit-comment"]`).first().simulate('click'); - await wait(); - expect(onCommentSaving).toBeCalled(); - expect(postComment).toBeCalledWith(sampleData, onCommentPosted); - expect(formHookMock.reset).toBeCalled(); + await waitFor(() => { + expect(onCommentSaving).toBeCalled(); + expect(postComment).toBeCalledWith(sampleData, onCommentPosted); + expect(formHookMock.reset).toBeCalled(); + }); }); it('should render spinner and disable submit when loading', () => { diff --git a/x-pack/plugins/security_solution/public/cases/components/case_view/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/case_view/index.test.tsx index 4e29db4022e65..278b972ada970 100644 --- a/x-pack/plugins/security_solution/public/cases/components/case_view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/case_view/index.test.tsx @@ -15,7 +15,9 @@ import { TestProviders } from '../../../common/mock'; import { useUpdateCase } from '../../containers/use_update_case'; import { useGetCase } from '../../containers/use_get_case'; import { useGetCaseUserActions } from '../../containers/use_get_case_user_actions'; -import { wait } from '../../../common/lib/helpers'; + +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { useConnectors } from '../../containers/configure/use_connectors'; import { connectorsMock } from '../../containers/configure/mock'; @@ -108,30 +110,33 @@ describe('CaseView ', () => { ); - await wait(); - expect(wrapper.find(`[data-test-subj="case-view-title"]`).first().prop('title')).toEqual( - data.title - ); - expect(wrapper.find(`[data-test-subj="case-view-status"]`).first().text()).toEqual(data.status); - expect( - wrapper - .find(`[data-test-subj="case-view-tag-list"] [data-test-subj="case-tag"]`) - .first() - .text() - ).toEqual(data.tags[0]); - expect(wrapper.find(`[data-test-subj="case-view-username"]`).first().text()).toEqual( - data.createdBy.username - ); - expect(wrapper.contains(`[data-test-subj="case-view-closedAt"]`)).toBe(false); - expect(wrapper.find(`[data-test-subj="case-view-createdAt"]`).first().prop('value')).toEqual( - data.createdAt - ); - expect( - wrapper - .find(`[data-test-subj="description-action"] [data-test-subj="user-action-markdown"]`) - .first() - .prop('raw') - ).toEqual(data.description); + await waitFor(() => { + expect(wrapper.find(`[data-test-subj="case-view-title"]`).first().prop('title')).toEqual( + data.title + ); + expect(wrapper.find(`[data-test-subj="case-view-status"]`).first().text()).toEqual( + data.status + ); + expect( + wrapper + .find(`[data-test-subj="case-view-tag-list"] [data-test-subj="case-tag"]`) + .first() + .text() + ).toEqual(data.tags[0]); + expect(wrapper.find(`[data-test-subj="case-view-username"]`).first().text()).toEqual( + data.createdBy.username + ); + expect(wrapper.contains(`[data-test-subj="case-view-closedAt"]`)).toBe(false); + expect(wrapper.find(`[data-test-subj="case-view-createdAt"]`).first().prop('value')).toEqual( + data.createdAt + ); + expect( + wrapper + .find(`[data-test-subj="description-action"] [data-test-subj="user-action-markdown"]`) + .first() + .prop('raw') + ).toEqual(data.description); + }); }); it('should show closed indicators in header when case is closed', async () => { @@ -146,14 +151,15 @@ describe('CaseView ', () => { ); - await wait(); - expect(wrapper.contains(`[data-test-subj="case-view-createdAt"]`)).toBe(false); - expect(wrapper.find(`[data-test-subj="case-view-closedAt"]`).first().prop('value')).toEqual( - basicCaseClosed.closedAt - ); - expect(wrapper.find(`[data-test-subj="case-view-status"]`).first().text()).toEqual( - basicCaseClosed.status - ); + await waitFor(() => { + expect(wrapper.contains(`[data-test-subj="case-view-createdAt"]`)).toBe(false); + expect(wrapper.find(`[data-test-subj="case-view-closedAt"]`).first().prop('value')).toEqual( + basicCaseClosed.closedAt + ); + expect(wrapper.find(`[data-test-subj="case-view-status"]`).first().text()).toEqual( + basicCaseClosed.status + ); + }); }); it('should dispatch update state when button is toggled', async () => { @@ -164,11 +170,12 @@ describe('CaseView ', () => { ); - await wait(); - wrapper - .find('input[data-test-subj="toggle-case-status"]') - .simulate('change', { target: { checked: true } }); - expect(updateCaseProperty).toHaveBeenCalled(); + await waitFor(() => { + wrapper + .find('input[data-test-subj="toggle-case-status"]') + .simulate('change', { target: { checked: true } }); + expect(updateCaseProperty).toHaveBeenCalled(); + }); }); it('should display EditableTitle isLoading', () => { @@ -296,17 +303,17 @@ describe('CaseView ', () => { ); - await wait(); + await waitFor(() => { + expect( + wrapper.find('[data-test-subj="has-data-to-push-button"]').first().exists() + ).toBeTruthy(); - expect( - wrapper.find('[data-test-subj="has-data-to-push-button"]').first().exists() - ).toBeTruthy(); + wrapper.find('[data-test-subj="push-to-external-service"]').first().simulate('click'); - wrapper.find('[data-test-subj="push-to-external-service"]').first().simulate('click'); + wrapper.update(); - wrapper.update(); - - expect(postPushToService).toHaveBeenCalled(); + expect(postPushToService).toHaveBeenCalled(); + }); }); it('should return null if error', () => { @@ -424,17 +431,19 @@ describe('CaseView ', () => { ); - await wait(); - wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); - wrapper.update(); - wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); - wrapper.update(); - wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click'); - wrapper.update(); - await wait(); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="dropdown-connectors"]').at(0).prop('valueOfSelected') - ).toBe('servicenow-1'); + await waitFor(() => { + wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); + wrapper.update(); + wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); + wrapper.update(); + wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click'); + wrapper.update(); + }); + await waitFor(() => { + wrapper.update(); + expect( + wrapper.find('[data-test-subj="dropdown-connectors"]').at(0).prop('valueOfSelected') + ).toBe('servicenow-1'); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx index 25c12a53f2f5b..aefb196e0678d 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx @@ -19,7 +19,9 @@ import { useGetTags } from '../../containers/use_get_tags'; jest.mock('../../../timelines/components/timeline/insert_timeline_popover/use_insert_timeline'); jest.mock('../../containers/use_post_case'); import { useForm } from '../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form'; -import { wait } from '../../../common/lib/helpers'; + +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; jest.mock( '../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form' @@ -97,8 +99,7 @@ describe('Create case', () => { ); wrapper.find(`[data-test-subj="create-case-submit"]`).first().simulate('click'); - await wait(); - expect(postCase).toBeCalledWith(sampleData); + await waitFor(() => expect(postCase).toBeCalledWith(sampleData)); }); it('should redirect to all cases on cancel click', () => { diff --git a/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.test.tsx index 564ce2e19df00..e531b71e8c90c 100644 --- a/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.test.tsx @@ -11,7 +11,8 @@ import { EditConnector } from './index'; import { getFormMock, useFormMock } from '../__mock__/form'; import { TestProviders } from '../../../common/mock'; import { connectorsMock } from '../../containers/configure/mock'; -import { wait } from '../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { act } from 'react-dom/test-utils'; jest.mock( '../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form' @@ -68,8 +69,7 @@ describe('EditConnector ', () => { await act(async () => { wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click'); - await wait(); - expect(onSubmit.mock.calls[0][0]).toBe(sampleConnector); + await waitFor(() => expect(onSubmit.mock.calls[0][0]).toBe(sampleConnector)); }); }); @@ -92,10 +92,11 @@ describe('EditConnector ', () => { await act(async () => { wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click'); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); + expect(formHookMock.setFieldValue).toHaveBeenCalledWith('connector', 'none'); + }); }); - expect(formHookMock.setFieldValue).toHaveBeenCalledWith('connector', 'none'); }); it('Resets selector on cancel', async () => { @@ -115,12 +116,13 @@ describe('EditConnector ', () => { await act(async () => { wrapper.find(`[data-test-subj="edit-connectors-cancel"]`).last().simulate('click'); - await wait(); - wrapper.update(); - expect(formHookMock.setFieldValue).toBeCalledWith( - 'connector', - defaultProps.selectedConnector - ); + await waitFor(() => { + wrapper.update(); + expect(formHookMock.setFieldValue).toBeCalledWith( + 'connector', + defaultProps.selectedConnector + ); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/cases/components/tag_list/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/tag_list/index.test.tsx index 950dd6f377945..939ddfde8b9dc 100644 --- a/x-pack/plugins/security_solution/public/cases/components/tag_list/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/tag_list/index.test.tsx @@ -11,7 +11,8 @@ import { act } from 'react-dom/test-utils'; import { TagList } from '.'; import { getFormMock } from '../__mock__/form'; import { TestProviders } from '../../../common/mock'; -import { wait } from '../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { useForm } from '../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form'; import { useGetTags } from '../../containers/use_get_tags'; @@ -77,8 +78,7 @@ describe('TagList ', () => { wrapper.find(`[data-test-subj="tag-list-edit-button"]`).last().simulate('click'); await act(async () => { wrapper.find(`[data-test-subj="edit-tags-submit"]`).last().simulate('click'); - await wait(); - expect(onSubmit).toBeCalledWith(sampleTags); + await waitFor(() => expect(onSubmit).toBeCalledWith(sampleTags)); }); }); it('Tag options render with new tags added', () => { @@ -107,9 +107,10 @@ describe('TagList ', () => { await act(async () => { expect(wrapper.find(`[data-test-subj="case-tag"]`).last().exists()).toBeFalsy(); wrapper.find(`[data-test-subj="edit-tags-cancel"]`).last().simulate('click'); - await wait(); - wrapper.update(); - expect(wrapper.find(`[data-test-subj="case-tag"]`).last().exists()).toBeTruthy(); + await waitFor(() => { + wrapper.update(); + expect(wrapper.find(`[data-test-subj="case-tag"]`).last().exists()).toBeTruthy(); + }); }); }); it('Renders disabled button', () => { diff --git a/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.test.tsx index 23f1fb222a841..9cf13b6f9930a 100644 --- a/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.test.tsx @@ -13,7 +13,8 @@ import { useUpdateComment } from '../../containers/use_update_comment'; import { basicCase, basicPush, getUserAction } from '../../containers/mock'; import { UserActionTree } from '.'; import { TestProviders } from '../../../common/mock'; -import { wait } from '../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { act } from 'react-dom/test-utils'; const fetchUserActions = jest.fn(); @@ -225,22 +226,23 @@ describe('UserActionTree ', () => { .first() .simulate('click'); await act(async () => { - await wait(); - wrapper.update(); - expect( - wrapper - .find( - `[data-test-subj="user-action-${props.data.comments[0].id}"] [data-test-subj="user-action-markdown-form"]` - ) - .exists() - ).toEqual(false); - expect(patchComment).toBeCalledWith({ - commentUpdate: sampleData.content, - caseId: props.data.id, - commentId: props.data.comments[0].id, - fetchUserActions, - updateCase, - version: props.data.comments[0].version, + await waitFor(() => { + wrapper.update(); + expect( + wrapper + .find( + `[data-test-subj="user-action-${props.data.comments[0].id}"] [data-test-subj="user-action-markdown-form"]` + ) + .exists() + ).toEqual(false); + expect(patchComment).toBeCalledWith({ + commentUpdate: sampleData.content, + caseId: props.data.id, + commentId: props.data.comments[0].id, + fetchUserActions, + updateCase, + version: props.data.comments[0].version, + }); }); }); }); @@ -269,15 +271,16 @@ describe('UserActionTree ', () => { .first() .simulate('click'); await act(async () => { - await wait(); - expect( - wrapper - .find( - `[data-test-subj="user-action-${props.data.id}"] [data-test-subj="user-action-markdown-form"]` - ) - .exists() - ).toEqual(false); - expect(onUpdateField).toBeCalledWith({ key: 'description', value: sampleData.content }); + await waitFor(() => { + expect( + wrapper + .find( + `[data-test-subj="user-action-${props.data.id}"] [data-test-subj="user-action-markdown-form"]` + ) + .exists() + ).toEqual(false); + expect(onUpdateField).toBeCalledWith({ key: 'description', value: sampleData.content }); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx index 2a7cbff5ee149..049953e21febd 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx @@ -10,7 +10,8 @@ import useResizeObserver from 'use-resize-observer/polyfilled'; import '../../mock/match_media'; import { mockIndexPattern, TestProviders } from '../../mock'; -import { wait } from '../../lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { mockEventViewerResponse } from './mock'; import { StatefulEventsViewer } from '.'; @@ -60,12 +61,13 @@ describe('EventsViewer', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find(`[data-test-subj="header-section-subtitle"]`).first().text()).toEqual( - 'Showing: 12 events' - ); + expect(wrapper.find(`[data-test-subj="header-section-subtitle"]`).first().text()).toEqual( + 'Showing: 12 events' + ); + }); }); test('it does NOT render fetch index pattern is loading', async () => { @@ -84,10 +86,13 @@ describe('EventsViewer', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find(`[data-test-subj="header-section-subtitle"]`).first().exists()).toBe(false); + expect(wrapper.find(`[data-test-subj="header-section-subtitle"]`).first().exists()).toBe( + false + ); + }); }); test('it does NOT render when start is empty', async () => { @@ -106,10 +111,13 @@ describe('EventsViewer', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find(`[data-test-subj="header-section-subtitle"]`).first().exists()).toBe(false); + expect(wrapper.find(`[data-test-subj="header-section-subtitle"]`).first().exists()).toBe( + false + ); + }); }); test('it does NOT render when end is empty', async () => { @@ -128,10 +136,13 @@ describe('EventsViewer', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find(`[data-test-subj="header-section-subtitle"]`).first().exists()).toBe(false); + expect(wrapper.find(`[data-test-subj="header-section-subtitle"]`).first().exists()).toBe( + false + ); + }); }); test('it renders the Fields Browser as a settings gear', async () => { @@ -148,10 +159,11 @@ describe('EventsViewer', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find(`[data-test-subj="show-field-browser"]`).first().exists()).toBe(true); + expect(wrapper.find(`[data-test-subj="show-field-browser"]`).first().exists()).toBe(true); + }); }); test('it renders the footer containing the Load More button', async () => { @@ -168,10 +180,11 @@ describe('EventsViewer', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find(`[data-test-subj="TimelineMoreButton"]`).first().exists()).toBe(true); + expect(wrapper.find(`[data-test-subj="TimelineMoreButton"]`).first().exists()).toBe(true); + }); }); defaultHeaders.forEach((header) => { @@ -189,14 +202,15 @@ describe('EventsViewer', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); - defaultHeaders.forEach((h) => - expect(wrapper.find(`[data-test-subj="header-text-${header.id}"]`).first().exists()).toBe( - true - ) - ); + defaultHeaders.forEach((h) => + expect(wrapper.find(`[data-test-subj="header-text-${header.id}"]`).first().exists()).toBe( + true + ) + ); + }); }); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx index 1ab390a85ec50..4509d01e82e25 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx @@ -9,7 +9,8 @@ import { MockedProvider } from 'react-apollo/test-utils'; import useResizeObserver from 'use-resize-observer/polyfilled'; import '../../mock/match_media'; -import { wait } from '../../lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { mockIndexPattern, TestProviders } from '../../mock'; import { useMountAppended } from '../../utils/use_mount_appended'; @@ -54,10 +55,11 @@ describe('StatefulEventsViewer', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find('[data-test-subj="events-viewer-panel"]').first().exists()).toBe(true); + expect(wrapper.find('[data-test-subj="events-viewer-panel"]').first().exists()).toBe(true); + }); }); // InspectButtonContainer controls displaying InspectButton components @@ -75,9 +77,10 @@ describe('StatefulEventsViewer', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find(`InspectButtonContainer`).exists()).toBe(true); + expect(wrapper.find(`InspectButtonContainer`).exists()).toBe(true); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx index 9d0d9e7b250a0..72df9d613abac 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx @@ -21,7 +21,8 @@ import { } from './test_dependencies'; import { UrlStateContainerPropTypes } from './types'; import { useUrlStateHooks } from './use_url_state'; -import { wait } from '../../lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; let mockProps: UrlStateContainerPropTypes; @@ -194,29 +195,32 @@ describe('UrlStateContainer', () => { }).relativeTimeSearch.undefinedQuery, }); wrapper.update(); - await wait(); if (CONSTANTS.detectionsPage === page) { - expect(mockSetRelativeRangeDatePicker.mock.calls[3][0]).toEqual({ - from: '2020-01-01T00:00:00.000Z', - fromStr: 'now-1d/d', - kind: 'relative', - to: '2020-01-01T00:00:00.000Z', - toStr: 'now-1d/d', - id: 'global', - }); + await waitFor(() => { + expect(mockSetRelativeRangeDatePicker.mock.calls[3][0]).toEqual({ + from: '2020-01-01T00:00:00.000Z', + fromStr: 'now-1d/d', + kind: 'relative', + to: '2020-01-01T00:00:00.000Z', + toStr: 'now-1d/d', + id: 'global', + }); - expect(mockSetRelativeRangeDatePicker.mock.calls[2][0]).toEqual({ - from: 1558732849370, - fromStr: 'now-15m', - kind: 'relative', - to: 1558733749370, - toStr: 'now', - id: 'timeline', + expect(mockSetRelativeRangeDatePicker.mock.calls[2][0]).toEqual({ + from: 1558732849370, + fromStr: 'now-15m', + kind: 'relative', + to: 1558733749370, + toStr: 'now', + id: 'timeline', + }); }); } else { - // There is no change in url state, so that's expected we only have two actions - expect(mockSetRelativeRangeDatePicker.mock.calls.length).toEqual(2); + await waitFor(() => { + // There is no change in url state, so that's expected we only have two actions + expect(mockSetRelativeRangeDatePicker.mock.calls.length).toEqual(2); + }); } } ); diff --git a/x-pack/plugins/security_solution/public/common/lib/helpers/index.tsx b/x-pack/plugins/security_solution/public/common/lib/helpers/index.tsx index 07e706ac2a9af..96b0343efdf72 100644 --- a/x-pack/plugins/security_solution/public/common/lib/helpers/index.tsx +++ b/x-pack/plugins/security_solution/public/common/lib/helpers/index.tsx @@ -19,12 +19,6 @@ export type WrapArrayIfExitts = (value: Many) => T[] | undefined; export const asArrayIfExists: WrapArrayIfExitts = (value) => !isUndefined(value) ? castArray(value) : undefined; -export const wait = (delay = 0): Promise => { - return new Promise((resolve) => { - return setTimeout(resolve, delay); - }); -}; - /** * Creates a Union Type for all the values of an object */ diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx index 9b2e0069f0ac0..a86c1b7ce1bea 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx @@ -13,7 +13,8 @@ import { StepAboutRule } from '.'; import { mockAboutStepRule } from '../../../pages/detection_engine/rules/all/__mocks__/mock'; import { StepRuleDescription } from '../description_step'; import { stepAboutDefaultValue } from './default_value'; -import { wait } from '@testing-library/react'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { AboutStepRule } from '../../../pages/detection_engine/rules/types'; const theme = () => ({ eui: euiDarkVars, darkMode: true }); @@ -162,31 +163,32 @@ describe('StepAboutRuleComponent', () => { .simulate('change', { target: { value: 'Test name text' } }); wrapper.find('button[data-test-subj="about-continue"]').first().simulate('click').update(); - await wait(); - const expected: Omit = { - author: [], - isAssociatedToEndpointList: false, - isBuildingBlock: false, - license: '', - ruleNameOverride: '', - timestampOverride: '', - description: 'Test description text', - falsePositives: [''], - name: 'Test name text', - note: '', - references: [''], - riskScore: { value: 50, mapping: [] }, - severity: { value: 'low', mapping: [] }, - tags: [], - threat: [ - { - framework: 'MITRE ATT&CK', - tactic: { id: 'none', name: 'none', reference: 'none' }, - technique: [], - }, - ], - }; - expect(stepDataMock.mock.calls[1][1]).toEqual(expected); + await waitFor(() => { + const expected: Omit = { + author: [], + isAssociatedToEndpointList: false, + isBuildingBlock: false, + license: '', + ruleNameOverride: '', + timestampOverride: '', + description: 'Test description text', + falsePositives: [''], + name: 'Test name text', + note: '', + references: [''], + riskScore: { value: 50, mapping: [] }, + severity: { value: 'low', mapping: [] }, + tags: [], + threat: [ + { + framework: 'MITRE ATT&CK', + tactic: { id: 'none', name: 'none', reference: 'none' }, + technique: [], + }, + ], + }; + expect(stepDataMock.mock.calls[1][1]).toEqual(expected); + }); }); test('it allows user to set the risk score as a number (and not a string)', async () => { @@ -221,30 +223,31 @@ describe('StepAboutRuleComponent', () => { .simulate('change', { target: { value: '80' } }); wrapper.find('[data-test-subj="about-continue"]').first().simulate('click').update(); - await wait(); - const expected: Omit = { - author: [], - isAssociatedToEndpointList: false, - isBuildingBlock: false, - license: '', - ruleNameOverride: '', - timestampOverride: '', - description: 'Test description text', - falsePositives: [''], - name: 'Test name text', - note: '', - references: [''], - riskScore: { value: 80, mapping: [] }, - severity: { value: 'low', mapping: [] }, - tags: [], - threat: [ - { - framework: 'MITRE ATT&CK', - tactic: { id: 'none', name: 'none', reference: 'none' }, - technique: [], - }, - ], - }; - expect(stepDataMock.mock.calls[1][1]).toEqual(expected); + await waitFor(() => { + const expected: Omit = { + author: [], + isAssociatedToEndpointList: false, + isBuildingBlock: false, + license: '', + ruleNameOverride: '', + timestampOverride: '', + description: 'Test description text', + falsePositives: [''], + name: 'Test name text', + note: '', + references: [''], + riskScore: { value: 80, mapping: [] }, + severity: { value: 'low', mapping: [] }, + tags: [], + threat: [ + { + framework: 'MITRE ATT&CK', + tactic: { id: 'none', name: 'none', reference: 'none' }, + technique: [], + }, + ], + }; + expect(stepDataMock.mock.calls[1][1]).toEqual(expected); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.test.tsx index 58344e9e97534..b07caa754aec9 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.test.tsx @@ -11,7 +11,8 @@ import { act } from 'react-dom/test-utils'; import '../../../../../common/mock/match_media'; import { createKibanaContextProviderMock } from '../../../../../common/mock/kibana_react'; import { TestProviders } from '../../../../../common/mock'; -import { wait } from '../../../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { AllRules } from './index'; jest.mock('react-router-dom', () => { @@ -202,10 +203,10 @@ describe('AllRules', () => { ); await act(async () => { - await wait(); - - expect(wrapper.exists('[data-test-subj="monitoring-table"]')).toBeFalsy(); - expect(wrapper.exists('[data-test-subj="rules-table"]')).toBeTruthy(); + await waitFor(() => { + expect(wrapper.exists('[data-test-subj="monitoring-table"]')).toBeFalsy(); + expect(wrapper.exists('[data-test-subj="rules-table"]')).toBeTruthy(); + }); }); }); @@ -234,11 +235,11 @@ describe('AllRules', () => { monitoringTab.simulate('click'); await act(async () => { - wrapper.update(); - await wait(); - - expect(wrapper.exists('[data-test-subj="monitoring-table"]')).toBeTruthy(); - expect(wrapper.exists('[data-test-subj="rules-table"]')).toBeFalsy(); + await waitFor(() => { + wrapper.update(); + expect(wrapper.exists('[data-test-subj="monitoring-table"]')).toBeTruthy(); + expect(wrapper.exists('[data-test-subj="rules-table"]')).toBeFalsy(); + }); }); }); }); diff --git a/x-pack/plugins/security_solution/public/hosts/components/first_last_seen_host/index.test.tsx b/x-pack/plugins/security_solution/public/hosts/components/first_last_seen_host/index.test.tsx index 9715c1cb5c8b4..a2f53be721816 100644 --- a/x-pack/plugins/security_solution/public/hosts/components/first_last_seen_host/index.test.tsx +++ b/x-pack/plugins/security_solution/public/hosts/components/first_last_seen_host/index.test.tsx @@ -7,10 +7,11 @@ import { cloneDeep } from 'lodash/fp'; import React from 'react'; import { MockedProvider } from 'react-apollo/test-utils'; -import { render, act } from '@testing-library/react'; + +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { render, act, wait as waitFor } from '@testing-library/react'; import { mockFirstLastSeenHostQuery } from '../../containers/hosts/first_last_seen/mock'; -import { wait } from '../../../common/lib/helpers'; import { TestProviders } from '../../../common/mock'; import { FirstLastSeenHost, FirstLastSeenHostType } from '.'; @@ -51,10 +52,12 @@ describe('FirstLastSeen Component', () => { ); - await act(() => wait()); - - expect(container.innerHTML).toBe( - `
${firstSeen}
` + await act(() => + waitFor(() => { + expect(container.innerHTML).toBe( + `
${firstSeen}
` + ); + }) ); }); @@ -66,9 +69,12 @@ describe('FirstLastSeen Component', () => { ); - await act(() => wait()); - expect(container.innerHTML).toBe( - `
${lastSeen}
` + await act(() => + waitFor(() => { + expect(container.innerHTML).toBe( + `
${lastSeen}
` + ); + }) ); }); @@ -83,10 +89,12 @@ describe('FirstLastSeen Component', () => { ); - await act(() => wait()); - - expect(container.innerHTML).toBe( - `
${lastSeen}
` + await act(() => + waitFor(() => { + expect(container.innerHTML).toBe( + `
${lastSeen}
` + ); + }) ); }); @@ -101,10 +109,12 @@ describe('FirstLastSeen Component', () => { ); - await act(() => wait()); - - expect(container.innerHTML).toBe( - `
${firstSeen}
` + await act(() => + waitFor(() => { + expect(container.innerHTML).toBe( + `
${firstSeen}
` + ); + }) ); }); @@ -118,8 +128,11 @@ describe('FirstLastSeen Component', () => { ); - await act(() => wait()); - expect(container.textContent).toBe('something-invalid'); + await act(() => + waitFor(() => { + expect(container.textContent).toBe('something-invalid'); + }) + ); }); test('Last Seen With a bad date time string', async () => { @@ -132,7 +145,10 @@ describe('FirstLastSeen Component', () => { ); - await act(() => wait()); - expect(container.textContent).toBe('something-invalid'); + await act(() => + waitFor(() => { + expect(container.textContent).toBe('something-invalid'); + }) + ); }); }); diff --git a/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx index 63126da0b9bb5..f7f1fbc30aeb7 100644 --- a/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx @@ -13,7 +13,8 @@ import { ThemeProvider } from 'styled-components'; import '../../../common/mock/match_media'; import { useQuery } from '../../../common/containers/matrix_histogram'; -import { wait } from '../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { mockIndexPattern, TestProviders } from '../../../common/mock'; import { AlertsByCategory } from '.'; @@ -57,34 +58,45 @@ describe('Alerts by category', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); + }); }); - test('it renders the expected title', () => { - expect(wrapper.find('[data-test-subj="header-section-title"]').text()).toEqual( - 'External alert trend' - ); + test('it renders the expected title', async () => { + await waitFor(() => { + expect(wrapper.find('[data-test-subj="header-section-title"]').text()).toEqual( + 'External alert trend' + ); + }); }); - test('it renders the subtitle (to prevent layout thrashing)', () => { - expect(wrapper.find('[data-test-subj="header-panel-subtitle"]').exists()).toBe(true); + test('it renders the subtitle (to prevent layout thrashing)', async () => { + await waitFor(() => { + expect(wrapper.find('[data-test-subj="header-panel-subtitle"]').exists()).toBe(true); + }); }); - test('it renders the expected filter fields', () => { - const expectedOptions = ['event.category', 'event.module']; + test('it renders the expected filter fields', async () => { + await waitFor(() => { + const expectedOptions = ['event.category', 'event.module']; - expectedOptions.forEach((option) => { - expect(wrapper.find(`option[value="${option}"]`).text()).toEqual(option); + expectedOptions.forEach((option) => { + expect(wrapper.find(`option[value="${option}"]`).text()).toEqual(option); + }); }); }); - test('it renders the `View alerts` button', () => { - expect(wrapper.find('[data-test-subj="view-alerts"]').exists()).toBe(true); + test('it renders the `View alerts` button', async () => { + await waitFor(() => { + expect(wrapper.find('[data-test-subj="view-alerts"]').exists()).toBe(true); + }); }); - test('it does NOT render the bar chart when data is not available', () => { - expect(wrapper.find(`.echChart`).exists()).toBe(false); + test('it does NOT render the bar chart when data is not available', async () => { + await waitFor(() => { + expect(wrapper.find(`.echChart`).exists()).toBe(false); + }); }); }); @@ -119,18 +131,21 @@ describe('Alerts by category', () => { ); - await wait(); wrapper.update(); }); - test('it renders the expected subtitle', () => { - expect(wrapper.find('[data-test-subj="header-panel-subtitle"]').text()).toEqual( - 'Showing: 6 external alerts' - ); + test('it renders the expected subtitle', async () => { + await waitFor(() => { + expect(wrapper.find('[data-test-subj="header-panel-subtitle"]').text()).toEqual( + 'Showing: 6 external alerts' + ); + }); }); - test('it renders the bar chart when data is available', () => { - expect(wrapper.find(`.echChart`).exists()).toBe(true); + test('it renders the bar chart when data is available', async () => { + await waitFor(() => { + expect(wrapper.find(`.echChart`).exists()).toBe(true); + }); }); }); }); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx index 30874e8874760..5ff78c9b29cf5 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx @@ -24,7 +24,8 @@ import { createStore, State } from '../../../common/store'; import { overviewHostQuery } from '../../containers/overview_host/index.gql_query'; import { GetOverviewHostQuery } from '../../../graphql/types'; -import { wait } from '../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; jest.mock('../../../common/lib/kibana'); jest.mock('../../../common/components/link_to'); @@ -147,11 +148,12 @@ describe('OverviewHost', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find('[data-test-subj="header-panel-subtitle"]').first().text()).toEqual( - 'Showing: 16 events' - ); + expect(wrapper.find('[data-test-subj="header-panel-subtitle"]').first().text()).toEqual( + 'Showing: 16 events' + ); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx index 9ac4f7125f34d..0bb887b38a4b1 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx @@ -22,7 +22,8 @@ import { OverviewNetwork } from '.'; import { createStore, State } from '../../../common/store'; import { overviewNetworkQuery } from '../../containers/overview_network/index.gql_query'; import { GetOverviewHostQuery } from '../../../graphql/types'; -import { wait } from '../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; jest.mock('../../../common/components/link_to'); const mockNavigateToApp = jest.fn(); @@ -155,12 +156,13 @@ describe('OverviewNetwork', () => { ); - await wait(); - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find('[data-test-subj="header-panel-subtitle"]').first().text()).toEqual( - 'Showing: 9 events' - ); + expect(wrapper.find('[data-test-subj="header-panel-subtitle"]').first().text()).toEqual( + 'Showing: 9 events' + ); + }); }); it('it renders View Network', () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx index e671244d97b57..6c1c88f511edb 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/index.test.tsx @@ -8,7 +8,8 @@ import { mount } from 'enzyme'; import { MockedProvider } from 'react-apollo/test-utils'; import React from 'react'; -import { wait } from '../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import '../../../common/mock/match_media'; import { TestProviders, apolloClient } from '../../../common/mock/test_providers'; import { mockOpenTimelineQueryResults } from '../../../common/mock/timeline_results'; @@ -119,15 +120,15 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); - - wrapper - .find('[data-test-subj="search-bar"] input') - .simulate('keyup', { key: 'Enter', target: { value: ' abcd ' } }); + await waitFor(() => { + wrapper + .find('[data-test-subj="search-bar"] input') + .simulate('keyup', { key: 'Enter', target: { value: ' abcd ' } }); - expect(wrapper.find('[data-test-subj="query-message"]').first().text()).toContain( - 'Showing: 11 timelines with' - ); + expect(wrapper.find('[data-test-subj="query-message"]').first().text()).toContain( + 'Showing: 11 timelines with' + ); + }); }); test('echos (renders) the query when the user enters a query', async () => { @@ -144,15 +145,15 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); - - wrapper - .find('[data-test-subj="search-bar"] input') - .simulate('keyup', { key: 'Enter', target: { value: ' abcd ' } }); + await waitFor(() => { + wrapper + .find('[data-test-subj="search-bar"] input') + .simulate('keyup', { key: 'Enter', target: { value: ' abcd ' } }); - expect(wrapper.find('[data-test-subj="selectable-query-text"]').first().text()).toEqual( - 'with "abcd"' - ); + expect(wrapper.find('[data-test-subj="selectable-query-text"]').first().text()).toEqual( + 'with "abcd"' + ); + }); }); }); @@ -171,12 +172,12 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); - - expect( - wrapper.find(`.${OPEN_TIMELINE_CLASS_NAME} input`).first().getDOMNode().id === - document.activeElement!.id - ).toBe(true); + await waitFor(() => { + expect( + wrapper.find(`.${OPEN_TIMELINE_CLASS_NAME} input`).first().getDOMNode().id === + document.activeElement!.id + ).toBe(true); + }); }); }); @@ -198,26 +199,26 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); - - wrapper - .find('.euiCheckbox__input') - .first() - .simulate('change', { target: { checked: true } }); - - wrapper.find('[data-test-subj="favorite-selected"]').first().simulate('click'); - - expect(addTimelinesToFavorites).toHaveBeenCalledWith([ - 'saved-timeline-11', - 'saved-timeline-10', - 'saved-timeline-9', - 'saved-timeline-8', - 'saved-timeline-6', - 'saved-timeline-5', - 'saved-timeline-4', - 'saved-timeline-3', - 'saved-timeline-2', - ]); + await waitFor(() => { + wrapper + .find('.euiCheckbox__input') + .first() + .simulate('change', { target: { checked: true } }); + + wrapper.find('[data-test-subj="favorite-selected"]').first().simulate('click'); + + expect(addTimelinesToFavorites).toHaveBeenCalledWith([ + 'saved-timeline-11', + 'saved-timeline-10', + 'saved-timeline-9', + 'saved-timeline-8', + 'saved-timeline-6', + 'saved-timeline-5', + 'saved-timeline-4', + 'saved-timeline-3', + 'saved-timeline-2', + ]); + }); }); }); @@ -239,26 +240,26 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); - - wrapper - .find('.euiCheckbox__input') - .first() - .simulate('change', { target: { checked: true } }); - - wrapper.find('[data-test-subj="delete-selected"]').first().simulate('click'); - - expect(deleteTimelines).toHaveBeenCalledWith([ - 'saved-timeline-11', - 'saved-timeline-10', - 'saved-timeline-9', - 'saved-timeline-8', - 'saved-timeline-6', - 'saved-timeline-5', - 'saved-timeline-4', - 'saved-timeline-3', - 'saved-timeline-2', - ]); + await waitFor(() => { + wrapper + .find('.euiCheckbox__input') + .first() + .simulate('change', { target: { checked: true } }); + + wrapper.find('[data-test-subj="delete-selected"]').first().simulate('click'); + + expect(deleteTimelines).toHaveBeenCalledWith([ + 'saved-timeline-11', + 'saved-timeline-10', + 'saved-timeline-9', + 'saved-timeline-8', + 'saved-timeline-6', + 'saved-timeline-5', + 'saved-timeline-4', + 'saved-timeline-3', + 'saved-timeline-2', + ]); + }); }); }); @@ -278,19 +279,19 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); - - wrapper - .find('.euiCheckbox__input') - .first() - .simulate('change', { target: { checked: true } }); + await waitFor(() => { + wrapper + .find('.euiCheckbox__input') + .first() + .simulate('change', { target: { checked: true } }); - const selectedItems: [] = wrapper - .find('[data-test-subj="open-timeline"]') - .last() - .prop('selectedItems'); + const selectedItems: [] = wrapper + .find('[data-test-subj="open-timeline"]') + .last() + .prop('selectedItems'); - expect(selectedItems.length).toEqual(13); // 13 because we did mock 13 timelines in the query + expect(selectedItems.length).toEqual(13); // 13 because we did mock 13 timelines in the query + }); }); }); @@ -366,29 +367,37 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); - wrapper.update(); - - expect( - wrapper.find('[data-test-subj="open-timeline"]').last().prop('itemIdToExpandedNotesRowMap') - ).toEqual({}); - - wrapper.find('[data-test-subj="expand-notes"]').first().simulate('click'); - - expect( - wrapper.find('[data-test-subj="open-timeline"]').last().prop('itemIdToExpandedNotesRowMap') - ).toEqual({ - '10849df0-7b44-11e9-a608-ab3d811609': ( - ({ ...note, savedObjectId: note.noteId }) - ) - : [] - } - /> - ), + await waitFor(() => { + wrapper.update(); + + expect( + wrapper + .find('[data-test-subj="open-timeline"]') + .last() + .prop('itemIdToExpandedNotesRowMap') + ).toEqual({}); + + wrapper.find('[data-test-subj="expand-notes"]').first().simulate('click'); + + expect( + wrapper + .find('[data-test-subj="open-timeline"]') + .last() + .prop('itemIdToExpandedNotesRowMap') + ).toEqual({ + '10849df0-7b44-11e9-a608-ab3d811609': ( + ({ ...note, savedObjectId: note.noteId }) + ) + : [] + } + /> + ), + }); }); }); @@ -407,21 +416,21 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); - - wrapper.update(); + await waitFor(() => { + wrapper.update(); - wrapper.find('[data-test-subj="expand-notes"]').first().simulate('click'); - expect(wrapper.find('[data-test-subj="note-previews-container"]').exists()).toEqual(true); - expect(wrapper.find('[data-test-subj="updated-by"]').exists()).toEqual(true); + wrapper.find('[data-test-subj="expand-notes"]').first().simulate('click'); + expect(wrapper.find('[data-test-subj="note-previews-container"]').exists()).toEqual(true); + expect(wrapper.find('[data-test-subj="updated-by"]').exists()).toEqual(true); - expect( - wrapper - .find('[data-test-subj="note-previews-container"]') - .find('[data-test-subj="updated-by"]') - .first() - .text() - ).toEqual('elastic'); + expect( + wrapper + .find('[data-test-subj="note-previews-container"]') + .find('[data-test-subj="updated-by"]') + .first() + .text() + ).toEqual('elastic'); + }); }); /** @@ -442,11 +451,11 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); - - expect(wrapper.find(`[data-test-subj="timeline-${TimelineTabsStyle.tab}"]`).exists()).toEqual( - true - ); + await waitFor(() => { + expect( + wrapper.find(`[data-test-subj="timeline-${TimelineTabsStyle.tab}"]`).exists() + ).toEqual(true); + }); }); }); @@ -467,13 +476,14 @@ describe('StatefulOpenTimeline', () => { ); const getSelectedItem = (): [] => wrapper.find('[data-test-subj="open-timeline"]').last().prop('selectedItems'); - await wait(); - expect(getSelectedItem().length).toEqual(0); - wrapper - .find('.euiCheckbox__input') - .first() - .simulate('change', { target: { checked: true } }); - expect(getSelectedItem().length).toEqual(13); + await waitFor(() => { + expect(getSelectedItem().length).toEqual(0); + wrapper + .find('.euiCheckbox__input') + .first() + .simulate('change', { target: { checked: true } }); + expect(getSelectedItem().length).toEqual(13); + }); }); }); @@ -492,13 +502,13 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); - - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find('[data-test-subj="query-message"]').first().text()).toContain( - 'Showing: 11 timelines ' - ); + expect(wrapper.find('[data-test-subj="query-message"]').first().text()).toContain( + 'Showing: 11 timelines ' + ); + }); }); // TODO - Have been skip because we need to re-implement the test as the component changed @@ -519,21 +529,21 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); - - wrapper - .find( - `[data-test-subj="title-${ - mockOpenTimelineQueryResults[0].result.data!.getAllTimeline.timeline[0].savedObjectId - }"]` - ) - .first() - .simulate('click'); - - expect(onOpenTimeline).toHaveBeenCalledWith({ - duplicate: false, - timelineId: mockOpenTimelineQueryResults[0].result.data!.getAllTimeline.timeline[0] - .savedObjectId, + await waitFor(() => { + wrapper + .find( + `[data-test-subj="title-${ + mockOpenTimelineQueryResults[0].result.data!.getAllTimeline.timeline[0].savedObjectId + }"]` + ) + .first() + .simulate('click'); + + expect(onOpenTimeline).toHaveBeenCalledWith({ + duplicate: false, + timelineId: mockOpenTimelineQueryResults[0].result.data!.getAllTimeline.timeline[0] + .savedObjectId, + }); }); }); @@ -555,10 +565,10 @@ describe('StatefulOpenTimeline', () => { ); - await wait(); + await waitFor(() => { + wrapper.find('[data-test-subj="open-duplicate"]').first().simulate('click'); - wrapper.find('[data-test-subj="open-duplicate"]').first().simulate('click'); - - expect(onOpenTimeline).toBeCalledWith({ duplicate: true, timelineId: 'saved-timeline-11' }); + expect(onOpenTimeline).toBeCalledWith({ duplicate: true, timelineId: 'saved-timeline-11' }); + }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/index.test.tsx index 8382af6056ca7..3017f553d59d5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/index.test.tsx @@ -10,7 +10,8 @@ import React from 'react'; import { MockedProvider } from 'react-apollo/test-utils'; import { ThemeProvider } from 'styled-components'; -import { wait } from '../../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { TestProviderWithoutDragAndDrop } from '../../../../common/mock/test_providers'; import { mockOpenTimelineQueryResults } from '../../../../common/mock/timeline_results'; import { useGetAllTimeline, getAllTimeline } from '../../../containers/all'; @@ -64,10 +65,15 @@ describe('OpenTimelineModal', () => { ); - await wait(); + await waitFor( + () => { + wrapper.update(); - wrapper.update(); - - expect(wrapper.find('div[data-test-subj="open-timeline-modal"].euiModal').length).toEqual(1); - }); + expect(wrapper.find('div[data-test-subj="open-timeline-modal"].euiModal').length).toEqual( + 1 + ); + }, + { timeout: 10000 } + ); + }, 20000); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_button.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_button.test.tsx index 80bca8096f615..a3f180ce84c58 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_button.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/open_timeline_modal/open_timeline_modal_button.test.tsx @@ -10,7 +10,8 @@ import React from 'react'; import { MockedProvider } from 'react-apollo/test-utils'; import { ThemeProvider } from 'styled-components'; -import { wait } from '../../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { TestProviderWithoutDragAndDrop } from '../../../../common/mock/test_providers'; import { mockOpenTimelineQueryResults } from '../../../../common/mock/timeline_results'; import * as i18n from '../translations'; @@ -29,13 +30,13 @@ describe('OpenTimelineModalButton', () => { ); - await wait(); - - wrapper.update(); + await waitFor(() => { + wrapper.update(); - expect(wrapper.find('[data-test-subj="open-timeline-button"]').first().text()).toEqual( - i18n.OPEN_TIMELINE - ); + expect(wrapper.find('[data-test-subj="open-timeline-button"]').first().text()).toEqual( + i18n.OPEN_TIMELINE + ); + }); }); describe('onClick prop', () => { @@ -51,13 +52,13 @@ describe('OpenTimelineModalButton', () => { ); - await wait(); - - wrapper.find('[data-test-subj="open-timeline-button"]').first().simulate('click'); + await waitFor(() => { + wrapper.find('[data-test-subj="open-timeline-button"]').first().simulate('click'); - wrapper.update(); + wrapper.update(); - expect(onClick).toBeCalled(); + expect(onClick).toBeCalled(); + }); }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx index b36f1dcc03261..5a98263cbd3fd 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.test.tsx @@ -16,7 +16,8 @@ import { TestProviders } from '../../../../common/mock/test_providers'; import { Body, BodyProps } from '.'; import { columnRenderers, rowRenderers } from './renderers'; import { Sort } from './sort'; -import { wait } from '../../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { useMountAppended } from '../../../../common/utils/use_mount_appended'; import { SELECTOR_TIMELINE_BODY_CLASS_NAME, TimelineBody } from '../styles'; import { TimelineType } from '../../../../../common/types/timeline'; @@ -130,16 +131,17 @@ describe('Body', () => { ); wrapper.update(); - await wait(); - wrapper.update(); - headersJustTimestamp.forEach(() => { - expect( - wrapper - .find('[data-test-subj="data-driven-columns"]') - .first() - .find('[data-test-subj="localized-date-tool-tip"]') - .exists() - ).toEqual(true); + await waitFor(() => { + wrapper.update(); + headersJustTimestamp.forEach(() => { + expect( + wrapper + .find('[data-test-subj="data-driven-columns"]') + .first() + .find('[data-test-subj="localized-date-tool-tip"]') + .exists() + ).toEqual(true); + }); }); }, 20000); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx index 8b75f8b398ac1..51edf7336c4e7 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx @@ -16,7 +16,8 @@ import { ReturnSignalIndex, } from '../../../detections/containers/detection_engine/alerts/use_signal_index'; import { mocksSource } from '../../../common/containers/source/mock'; -import { wait } from '../../../common/lib/helpers'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { defaultHeaders, mockTimelineData, TestProviders } from '../../../common/mock'; import { Direction } from '../../../graphql/types'; import { timelineQuery } from '../../containers/index.gql_query'; @@ -124,12 +125,13 @@ describe('StatefulTimeline', () => { ); await act(async () => { - await wait(); - wrapper.update(); - const timeline = wrapper.find(Timeline); - expect(timeline.props().indexToAdd).toEqual([ - 'no-alert-index-049FC71A-4C2C-446F-9901-37XMC5024C51', - ]); + await waitFor(() => { + wrapper.update(); + const timeline = wrapper.find(Timeline); + expect(timeline.props().indexToAdd).toEqual([ + 'no-alert-index-049FC71A-4C2C-446F-9901-37XMC5024C51', + ]); + }); }); }); @@ -147,10 +149,11 @@ describe('StatefulTimeline', () => { ); await act(async () => { - await wait(); - wrapper.update(); - const timeline = wrapper.find(Timeline); - expect(timeline.props().indexToAdd).toEqual(['mock-siem-signals-index']); + await waitFor(() => { + wrapper.update(); + const timeline = wrapper.find(Timeline); + expect(timeline.props().indexToAdd).toEqual(['mock-siem-signals-index']); + }); }); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx index 1e0e85d4a48d9..06dd6f44bea94 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx @@ -7,6 +7,8 @@ import React from 'react'; import { shallow } from 'enzyme'; +// we don't have the types for waitFor just yet, so using "as waitFor" for when we do +import { wait as waitFor } from '@testing-library/react'; import '../../../common/mock/match_media'; import { mockGlobalState, @@ -44,10 +46,6 @@ import { TimelineStatus, TimelineType } from '../../../../common/types/timeline' jest.mock('../../containers/local_storage'); -const wait = (ms: number = 500): Promise => { - return new Promise((resolve) => setTimeout(resolve, ms)); -}; - const addTimelineInStorageMock = addTimelineInStorage as jest.Mock; describe('epicLocalStorage', () => { @@ -128,8 +126,7 @@ describe('epicLocalStorage', () => { ); store.dispatch(upsertColumn({ id: 'test', index: 1, column: defaultHeaders[0] })); - await wait(); - expect(addTimelineInStorageMock).toHaveBeenCalled(); + await waitFor(() => expect(addTimelineInStorageMock).toHaveBeenCalled()); }); it('persist timeline when removing a column ', async () => { @@ -139,8 +136,7 @@ describe('epicLocalStorage', () => { ); store.dispatch(removeColumn({ id: 'test', columnId: '@timestamp' })); - await wait(); - expect(addTimelineInStorageMock).toHaveBeenCalled(); + await waitFor(() => expect(addTimelineInStorageMock).toHaveBeenCalled()); }); it('persists resizing of a column', async () => { @@ -150,8 +146,7 @@ describe('epicLocalStorage', () => { ); store.dispatch(applyDeltaToColumnWidth({ id: 'test', columnId: '@timestamp', delta: 80 })); - await wait(); - expect(addTimelineInStorageMock).toHaveBeenCalled(); + await waitFor(() => expect(addTimelineInStorageMock).toHaveBeenCalled()); }); it('persist the resetting of the fields', async () => { @@ -161,8 +156,7 @@ describe('epicLocalStorage', () => { ); store.dispatch(updateColumns({ id: 'test', columns: defaultHeaders })); - await wait(); - expect(addTimelineInStorageMock).toHaveBeenCalled(); + await waitFor(() => expect(addTimelineInStorageMock).toHaveBeenCalled()); }); it('persist items per page', async () => { @@ -172,8 +166,7 @@ describe('epicLocalStorage', () => { ); store.dispatch(updateItemsPerPage({ id: 'test', itemsPerPage: 50 })); - await wait(); - expect(addTimelineInStorageMock).toHaveBeenCalled(); + await waitFor(() => expect(addTimelineInStorageMock).toHaveBeenCalled()); }); it('persist the sorting of a column', async () => { @@ -191,7 +184,6 @@ describe('epicLocalStorage', () => { }, }) ); - await wait(); - expect(addTimelineInStorageMock).toHaveBeenCalled(); + await waitFor(() => expect(addTimelineInStorageMock).toHaveBeenCalled()); }); }); From 21977a7e6af04bb782f8c5434e24141fca4edc8e Mon Sep 17 00:00:00 2001 From: Yara Tercero Date: Mon, 20 Jul 2020 19:18:42 -0400 Subject: [PATCH 26/77] [Security Solution][Exceptions] - Make esTypes and subType available to index patterns (#72336) ## Summary This PR updates the following: - `useFetchIndexPatterns` now returns `indexPatterns` whose fields include `esTypes` and `subType` - Why?? The exceptions builder needs these two fields to determine what fields are of ES type `nested` and parent paths - exceptions add and edit modals now use the `rule.index` field to pass into `useFetchindexPatterns` - Before we were using the signals index and alerts index for endpoint, needs to be rule's index patterns - if no index patterns exist on the rule (if rule created via API, it's not required), then uses `DEFAULT_INDEX_PATTERN` - updates the autocomplete validation to use `IField.esTypes` to check type instead of `IField.type` --- .../autocomplete/field_value_lists.test.tsx | 115 ++++++++++++++---- .../autocomplete/field_value_lists.tsx | 8 +- .../autocomplete/field_value_match.tsx | 8 +- .../autocomplete/field_value_match_any.tsx | 2 +- .../components/autocomplete/helpers.test.ts | 32 +---- .../common/components/autocomplete/helpers.ts | 36 +++--- .../exceptions/add_exception_modal/index.tsx | 50 +++----- .../components/exceptions/builder/index.tsx | 23 ++-- .../exceptions/edit_exception_modal/index.tsx | 40 +++--- .../exceptions/viewer/index.test.tsx | 3 + .../components/exceptions/viewer/index.tsx | 10 +- .../containers/source/index.gql_query.ts | 2 + .../public/common/containers/source/index.tsx | 2 +- .../alerts_table/default_config.tsx | 9 +- .../components/alerts_table/index.tsx | 26 ++-- .../detection_engine/rules/details/index.tsx | 3 +- .../public/graphql/introspection.json | 36 ++++++ .../security_solution/public/graphql/types.ts | 12 ++ .../server/graphql/ecs/resolvers.ts | 34 +++++- .../server/graphql/ecs/schema.gql.ts | 1 + .../server/graphql/source_status/resolvers.ts | 39 ++++++ .../graphql/source_status/schema.gql.ts | 5 + .../security_solution/server/graphql/types.ts | 32 +++++ .../server/lib/index_fields/types.ts | 3 + 24 files changed, 362 insertions(+), 169 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx index 7734344d193b8..1ff5d770521f3 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx @@ -8,14 +8,27 @@ import { ThemeProvider } from 'styled-components'; import { mount } from 'enzyme'; import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; +// we don't have the types for waitFor just yet, so using "as waitFor" until when we do +import { wait as waitFor } from '@testing-library/react'; import { getField } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; -import { AutocompleteFieldListsComponent } from './field_value_lists'; +import { ListSchema } from '../../../lists_plugin_deps'; import { getFoundListSchemaMock } from '../../../../../lists/common/schemas/response/found_list_schema.mock'; +import { getListResponseMock } from '../../../../../lists/common/schemas/response/list_schema.mock'; +import { DATE_NOW } from '../../../../../lists/common/constants.mock'; + +import { AutocompleteFieldListsComponent } from './field_value_lists'; -const mockStart = jest.fn(); -const mockResult = getFoundListSchemaMock(); jest.mock('../../../common/lib/kibana'); +const mockStart = jest.fn(); +const mockKeywordList: ListSchema = { + ...getListResponseMock(), + id: 'keyword_list', + type: 'keyword', + name: 'keyword list', +}; +const mockResult = { ...getFoundListSchemaMock() }; +mockResult.data = [...mockResult.data, mockKeywordList]; jest.mock('../../../lists_plugin_deps', () => { const originalModule = jest.requireActual('../../../lists_plugin_deps'); @@ -31,7 +44,7 @@ jest.mock('../../../lists_plugin_deps', () => { }); describe('AutocompleteFieldListsComponent', () => { - test('it renders disabled if "isDisabled" is true', () => { + test('it renders disabled if "isDisabled" is true', async () => { const wrapper = mount( ({ eui: euiLightVars, darkMode: false })}> { ); - expect( - wrapper - .find(`[data-test-subj="valuesAutocompleteComboBox listsComboxBox"] input`) - .prop('disabled') - ).toBeTruthy(); + await waitFor(() => { + expect( + wrapper + .find(`[data-test-subj="valuesAutocompleteComboBox listsComboxBox"] input`) + .prop('disabled') + ).toBeTruthy(); + }); }); - test('it renders loading if "isLoading" is true', () => { + test('it renders loading if "isLoading" is true', async () => { const wrapper = mount( ({ eui: euiLightVars, darkMode: false })}> { /> ); - wrapper - .find(`[data-test-subj="valuesAutocompleteComboBox listsComboxBox"] button`) - .at(0) - .simulate('click'); - expect( + + await waitFor(() => { wrapper - .find( - `EuiComboBoxOptionsList[data-test-subj="valuesAutocompleteComboBox listsComboxBox-optionsList"]` - ) - .prop('isLoading') - ).toBeTruthy(); + .find(`[data-test-subj="valuesAutocompleteComboBox listsComboxBox"] button`) + .at(0) + .simulate('click'); + expect( + wrapper + .find( + `EuiComboBoxOptionsList[data-test-subj="valuesAutocompleteComboBox listsComboxBox-optionsList"]` + ) + .prop('isLoading') + ).toBeTruthy(); + }); }); - test('it allows user to clear values if "isClearable" is true', () => { + test('it allows user to clear values if "isClearable" is true', async () => { const wrapper = mount( ({ eui: euiLightVars, darkMode: false })}> { /> ); - expect( wrapper .find(`[data-test-subj="comboBoxInput"]`) @@ -102,7 +119,55 @@ describe('AutocompleteFieldListsComponent', () => { ).toBeTruthy(); }); - test('it correctly displays selected list', () => { + test('it correctly displays lists that match the selected "keyword" field esType', () => { + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + wrapper.find('[data-test-subj="comboBoxToggleListButton"] button').simulate('click'); + + expect( + wrapper + .find('EuiComboBox[data-test-subj="valuesAutocompleteComboBox listsComboxBox"]') + .prop('options') + ).toEqual([{ label: 'keyword list' }]); + }); + + test('it correctly displays lists that match the selected "ip" field esType', () => { + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + wrapper.find('[data-test-subj="comboBoxToggleListButton"] button').simulate('click'); + + expect( + wrapper + .find('EuiComboBox[data-test-subj="valuesAutocompleteComboBox listsComboxBox"]') + .prop('options') + ).toEqual([{ label: 'some name' }]); + }); + + test('it correctly displays selected list', async () => { const wrapper = mount( ({ eui: euiLightVars, darkMode: false })}> { }).onChange([{ label: 'some name' }]); expect(mockOnChange).toHaveBeenCalledWith({ - created_at: '2020-04-20T15:25:31.830Z', + created_at: DATE_NOW, created_by: 'some user', description: 'some description', id: 'some-list-id', @@ -154,7 +219,7 @@ describe('AutocompleteFieldListsComponent', () => { name: 'some name', tie_breaker_id: '6a76b69d-80df-4ab2-8c3e-85f466b06a0e', type: 'ip', - updated_at: '2020-04-20T15:25:31.830Z', + updated_at: DATE_NOW, updated_by: 'some user', }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.tsx index d8ce27e97874d..a9d85452651b5 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.tsx @@ -36,8 +36,12 @@ export const AutocompleteFieldListsComponent: React.FC name, []); const optionsMemo = useMemo(() => { - if (selectedField != null) { - return lists.filter(({ type }) => type === selectedField.type); + if ( + selectedField != null && + selectedField.esTypes != null && + selectedField.esTypes.length > 0 + ) { + return lists.filter(({ type }) => selectedField.esTypes?.includes(type)); } else { return []; } diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx index 32a82af114bae..a082811920f88 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx @@ -79,10 +79,10 @@ export const AutocompleteFieldMatchComponent: React.FC validateParams(selectedValue, selectedField ? selectedField.type : ''), - [selectedField, selectedValue] - ); + const isValid = useMemo((): boolean => validateParams(selectedValue, selectedField), [ + selectedField, + selectedValue, + ]); return ( { const areAnyInvalid = selectedComboOptions.filter( - ({ label }) => !validateParams(label, selectedField ? selectedField.type : '') + ({ label }) => !validateParams(label, selectedField) ); return areAnyInvalid.length === 0; }, [selectedComboOptions, selectedField]); diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts index cfe23b9391ec0..cb07d99913107 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts @@ -55,49 +55,25 @@ describe('helpers', () => { describe('#validateParams', () => { test('returns true if value is undefined', () => { - const isValid = validateParams(undefined, 'date'); + const isValid = validateParams(undefined, getField('@timestamp')); expect(isValid).toBeTruthy(); }); test('returns true if value is empty string', () => { - const isValid = validateParams('', 'date'); + const isValid = validateParams('', getField('@timestamp')); expect(isValid).toBeTruthy(); }); test('returns true if type is "date" and value is valid', () => { - const isValid = validateParams('1994-11-05T08:15:30-05:00', 'date'); + const isValid = validateParams('1994-11-05T08:15:30-05:00', getField('@timestamp')); expect(isValid).toBeTruthy(); }); test('returns false if type is "date" and value is not valid', () => { - const isValid = validateParams('1593478826', 'date'); - - expect(isValid).toBeFalsy(); - }); - - test('returns true if type is "ip" and value is valid', () => { - const isValid = validateParams('126.45.211.34', 'ip'); - - expect(isValid).toBeTruthy(); - }); - - test('returns false if type is "ip" and value is not valid', () => { - const isValid = validateParams('hellooo', 'ip'); - - expect(isValid).toBeFalsy(); - }); - - test('returns true if type is "number" and value is valid', () => { - const isValid = validateParams('123', 'number'); - - expect(isValid).toBeTruthy(); - }); - - test('returns false if type is "number" and value is not valid', () => { - const isValid = validateParams('not a number', 'number'); + const isValid = validateParams('1593478826', getField('@timestamp')); expect(isValid).toBeFalsy(); }); diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts index 483ca5d6d332e..16659593784db 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts @@ -7,7 +7,7 @@ import dateMath from '@elastic/datemath'; import { EuiComboBoxOptionOption } from '@elastic/eui'; -import { IFieldType, Ipv4Address } from '../../../../../../../src/plugins/data/common'; +import { IFieldType } from '../../../../../../../src/plugins/data/common'; import { EXCEPTION_OPERATORS, @@ -30,29 +30,27 @@ export const getOperators = (field: IFieldType | undefined): OperatorOption[] => } }; -export function validateParams(params: string | undefined, type: string) { +export const validateParams = ( + params: string | undefined, + field: IFieldType | undefined +): boolean => { // Box would show error state if empty otherwise if (params == null || params === '') { return true; } - switch (type) { - case 'date': - const moment = dateMath.parse(params); - return Boolean(moment && moment.isValid()); - case 'ip': - try { - return Boolean(new Ipv4Address(params)); - } catch (e) { - return false; - } - case 'number': - const val = parseFloat(params); - return typeof val === 'number' && !isNaN(val); - default: - return true; - } -} + const types = field != null && field.esTypes != null ? field.esTypes : []; + + return types.reduce((acc, type) => { + switch (type) { + case 'date': + const moment = dateMath.parse(params); + return Boolean(moment && moment.isValid()); + default: + return acc; + } + }, true); +}; export function getGenericComboBoxProps({ options, diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx index 53c53f48f076b..e630645ef8c4e 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx @@ -22,7 +22,6 @@ import { EuiText, } from '@elastic/eui'; import { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; -import { alertsIndexPattern } from '../../../../../common/endpoint/constants'; import { ExceptionListItemSchema, CreateExceptionListItemSchema, @@ -48,24 +47,18 @@ import { } from '../helpers'; import { useFetchIndexPatterns } from '../../../../detections/containers/detection_engine/rules'; -export interface AddExceptionOnClick { +export interface AddExceptionModalBaseProps { ruleName: string; ruleId: string; exceptionListType: ExceptionListType; + ruleIndices: string[]; alertData?: { ecsData: Ecs; nonEcsData: TimelineNonEcsData[]; }; } -interface AddExceptionModalProps { - ruleName: string; - ruleId: string; - exceptionListType: ExceptionListType; - alertData?: { - ecsData: Ecs; - nonEcsData: TimelineNonEcsData[]; - }; +export interface AddExceptionModalProps extends AddExceptionModalBaseProps { onCancel: () => void; onConfirm: (didCloseAlert: boolean) => void; alertStatus?: Status; @@ -78,10 +71,8 @@ const Modal = styled(EuiModal)` `; const ModalHeader = styled(EuiModalHeader)` - ${({ theme }) => css` - flex-direction: column; - align-items: flex-start; - `} + flex-direction: column; + align-items: flex-start; `; const ModalHeaderSubtitle = styled.div` @@ -103,6 +94,7 @@ const ModalBodySection = styled.section` export const AddExceptionModal = memo(function AddExceptionModal({ ruleName, ruleId, + ruleIndices, exceptionListType, alertData, onCancel, @@ -120,10 +112,11 @@ export const AddExceptionModal = memo(function AddExceptionModal({ const [fetchOrCreateListError, setFetchOrCreateListError] = useState(false); const { addError, addSuccess } = useAppToasts(); const { loading: isSignalIndexLoading, signalIndexName } = useSignalIndex(); + const [ + { isLoading: isSignalIndexPatternLoading, indexPatterns: signalIndexPatterns }, + ] = useFetchIndexPatterns(signalIndexName !== null ? [signalIndexName] : []); - const [{ isLoading: indexPatternLoading, indexPatterns }] = useFetchIndexPatterns( - signalIndexName !== null ? [signalIndexName] : [] - ); + const [{ isLoading: isIndexPatternLoading, indexPatterns }] = useFetchIndexPatterns(ruleIndices); const onError = useCallback( (error: Error) => { @@ -183,19 +176,19 @@ export const AddExceptionModal = memo(function AddExceptionModal({ }, [alertData, exceptionListType, ruleExceptionList, ruleName]); useEffect(() => { - if (indexPatternLoading === false && isSignalIndexLoading === false) { + if (isSignalIndexPatternLoading === false && isSignalIndexLoading === false) { setShouldDisableBulkClose( entryHasListType(exceptionItemsToAdd) || - entryHasNonEcsType(exceptionItemsToAdd, indexPatterns) || + entryHasNonEcsType(exceptionItemsToAdd, signalIndexPatterns) || exceptionItemsToAdd.length === 0 ); } }, [ setShouldDisableBulkClose, exceptionItemsToAdd, - indexPatternLoading, + isSignalIndexPatternLoading, isSignalIndexLoading, - indexPatterns, + signalIndexPatterns, ]); useEffect(() => { @@ -274,15 +267,8 @@ export const AddExceptionModal = memo(function AddExceptionModal({ [fetchOrCreateListError, exceptionItemsToAdd] ); - const indexPatternConfig = useCallback(() => { - if (exceptionListType === 'endpoint') { - return [alertsIndexPattern]; - } - return signalIndexName ? [signalIndexName] : []; - }, [exceptionListType, signalIndexName]); - return ( - + {i18n.ADD_EXCEPTION} @@ -301,8 +287,9 @@ export const AddExceptionModal = memo(function AddExceptionModal({ )} {fetchOrCreateListError === false && !isSignalIndexLoading && - !indexPatternLoading && + !isSignalIndexPatternLoading && !isLoadingExceptionList && + !isIndexPatternLoading && ruleExceptionList && ( <> @@ -314,8 +301,7 @@ export const AddExceptionModal = memo(function AddExceptionModal({ listId={ruleExceptionList.list_id} listNamespaceType={ruleExceptionList.namespace_type} ruleName={ruleName} - indexPatternConfig={indexPatternConfig()} - isLoading={false} + indexPatterns={indexPatterns} isOrDisabled={false} isAndDisabled={false} data-test-subj="alert-exception-builder" diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx index 08e5b49073ecf..f6feca591dc6d 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx @@ -3,12 +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 React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState, useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import styled from 'styled-components'; import { ExceptionListItemComponent } from './builder_exception_item'; -import { useFetchIndexPatterns } from '../../../../detections/containers/detection_engine/rules/fetch_index_patterns'; +import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; import { ExceptionListItemSchema, NamespaceType, @@ -22,7 +22,6 @@ import { AndOrBadge } from '../../and_or_badge'; import { BuilderButtonOptions } from './builder_button_options'; import { getNewExceptionItem, filterExceptionItems } from '../helpers'; import { ExceptionsBuilderExceptionItem, CreateExceptionListItemBuilderSchema } from '../types'; -import { Loader } from '../../loader'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import exceptionableFields from '../exceptionable_fields.json'; @@ -51,8 +50,7 @@ interface ExceptionBuilderProps { listId: string; listNamespaceType: NamespaceType; ruleName: string; - indexPatternConfig: string[]; - isLoading: boolean; + indexPatterns: IIndexPattern; isOrDisabled: boolean; isAndDisabled: boolean; onChange: (arg: OnChangeProps) => void; @@ -64,8 +62,7 @@ export const ExceptionBuilder = ({ listId, listNamespaceType, ruleName, - indexPatternConfig, - isLoading, + indexPatterns, isOrDisabled, isAndDisabled, onChange, @@ -75,9 +72,6 @@ export const ExceptionBuilder = ({ exceptionListItems ); const [exceptionsToDelete, setExceptionsToDelete] = useState([]); - const [{ isLoading: indexPatternLoading, indexPatterns }] = useFetchIndexPatterns( - indexPatternConfig ?? [] - ); const handleCheckAndLogic = (items: ExceptionsBuilderExceptionItem[]): void => { setAndLogicIncluded(items.filter(({ entries }) => entries.length > 1).length > 0); @@ -154,7 +148,7 @@ export const ExceptionBuilder = ({ }, [setExceptions, listType, listId, listNamespaceType, ruleName]); // Filters index pattern fields by exceptionable fields if list type is endpoint - const filterIndexPatterns = useCallback(() => { + const filterIndexPatterns = useMemo((): IIndexPattern => { if (listType === 'endpoint') { return { ...indexPatterns, @@ -196,9 +190,6 @@ export const ExceptionBuilder = ({ return ( - {(isLoading || indexPatternLoading) && ( - - )} {exceptions.map((exceptionListItem, index) => ( @@ -224,8 +215,8 @@ export const ExceptionBuilder = ({ key={getExceptionListItemId(exceptionListItem, index)} exceptionItem={exceptionListItem} exceptionId={getExceptionListItemId(exceptionListItem, index)} - indexPattern={filterIndexPatterns()} - isLoading={indexPatternLoading} + indexPattern={filterIndexPatterns} + isLoading={indexPatterns.fields.length === 0} exceptionItemIndex={index} andLogicIncluded={andLogicIncluded} isOnlyItem={exceptions.length === 1} diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx index 51cc684a01de6..d07a8b5f0d2f6 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx @@ -20,7 +20,6 @@ import { EuiFormRow, EuiText, } from '@elastic/eui'; -import { alertsIndexPattern } from '../../../../../common/endpoint/constants'; import { useFetchIndexPatterns } from '../../../../detections/containers/detection_engine/rules'; import { useSignalIndex } from '../../../../detections/containers/detection_engine/alerts/use_signal_index'; import { @@ -45,6 +44,7 @@ import { Loader } from '../../loader'; interface EditExceptionModalProps { ruleName: string; + ruleIndices: string[]; exceptionItem: ExceptionListItemSchema; exceptionListType: ExceptionListType; onCancel: () => void; @@ -58,10 +58,8 @@ const Modal = styled(EuiModal)` `; const ModalHeader = styled(EuiModalHeader)` - ${({ theme }) => css` - flex-direction: column; - align-items: flex-start; - `} + flex-direction: column; + align-items: flex-start; `; const ModalHeaderSubtitle = styled.div` @@ -82,6 +80,7 @@ const ModalBodySection = styled.section` export const EditExceptionModal = memo(function EditExceptionModal({ ruleName, + ruleIndices, exceptionItem, exceptionListType, onCancel, @@ -96,10 +95,11 @@ export const EditExceptionModal = memo(function EditExceptionModal({ >([]); const { addError, addSuccess } = useAppToasts(); const { loading: isSignalIndexLoading, signalIndexName } = useSignalIndex(); + const [ + { isLoading: isSignalIndexPatternLoading, indexPatterns: signalIndexPatterns }, + ] = useFetchIndexPatterns(signalIndexName !== null ? [signalIndexName] : []); - const [{ isLoading: indexPatternLoading, indexPatterns }] = useFetchIndexPatterns( - signalIndexName !== null ? [signalIndexName] : [] - ); + const [{ isLoading: isIndexPatternLoading, indexPatterns }] = useFetchIndexPatterns(ruleIndices); const onError = useCallback( (error) => { @@ -122,19 +122,19 @@ export const EditExceptionModal = memo(function EditExceptionModal({ ); useEffect(() => { - if (indexPatternLoading === false && isSignalIndexLoading === false) { + if (isSignalIndexPatternLoading === false && isSignalIndexLoading === false) { setShouldDisableBulkClose( entryHasListType(exceptionItemsToAdd) || - entryHasNonEcsType(exceptionItemsToAdd, indexPatterns) || + entryHasNonEcsType(exceptionItemsToAdd, signalIndexPatterns) || exceptionItemsToAdd.length === 0 ); } }, [ setShouldDisableBulkClose, exceptionItemsToAdd, - indexPatternLoading, + isSignalIndexPatternLoading, isSignalIndexLoading, - indexPatterns, + signalIndexPatterns, ]); useEffect(() => { @@ -189,15 +189,8 @@ export const EditExceptionModal = memo(function EditExceptionModal({ } }, [addOrUpdateExceptionItems, enrichExceptionItems, shouldBulkCloseAlert, signalIndexName]); - const indexPatternConfig = useCallback(() => { - if (exceptionListType === 'endpoint') { - return [alertsIndexPattern]; - } - return signalIndexName ? [signalIndexName] : []; - }, [exceptionListType, signalIndexName]); - return ( - + {i18n.EDIT_EXCEPTION_TITLE} @@ -206,11 +199,11 @@ export const EditExceptionModal = memo(function EditExceptionModal({ - {(addExceptionIsLoading || indexPatternLoading || isSignalIndexLoading) && ( + {(addExceptionIsLoading || isIndexPatternLoading || isSignalIndexLoading) && ( )} - {!isSignalIndexLoading && !addExceptionIsLoading && !indexPatternLoading && ( + {!isSignalIndexLoading && !addExceptionIsLoading && !isIndexPatternLoading && ( <> {i18n.EXCEPTION_BUILDER_INFO} @@ -221,13 +214,12 @@ export const EditExceptionModal = memo(function EditExceptionModal({ listId={exceptionItem.list_id} listNamespaceType={exceptionItem.namespace_type} ruleName={ruleName} - isLoading={false} isOrDisabled={false} isAndDisabled={false} data-test-subj="edit-exception-modal-builder" id-aria="edit-exception-modal-builder" onChange={handleBuilderOnChange} - indexPatternConfig={indexPatternConfig()} + indexPatterns={indexPatterns} /> diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx index f72008cbdffe1..986f27f6495ec 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx @@ -67,6 +67,7 @@ describe('ExceptionsViewer', () => { ({ eui: euiLightVars, darkMode: false })}> { const wrapper = mount( ({ eui: euiLightVars, darkMode: false })}> { const wrapper = mount( ({ eui: euiLightVars, darkMode: false })}> { + }: UseExceptionListSuccess): void => { dispatch({ type: 'setExceptions', lists: newLists, @@ -253,10 +255,11 @@ const ExceptionsViewerComponent = ({ return ( <> {currentModal === 'editModal' && - exceptionToEdit !== null && - exceptionListTypeToEdit !== null && ( + exceptionToEdit != null && + exceptionListTypeToEdit != null && ( 0 ? { fields: fields.map((field) => - pick(['name', 'searchable', 'type', 'aggregatable'], field) + pick(['name', 'searchable', 'type', 'aggregatable', 'esTypes', 'subType'], field) ), title, } diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx index 71cf5c10de764..a4ce6c0200eb3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx @@ -12,6 +12,7 @@ import { Dispatch } from 'redux'; import { EuiText } from '@elastic/eui'; import { RowRendererId } from '../../../../common/types/timeline'; +import { DEFAULT_INDEX_PATTERN } from '../../../../common/constants'; import { Status } from '../../../../common/detection_engine/schemas/common/schemas'; import { Filter } from '../../../../../../../src/plugins/data/common/es_query'; import { @@ -38,7 +39,7 @@ import { UpdateTimelineLoading, } from './types'; import { Ecs, TimelineNonEcsData } from '../../../graphql/types'; -import { AddExceptionOnClick } from '../../../common/components/exceptions/add_exception_modal'; +import { AddExceptionModalBaseProps } from '../../../common/components/exceptions/add_exception_modal'; import { getMappedNonEcsValue } from '../../../common/components/exceptions/helpers'; export const buildAlertStatusFilter = (status: Status): Filter[] => [ @@ -225,7 +226,7 @@ interface AlertActionArgs { alertData, ruleName, ruleId, - }: AddExceptionOnClick) => void; + }: AddExceptionModalBaseProps) => void; } export const getAlertActions = ({ @@ -346,10 +347,12 @@ export const getAlertActions = ({ onClick: ({ ecsData, data }: TimelineRowActionOnClick) => { const [ruleName] = getMappedNonEcsValue({ data, fieldName: 'signal.rule.name' }); const [ruleId] = getMappedNonEcsValue({ data, fieldName: 'signal.rule.id' }); + const ruleIndices = getMappedNonEcsValue({ data, fieldName: 'signal.rule.index' }); if (ruleId !== undefined) { openAddExceptionModal({ ruleName: ruleName ?? '', ruleId, + ruleIndices: ruleIndices.length > 0 ? ruleIndices : DEFAULT_INDEX_PATTERN, exceptionListType: 'endpoint', alertData: { ecsData, @@ -369,10 +372,12 @@ export const getAlertActions = ({ onClick: ({ ecsData, data }: TimelineRowActionOnClick) => { const [ruleName] = getMappedNonEcsValue({ data, fieldName: 'signal.rule.name' }); const [ruleId] = getMappedNonEcsValue({ data, fieldName: 'signal.rule.id' }); + const ruleIndices = getMappedNonEcsValue({ data, fieldName: 'signal.rule.index' }); if (ruleId !== undefined) { openAddExceptionModal({ ruleName: ruleName ?? '', ruleId, + ruleIndices: ruleIndices.length > 0 ? ruleIndices : DEFAULT_INDEX_PATTERN, exceptionListType: 'detection', alertData: { ecsData, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index 1d4c97d85443f..1eda358fe5944 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -54,7 +54,7 @@ import { import { getInvestigateInResolverAction } from '../../../timelines/components/timeline/body/helpers'; import { AddExceptionModal, - AddExceptionOnClick, + AddExceptionModalBaseProps, } from '../../../common/components/exceptions/add_exception_modal'; interface OwnProps { @@ -73,9 +73,10 @@ interface OwnProps { type AlertsTableComponentProps = OwnProps & PropsFromRedux; -const addExceptionModalInitialState: AddExceptionOnClick = { +const addExceptionModalInitialState: AddExceptionModalBaseProps = { ruleName: '', ruleId: '', + ruleIndices: [], exceptionListType: 'detection', alertData: undefined, }; @@ -112,7 +113,7 @@ export const AlertsTableComponent: React.FC = ({ const [showClearSelectionAction, setShowClearSelectionAction] = useState(false); const [filterGroup, setFilterGroup] = useState(FILTER_OPEN); const [shouldShowAddExceptionModal, setShouldShowAddExceptionModal] = useState(false); - const [addExceptionModalState, setAddExceptionModalState] = useState( + const [addExceptionModalState, setAddExceptionModalState] = useState( addExceptionModalInitialState ); const [{ browserFields, indexPatterns }] = useFetchIndexPatterns( @@ -216,12 +217,19 @@ export const AlertsTableComponent: React.FC = ({ ); const openAddExceptionModalCallback = useCallback( - ({ ruleName, ruleId, exceptionListType, alertData }: AddExceptionOnClick) => { + ({ + ruleName, + ruleIndices, + ruleId, + exceptionListType, + alertData, + }: AddExceptionModalBaseProps) => { if (alertData !== null && alertData !== undefined) { setShouldShowAddExceptionModal(true); setAddExceptionModalState({ ruleName, ruleId, + ruleIndices, exceptionListType, alertData, }); @@ -421,12 +429,9 @@ export const AlertsTableComponent: React.FC = ({ closeAddExceptionModal(); }, [closeAddExceptionModal]); - const onAddExceptionConfirm = useCallback( - (didCloseAlert: boolean) => { - closeAddExceptionModal(); - }, - [closeAddExceptionModal] - ); + const onAddExceptionConfirm = useCallback(() => closeAddExceptionModal(), [ + closeAddExceptionModal, + ]); if (loading || isEmpty(signalsIndex)) { return ( @@ -454,6 +459,7 @@ export const AlertsTableComponent: React.FC = ({ = ({ ; format?: Maybe; + /** the elastic type as mapped in the index */ + esTypes?: Maybe; + + subType?: Maybe; } export interface AuthenticationsData { @@ -2780,6 +2788,10 @@ export namespace SourceQuery { aggregatable: boolean; format: Maybe; + + esTypes: Maybe; + + subType: Maybe; }; } diff --git a/x-pack/plugins/security_solution/server/graphql/ecs/resolvers.ts b/x-pack/plugins/security_solution/server/graphql/ecs/resolvers.ts index f30b7d192d05d..414e5b5d95bec 100644 --- a/x-pack/plugins/security_solution/server/graphql/ecs/resolvers.ts +++ b/x-pack/plugins/security_solution/server/graphql/ecs/resolvers.ts @@ -47,9 +47,41 @@ export const toStringArrayScalar = new GraphQLScalarType({ return null; }, }); - +export const toStringArrayNoNullableScalar = new GraphQLScalarType({ + name: 'StringArray', + description: 'Represents value in detail item from the timeline who wants to more than one type', + serialize(value): string[] | undefined { + if (value == null) { + return undefined; + } else if (Array.isArray(value)) { + return convertArrayToString(value) as string[]; + } else if (isBoolean(value) || isNumber(value) || isObject(value)) { + return [convertToString(value)]; + } + return [value]; + }, + parseValue(value) { + return value; + }, + parseLiteral(ast) { + switch (ast.kind) { + case Kind.INT: + return parseInt(ast.value, 10); + case Kind.FLOAT: + return parseFloat(ast.value); + case Kind.STRING: + return ast.value; + case Kind.LIST: + return ast.values; + case Kind.OBJECT: + return ast.fields; + } + return undefined; + }, +}); export const createScalarToStringArrayValueResolvers = () => ({ ToStringArray: toStringArrayScalar, + ToStringArrayNoNullable: toStringArrayNoNullableScalar, }); const convertToString = (value: object | number | boolean | string): string => { diff --git a/x-pack/plugins/security_solution/server/graphql/ecs/schema.gql.ts b/x-pack/plugins/security_solution/server/graphql/ecs/schema.gql.ts index 5b093a02b6514..bdc69f85d3542 100644 --- a/x-pack/plugins/security_solution/server/graphql/ecs/schema.gql.ts +++ b/x-pack/plugins/security_solution/server/graphql/ecs/schema.gql.ts @@ -8,6 +8,7 @@ import gql from 'graphql-tag'; export const ecsSchema = gql` scalar ToStringArray + scalar ToStringArrayNoNullable type EventEcsFields { action: ToStringArray diff --git a/x-pack/plugins/security_solution/server/graphql/source_status/resolvers.ts b/x-pack/plugins/security_solution/server/graphql/source_status/resolvers.ts index 24589822f0250..8d55e645d6791 100644 --- a/x-pack/plugins/security_solution/server/graphql/source_status/resolvers.ts +++ b/x-pack/plugins/security_solution/server/graphql/source_status/resolvers.ts @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import { GraphQLScalarType, Kind } from 'graphql'; import { SourceStatusResolvers } from '../../graphql/types'; import { AppResolverOf, ChildResolverOf } from '../../lib/framework'; import { IndexFields } from '../../lib/index_fields'; import { SourceStatus } from '../../lib/source_status'; import { QuerySourceResolver } from '../sources/resolvers'; +import { IFieldSubType } from '../../../../../../src/plugins/data/common/index_patterns/types'; export type SourceStatusIndicesExistResolver = ChildResolverOf< AppResolverOf, @@ -50,3 +52,40 @@ export const createSourceStatusResolvers = (libs: { }, }, }); + +export const toIFieldSubTypeNonNullableScalar = new GraphQLScalarType({ + name: 'IFieldSubType', + description: 'Represents value in index pattern field item', + serialize(value): IFieldSubType | undefined { + if (value == null) { + return undefined; + } + + return { + multi: value.multi ?? undefined, + nested: value.nested ?? undefined, + }; + }, + parseValue(value) { + return value; + }, + parseLiteral(ast) { + switch (ast.kind) { + case Kind.INT: + return undefined; + case Kind.FLOAT: + return undefined; + case Kind.STRING: + return undefined; + case Kind.LIST: + return undefined; + case Kind.OBJECT: + return ast; + } + return undefined; + }, +}); + +export const createScalarToIFieldSubTypeNonNullableScalarResolvers = () => ({ + ToIFieldSubTypeNonNullable: toIFieldSubTypeNonNullableScalar, +}); diff --git a/x-pack/plugins/security_solution/server/graphql/source_status/schema.gql.ts b/x-pack/plugins/security_solution/server/graphql/source_status/schema.gql.ts index e484b60f8f364..3062113f1b635 100644 --- a/x-pack/plugins/security_solution/server/graphql/source_status/schema.gql.ts +++ b/x-pack/plugins/security_solution/server/graphql/source_status/schema.gql.ts @@ -7,6 +7,8 @@ import gql from 'graphql-tag'; export const sourceStatusSchema = gql` + scalar ToIFieldSubTypeNonNullable + "A descriptor of a field in an index" type IndexField { "Where the field belong" @@ -26,6 +28,9 @@ export const sourceStatusSchema = gql` "Description of the field" description: String format: String + "the elastic type as mapped in the index" + esTypes: ToStringArrayNoNullable + subType: ToIFieldSubTypeNonNullable } extend type SourceStatus { diff --git a/x-pack/plugins/security_solution/server/graphql/types.ts b/x-pack/plugins/security_solution/server/graphql/types.ts index f8a614e86f28e..1e397a4e6bb6c 100644 --- a/x-pack/plugins/security_solution/server/graphql/types.ts +++ b/x-pack/plugins/security_solution/server/graphql/types.ts @@ -430,6 +430,10 @@ export enum FlowDirection { biDirectional = 'biDirectional', } +export type ToStringArrayNoNullable = any; + +export type ToIFieldSubTypeNonNullable = any; + export type ToStringArray = string[] | string; export type Date = string; @@ -629,6 +633,10 @@ export interface IndexField { description?: Maybe; format?: Maybe; + /** the elastic type as mapped in the index */ + esTypes?: Maybe; + + subType?: Maybe; } export interface AuthenticationsData { @@ -3579,6 +3587,10 @@ export namespace IndexFieldResolvers { description?: DescriptionResolver, TypeParent, TContext>; format?: FormatResolver, TypeParent, TContext>; + /** the elastic type as mapped in the index */ + esTypes?: EsTypesResolver, TypeParent, TContext>; + + subType?: SubTypeResolver, TypeParent, TContext>; } export type CategoryResolver = Resolver< @@ -3626,6 +3638,16 @@ export namespace IndexFieldResolvers { Parent = IndexField, TContext = SiemContext > = Resolver; + export type EsTypesResolver< + R = Maybe, + Parent = IndexField, + TContext = SiemContext + > = Resolver; + export type SubTypeResolver< + R = Maybe, + Parent = IndexField, + TContext = SiemContext + > = Resolver; } export namespace AuthenticationsDataResolvers { @@ -9317,6 +9339,14 @@ export interface DeprecatedDirectiveArgs { reason?: string; } +export interface ToStringArrayNoNullableScalarConfig + extends GraphQLScalarTypeConfig { + name: 'ToStringArrayNoNullable'; +} +export interface ToIFieldSubTypeNonNullableScalarConfig + extends GraphQLScalarTypeConfig { + name: 'ToIFieldSubTypeNonNullable'; +} export interface ToStringArrayScalarConfig extends GraphQLScalarTypeConfig { name: 'ToStringArray'; } @@ -9490,6 +9520,8 @@ export type IResolvers = { EventsTimelineData?: EventsTimelineDataResolvers.Resolvers; OsFields?: OsFieldsResolvers.Resolvers; HostFields?: HostFieldsResolvers.Resolvers; + ToStringArrayNoNullable?: GraphQLScalarType; + ToIFieldSubTypeNonNullable?: GraphQLScalarType; ToStringArray?: GraphQLScalarType; Date?: GraphQLScalarType; ToNumberArray?: GraphQLScalarType; diff --git a/x-pack/plugins/security_solution/server/lib/index_fields/types.ts b/x-pack/plugins/security_solution/server/lib/index_fields/types.ts index 0c894c6980a31..67b3c254007e2 100644 --- a/x-pack/plugins/security_solution/server/lib/index_fields/types.ts +++ b/x-pack/plugins/security_solution/server/lib/index_fields/types.ts @@ -6,6 +6,7 @@ import { IndexField } from '../../graphql/types'; import { FrameworkRequest } from '../framework'; +import { IFieldSubType } from '../../../../../../src/plugins/data/common'; export interface FieldsAdapter { getIndexFields(req: FrameworkRequest, indices: string[]): Promise; @@ -16,4 +17,6 @@ export interface IndexFieldDescriptor { type: string; searchable: boolean; aggregatable: boolean; + esTypes?: string[]; + subType?: IFieldSubType; } From 3760dc4f45c466f4379346bf7d6a20c8dfdd2080 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen <43350163+qn895@users.noreply.github.com> Date: Mon, 20 Jul 2020 19:34:53 -0500 Subject: [PATCH 27/77] [ML] Fix annotation detector linking & delayed_data(0) (#72468) --- .../annotations_table/annotations_table.js | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js index 86398a57c3a45..69f7635a66032 100644 --- a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js +++ b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js @@ -256,7 +256,7 @@ export class AnnotationsTable extends Component { // if the annotation is at the series level // then pass the partitioning field(s) and detector index to the Single Metric Viewer if (_.has(annotation, 'detector_index')) { - mlTimeSeriesExplorer.detector_index = annotation.detector_index; + mlTimeSeriesExplorer.detectorIndex = annotation.detector_index; } if (_.has(annotation, 'partition_field_value')) { entityCondition[annotation.partition_field_name] = annotation.partition_field_value; @@ -523,10 +523,26 @@ export class AnnotationsTable extends Component { const aggregations = this.props.aggregations ?? this.state.aggregations; if (aggregations) { const buckets = aggregations.event.buckets; - const foundUser = buckets.findIndex((d) => d.key === ANNOTATION_EVENT_USER) > -1; - filterOptions = foundUser - ? buckets - : [{ key: ANNOTATION_EVENT_USER, doc_count: 0 }, ...buckets]; + let foundUser = false; + let foundDelayedData = false; + + buckets.forEach((bucket) => { + if (bucket.key === ANNOTATION_EVENT_USER) { + foundUser = true; + } + if (bucket.key === ANNOTATION_EVENT_DELAYED_DATA) { + foundDelayedData = true; + } + }); + const adjustedBuckets = []; + if (!foundUser) { + adjustedBuckets.push({ key: ANNOTATION_EVENT_USER, doc_count: 0 }); + } + if (!foundDelayedData) { + adjustedBuckets.push({ key: ANNOTATION_EVENT_DELAYED_DATA, doc_count: 0 }); + } + + filterOptions = [...adjustedBuckets, ...buckets]; } const filters = [ { From 990d4c5eec01bc66b434c9d224e7a0965a4c4770 Mon Sep 17 00:00:00 2001 From: Brent Kimmel Date: Mon, 20 Jul 2020 20:59:55 -0400 Subject: [PATCH 28/77] [Security_Solution][Resolver][Bug]: Restore breadcrumb background (#72538) --- .../public/resolver/view/panels/panel_content_utilities.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_utilities.tsx b/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_utilities.tsx index 4dedafe55bb2c..55b5be21fb4a4 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_utilities.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_utilities.tsx @@ -32,7 +32,7 @@ export interface CrumbInfo { } const ThemedBreadcrumbs = styled(EuiBreadcrumbs)<{ background: string; text: string }>` - &.euiBreadcrumbs.euiBreadcrumbs--responsive { + &.euiBreadcrumbs { background-color: ${(props) => props.background}; color: ${(props) => props.text}; padding: 1em; From bfbb8d213816d7d28fbbb121dc58b52d1bb42e0d Mon Sep 17 00:00:00 2001 From: Clint Andrew Hall Date: Mon, 20 Jul 2020 22:18:20 -0400 Subject: [PATCH 29/77] [pre-req] Move .storybook to storybook; standardize files (#72384) --- .eslintignore | 2 +- .eslintrc.js | 6 + src/dev/precommit_hook/casing_check_config.js | 2 +- x-pack/plugins/canvas/.gitignore | 2 +- ...shot => advanced_filter.stories.storyshot} | 0 ...amples.tsx => advanced_filter.stories.tsx} | 0 ...shot => dropdown_filter.stories.storyshot} | 0 ...amples.tsx => dropdown_filter.stories.tsx} | 0 .../time_filter.examples.storyshot | 134 ----- ...ples.storyshot => asset.stories.storyshot} | 0 .../asset_manager.examples.storyshot | 37 -- .../{asset.examples.tsx => asset.stories.tsx} | 0 .../__examples__/color_picker.stories.tsx | 3 +- ...=> custom_element_modal.stories.storyshot} | 0 ...s.tsx => custom_element_modal.stories.tsx} | 0 ...ples.storyshot => debug.stories.storyshot} | 0 .../{debug.examples.tsx => debug.stories.tsx} | 0 .../element_controls.examples.storyshot | 98 ---- ...hot => expression_input.stories.storyshot} | 0 ...mples.tsx => expression_input.stories.tsx} | 0 ....storyshot => edit_menu.stories.storyshot} | 0 ...enu.examples.tsx => edit_menu.stories.tsx} | 0 ...oryshot => element_menu.stories.storyshot} | 0 ....examples.tsx => element_menu.stories.tsx} | 0 ...storyshot => share_menu.stories.storyshot} | 0 ...nu.examples.tsx => share_menu.stories.tsx} | 0 ...ot => extended_template.stories.storyshot} | 0 ...shot => simple_template.stories.storyshot} | 0 ...ples.tsx => extended_template.stories.tsx} | 0 ...amples.tsx => simple_template.stories.tsx} | 0 ...ot => extended_template.stories.storyshot} | 0 ...shot => simple_template.stories.storyshot} | 0 ...ples.tsx => extended_template.stories.tsx} | 3 +- ...amples.tsx => simple_template.stories.tsx} | 0 x-pack/plugins/canvas/scripts/jest.js | 2 +- x-pack/plugins/canvas/scripts/storybook.js | 6 +- ...les.storyshot => canvas.stories.storyshot} | 0 ...mples.storyshot => page.stories.storyshot} | 0 ...hot => rendered_element.stories.storyshot} | 0 ...canvas.examples.tsx => canvas.stories.tsx} | 0 .../{page.examples.tsx => page.stories.tsx} | 0 ...mples.tsx => rendered_element.stories.tsx} | 0 .../footer.components.examples.storyshot | 140 ----- ...les.storyshot => footer.stories.storyshot} | 0 ...ryshot => page_controls.stories.storyshot} | 0 ...s.storyshot => scrubber.stories.storyshot} | 0 ...ples.storyshot => title.stories.storyshot} | 0 ...footer.examples.tsx => footer.stories.tsx} | 0 ...examples.tsx => page_controls.stories.tsx} | 0 ...bber.examples.tsx => scrubber.stories.tsx} | 0 .../{title.examples.tsx => title.stories.tsx} | 0 ...ot => autoplay_settings.stories.storyshot} | 0 .../settings.components.examples.storyshot | 479 ------------------ ...s.storyshot => settings.stories.storyshot} | 0 ...hot => toolbar_settings.stories.storyshot} | 0 ...ples.tsx => autoplay_settings.stories.tsx} | 0 ...ings.examples.tsx => settings.stories.tsx} | 0 ...mples.tsx => toolbar_settings.stories.tsx} | 0 .../canvas/{.storybook => storybook}/.babelrc | 0 .../{.storybook => storybook}/addons.js | 0 .../{.storybook => storybook}/config.js | 25 +- .../{.storybook => storybook}/constants.js | 0 .../canvas/storybook/decorators/index.ts | 19 + .../storybook/decorators/kibana_decorator.tsx | 26 + .../storybook/decorators/router_decorator.tsx | 30 ++ .../{.storybook => storybook}/dll_contexts.js | 6 +- .../{.storybook => storybook}/middleware.js | 9 +- .../preview-head.html | 0 .../storyshots.test.js | 14 +- .../webpack.config.js | 29 +- .../webpack.dll.config.js | 2 +- 71 files changed, 136 insertions(+), 938 deletions(-) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/advanced_filter/component/__examples__/__snapshots__/{advanced_filter.examples.storyshot => advanced_filter.stories.storyshot} (100%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/advanced_filter/component/__examples__/{advanced_filter.examples.tsx => advanced_filter.stories.tsx} (100%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/dropdown_filter/component/__examples__/__snapshots__/{dropdown_filter.examples.storyshot => dropdown_filter.stories.storyshot} (100%) rename x-pack/plugins/canvas/canvas_plugin_src/renderers/dropdown_filter/component/__examples__/{dropdown_filter.examples.tsx => dropdown_filter.stories.tsx} (100%) delete mode 100644 x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/__examples__/__snapshots__/time_filter.examples.storyshot rename x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/{asset.examples.storyshot => asset.stories.storyshot} (100%) delete mode 100644 x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset_manager.examples.storyshot rename x-pack/plugins/canvas/public/components/asset_manager/__examples__/{asset.examples.tsx => asset.stories.tsx} (100%) rename x-pack/plugins/canvas/public/components/custom_element_modal/__examples__/__snapshots__/{custom_element_modal.examples.storyshot => custom_element_modal.stories.storyshot} (100%) rename x-pack/plugins/canvas/public/components/custom_element_modal/__examples__/{custom_element_modal.examples.tsx => custom_element_modal.stories.tsx} (100%) rename x-pack/plugins/canvas/public/components/debug/__examples__/__snapshots__/{debug.examples.storyshot => debug.stories.storyshot} (100%) rename x-pack/plugins/canvas/public/components/debug/__examples__/{debug.examples.tsx => debug.stories.tsx} (100%) delete mode 100644 x-pack/plugins/canvas/public/components/element_card/__examples__/__snapshots__/element_controls.examples.storyshot rename x-pack/plugins/canvas/public/components/expression_input/__examples__/__snapshots__/{expression_input.examples.storyshot => expression_input.stories.storyshot} (100%) rename x-pack/plugins/canvas/public/components/expression_input/__examples__/{expression_input.examples.tsx => expression_input.stories.tsx} (100%) rename x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__examples__/__snapshots__/{edit_menu.examples.storyshot => edit_menu.stories.storyshot} (100%) rename x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__examples__/{edit_menu.examples.tsx => edit_menu.stories.tsx} (100%) rename x-pack/plugins/canvas/public/components/workpad_header/element_menu/__examples__/__snapshots__/{element_menu.examples.storyshot => element_menu.stories.storyshot} (100%) rename x-pack/plugins/canvas/public/components/workpad_header/element_menu/__examples__/{element_menu.examples.tsx => element_menu.stories.tsx} (100%) rename x-pack/plugins/canvas/public/components/workpad_header/share_menu/__examples__/__snapshots__/{share_menu.examples.storyshot => share_menu.stories.storyshot} (100%) rename x-pack/plugins/canvas/public/components/workpad_header/share_menu/__examples__/{share_menu.examples.tsx => share_menu.stories.tsx} (100%) rename x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/__snapshots__/{extended_template.examples.storyshot => extended_template.stories.storyshot} (100%) rename x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/__snapshots__/{simple_template.examples.storyshot => simple_template.stories.storyshot} (100%) rename x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/{extended_template.examples.tsx => extended_template.stories.tsx} (100%) rename x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/{simple_template.examples.tsx => simple_template.stories.tsx} (100%) rename x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/{extended_template.examples.storyshot => extended_template.stories.storyshot} (100%) rename x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/{simple_template.examples.storyshot => simple_template.stories.storyshot} (100%) rename x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/{extended_template.examples.tsx => extended_template.stories.tsx} (95%) rename x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/{simple_template.examples.tsx => simple_template.stories.tsx} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/{canvas.examples.storyshot => canvas.stories.storyshot} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/{page.examples.storyshot => page.stories.storyshot} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/{rendered_element.examples.storyshot => rendered_element.stories.storyshot} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/__examples__/{canvas.examples.tsx => canvas.stories.tsx} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/__examples__/{page.examples.tsx => page.stories.tsx} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/__examples__/{rendered_element.examples.tsx => rendered_element.stories.tsx} (100%) delete mode 100644 x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/footer.components.examples.storyshot rename x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/{footer.examples.storyshot => footer.stories.storyshot} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/{page_controls.examples.storyshot => page_controls.stories.storyshot} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/{scrubber.examples.storyshot => scrubber.stories.storyshot} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/{title.examples.storyshot => title.stories.storyshot} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/{footer.examples.tsx => footer.stories.tsx} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/{page_controls.examples.tsx => page_controls.stories.tsx} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/{scrubber.examples.tsx => scrubber.stories.tsx} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/{title.examples.tsx => title.stories.tsx} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/{autoplay_settings.examples.storyshot => autoplay_settings.stories.storyshot} (100%) delete mode 100644 x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/settings.components.examples.storyshot rename x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/{settings.examples.storyshot => settings.stories.storyshot} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/{toolbar_settings.examples.storyshot => toolbar_settings.stories.storyshot} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/{autoplay_settings.examples.tsx => autoplay_settings.stories.tsx} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/{settings.examples.tsx => settings.stories.tsx} (100%) rename x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/{toolbar_settings.examples.tsx => toolbar_settings.stories.tsx} (100%) rename x-pack/plugins/canvas/{.storybook => storybook}/.babelrc (100%) rename x-pack/plugins/canvas/{.storybook => storybook}/addons.js (100%) rename x-pack/plugins/canvas/{.storybook => storybook}/config.js (67%) rename x-pack/plugins/canvas/{.storybook => storybook}/constants.js (100%) create mode 100644 x-pack/plugins/canvas/storybook/decorators/index.ts create mode 100644 x-pack/plugins/canvas/storybook/decorators/kibana_decorator.tsx create mode 100644 x-pack/plugins/canvas/storybook/decorators/router_decorator.tsx rename x-pack/plugins/canvas/{.storybook => storybook}/dll_contexts.js (88%) rename x-pack/plugins/canvas/{.storybook => storybook}/middleware.js (72%) rename x-pack/plugins/canvas/{.storybook => storybook}/preview-head.html (100%) rename x-pack/plugins/canvas/{.storybook => storybook}/storyshots.test.js (95%) rename x-pack/plugins/canvas/{.storybook => storybook}/webpack.config.js (88%) rename x-pack/plugins/canvas/{.storybook => storybook}/webpack.dll.config.js (100%) diff --git a/.eslintignore b/.eslintignore index d983c4bedfaab..9263b483b8de9 100644 --- a/.eslintignore +++ b/.eslintignore @@ -33,7 +33,7 @@ target /x-pack/plugins/canvas/canvas_plugin /x-pack/plugins/canvas/canvas_plugin_src/lib/flot-charts /x-pack/plugins/canvas/shareable_runtime/build -/x-pack/plugins/canvas/storybook +/x-pack/plugins/canvas/storybook/build /x-pack/plugins/monitoring/public/lib/jquery_flot /x-pack/plugins/reporting/server/export_types/printable_pdf/server/lib/pdf/assets/** /x-pack/legacy/plugins/infra/common/graphql/types.ts diff --git a/.eslintrc.js b/.eslintrc.js index a9ffe2850aa72..e2674e8d7b407 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1222,6 +1222,12 @@ module.exports = { ], }, }, + { + files: ['x-pack/plugins/canvas/storybook/**'], + rules: { + 'import/no-extraneous-dependencies': 0, + }, + }, { files: ['x-pack/plugins/canvas/canvas_plugin_src/**/*.js'], globals: { canvas: true, $: true }, diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index 929de8c6701d4..1e4f048be8ea4 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -51,7 +51,7 @@ export const IGNORE_FILE_GLOBS = [ '.ci/pipeline-library/**/*', // Files in this directory must match a pre-determined name in some cases. - 'x-pack/plugins/canvas/.storybook/*', + 'x-pack/plugins/canvas/storybook/*', // filename must match language code which requires capital letters '**/translations/*.json', diff --git a/x-pack/plugins/canvas/.gitignore b/x-pack/plugins/canvas/.gitignore index 1c6258670c59c..d47bd8acf6be2 100644 --- a/x-pack/plugins/canvas/.gitignore +++ b/x-pack/plugins/canvas/.gitignore @@ -57,4 +57,4 @@ canvas_plugin/* webpack_stats.json # Don't commit storybook builds -storybook +storybook/build diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/advanced_filter/component/__examples__/__snapshots__/advanced_filter.examples.storyshot b/x-pack/plugins/canvas/canvas_plugin_src/renderers/advanced_filter/component/__examples__/__snapshots__/advanced_filter.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/advanced_filter/component/__examples__/__snapshots__/advanced_filter.examples.storyshot rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/advanced_filter/component/__examples__/__snapshots__/advanced_filter.stories.storyshot diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/advanced_filter/component/__examples__/advanced_filter.examples.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/advanced_filter/component/__examples__/advanced_filter.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/advanced_filter/component/__examples__/advanced_filter.examples.tsx rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/advanced_filter/component/__examples__/advanced_filter.stories.tsx diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/dropdown_filter/component/__examples__/__snapshots__/dropdown_filter.examples.storyshot b/x-pack/plugins/canvas/canvas_plugin_src/renderers/dropdown_filter/component/__examples__/__snapshots__/dropdown_filter.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/dropdown_filter/component/__examples__/__snapshots__/dropdown_filter.examples.storyshot rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/dropdown_filter/component/__examples__/__snapshots__/dropdown_filter.stories.storyshot diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/dropdown_filter/component/__examples__/dropdown_filter.examples.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/dropdown_filter/component/__examples__/dropdown_filter.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/canvas_plugin_src/renderers/dropdown_filter/component/__examples__/dropdown_filter.examples.tsx rename to x-pack/plugins/canvas/canvas_plugin_src/renderers/dropdown_filter/component/__examples__/dropdown_filter.stories.tsx diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/__examples__/__snapshots__/time_filter.examples.storyshot b/x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/__examples__/__snapshots__/time_filter.examples.storyshot deleted file mode 100644 index d555fbbe0ce92..0000000000000 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/__examples__/__snapshots__/time_filter.examples.storyshot +++ /dev/null @@ -1,134 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots renderers/TimeFilter default 1`] = ` -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
- → -
-
-
-
- -
-
-
-
-
-
-
-
-`; diff --git a/x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset.examples.storyshot b/x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset.examples.storyshot rename to x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset.stories.storyshot diff --git a/x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset_manager.examples.storyshot b/x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset_manager.examples.storyshot deleted file mode 100644 index 9f91668e602a4..0000000000000 --- a/x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset_manager.examples.storyshot +++ /dev/null @@ -1,37 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots components/Assets/AssetManager no assets 1`] = ` - -`; - -exports[`Storyshots components/Assets/AssetManager two assets 1`] = ` - -`; diff --git a/x-pack/plugins/canvas/public/components/asset_manager/__examples__/asset.examples.tsx b/x-pack/plugins/canvas/public/components/asset_manager/__examples__/asset.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/public/components/asset_manager/__examples__/asset.examples.tsx rename to x-pack/plugins/canvas/public/components/asset_manager/__examples__/asset.stories.tsx diff --git a/x-pack/plugins/canvas/public/components/color_picker/__examples__/color_picker.stories.tsx b/x-pack/plugins/canvas/public/components/color_picker/__examples__/color_picker.stories.tsx index 0a7ed75ee728e..c5d42be2d201e 100644 --- a/x-pack/plugins/canvas/public/components/color_picker/__examples__/color_picker.stories.tsx +++ b/x-pack/plugins/canvas/public/components/color_picker/__examples__/color_picker.stories.tsx @@ -5,7 +5,7 @@ */ import { action } from '@storybook/addon-actions'; -import { boolean, withKnobs } from '@storybook/addon-knobs'; +import { boolean } from '@storybook/addon-knobs'; import { storiesOf } from '@storybook/react'; import React from 'react'; import { ColorPicker } from '../color_picker'; @@ -54,7 +54,6 @@ class Interactive extends React.Component< } storiesOf('components/Color/ColorPicker', module) - .addDecorator(withKnobs) .addParameters({ info: { inline: true, diff --git a/x-pack/plugins/canvas/public/components/custom_element_modal/__examples__/__snapshots__/custom_element_modal.examples.storyshot b/x-pack/plugins/canvas/public/components/custom_element_modal/__examples__/__snapshots__/custom_element_modal.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/public/components/custom_element_modal/__examples__/__snapshots__/custom_element_modal.examples.storyshot rename to x-pack/plugins/canvas/public/components/custom_element_modal/__examples__/__snapshots__/custom_element_modal.stories.storyshot diff --git a/x-pack/plugins/canvas/public/components/custom_element_modal/__examples__/custom_element_modal.examples.tsx b/x-pack/plugins/canvas/public/components/custom_element_modal/__examples__/custom_element_modal.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/public/components/custom_element_modal/__examples__/custom_element_modal.examples.tsx rename to x-pack/plugins/canvas/public/components/custom_element_modal/__examples__/custom_element_modal.stories.tsx diff --git a/x-pack/plugins/canvas/public/components/debug/__examples__/__snapshots__/debug.examples.storyshot b/x-pack/plugins/canvas/public/components/debug/__examples__/__snapshots__/debug.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/public/components/debug/__examples__/__snapshots__/debug.examples.storyshot rename to x-pack/plugins/canvas/public/components/debug/__examples__/__snapshots__/debug.stories.storyshot diff --git a/x-pack/plugins/canvas/public/components/debug/__examples__/debug.examples.tsx b/x-pack/plugins/canvas/public/components/debug/__examples__/debug.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/public/components/debug/__examples__/debug.examples.tsx rename to x-pack/plugins/canvas/public/components/debug/__examples__/debug.stories.tsx diff --git a/x-pack/plugins/canvas/public/components/element_card/__examples__/__snapshots__/element_controls.examples.storyshot b/x-pack/plugins/canvas/public/components/element_card/__examples__/__snapshots__/element_controls.examples.storyshot deleted file mode 100644 index 5e076ba76a9c1..0000000000000 --- a/x-pack/plugins/canvas/public/components/element_card/__examples__/__snapshots__/element_controls.examples.storyshot +++ /dev/null @@ -1,98 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots components/ElementTypes/ElementControls has two buttons 1`] = ` -
-
-
- - - -
-
- - - -
-
-
-`; diff --git a/x-pack/plugins/canvas/public/components/expression_input/__examples__/__snapshots__/expression_input.examples.storyshot b/x-pack/plugins/canvas/public/components/expression_input/__examples__/__snapshots__/expression_input.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/public/components/expression_input/__examples__/__snapshots__/expression_input.examples.storyshot rename to x-pack/plugins/canvas/public/components/expression_input/__examples__/__snapshots__/expression_input.stories.storyshot diff --git a/x-pack/plugins/canvas/public/components/expression_input/__examples__/expression_input.examples.tsx b/x-pack/plugins/canvas/public/components/expression_input/__examples__/expression_input.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/public/components/expression_input/__examples__/expression_input.examples.tsx rename to x-pack/plugins/canvas/public/components/expression_input/__examples__/expression_input.stories.tsx diff --git a/x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__examples__/__snapshots__/edit_menu.examples.storyshot b/x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__examples__/__snapshots__/edit_menu.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__examples__/__snapshots__/edit_menu.examples.storyshot rename to x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__examples__/__snapshots__/edit_menu.stories.storyshot diff --git a/x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__examples__/edit_menu.examples.tsx b/x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__examples__/edit_menu.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__examples__/edit_menu.examples.tsx rename to x-pack/plugins/canvas/public/components/workpad_header/edit_menu/__examples__/edit_menu.stories.tsx diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__examples__/__snapshots__/element_menu.examples.storyshot b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__examples__/__snapshots__/element_menu.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/public/components/workpad_header/element_menu/__examples__/__snapshots__/element_menu.examples.storyshot rename to x-pack/plugins/canvas/public/components/workpad_header/element_menu/__examples__/__snapshots__/element_menu.stories.storyshot diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__examples__/element_menu.examples.tsx b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__examples__/element_menu.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/public/components/workpad_header/element_menu/__examples__/element_menu.examples.tsx rename to x-pack/plugins/canvas/public/components/workpad_header/element_menu/__examples__/element_menu.stories.tsx diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/__examples__/__snapshots__/share_menu.examples.storyshot b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/__examples__/__snapshots__/share_menu.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/public/components/workpad_header/share_menu/__examples__/__snapshots__/share_menu.examples.storyshot rename to x-pack/plugins/canvas/public/components/workpad_header/share_menu/__examples__/__snapshots__/share_menu.stories.storyshot diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/__examples__/share_menu.examples.tsx b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/__examples__/share_menu.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/public/components/workpad_header/share_menu/__examples__/share_menu.examples.tsx rename to x-pack/plugins/canvas/public/components/workpad_header/share_menu/__examples__/share_menu.stories.tsx diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/__snapshots__/extended_template.examples.storyshot b/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/__snapshots__/extended_template.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/__snapshots__/extended_template.examples.storyshot rename to x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/__snapshots__/extended_template.stories.storyshot diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/__snapshots__/simple_template.examples.storyshot b/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/__snapshots__/simple_template.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/__snapshots__/simple_template.examples.storyshot rename to x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/__snapshots__/simple_template.stories.storyshot diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/extended_template.examples.tsx b/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/extended_template.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/extended_template.examples.tsx rename to x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/extended_template.stories.tsx diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/simple_template.examples.tsx b/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/simple_template.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/simple_template.examples.tsx rename to x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__examples__/simple_template.stories.tsx diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/extended_template.examples.storyshot b/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/extended_template.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/extended_template.examples.storyshot rename to x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/extended_template.stories.storyshot diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/simple_template.examples.storyshot b/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/simple_template.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/simple_template.examples.storyshot rename to x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/__snapshots__/simple_template.stories.storyshot diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/extended_template.examples.tsx b/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/extended_template.stories.tsx similarity index 95% rename from x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/extended_template.examples.tsx rename to x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/extended_template.stories.tsx index 4a300b3de8923..a831f35ad597e 100644 --- a/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/extended_template.examples.tsx +++ b/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/extended_template.stories.tsx @@ -6,7 +6,7 @@ import { action } from '@storybook/addon-actions'; import { storiesOf } from '@storybook/react'; -import { withKnobs, array, radios, boolean } from '@storybook/addon-knobs'; +import { array, radios, boolean } from '@storybook/addon-knobs'; import React from 'react'; import { ExtendedTemplate } from '../extended_template'; @@ -64,7 +64,6 @@ storiesOf('arguments/SeriesStyle', module) .addDecorator((story) => (
{story()}
)) - .addDecorator(withKnobs) .add('extended', () => ); storiesOf('arguments/SeriesStyle/components', module) diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/simple_template.examples.tsx b/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/simple_template.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/simple_template.examples.tsx rename to x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__examples__/simple_template.stories.tsx diff --git a/x-pack/plugins/canvas/scripts/jest.js b/x-pack/plugins/canvas/scripts/jest.js index b30cb02d2c99a..a91431a0141c5 100644 --- a/x-pack/plugins/canvas/scripts/jest.js +++ b/x-pack/plugins/canvas/scripts/jest.js @@ -60,7 +60,7 @@ run( if (all) { log.info('Running all available tests. This will take a while...'); } else if (storybook) { - path = 'plugins/canvas/.storybook'; + path = 'plugins/canvas/storybook'; log.info('Running Storybook Snapshot tests...'); } else { log.info('Running tests. This does not include Storybook Snapshots...'); diff --git a/x-pack/plugins/canvas/scripts/storybook.js b/x-pack/plugins/canvas/scripts/storybook.js index c9e6c6c65436c..beea1814b54d2 100644 --- a/x-pack/plugins/canvas/scripts/storybook.js +++ b/x-pack/plugins/canvas/scripts/storybook.js @@ -10,7 +10,7 @@ const del = require('del'); const { run } = require('@kbn/dev-utils'); const storybook = require('@storybook/react/standalone'); const execa = require('execa'); -const { DLL_OUTPUT } = require('./../.storybook/constants'); +const { DLL_OUTPUT } = require('./../storybook/constants'); const options = { stdio: ['ignore', 'inherit', 'inherit'], @@ -18,7 +18,7 @@ const options = { }; const storybookOptions = { - configDir: path.resolve(__dirname, './../.storybook'), + configDir: path.resolve(__dirname, './../storybook'), mode: 'dev', }; @@ -51,7 +51,7 @@ run( [ 'webpack', '--config', - 'x-pack/plugins/canvas/.storybook/webpack.dll.config.js', + 'x-pack/plugins/canvas/storybook/webpack.dll.config.js', '--progress', '--hide-modules', '--display-entrypoints', diff --git a/x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/canvas.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/canvas.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/canvas.examples.storyshot rename to x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/canvas.stories.storyshot diff --git a/x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/page.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/page.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/page.examples.storyshot rename to x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/page.stories.storyshot diff --git a/x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/rendered_element.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/rendered_element.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/rendered_element.examples.storyshot rename to x-pack/plugins/canvas/shareable_runtime/components/__examples__/__snapshots__/rendered_element.stories.storyshot diff --git a/x-pack/plugins/canvas/shareable_runtime/components/__examples__/canvas.examples.tsx b/x-pack/plugins/canvas/shareable_runtime/components/__examples__/canvas.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/__examples__/canvas.examples.tsx rename to x-pack/plugins/canvas/shareable_runtime/components/__examples__/canvas.stories.tsx diff --git a/x-pack/plugins/canvas/shareable_runtime/components/__examples__/page.examples.tsx b/x-pack/plugins/canvas/shareable_runtime/components/__examples__/page.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/__examples__/page.examples.tsx rename to x-pack/plugins/canvas/shareable_runtime/components/__examples__/page.stories.tsx diff --git a/x-pack/plugins/canvas/shareable_runtime/components/__examples__/rendered_element.examples.tsx b/x-pack/plugins/canvas/shareable_runtime/components/__examples__/rendered_element.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/__examples__/rendered_element.examples.tsx rename to x-pack/plugins/canvas/shareable_runtime/components/__examples__/rendered_element.stories.tsx diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/footer.components.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/footer.components.examples.storyshot deleted file mode 100644 index 6d783a26d8424..0000000000000 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/footer.components.examples.storyshot +++ /dev/null @@ -1,140 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots shareables/Footer/components PageControls 1`] = ` -
-
- -
-
- -
-
- -
-
-`; - -exports[`Storyshots shareables/Footer/components Title 1`] = ` -
-
-
- -
-
-
-
-
- This is a test title. -
-
-
-
-
-
-`; diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/footer.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/footer.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/footer.examples.storyshot rename to x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/footer.stories.storyshot diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/page_controls.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/page_controls.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/page_controls.examples.storyshot rename to x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/page_controls.stories.storyshot diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/scrubber.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/scrubber.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/scrubber.examples.storyshot rename to x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/scrubber.stories.storyshot diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/title.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/title.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/title.examples.storyshot rename to x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/__snapshots__/title.stories.storyshot diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/footer.examples.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/footer.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/footer.examples.tsx rename to x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/footer.stories.tsx diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/page_controls.examples.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/page_controls.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/page_controls.examples.tsx rename to x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/page_controls.stories.tsx diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/scrubber.examples.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/scrubber.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/scrubber.examples.tsx rename to x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/scrubber.stories.tsx diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/title.examples.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/title.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/title.examples.tsx rename to x-pack/plugins/canvas/shareable_runtime/components/footer/__examples__/title.stories.tsx diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/autoplay_settings.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/autoplay_settings.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/autoplay_settings.examples.storyshot rename to x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/autoplay_settings.stories.storyshot diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/settings.components.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/settings.components.examples.storyshot deleted file mode 100644 index 1922bd84b174c..0000000000000 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/settings.components.examples.storyshot +++ /dev/null @@ -1,479 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots shareables/Settings/components AutoplaySettings, autoplay disabled 1`] = ` -
-
- - - - - - - - - -
-
-
-
-
-
-
- -
-
-
-
- -
-
-
- Use shorthand notation, like 30s, 10m, or 1h -
-
-
-
-
-
-
- -
-
- -
-
-
-
-
-
-`; - -exports[`Storyshots shareables/Settings/components AutoplaySettings, autoplay enabled 1`] = ` -
-
- - - - - - - - - -
-
-
-
-
-
-
- -
-
-
-
- -
-
-
- Use shorthand notation, like 30s, 10m, or 1h -
-
-
-
-
-
-
- -
-
- -
-
-
-
-
-
-`; - -exports[`Storyshots shareables/Settings/components ToolbarSettings, autohide disabled 1`] = ` -
-
-
-
- - - - - - - - - -
-
- Hide the toolbar when the mouse is not within the Canvas? -
-
-
-
-`; - -exports[`Storyshots shareables/Settings/components ToolbarSettings, autohide enabled 1`] = ` -
-
-
-
- - - - - - - - - -
-
- Hide the toolbar when the mouse is not within the Canvas? -
-
-
-
-`; diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/settings.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/settings.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/settings.examples.storyshot rename to x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/settings.stories.storyshot diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/toolbar_settings.examples.storyshot b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/toolbar_settings.stories.storyshot similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/toolbar_settings.examples.storyshot rename to x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/__snapshots__/toolbar_settings.stories.storyshot diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/autoplay_settings.examples.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/autoplay_settings.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/autoplay_settings.examples.tsx rename to x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/autoplay_settings.stories.tsx diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/settings.examples.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/settings.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/settings.examples.tsx rename to x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/settings.stories.tsx diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/toolbar_settings.examples.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/toolbar_settings.stories.tsx similarity index 100% rename from x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/toolbar_settings.examples.tsx rename to x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__examples__/toolbar_settings.stories.tsx diff --git a/x-pack/plugins/canvas/.storybook/.babelrc b/x-pack/plugins/canvas/storybook/.babelrc similarity index 100% rename from x-pack/plugins/canvas/.storybook/.babelrc rename to x-pack/plugins/canvas/storybook/.babelrc diff --git a/x-pack/plugins/canvas/.storybook/addons.js b/x-pack/plugins/canvas/storybook/addons.js similarity index 100% rename from x-pack/plugins/canvas/.storybook/addons.js rename to x-pack/plugins/canvas/storybook/addons.js diff --git a/x-pack/plugins/canvas/.storybook/config.js b/x-pack/plugins/canvas/storybook/config.js similarity index 67% rename from x-pack/plugins/canvas/.storybook/config.js rename to x-pack/plugins/canvas/storybook/config.js index 04b4e2a8e7b4b..f349f9b7ccf98 100644 --- a/x-pack/plugins/canvas/.storybook/config.js +++ b/x-pack/plugins/canvas/storybook/config.js @@ -4,13 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; import { configure, addDecorator, addParameters } from '@storybook/react'; -import { withKnobs } from '@storybook/addon-knobs/react'; import { withInfo } from '@storybook/addon-info'; import { create } from '@storybook/theming'; -import { KibanaContextProvider } from '../../../../src/plugins/kibana_react/public'; +import { addDecorators } from './decorators'; // If we're running Storyshots, be sure to register the require context hook. // Otherwise, add the other decorators. @@ -31,18 +29,9 @@ if (process.env.NODE_ENV === 'test') { }, }) ); - - // Add optional knobs to customize each story. - addDecorator(withKnobs); } -// Add New Platform Context for any stories that need it -const settings = new Map(); -settings.set('darkMode', true); -const platform = { - uiSettings: settings, -}; -addDecorator(fn => {fn()}); +addDecorators(); function loadStories() { require('./dll_contexts'); @@ -54,14 +43,14 @@ function loadStories() { true, /plugins\/(?=canvas).*light\.css/ ); - css.keys().forEach(filename => css(filename)); + css.keys().forEach((filename) => css(filename)); - // Find all files ending in *.examples.ts - const req = require.context('./..', true, /.(stories|examples).tsx$/); - req.keys().forEach(filename => req(filename)); + // Find all files ending in *.stories.tsx + const req = require.context('./..', true, /.(stories).tsx$/); + req.keys().forEach((filename) => req(filename)); // Import Canvas CSS - require('../public/style/index.scss') + require('../public/style/index.scss'); } // Set up the Storybook environment with custom settings. diff --git a/x-pack/plugins/canvas/.storybook/constants.js b/x-pack/plugins/canvas/storybook/constants.js similarity index 100% rename from x-pack/plugins/canvas/.storybook/constants.js rename to x-pack/plugins/canvas/storybook/constants.js diff --git a/x-pack/plugins/canvas/storybook/decorators/index.ts b/x-pack/plugins/canvas/storybook/decorators/index.ts new file mode 100644 index 0000000000000..aa1e958a410f5 --- /dev/null +++ b/x-pack/plugins/canvas/storybook/decorators/index.ts @@ -0,0 +1,19 @@ +/* + * 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 { addDecorator } from '@storybook/react'; +import { withKnobs } from '@storybook/addon-knobs'; +// @ts-expect-error +import { withInfo } from '@storybook/addon-info'; + +import { routerContextDecorator } from './router_decorator'; +import { kibanaContextDecorator } from './kibana_decorator'; + +export const addDecorators = () => { + addDecorator(withKnobs); + addDecorator(kibanaContextDecorator); + addDecorator(routerContextDecorator); +}; diff --git a/x-pack/plugins/canvas/storybook/decorators/kibana_decorator.tsx b/x-pack/plugins/canvas/storybook/decorators/kibana_decorator.tsx new file mode 100644 index 0000000000000..a55efba5a5183 --- /dev/null +++ b/x-pack/plugins/canvas/storybook/decorators/kibana_decorator.tsx @@ -0,0 +1,26 @@ +/* + * 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 { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public'; + +const settings = new Map(); +settings.set('darkMode', true); +const platform = { + http: { + basePath: { + get: () => '', + prepend: () => '', + remove: () => '', + serverBasePath: '', + }, + }, + uiSettings: settings, +}; + +export const kibanaContextDecorator = (story: Function) => ( + {story()} +); diff --git a/x-pack/plugins/canvas/storybook/decorators/router_decorator.tsx b/x-pack/plugins/canvas/storybook/decorators/router_decorator.tsx new file mode 100644 index 0000000000000..43b0da6473f23 --- /dev/null +++ b/x-pack/plugins/canvas/storybook/decorators/router_decorator.tsx @@ -0,0 +1,30 @@ +/* + * 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 PropTypes from 'prop-types'; + +class RouterContext extends React.Component { + static childContextTypes = { + router: PropTypes.object.isRequired, + }; + + getChildContext() { + return { + router: { + getFullPath: () => 'path', + create: () => '', + }, + }; + } + render() { + return <>{this.props.children}; + } +} + +export function routerContextDecorator(story: Function) { + return {story()}; +} diff --git a/x-pack/plugins/canvas/.storybook/dll_contexts.js b/x-pack/plugins/canvas/storybook/dll_contexts.js similarity index 88% rename from x-pack/plugins/canvas/.storybook/dll_contexts.js rename to x-pack/plugins/canvas/storybook/dll_contexts.js index 529fd8aa5c791..85f2ab66cab88 100644 --- a/x-pack/plugins/canvas/.storybook/dll_contexts.js +++ b/x-pack/plugins/canvas/storybook/dll_contexts.js @@ -15,7 +15,7 @@ const css = require.context( true, /\.\/plugins\/(?!canvas).*light\.css/ ); -css.keys().forEach(filename => { +css.keys().forEach((filename) => { css(filename); }); @@ -25,7 +25,7 @@ const uiStyles = require.context( false, /[\/\\](?!mixins|variables|_|\.|bootstrap_(light|dark))[^\/\\]+\.less/ ); -uiStyles.keys().forEach(key => uiStyles(key)); +uiStyles.keys().forEach((key) => uiStyles(key)); const json = require.context('../shareable_runtime/test/workpads', false, /\.json$/); -json.keys().forEach(key => json(key)); +json.keys().forEach((key) => json(key)); diff --git a/x-pack/plugins/canvas/.storybook/middleware.js b/x-pack/plugins/canvas/storybook/middleware.js similarity index 72% rename from x-pack/plugins/canvas/.storybook/middleware.js rename to x-pack/plugins/canvas/storybook/middleware.js index 8bbd2b6c1a22f..baa524aefa709 100644 --- a/x-pack/plugins/canvas/.storybook/middleware.js +++ b/x-pack/plugins/canvas/storybook/middleware.js @@ -4,10 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -const serve = require('serve-static'); const path = require('path'); +const serve = require('serve-static'); // Extend the Storybook Middleware to include a route to access Legacy UI assets -module.exports = function(router) { - router.get('/ui', serve(path.resolve(__dirname, '../../../../../src/core/server/core_app/assets'))); +module.exports = function (router) { + router.get( + '/ui', + serve(path.resolve(__dirname, '../../../../../src/core/server/core_app/assets')) + ); }; diff --git a/x-pack/plugins/canvas/.storybook/preview-head.html b/x-pack/plugins/canvas/storybook/preview-head.html similarity index 100% rename from x-pack/plugins/canvas/.storybook/preview-head.html rename to x-pack/plugins/canvas/storybook/preview-head.html diff --git a/x-pack/plugins/canvas/.storybook/storyshots.test.js b/x-pack/plugins/canvas/storybook/storyshots.test.js similarity index 95% rename from x-pack/plugins/canvas/.storybook/storyshots.test.js rename to x-pack/plugins/canvas/storybook/storyshots.test.js index 7195b97712464..ba4013f7cc816 100644 --- a/x-pack/plugins/canvas/.storybook/storyshots.test.js +++ b/x-pack/plugins/canvas/storybook/storyshots.test.js @@ -53,7 +53,7 @@ jest.mock('@elastic/eui/packages/react-datepicker', () => { }); // Mock React Portal for components that use modals, tooltips, etc -ReactDOM.createPortal = jest.fn(element => { +ReactDOM.createPortal = jest.fn((element) => { return element; }); @@ -67,7 +67,7 @@ jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => { // https://github.com/elastic/eui/issues/3712 jest.mock('@elastic/eui/lib/components/overlay_mask/overlay_mask', () => { return { - EuiOverlayMask: ({children}) => children, + EuiOverlayMask: ({ children }) => children, }; }); @@ -79,19 +79,19 @@ jest.mock( } ); +import { EuiObserver } from '@elastic/eui/test-env/components/observer/observer'; +jest.mock('@elastic/eui/test-env/components/observer/observer'); +EuiObserver.mockImplementation(() => 'EuiObserver'); + // This element uses a `ref` and cannot be rendered by Jest snapshots. import { RenderedElement } from '../shareable_runtime/components/rendered_element'; jest.mock('../shareable_runtime/components/rendered_element'); RenderedElement.mockImplementation(() => 'RenderedElement'); -import { EuiObserver } from '@elastic/eui/test-env/components/observer/observer'; -jest.mock('@elastic/eui/test-env/components/observer/observer'); -EuiObserver.mockImplementation(() => 'EuiObserver'); - addSerializer(styleSheetSerializer); // Initialize Storyshots and build the Jest Snapshots initStoryshots({ - configPath: path.resolve(__dirname, './../.storybook'), + configPath: path.resolve(__dirname, './../storybook'), test: multiSnapshotWithOptions({}), }); diff --git a/x-pack/plugins/canvas/.storybook/webpack.config.js b/x-pack/plugins/canvas/storybook/webpack.config.js similarity index 88% rename from x-pack/plugins/canvas/.storybook/webpack.config.js rename to x-pack/plugins/canvas/storybook/webpack.config.js index 3148a6742f76a..1e0e36f796128 100644 --- a/x-pack/plugins/canvas/.storybook/webpack.config.js +++ b/x-pack/plugins/canvas/storybook/webpack.config.js @@ -14,7 +14,7 @@ const { DLL_OUTPUT, KIBANA_ROOT } = require('./constants'); module.exports = async ({ config }) => { // Find and alter the CSS rule to replace the Kibana public path string with a path // to the route we've added in middleware.js - const cssRule = config.module.rules.find(rule => rule.test.source.includes('.css$')); + const cssRule = config.module.rules.find((rule) => rule.test.source.includes('.css$')); cssRule.use.push({ loader: 'string-replace-loader', options: { @@ -153,7 +153,7 @@ module.exports = async ({ config }) => { config.plugins.push( // replace imports for `uiExports/*` modules with a synthetic module // created by create_ui_exports_module.js - new webpack.NormalModuleReplacementPlugin(/^uiExports\//, resource => { + new webpack.NormalModuleReplacementPlugin(/^uiExports\//, (resource) => { // uiExports used by Canvas const extensions = { hacks: [], @@ -179,10 +179,22 @@ module.exports = async ({ config }) => { }), // Mock out libs used by a few componets to avoid loading in kibana_legacy and platform - new webpack.NormalModuleReplacementPlugin(/(lib)?\/notify/, path.resolve(__dirname, '../tasks/mocks/uiNotify')), - new webpack.NormalModuleReplacementPlugin(/lib\/download_workpad/, path.resolve(__dirname, '../tasks/mocks/downloadWorkpad')), - new webpack.NormalModuleReplacementPlugin(/(lib)?\/custom_element_service/, path.resolve(__dirname, '../tasks/mocks/customElementService')), - new webpack.NormalModuleReplacementPlugin(/(lib)?\/ui_metric/, path.resolve(__dirname, '../tasks/mocks/uiMetric')), + new webpack.NormalModuleReplacementPlugin( + /(lib)?\/notify/, + path.resolve(__dirname, '../tasks/mocks/uiNotify') + ), + new webpack.NormalModuleReplacementPlugin( + /lib\/download_workpad/, + path.resolve(__dirname, '../tasks/mocks/downloadWorkpad') + ), + new webpack.NormalModuleReplacementPlugin( + /(lib)?\/custom_element_service/, + path.resolve(__dirname, '../tasks/mocks/customElementService') + ), + new webpack.NormalModuleReplacementPlugin( + /(lib)?\/ui_metric/, + path.resolve(__dirname, '../tasks/mocks/uiMetric') + ) ); // Tell Webpack about relevant extensions @@ -196,7 +208,10 @@ module.exports = async ({ config }) => { '../tasks/mocks/uiNotifyFormatMsg' ); config.resolve.alias['ui/notify'] = path.resolve(__dirname, '../tasks/mocks/uiNotify'); - config.resolve.alias['ui/url/absolute_to_parsed_url'] = path.resolve(__dirname, '../tasks/mocks/uiAbsoluteToParsedUrl'); + config.resolve.alias['ui/url/absolute_to_parsed_url'] = path.resolve( + __dirname, + '../tasks/mocks/uiAbsoluteToParsedUrl' + ); config.resolve.alias['ui/chrome'] = path.resolve(__dirname, '../tasks/mocks/uiChrome'); config.resolve.alias.ui = path.resolve(KIBANA_ROOT, 'src/legacy/ui/public'); config.resolve.alias.ng_mock$ = path.resolve(KIBANA_ROOT, 'src/test_utils/public/ng_mock'); diff --git a/x-pack/plugins/canvas/.storybook/webpack.dll.config.js b/x-pack/plugins/canvas/storybook/webpack.dll.config.js similarity index 100% rename from x-pack/plugins/canvas/.storybook/webpack.dll.config.js rename to x-pack/plugins/canvas/storybook/webpack.dll.config.js index 5fdc4519f3bd7..0e9371e4cb5e4 100644 --- a/x-pack/plugins/canvas/.storybook/webpack.dll.config.js +++ b/x-pack/plugins/canvas/storybook/webpack.dll.config.js @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -const webpack = require('webpack'); const path = require('path'); +const webpack = require('webpack'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const { DLL_NAME, DLL_OUTPUT, KIBANA_ROOT } = require('./constants'); From a1753ffffdfc248f48561ab5fc2116c4a5e0b8ee Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 20 Jul 2020 20:35:15 -0700 Subject: [PATCH 30/77] [ftr/webdriver] retry on all errors, use Rx so that timers are canceled (#72540) * [ftr/webdriver] retry on all errors, use Rx so that timers are canceled * throw if attemptToCreateCommand() aborts by resolving to undefined Co-authored-by: spalger --- test/functional/services/remote/webdriver.ts | 45 +++++++++++--------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/test/functional/services/remote/webdriver.ts b/test/functional/services/remote/webdriver.ts index 0611c80f59b92..09fede7fe2546 100644 --- a/test/functional/services/remote/webdriver.ts +++ b/test/functional/services/remote/webdriver.ts @@ -21,10 +21,9 @@ import { resolve } from 'path'; import Fs from 'fs'; import * as Rx from 'rxjs'; -import { mergeMap, map, takeUntil } from 'rxjs/operators'; +import { mergeMap, map, takeUntil, catchError } from 'rxjs/operators'; import { Lifecycle } from '@kbn/test/src/functional_test_runner/lib/lifecycle'; import { ToolingLog } from '@kbn/dev-utils'; -import { delay } from 'bluebird'; import chromeDriver from 'chromedriver'; // @ts-ignore types not available import geckoDriver from 'geckodriver'; @@ -337,25 +336,33 @@ export async function initWebDriver( edgePaths = await installDriver(); } - return await Promise.race([ - (async () => { - await delay(2 * MINUTE); - throw new Error('remote failed to start within 2 minutes'); - })(), - - (async () => { - while (true) { - const command = await Promise.race([ - delay(30 * SECOND), - attemptToCreateCommand(log, browserType, lifecycle, config), - ]); + return await Rx.race( + Rx.timer(2 * MINUTE).pipe( + map(() => { + throw new Error('remote failed to start within 2 minutes'); + }) + ), + Rx.race( + Rx.defer(async () => { + const command = await attemptToCreateCommand(log, browserType, lifecycle, config); if (!command) { - continue; + throw new Error('remote creation aborted'); } - return command; - } - })(), - ]); + }), + Rx.timer(30 * SECOND).pipe( + map(() => { + throw new Error('remote failed to start within 30 seconds'); + }) + ) + ).pipe( + catchError((error, resubscribe) => { + log.warning('Failure while creating webdriver instance'); + log.warning(error); + log.warning('...retrying...'); + return resubscribe; + }) + ) + ).toPromise(); } From 7f6cd5148a042fbdfbc7711037f90a319ca68a07 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Tue, 21 Jul 2020 07:09:25 +0200 Subject: [PATCH 31/77] [Discover] Improve histogram tests (#72235) --- ...er_histogram.js => _discover_histogram.ts} | 54 ++++++------------- .../data.json | 17 ++++++ 2 files changed, 33 insertions(+), 38 deletions(-) rename test/functional/apps/discover/{_discover_histogram.js => _discover_histogram.ts} (61%) create mode 100644 test/functional/fixtures/es_archiver/long_window_logstash_index_pattern/data.json diff --git a/test/functional/apps/discover/_discover_histogram.js b/test/functional/apps/discover/_discover_histogram.ts similarity index 61% rename from test/functional/apps/discover/_discover_histogram.js rename to test/functional/apps/discover/_discover_histogram.ts index e53c953f1514e..5c78bfccbb966 100644 --- a/test/functional/apps/discover/_discover_histogram.js +++ b/test/functional/apps/discover/_discover_histogram.ts @@ -18,14 +18,12 @@ */ import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; -export default function ({ getService, getPageObjects }) { - const log = getService('log'); +export default function ({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); - const browser = getService('browser'); const elasticChart = getService('elasticChart'); const kibanaServer = getService('kibanaServer'); - const security = getService('security'); const PageObjects = getPageObjects(['settings', 'common', 'discover', 'header', 'timePicker']); const defaultSettings = { defaultIndex: 'long-window-logstash-*', @@ -33,63 +31,43 @@ export default function ({ getService, getPageObjects }) { }; describe('discover histogram', function describeIndexTests() { - before(async function () { - log.debug('load kibana index with default index pattern'); - await PageObjects.common.navigateToApp('settings'); - await security.testUser.setRoles([ - 'kibana_admin', - 'test_logstash_reader', - 'long_window_logstash', - ]); + before(async () => { await esArchiver.loadIfNeeded('logstash_functional'); await esArchiver.load('long_window_logstash'); - await esArchiver.load('visualize'); - await esArchiver.load('discover'); - - log.debug('create long_window_logstash index pattern'); - // NOTE: long_window_logstash load does NOT create index pattern - await PageObjects.settings.createIndexPattern('long-window-logstash-*'); + await esArchiver.load('long_window_logstash_index_pattern'); await kibanaServer.uiSettings.replace(defaultSettings); - await browser.refresh(); - - log.debug('discover'); await PageObjects.common.navigateToApp('discover'); - await PageObjects.discover.selectIndexPattern('long-window-logstash-*'); - // NOTE: For some reason without setting this relative time, the abs times will not fetch data. - await PageObjects.timePicker.setCommonlyUsedTime('Last_1 year'); }); after(async () => { await esArchiver.unload('long_window_logstash'); - await esArchiver.unload('visualize'); - await esArchiver.unload('discover'); - await security.testUser.restoreDefaults(); + await esArchiver.unload('long_window_logstash_index_pattern'); }); + async function prepareTest(fromTime: string, toTime: string, interval: string) { + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await PageObjects.discover.setChartInterval(interval); + await PageObjects.header.waitUntilLoadingHasFinished(); + } + it('should visualize monthly data with different day intervals', async () => { const fromTime = 'Nov 01, 2017 @ 00:00:00.000'; const toTime = 'Mar 21, 2018 @ 00:00:00.000'; - await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); - await PageObjects.discover.setChartInterval('Month'); - await PageObjects.header.waitUntilLoadingHasFinished(); + await prepareTest(fromTime, toTime, 'Month'); const chartCanvasExist = await elasticChart.canvasExists(); expect(chartCanvasExist).to.be(true); }); it('should visualize weekly data with within DST changes', async () => { const fromTime = 'Mar 01, 2018 @ 00:00:00.000'; const toTime = 'May 01, 2018 @ 00:00:00.000'; - await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); - await PageObjects.discover.setChartInterval('Week'); - await PageObjects.header.waitUntilLoadingHasFinished(); + await prepareTest(fromTime, toTime, 'Week'); const chartCanvasExist = await elasticChart.canvasExists(); expect(chartCanvasExist).to.be(true); }); - it('should visualize monthly data with different years Scaled to 30 days', async () => { + it('should visualize monthly data with different years scaled to 30 days', async () => { const fromTime = 'Jan 01, 2010 @ 00:00:00.000'; const toTime = 'Mar 21, 2019 @ 00:00:00.000'; - - await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); - await PageObjects.discover.setChartInterval('Day'); - await PageObjects.header.waitUntilLoadingHasFinished(); + await prepareTest(fromTime, toTime, 'Day'); const chartCanvasExist = await elasticChart.canvasExists(); expect(chartCanvasExist).to.be(true); const chartIntervalIconTip = await PageObjects.discover.getChartIntervalWarningIcon(); diff --git a/test/functional/fixtures/es_archiver/long_window_logstash_index_pattern/data.json b/test/functional/fixtures/es_archiver/long_window_logstash_index_pattern/data.json new file mode 100644 index 0000000000000..75aa6f06bb11a --- /dev/null +++ b/test/functional/fixtures/es_archiver/long_window_logstash_index_pattern/data.json @@ -0,0 +1,17 @@ +{ + "type": "doc", + "value": { + "id": "index-pattern:long-window-logstash-*", + "index": ".kibana", + "source": { + "index-pattern": { + "fields": "[{\"name\":\"referer\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"agent\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:image:width\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"xss.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"headings.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"meta.user.lastname\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.article:tag.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"geo.dest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.twitter:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.article:section.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"utc_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.twitter:card\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"meta.char\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"clientip\",\"type\":\"ip\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:image:height\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"host\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"machine.ram\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"links\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"id\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@tags.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"phpmemory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.twitter:card.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"ip\",\"type\":\"ip\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.article:modified_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:site_name.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"request.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.article:tag\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"agent.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"spaces\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:site.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"headings\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"_source\",\"type\":\"_source\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"relatedContent.og:image.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"request\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"index.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"extension\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"memory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"_index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"relatedContent.twitter:site\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"geo.coordinates\",\"type\":\"geo_point\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"meta.related\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:title.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:title.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"response.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@message.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"machine.os\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.article:section\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"xss\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"links.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"geo.srcdest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"extension.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"machine.os.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@tags\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"host.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:type.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"geo.src\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"spaces.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:image:height.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:description.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:site_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"@message\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.twitter:image.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"@timestamp\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"bytes\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"response\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"meta.user.firstname\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":true,\"doc_values\":false},{\"name\":\"relatedContent.og:image:width.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.og:description.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"relatedContent.article:published_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"indexed\":true,\"analyzed\":false,\"doc_values\":true},{\"name\":\"_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"_type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"indexed\":false,\"analyzed\":false,\"doc_values\":false}]", + "timeFieldName": "@timestamp", + "title": "long-window-logstash-*" + }, + "type": "index-pattern" + } + } +} + + From 511e4543a7828cf0cdb157b88b01352947e0384f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Tue, 21 Jul 2020 08:41:15 +0200 Subject: [PATCH 32/77] [APM] Handle ML errors (#72316) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [APM] Handle ML errors * Add capability check * Improve test * Address Caue’s feedback * Move getSeverity * Fix tsc * Fix copy --- .../plugins/apm/common/anomaly_detection.ts | 50 +++++++++++ .../apm/common/ml_job_constants.test.ts | 41 --------- .../ServiceMap/Popover/AnomalyDetection.tsx | 2 +- .../ServiceMap/Popover/getSeverity.test.ts | 39 +++++++++ .../app/ServiceMap/Popover/getSeverity.ts} | 2 + .../generate_service_map_elements.ts | 2 +- .../app/ServiceMap/cytoscapeOptions.ts | 2 +- .../anomaly_detection/add_environments.tsx | 17 +++- .../Settings/anomaly_detection/create_jobs.ts | 80 +++++++++++------- .../app/Settings/anomaly_detection/index.tsx | 33 ++++++-- .../Settings/anomaly_detection/jobs_list.tsx | 84 +++++++++---------- .../apm/AnomalyDetectionSetupLink.test.tsx | 39 +++++---- .../Links/apm/AnomalyDetectionSetupLink.tsx | 20 ++++- .../anomaly_detection_error.ts | 16 ++++ .../create_anomaly_detection_jobs.ts | 26 +++--- .../get_anomaly_detection_jobs.ts | 16 ++-- .../routes/settings/anomaly_detection.ts | 62 +++++++++++--- 17 files changed, 355 insertions(+), 176 deletions(-) delete mode 100644 x-pack/plugins/apm/common/ml_job_constants.test.ts create mode 100644 x-pack/plugins/apm/public/components/app/ServiceMap/Popover/getSeverity.test.ts rename x-pack/plugins/apm/{common/ml_job_constants.ts => public/components/app/ServiceMap/Popover/getSeverity.ts} (80%) create mode 100644 x-pack/plugins/apm/server/lib/anomaly_detection/anomaly_detection_error.ts diff --git a/x-pack/plugins/apm/common/anomaly_detection.ts b/x-pack/plugins/apm/common/anomaly_detection.ts index 1fd927d82f186..9e0a3e3d0d889 100644 --- a/x-pack/plugins/apm/common/anomaly_detection.ts +++ b/x-pack/plugins/apm/common/anomaly_detection.ts @@ -4,9 +4,59 @@ * you may not use this file except in compliance with the Elastic License. */ +import { i18n } from '@kbn/i18n'; + export interface ServiceAnomalyStats { transactionType?: string; anomalyScore?: number; actualValue?: number; jobId?: string; } + +export const MLErrorMessages: Record = { + INSUFFICIENT_LICENSE: i18n.translate( + 'xpack.apm.anomaly_detection.error.insufficient_license', + { + defaultMessage: + 'You must have a platinum license to use Anomaly Detection', + } + ), + MISSING_READ_PRIVILEGES: i18n.translate( + 'xpack.apm.anomaly_detection.error.missing_read_privileges', + { + defaultMessage: + 'You must have "read" privileges to Machine Learning in order to view Anomaly Detection jobs', + } + ), + MISSING_WRITE_PRIVILEGES: i18n.translate( + 'xpack.apm.anomaly_detection.error.missing_write_privileges', + { + defaultMessage: + 'You must have "write" privileges to Machine Learning and APM in order to create Anomaly Detection jobs', + } + ), + ML_NOT_AVAILABLE: i18n.translate( + 'xpack.apm.anomaly_detection.error.not_available', + { + defaultMessage: 'Machine learning is not available', + } + ), + ML_NOT_AVAILABLE_IN_SPACE: i18n.translate( + 'xpack.apm.anomaly_detection.error.not_available_in_space', + { + defaultMessage: 'Machine learning is not available in the selected space', + } + ), + UNEXPECTED: i18n.translate('xpack.apm.anomaly_detection.error.unexpected', { + defaultMessage: 'An unexpected error occurred', + }), +}; + +export enum ErrorCode { + INSUFFICIENT_LICENSE = 'INSUFFICIENT_LICENSE', + MISSING_READ_PRIVILEGES = 'MISSING_READ_PRIVILEGES', + MISSING_WRITE_PRIVILEGES = 'MISSING_WRITE_PRIVILEGES', + ML_NOT_AVAILABLE = 'ML_NOT_AVAILABLE', + ML_NOT_AVAILABLE_IN_SPACE = 'ML_NOT_AVAILABLE_IN_SPACE', + UNEXPECTED = 'UNEXPECTED', +} diff --git a/x-pack/plugins/apm/common/ml_job_constants.test.ts b/x-pack/plugins/apm/common/ml_job_constants.test.ts deleted file mode 100644 index 96e3ba826d201..0000000000000 --- a/x-pack/plugins/apm/common/ml_job_constants.test.ts +++ /dev/null @@ -1,41 +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 { getSeverity, severity } from './ml_job_constants'; - -describe('ml_job_constants', () => { - describe('getSeverity', () => { - describe('when score is undefined', () => { - it('returns undefined', () => { - expect(getSeverity(undefined)).toEqual(undefined); - }); - }); - - describe('when score < 25', () => { - it('returns warning', () => { - expect(getSeverity(10)).toEqual(severity.warning); - }); - }); - - describe('when score is between 25 and 50', () => { - it('returns minor', () => { - expect(getSeverity(40)).toEqual(severity.minor); - }); - }); - - describe('when score is between 50 and 75', () => { - it('returns major', () => { - expect(getSeverity(60)).toEqual(severity.major); - }); - }); - - describe('when score is 75 or more', () => { - it('returns critical', () => { - expect(getSeverity(100)).toEqual(severity.critical); - }); - }); - }); -}); diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/AnomalyDetection.tsx b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/AnomalyDetection.tsx index 410ba8b5027fb..b3d19e1aab2cc 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/AnomalyDetection.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/AnomalyDetection.tsx @@ -19,9 +19,9 @@ import { fontSize, px } from '../../../../style/variables'; import { asInteger, asDuration } from '../../../../utils/formatters'; import { MLJobLink } from '../../../shared/Links/MachineLearningLinks/MLJobLink'; import { getSeverityColor, popoverWidth } from '../cytoscapeOptions'; -import { getSeverity } from '../../../../../common/ml_job_constants'; import { TRANSACTION_REQUEST } from '../../../../../common/transaction_types'; import { ServiceAnomalyStats } from '../../../../../common/anomaly_detection'; +import { getSeverity } from './getSeverity'; const HealthStatusTitle = styled(EuiTitle)` display: inline; diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/getSeverity.test.ts b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/getSeverity.test.ts new file mode 100644 index 0000000000000..52b7d54236db6 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/getSeverity.test.ts @@ -0,0 +1,39 @@ +/* + * 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 { getSeverity, severity } from './getSeverity'; + +describe('getSeverity', () => { + describe('when score is undefined', () => { + it('returns undefined', () => { + expect(getSeverity(undefined)).toEqual(undefined); + }); + }); + + describe('when score < 25', () => { + it('returns warning', () => { + expect(getSeverity(10)).toEqual(severity.warning); + }); + }); + + describe('when score is between 25 and 50', () => { + it('returns minor', () => { + expect(getSeverity(40)).toEqual(severity.minor); + }); + }); + + describe('when score is between 50 and 75', () => { + it('returns major', () => { + expect(getSeverity(60)).toEqual(severity.major); + }); + }); + + describe('when score is 75 or more', () => { + it('returns critical', () => { + expect(getSeverity(100)).toEqual(severity.critical); + }); + }); +}); diff --git a/x-pack/plugins/apm/common/ml_job_constants.ts b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/getSeverity.ts similarity index 80% rename from x-pack/plugins/apm/common/ml_job_constants.ts rename to x-pack/plugins/apm/public/components/app/ServiceMap/Popover/getSeverity.ts index b8c2546bd0c84..f4eb2033e9231 100644 --- a/x-pack/plugins/apm/common/ml_job_constants.ts +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/getSeverity.ts @@ -11,6 +11,8 @@ export enum severity { warning = 'warning', } +// TODO: Replace with `getSeverity` from: +// https://github.com/elastic/kibana/blob/0f964f66916480f2de1f4b633e5afafc08cf62a0/x-pack/plugins/ml/common/util/anomaly_utils.ts#L129 export function getSeverity(score?: number) { if (typeof score !== 'number') { return undefined; diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/generate_service_map_elements.ts b/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/generate_service_map_elements.ts index e7d55cd570710..012256db3ab98 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/generate_service_map_elements.ts +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/generate_service_map_elements.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getSeverity } from '../../../../../common/ml_job_constants'; +import { getSeverity } from '../Popover/getSeverity'; export function generateServiceMapElements(size: number): any[] { const services = range(size).map((i) => { diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/cytoscapeOptions.ts b/x-pack/plugins/apm/public/components/app/ServiceMap/cytoscapeOptions.ts index dfcfbee1806a4..4a271019e06db 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/cytoscapeOptions.ts +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/cytoscapeOptions.ts @@ -10,9 +10,9 @@ import { SPAN_DESTINATION_SERVICE_RESOURCE, } from '../../../../common/elasticsearch_fieldnames'; import { EuiTheme } from '../../../../../observability/public'; -import { severity, getSeverity } from '../../../../common/ml_job_constants'; import { defaultIcon, iconForNode } from './icons'; import { ServiceAnomalyStats } from '../../../../common/anomaly_detection'; +import { severity, getSeverity } from './Popover/getSeverity'; export const popoverWidth = 280; diff --git a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/add_environments.tsx b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/add_environments.tsx index 4c056d48f4b14..c9328c4988e5f 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/add_environments.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/add_environments.tsx @@ -17,8 +17,10 @@ import { EuiFlexGroup, EuiFlexItem, EuiFormRow, + EuiEmptyPrompt, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { MLErrorMessages } from '../../../../../common/anomaly_detection'; import { useFetcher, FETCH_STATUS } from '../../../../hooks/useFetcher'; import { useApmPluginContext } from '../../../../hooks/useApmPluginContext'; import { createJobs } from './create_jobs'; @@ -34,7 +36,9 @@ export const AddEnvironments = ({ onCreateJobSuccess, onCancel, }: Props) => { - const { toasts } = useApmPluginContext().core.notifications; + const { notifications, application } = useApmPluginContext().core; + const canCreateJob = !!application.capabilities.ml.canCreateJob; + const { toasts } = notifications; const { data = [], status } = useFetcher( (callApmApi) => callApmApi({ @@ -56,6 +60,17 @@ export const AddEnvironments = ({ Array> >([]); + if (!canCreateJob) { + return ( + + {MLErrorMessages.MISSING_WRITE_PRIVILEGES}} + /> + + ); + } + const isLoading = status === FETCH_STATUS.PENDING || status === FETCH_STATUS.LOADING; return ( diff --git a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/create_jobs.ts b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/create_jobs.ts index 614632a5a3b09..acea38732b40a 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/create_jobs.ts +++ b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/create_jobs.ts @@ -6,8 +6,19 @@ import { i18n } from '@kbn/i18n'; import { NotificationsStart } from 'kibana/public'; +import { MLErrorMessages } from '../../../../../common/anomaly_detection'; import { callApmApi } from '../../../../services/rest/createCallApmApi'; +const errorToastTitle = i18n.translate( + 'xpack.apm.anomalyDetection.createJobs.failed.title', + { defaultMessage: 'Anomaly detection jobs could not be created' } +); + +const successToastTitle = i18n.translate( + 'xpack.apm.anomalyDetection.createJobs.succeeded.title', + { defaultMessage: 'Anomaly detection jobs created' } +); + export async function createJobs({ environments, toasts, @@ -16,7 +27,7 @@ export async function createJobs({ toasts: NotificationsStart['toasts']; }) { try { - await callApmApi({ + const res = await callApmApi({ pathname: '/api/apm/settings/anomaly-detection/jobs', method: 'POST', params: { @@ -24,41 +35,50 @@ export async function createJobs({ }, }); + // a known error occurred + if (res?.errorCode) { + toasts.addDanger({ + title: errorToastTitle, + text: MLErrorMessages[res.errorCode], + }); + return false; + } + + // job created successfully toasts.addSuccess({ - title: i18n.translate( - 'xpack.apm.anomalyDetection.createJobs.succeeded.title', - { defaultMessage: 'Anomaly detection jobs created' } - ), - text: i18n.translate( - 'xpack.apm.anomalyDetection.createJobs.succeeded.text', - { - defaultMessage: - 'Anomaly detection jobs successfully created for APM service environments [{environments}]. It will take some time for machine learning to start analyzing traffic for anomalies.', - values: { environments: environments.join(', ') }, - } - ), + title: successToastTitle, + text: getSuccessToastMessage(environments), }); return true; + + // an unknown/unexpected error occurred } catch (error) { toasts.addDanger({ - title: i18n.translate( - 'xpack.apm.anomalyDetection.createJobs.failed.title', - { - defaultMessage: 'Anomaly detection jobs could not be created', - } - ), - text: i18n.translate( - 'xpack.apm.anomalyDetection.createJobs.failed.text', - { - defaultMessage: - 'Something went wrong when creating one ore more anomaly detection jobs for APM service environments [{environments}]. Error: "{errorMessage}"', - values: { - environments: environments.join(', '), - errorMessage: error.message, - }, - } - ), + title: errorToastTitle, + text: getErrorToastMessage(environments, error), }); return false; } } + +function getSuccessToastMessage(environments: string[]) { + return i18n.translate( + 'xpack.apm.anomalyDetection.createJobs.succeeded.text', + { + defaultMessage: + 'Anomaly detection jobs successfully created for APM service environments [{environments}]. It will take some time for machine learning to start analyzing traffic for anomalies.', + values: { environments: environments.join(', ') }, + } + ); +} + +function getErrorToastMessage(environments: string[], error: Error) { + return i18n.translate('xpack.apm.anomalyDetection.createJobs.failed.text', { + defaultMessage: + 'Something went wrong when creating one ore more anomaly detection jobs for APM service environments [{environments}]. Error: "{errorMessage}"', + values: { + environments: environments.join(', '), + errorMessage: error.message, + }, + }); +} diff --git a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/index.tsx index f02350fafbabb..abbe1e2c83c7b 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/index.tsx @@ -7,7 +7,9 @@ import React, { useState } from 'react'; import { EuiTitle, EuiSpacer, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { EuiPanel } from '@elastic/eui'; +import { EuiPanel, EuiEmptyPrompt } from '@elastic/eui'; +import { MLErrorMessages } from '../../../../../common/anomaly_detection'; +import { useApmPluginContext } from '../../../../hooks/useApmPluginContext'; import { JobsList } from './jobs_list'; import { AddEnvironments } from './add_environments'; import { useFetcher } from '../../../../hooks/useFetcher'; @@ -16,24 +18,31 @@ import { useLicense } from '../../../../hooks/useLicense'; import { APIReturnType } from '../../../../services/rest/createCallApmApi'; export type AnomalyDetectionApiResponse = APIReturnType< - '/api/apm/settings/anomaly-detection' + '/api/apm/settings/anomaly-detection', + 'GET' >; const DEFAULT_VALUE: AnomalyDetectionApiResponse = { jobs: [], hasLegacyJobs: false, + errorCode: undefined, }; export const AnomalyDetection = () => { + const plugin = useApmPluginContext(); + const canGetJobs = !!plugin.core.application.capabilities.ml.canGetJobs; const license = useLicense(); const hasValidLicense = license?.isActive && license?.hasAtLeast('platinum'); const [viewAddEnvironments, setViewAddEnvironments] = useState(false); const { refetch, data = DEFAULT_VALUE, status } = useFetcher( - (callApmApi) => - callApmApi({ pathname: `/api/apm/settings/anomaly-detection` }), - [], + (callApmApi) => { + if (canGetJobs) { + return callApmApi({ pathname: `/api/apm/settings/anomaly-detection` }); + } + }, + [canGetJobs], { preservePreviousData: false, showToastOnError: false } ); @@ -53,6 +62,17 @@ export const AnomalyDetection = () => { ); } + if (!canGetJobs) { + return ( + + {MLErrorMessages.MISSING_READ_PRIVILEGES}} + /> + + ); + } + return ( <> @@ -83,9 +103,8 @@ export const AnomalyDetection = () => { /> ) : ( { setViewAddEnvironments(true); }} diff --git a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx index 5954b82f3b9e7..67227f99cb5f1 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx @@ -16,6 +16,10 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { + MLErrorMessages, + ErrorCode, +} from '../../../../../common/anomaly_detection'; import { FETCH_STATUS } from '../../../../hooks/useFetcher'; import { ITableColumn, ManagedTable } from '../../../shared/ManagedTable'; import { LoadingStatePrompt } from '../../../shared/LoadingStatePrompt'; @@ -57,21 +61,12 @@ const columns: Array> = [ ]; interface Props { + data: AnomalyDetectionApiResponse; status: FETCH_STATUS; onAddEnvironments: () => void; - jobs: Jobs; - hasLegacyJobs: boolean; } -export const JobsList = ({ - status, - onAddEnvironments, - jobs, - hasLegacyJobs, -}: Props) => { - const isLoading = - status === FETCH_STATUS.PENDING || status === FETCH_STATUS.LOADING; - - const hasFetchFailure = status === FETCH_STATUS.FAILURE; +export const JobsList = ({ data, status, onAddEnvironments }: Props) => { + const { jobs, hasLegacyJobs, errorCode } = data; return ( @@ -120,15 +115,10 @@ export const JobsList = ({ - ) : hasFetchFailure ? ( - - ) : ( - - ) - } + noItemsMessage={getNoItemsMessage({ + status, + errorCode, + })} columns={columns} items={jobs} /> @@ -139,28 +129,36 @@ export const JobsList = ({ ); }; -function EmptyStatePrompt() { - return ( - <> - {i18n.translate( - 'xpack.apm.settings.anomalyDetection.jobList.emptyListText', - { - defaultMessage: 'No anomaly detection jobs.', - } - )} - - ); -} +function getNoItemsMessage({ + status, + errorCode, +}: { + status: FETCH_STATUS; + errorCode?: ErrorCode; +}) { + // loading state + const isLoading = + status === FETCH_STATUS.PENDING || status === FETCH_STATUS.LOADING; + if (isLoading) { + return ; + } -function FailureStatePrompt() { - return ( - <> - {i18n.translate( - 'xpack.apm.settings.anomalyDetection.jobList.failedFetchText', - { - defaultMessage: 'Unabled to fetch anomaly detection jobs.', - } - )} - + // A known error occured. Show specific error message + if (errorCode) { + return MLErrorMessages[errorCode]; + } + + // An unexpected error occurred. Show default error message + if (status === FETCH_STATUS.FAILURE) { + return i18n.translate( + 'xpack.apm.settings.anomalyDetection.jobList.failedFetchText', + { defaultMessage: 'Unabled to fetch anomaly detection jobs.' } + ); + } + + // no errors occurred + return i18n.translate( + 'xpack.apm.settings.anomalyDetection.jobList.emptyListText', + { defaultMessage: 'No anomaly detection jobs.' } ); } diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/AnomalyDetectionSetupLink.test.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/AnomalyDetectionSetupLink.test.tsx index 268d8bd7ea823..2149cb676f0d8 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/AnomalyDetectionSetupLink.test.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/AnomalyDetectionSetupLink.test.tsx @@ -6,37 +6,48 @@ import { showAlert } from './AnomalyDetectionSetupLink'; +const dataWithJobs = { + hasLegacyJobs: false, + jobs: [ + { job_id: 'job1', environment: 'staging' }, + { job_id: 'job2', environment: 'production' }, + ], +}; +const dataWithoutJobs = ({ jobs: [] } as unknown) as any; + describe('#showAlert', () => { describe('when an environment is selected', () => { it('should return true when there are no jobs', () => { - const result = showAlert([], 'testing'); + const result = showAlert(dataWithoutJobs, 'testing'); expect(result).toBe(true); }); it('should return true when environment is not included in the jobs', () => { - const result = showAlert( - [{ environment: 'staging' }, { environment: 'production' }], - 'testing' - ); + const result = showAlert(dataWithJobs, 'testing'); expect(result).toBe(true); }); it('should return false when environment is included in the jobs', () => { - const result = showAlert( - [{ environment: 'staging' }, { environment: 'production' }], - 'staging' - ); + const result = showAlert(dataWithJobs, 'staging'); expect(result).toBe(false); }); }); + describe('there is no environment selected (All)', () => { it('should return true when there are no jobs', () => { - const result = showAlert([], undefined); + const result = showAlert(dataWithoutJobs, undefined); expect(result).toBe(true); }); it('should return false when there are any number of jobs', () => { - const result = showAlert( - [{ environment: 'staging' }, { environment: 'production' }], - undefined - ); + const result = showAlert(dataWithJobs, undefined); + expect(result).toBe(false); + }); + }); + + describe('when a known error occurred', () => { + it('should return false', () => { + const data = ({ + errorCode: 'MISSING_READ_PRIVILEGES', + } as unknown) as any; + const result = showAlert(data, undefined); expect(result).toBe(false); }); }); diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/AnomalyDetectionSetupLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/AnomalyDetectionSetupLink.tsx index 6f3a5df480d7e..e989244d43148 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/AnomalyDetectionSetupLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/AnomalyDetectionSetupLink.tsx @@ -6,16 +6,25 @@ import React from 'react'; import { EuiButtonEmpty, EuiToolTip, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { ErrorCode } from '../../../../../common/anomaly_detection'; +import { APIReturnType } from '../../../../services/rest/createCallApmApi'; import { APMLink } from './APMLink'; import { getEnvironmentLabel } from '../../../../../common/environment_filter_values'; import { useUrlParams } from '../../../../hooks/useUrlParams'; import { useFetcher, FETCH_STATUS } from '../../../../hooks/useFetcher'; +export type AnomalyDetectionApiResponse = APIReturnType< + '/api/apm/settings/anomaly-detection', + 'GET' +>; + +const DEFAULT_DATA = { jobs: [], hasLegacyJobs: false, errorCode: undefined }; + export function AnomalyDetectionSetupLink() { const { uiFilters } = useUrlParams(); const environment = uiFilters.environment; - const { data = { jobs: [], hasLegacyJobs: false }, status } = useFetcher( + const { data = DEFAULT_DATA, status } = useFetcher( (callApmApi) => callApmApi({ pathname: `/api/apm/settings/anomaly-detection` }), [], @@ -28,7 +37,7 @@ export function AnomalyDetectionSetupLink() { {ANOMALY_DETECTION_LINK_LABEL} - {isFetchSuccess && showAlert(data.jobs, environment) && ( + {isFetchSuccess && showAlert(data, environment) && ( @@ -59,9 +68,14 @@ const ANOMALY_DETECTION_LINK_LABEL = i18n.translate( ); export function showAlert( - jobs: Array<{ environment: string }> = [], + { jobs = [], errorCode }: AnomalyDetectionApiResponse, environment: string | undefined ) { + // don't show warning if the user is missing read privileges + if (errorCode === ErrorCode.MISSING_READ_PRIVILEGES) { + return false; + } + return ( // No job exists, or jobs.length === 0 || diff --git a/x-pack/plugins/apm/server/lib/anomaly_detection/anomaly_detection_error.ts b/x-pack/plugins/apm/server/lib/anomaly_detection/anomaly_detection_error.ts new file mode 100644 index 0000000000000..993dcf4c5354b --- /dev/null +++ b/x-pack/plugins/apm/server/lib/anomaly_detection/anomaly_detection_error.ts @@ -0,0 +1,16 @@ +/* + * 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 { ErrorCode, MLErrorMessages } from '../../../common/anomaly_detection'; + +export class AnomalyDetectionError extends Error { + constructor(public code: ErrorCode) { + super(MLErrorMessages[code]); + + this.name = this.constructor.name; + Error.captureStackTrace(this, this.constructor); + } +} diff --git a/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts b/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts index c387c5152b1c5..e5338ac9f5797 100644 --- a/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts +++ b/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts @@ -7,6 +7,7 @@ import { Logger } from 'kibana/server'; import uuid from 'uuid/v4'; import { snakeCase } from 'lodash'; +import { ErrorCode } from '../../../common/anomaly_detection'; import { PromiseReturnType } from '../../../../observability/typings/common'; import { Setup } from '../helpers/setup_request'; import { @@ -15,6 +16,7 @@ import { } from '../../../common/elasticsearch_fieldnames'; import { APM_ML_JOB_GROUP, ML_MODULE_ID_APM_TRANSACTION } from './constants'; import { getEnvironmentUiFilterES } from '../helpers/convert_ui_filters/get_environment_ui_filter_es'; +import { AnomalyDetectionError } from './anomaly_detection_error'; export type CreateAnomalyDetectionJobsAPIResponse = PromiseReturnType< typeof createAnomalyDetectionJobs @@ -25,21 +27,20 @@ export async function createAnomalyDetectionJobs( logger: Logger ) { const { ml, indices } = setup; + if (!ml) { - logger.warn('Anomaly detection plugin is not available.'); - return []; + throw new AnomalyDetectionError(ErrorCode.ML_NOT_AVAILABLE); } + const mlCapabilities = await ml.mlSystem.mlCapabilities(); if (!mlCapabilities.mlFeatureEnabledInSpace) { - logger.warn('Anomaly detection feature is not enabled for the space.'); - return []; + throw new AnomalyDetectionError(ErrorCode.ML_NOT_AVAILABLE_IN_SPACE); } + if (!mlCapabilities.isPlatinumOrTrialLicense) { - logger.warn( - 'Unable to create anomaly detection jobs due to insufficient license.' - ); - return []; + throw new AnomalyDetectionError(ErrorCode.INSUFFICIENT_LICENSE); } + logger.info( `Creating ML anomaly detection jobs for environments: [${environments}].` ); @@ -59,9 +60,8 @@ export async function createAnomalyDetectionJobs( `Failed to create anomaly detection ML jobs for: [${failedJobIds}]:` ); failedJobs.forEach(({ error }) => logger.error(JSON.stringify(error))); - throw new Error( - `Failed to create anomaly detection ML jobs for: [${failedJobIds}].` - ); + + throw new AnomalyDetectionError(ErrorCode.UNEXPECTED); } return jobResponses; @@ -70,11 +70,11 @@ export async function createAnomalyDetectionJobs( async function createAnomalyDetectionJob({ ml, environment, - indexPatternName = 'apm-*-transaction-*', + indexPatternName, }: { ml: Required['ml']; environment: string; - indexPatternName?: string | undefined; + indexPatternName: string; }) { const randomToken = uuid().substr(-4); diff --git a/x-pack/plugins/apm/server/lib/anomaly_detection/get_anomaly_detection_jobs.ts b/x-pack/plugins/apm/server/lib/anomaly_detection/get_anomaly_detection_jobs.ts index 13b30f159eed1..62d4243a06028 100644 --- a/x-pack/plugins/apm/server/lib/anomaly_detection/get_anomaly_detection_jobs.ts +++ b/x-pack/plugins/apm/server/lib/anomaly_detection/get_anomaly_detection_jobs.ts @@ -5,8 +5,10 @@ */ import { Logger } from 'kibana/server'; +import { ErrorCode } from '../../../common/anomaly_detection'; import { Setup } from '../helpers/setup_request'; import { getMlJobsWithAPMGroup } from './get_ml_jobs_with_apm_group'; +import { AnomalyDetectionError } from './anomaly_detection_error'; export async function getAnomalyDetectionJobs(setup: Setup, logger: Logger) { const { ml } = setup; @@ -15,14 +17,12 @@ export async function getAnomalyDetectionJobs(setup: Setup, logger: Logger) { } const mlCapabilities = await ml.mlSystem.mlCapabilities(); - if ( - !( - mlCapabilities.mlFeatureEnabledInSpace && - mlCapabilities.isPlatinumOrTrialLicense - ) - ) { - logger.warn('Anomaly detection integration is not availble for this user.'); - return []; + if (!mlCapabilities.mlFeatureEnabledInSpace) { + throw new AnomalyDetectionError(ErrorCode.ML_NOT_AVAILABLE_IN_SPACE); + } + + if (!mlCapabilities.isPlatinumOrTrialLicense) { + throw new AnomalyDetectionError(ErrorCode.INSUFFICIENT_LICENSE); } const response = await getMlJobsWithAPMGroup(ml); diff --git a/x-pack/plugins/apm/server/routes/settings/anomaly_detection.ts b/x-pack/plugins/apm/server/routes/settings/anomaly_detection.ts index 4d564b773e397..218d47fcf9bb4 100644 --- a/x-pack/plugins/apm/server/routes/settings/anomaly_detection.ts +++ b/x-pack/plugins/apm/server/routes/settings/anomaly_detection.ts @@ -5,12 +5,32 @@ */ import * as t from 'io-ts'; +import { ErrorCode } from '../../../common/anomaly_detection'; +import { PromiseReturnType } from '../../../typings/common'; +import { InsufficientMLCapabilities } from '../../../../ml/server'; import { createRoute } from '../create_route'; import { getAnomalyDetectionJobs } from '../../lib/anomaly_detection/get_anomaly_detection_jobs'; import { createAnomalyDetectionJobs } from '../../lib/anomaly_detection/create_anomaly_detection_jobs'; import { setupRequest } from '../../lib/helpers/setup_request'; import { getAllEnvironments } from '../../lib/environments/get_all_environments'; import { hasLegacyJobs } from '../../lib/anomaly_detection/has_legacy_jobs'; +import { AnomalyDetectionError } from '../../lib/anomaly_detection/anomaly_detection_error'; + +type Jobs = PromiseReturnType; + +function getMlErrorCode(e: Error) { + // Missing privileges + if (e instanceof InsufficientMLCapabilities) { + return ErrorCode.MISSING_READ_PRIVILEGES; + } + + if (e instanceof AnomalyDetectionError) { + return e.code; + } + + // unexpected error + return ErrorCode.UNEXPECTED; +} // get ML anomaly detection jobs for each environment export const anomalyDetectionJobsRoute = createRoute(() => ({ @@ -18,14 +38,25 @@ export const anomalyDetectionJobsRoute = createRoute(() => ({ path: '/api/apm/settings/anomaly-detection', handler: async ({ context, request }) => { const setup = await setupRequest(context, request); - const [jobs, legacyJobs] = await Promise.all([ - getAnomalyDetectionJobs(setup, context.logger), - hasLegacyJobs(setup), - ]); - return { - jobs, - hasLegacyJobs: legacyJobs, - }; + + try { + const [jobs, legacyJobs] = await Promise.all([ + getAnomalyDetectionJobs(setup, context.logger), + hasLegacyJobs(setup), + ]); + return { + jobs, + hasLegacyJobs: legacyJobs, + }; + } catch (e) { + const mlErrorCode = getMlErrorCode(e); + context.logger.warn(`Error while retrieving ML jobs: "${e.message}"`); + return { + jobs: [] as Jobs, + hasLegacyJobs: false, + errorCode: mlErrorCode, + }; + } }, })); @@ -44,11 +75,16 @@ export const createAnomalyDetectionJobsRoute = createRoute(() => ({ handler: async ({ context, request }) => { const { environments } = context.params.body; const setup = await setupRequest(context, request); - return await createAnomalyDetectionJobs( - setup, - environments, - context.logger - ); + + try { + await createAnomalyDetectionJobs(setup, environments, context.logger); + } catch (e) { + const mlErrorCode = getMlErrorCode(e); + context.logger.warn(`Error while creating ML job: "${e.message}"`); + return { + errorCode: mlErrorCode, + }; + } }, })); From 005a1121cc2b50bfd931838592456716e5eb0bff Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Tue, 21 Jul 2020 09:44:25 +0200 Subject: [PATCH 33/77] use KibanaClient interface instead of Client for new client interface (#72388) * use KibanaClient interface instead of Client * add back helpers to ElasticsearchClient interface * use TransportRequestPromise for transport.request * update generated doc --- ...in-core-server.httpservicesetup.registeronpostauth.md | 2 +- ...gin-core-server.httpservicesetup.registeronpreauth.md | 2 +- .../development/core/server/kibana-plugin-core-server.md | 2 +- .../kibana-plugin-core-server.onpreresponsetoolkit.md | 2 +- src/core/server/elasticsearch/client/types.ts | 9 +++++---- src/core/server/server.api.md | 3 ++- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registeronpostauth.md b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registeronpostauth.md index eff53b7b75fa5..41b82f428948a 100644 --- a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registeronpostauth.md +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registeronpostauth.md @@ -14,5 +14,5 @@ registerOnPostAuth: (handler: OnPostAuthHandler) => void; ## Remarks -The auth state is available at stage via http.auth.get(..) Can register any number of registerOnPreRouting, which are called in sequence (from the first registered to the last). See [OnPostAuthHandler](./kibana-plugin-core-server.onpostauthhandler.md). +The auth state is available at stage via http.auth.get(..) Can register any number of registerOnPostAuth, which are called in sequence (from the first registered to the last). See [OnPostAuthHandler](./kibana-plugin-core-server.onpostauthhandler.md). diff --git a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registeronpreauth.md b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registeronpreauth.md index ce4cacb1c8749..57b1833df5e03 100644 --- a/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registeronpreauth.md +++ b/docs/development/core/server/kibana-plugin-core-server.httpservicesetup.registeronpreauth.md @@ -14,5 +14,5 @@ registerOnPreAuth: (handler: OnPreAuthHandler) => void; ## Remarks -Can register any number of registerOnPostAuth, which are called in sequence (from the first registered to the last). See [OnPreRoutingHandler](./kibana-plugin-core-server.onpreroutinghandler.md). +Can register any number of registerOnPreAuth, which are called in sequence (from the first registered to the last). See [OnPreAuthHandler](./kibana-plugin-core-server.onpreauthhandler.md). diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index a665327454c1a..61ffc532f0de5 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -122,7 +122,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [OnPreAuthToolkit](./kibana-plugin-core-server.onpreauthtoolkit.md) | A tool set defining an outcome of OnPreAuth interceptor for incoming request. | | [OnPreResponseExtensions](./kibana-plugin-core-server.onpreresponseextensions.md) | Additional data to extend a response. | | [OnPreResponseInfo](./kibana-plugin-core-server.onpreresponseinfo.md) | Response status code. | -| [OnPreResponseToolkit](./kibana-plugin-core-server.onpreresponsetoolkit.md) | A tool set defining an outcome of OnPreRouting interceptor for incoming request. | +| [OnPreResponseToolkit](./kibana-plugin-core-server.onpreresponsetoolkit.md) | A tool set defining an outcome of OnPreResponse interceptor for incoming request. | | [OnPreRoutingToolkit](./kibana-plugin-core-server.onpreroutingtoolkit.md) | A tool set defining an outcome of OnPreRouting interceptor for incoming request. | | [OpsMetrics](./kibana-plugin-core-server.opsmetrics.md) | Regroups metrics gathered by all the collectors. This contains metrics about the os/runtime, the kibana process and the http server. | | [OpsOsMetrics](./kibana-plugin-core-server.opsosmetrics.md) | OS related metrics | diff --git a/docs/development/core/server/kibana-plugin-core-server.onpreresponsetoolkit.md b/docs/development/core/server/kibana-plugin-core-server.onpreresponsetoolkit.md index 306c375ba4a3c..44da09d0cc68e 100644 --- a/docs/development/core/server/kibana-plugin-core-server.onpreresponsetoolkit.md +++ b/docs/development/core/server/kibana-plugin-core-server.onpreresponsetoolkit.md @@ -4,7 +4,7 @@ ## OnPreResponseToolkit interface -A tool set defining an outcome of OnPreRouting interceptor for incoming request. +A tool set defining an outcome of OnPreResponse interceptor for incoming request. Signature: diff --git a/src/core/server/elasticsearch/client/types.ts b/src/core/server/elasticsearch/client/types.ts index 934120c330e92..7ce998aab7669 100644 --- a/src/core/server/elasticsearch/client/types.ts +++ b/src/core/server/elasticsearch/client/types.ts @@ -17,11 +17,12 @@ * under the License. */ -import type { Client } from '@elastic/elasticsearch'; +import type { KibanaClient } from '@elastic/elasticsearch/api/kibana'; import type { ApiResponse, TransportRequestOptions, TransportRequestParams, + TransportRequestPromise, } from '@elastic/elasticsearch/lib/Transport'; /** @@ -30,13 +31,13 @@ import type { * @public */ export type ElasticsearchClient = Omit< - Client, - 'connectionPool' | 'transport' | 'serializer' | 'extend' | 'helpers' | 'child' | 'close' + KibanaClient, + 'connectionPool' | 'transport' | 'serializer' | 'extend' | 'child' | 'close' > & { transport: { request( params: TransportRequestParams, options?: TransportRequestOptions - ): Promise; + ): TransportRequestPromise; }; }; diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index a0e16602ba4bf..4b6bcbc8ad7a0 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -22,7 +22,6 @@ import { CatTasksParams } from 'elasticsearch'; import { CatThreadPoolParams } from 'elasticsearch'; import { ClearScrollParams } from 'elasticsearch'; import { Client } from 'elasticsearch'; -import { Client as Client_2 } from '@elastic/elasticsearch'; import { ClientOptions } from '@elastic/elasticsearch'; import { ClusterAllocationExplainParams } from 'elasticsearch'; import { ClusterGetSettingsParams } from 'elasticsearch'; @@ -93,6 +92,7 @@ import { IngestDeletePipelineParams } from 'elasticsearch'; import { IngestGetPipelineParams } from 'elasticsearch'; import { IngestPutPipelineParams } from 'elasticsearch'; import { IngestSimulateParams } from 'elasticsearch'; +import { KibanaClient } from '@elastic/elasticsearch/api/kibana'; import { KibanaConfigType } from 'src/core/server/kibana_config'; import { MGetParams } from 'elasticsearch'; import { MGetResponse } from 'elasticsearch'; @@ -143,6 +143,7 @@ import { TasksListParams } from 'elasticsearch'; import { TermvectorsParams } from 'elasticsearch'; import { TransportRequestOptions } from '@elastic/elasticsearch/lib/Transport'; import { TransportRequestParams } from '@elastic/elasticsearch/lib/Transport'; +import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport'; import { Type } from '@kbn/config-schema'; import { TypeOf } from '@kbn/config-schema'; import { UpdateDocumentByQueryParams } from 'elasticsearch'; From efa1795cfddd76f0a7644546072af601481abc20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Tue, 21 Jul 2020 09:09:30 +0100 Subject: [PATCH 34/77] fixing error occurences tooltip (#72425) --- .../components/app/ErrorGroupDetails/Distribution/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx index aa95918939dfa..80c749e58c88c 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx @@ -12,7 +12,6 @@ import d3 from 'd3'; import { scaleUtc } from 'd3-scale'; import { mean } from 'lodash'; import React from 'react'; -import { px } from '../../../../style/variables'; import { asRelativeDateTimeRange } from '../../../../utils/formatters'; import { getTimezoneOffsetInMs } from '../../../shared/charts/CustomPlot/getTimezoneOffsetInMs'; // @ts-ignore @@ -89,7 +88,7 @@ export function ErrorDistribution({ distribution, title }: Props) { {title} bucket.x} From 20c6d9fe524789b450bbda03222f55d0cb927656 Mon Sep 17 00:00:00 2001 From: MadameSheema Date: Tue, 21 Jul 2020 10:35:31 +0200 Subject: [PATCH 35/77] [SIEM][Detections] Updates text for severity and risk_score overrides (#72244) * updates severity mapping description text * updates risk score mapping description * updates default messages with the given suggestions Co-authored-by: Elastic Machine --- .../components/rules/risk_score_mapping/translations.tsx | 2 +- .../components/rules/severity_mapping/translations.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/translations.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/translations.tsx index 24e82a8f95a6b..c64a1e6891a44 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/translations.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/translations.tsx @@ -51,7 +51,7 @@ export const RISK_SCORE_DESCRIPTION = i18n.translate( export const RISK_SCORE_MAPPING_DESCRIPTION = i18n.translate( 'xpack.securitySolution.alerts.riskScoreMapping.mappingDescriptionLabel', { - defaultMessage: 'Map a field from the source event (scaled 1-100) to risk score.', + defaultMessage: 'Use a source event value to override the default risk score.', } ); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/translations.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/translations.tsx index f0bfc5f4637ab..12653ec5806bb 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/translations.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/translations.tsx @@ -51,7 +51,7 @@ export const SEVERITY_DESCRIPTION = i18n.translate( export const SEVERITY_MAPPING_DESCRIPTION = i18n.translate( 'xpack.securitySolution.alerts.severityMapping.mappingDescriptionLabel', { - defaultMessage: 'Map a value from the source event to a specific severity.', + defaultMessage: 'Use source event values to override the default severity.', } ); From 517c34a7ebf6ad6e02dab08c04155f7e0ab17956 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Tue, 21 Jul 2020 11:34:04 +0200 Subject: [PATCH 36/77] preserve 401 errors from new es client (#71248) * intercept 401 error from new client in routing layer * improvements * lint * fix mocked client construction due to 7.9-rc1 bump * use default WWW-Authenticate value when not provided by ES 401 --- .../elasticsearch/client/errors.test.ts | 82 ++++++++++++ .../server/elasticsearch/client/errors.ts | 32 +++++ .../server/elasticsearch/client/mocks.test.ts | 6 + src/core/server/elasticsearch/client/mocks.ts | 15 ++- .../core_service.test.mocks.ts | 17 ++- .../integration_tests/core_services.test.ts | 117 +++++++++++++++++- src/core/server/http/router/router.ts | 34 ++++- 7 files changed, 288 insertions(+), 15 deletions(-) create mode 100644 src/core/server/elasticsearch/client/errors.test.ts create mode 100644 src/core/server/elasticsearch/client/errors.ts diff --git a/src/core/server/elasticsearch/client/errors.test.ts b/src/core/server/elasticsearch/client/errors.test.ts new file mode 100644 index 0000000000000..35ad4ca71f48c --- /dev/null +++ b/src/core/server/elasticsearch/client/errors.test.ts @@ -0,0 +1,82 @@ +/* + * 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 { + ResponseError, + ConnectionError, + ConfigurationError, +} from '@elastic/elasticsearch/lib/errors'; +import { ApiResponse } from '@elastic/elasticsearch'; +import { isResponseError, isUnauthorizedError } from './errors'; + +const createApiResponseError = ({ + statusCode = 200, + headers = {}, + body = {}, +}: { + statusCode?: number; + headers?: Record; + body?: Record; +} = {}): ApiResponse => { + return { + body, + statusCode, + headers, + warnings: [], + meta: {} as any, + }; +}; + +describe('isResponseError', () => { + it('returns `true` when the input is a `ResponseError`', () => { + expect(isResponseError(new ResponseError(createApiResponseError()))).toBe(true); + }); + + it('returns `false` when the input is not a `ResponseError`', () => { + expect(isResponseError(new Error('foo'))).toBe(false); + expect(isResponseError(new ConnectionError('error', createApiResponseError()))).toBe(false); + expect(isResponseError(new ConfigurationError('foo'))).toBe(false); + }); +}); + +describe('isUnauthorizedError', () => { + it('returns true when the input is a `ResponseError` and statusCode === 401', () => { + expect( + isUnauthorizedError(new ResponseError(createApiResponseError({ statusCode: 401 }))) + ).toBe(true); + }); + + it('returns false when the input is a `ResponseError` and statusCode !== 401', () => { + expect( + isUnauthorizedError(new ResponseError(createApiResponseError({ statusCode: 200 }))) + ).toBe(false); + expect( + isUnauthorizedError(new ResponseError(createApiResponseError({ statusCode: 403 }))) + ).toBe(false); + expect( + isUnauthorizedError(new ResponseError(createApiResponseError({ statusCode: 500 }))) + ).toBe(false); + }); + + it('returns `false` when the input is not a `ResponseError`', () => { + expect(isUnauthorizedError(new Error('foo'))).toBe(false); + expect(isUnauthorizedError(new ConnectionError('error', createApiResponseError()))).toBe(false); + expect(isUnauthorizedError(new ConfigurationError('foo'))).toBe(false); + }); +}); diff --git a/src/core/server/elasticsearch/client/errors.ts b/src/core/server/elasticsearch/client/errors.ts new file mode 100644 index 0000000000000..31a27170e1155 --- /dev/null +++ b/src/core/server/elasticsearch/client/errors.ts @@ -0,0 +1,32 @@ +/* + * 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 { ResponseError } from '@elastic/elasticsearch/lib/errors'; + +export type UnauthorizedError = ResponseError & { + statusCode: 401; +}; + +export function isResponseError(error: any): error is ResponseError { + return Boolean(error.body && error.statusCode && error.headers); +} + +export function isUnauthorizedError(error: any): error is UnauthorizedError { + return isResponseError(error) && error.statusCode === 401; +} diff --git a/src/core/server/elasticsearch/client/mocks.test.ts b/src/core/server/elasticsearch/client/mocks.test.ts index b882f8d0c5d79..a6ce95155331e 100644 --- a/src/core/server/elasticsearch/client/mocks.test.ts +++ b/src/core/server/elasticsearch/client/mocks.test.ts @@ -49,6 +49,12 @@ describe('Mocked client', () => { expectMocked(client.close); }); + it('used EventEmitter functions should be mocked', () => { + expectMocked(client.on); + expectMocked(client.off); + expectMocked(client.once); + }); + it('`child` should be mocked and return a mocked Client', () => { expectMocked(client.child); diff --git a/src/core/server/elasticsearch/client/mocks.ts b/src/core/server/elasticsearch/client/mocks.ts index 34e83922d4d86..ec2885dfdf922 100644 --- a/src/core/server/elasticsearch/client/mocks.ts +++ b/src/core/server/elasticsearch/client/mocks.ts @@ -54,13 +54,20 @@ const createInternalClientMock = (): DeeplyMockedKeys => { mockify(client, omittedProps); - client.transport = { + // client got some read-only (getter) properties + // so we need to extend it to override the getter-only props. + const mock: any = { ...client }; + + mock.transport = { request: jest.fn(), }; - client.close = jest.fn().mockReturnValue(Promise.resolve()); - client.child = jest.fn().mockImplementation(() => createInternalClientMock()); + mock.close = jest.fn().mockReturnValue(Promise.resolve()); + mock.child = jest.fn().mockImplementation(() => createInternalClientMock()); + mock.on = jest.fn(); + mock.off = jest.fn(); + mock.once = jest.fn(); - return (client as unknown) as DeeplyMockedKeys; + return (mock as unknown) as DeeplyMockedKeys; }; export type ElasticSearchClientMock = DeeplyMockedKeys; diff --git a/src/core/server/http/integration_tests/core_service.test.mocks.ts b/src/core/server/http/integration_tests/core_service.test.mocks.ts index c23724b7d332f..515dad5383c01 100644 --- a/src/core/server/http/integration_tests/core_service.test.mocks.ts +++ b/src/core/server/http/integration_tests/core_service.test.mocks.ts @@ -18,10 +18,12 @@ */ import { elasticsearchServiceMock } from '../../elasticsearch/elasticsearch_service.mock'; -export const clusterClientMock = jest.fn(); -export const clusterClientInstanceMock = elasticsearchServiceMock.createLegacyScopedClusterClient(); +export const MockLegacyScopedClusterClient = jest.fn(); +export const legacyClusterClientInstanceMock = elasticsearchServiceMock.createLegacyScopedClusterClient(); jest.doMock('../../elasticsearch/legacy/scoped_cluster_client', () => ({ - LegacyScopedClusterClient: clusterClientMock.mockImplementation(() => clusterClientInstanceMock), + LegacyScopedClusterClient: MockLegacyScopedClusterClient.mockImplementation( + () => legacyClusterClientInstanceMock + ), })); jest.doMock('elasticsearch', () => { @@ -34,3 +36,12 @@ jest.doMock('elasticsearch', () => { }, }; }); + +export const MockElasticsearchClient = jest.fn(); +jest.doMock('@elastic/elasticsearch', () => { + const real = jest.requireActual('@elastic/elasticsearch'); + return { + ...real, + Client: MockElasticsearchClient, + }; +}); diff --git a/src/core/server/http/integration_tests/core_services.test.ts b/src/core/server/http/integration_tests/core_services.test.ts index 3c5f22500e5e0..6338326626d54 100644 --- a/src/core/server/http/integration_tests/core_services.test.ts +++ b/src/core/server/http/integration_tests/core_services.test.ts @@ -17,14 +17,21 @@ * under the License. */ -import { clusterClientMock, clusterClientInstanceMock } from './core_service.test.mocks'; +import { + MockLegacyScopedClusterClient, + MockElasticsearchClient, + legacyClusterClientInstanceMock, +} from './core_service.test.mocks'; import Boom from 'boom'; import { Request } from 'hapi'; import { errors as esErrors } from 'elasticsearch'; import { LegacyElasticsearchErrorHelpers } from '../../elasticsearch/legacy'; +import { elasticsearchClientMock } from '../../elasticsearch/client/mocks'; +import { ResponseError } from '@elastic/elasticsearch/lib/errors'; import * as kbnTestServer from '../../../../test_utils/kbn_server'; +import { InternalElasticsearchServiceStart } from '../../elasticsearch'; interface User { id: string; @@ -44,6 +51,17 @@ const cookieOptions = { }; describe('http service', () => { + let esClient: ReturnType; + + beforeEach(async () => { + esClient = elasticsearchClientMock.createInternalClient(); + MockElasticsearchClient.mockImplementation(() => esClient); + }, 30000); + + afterEach(async () => { + MockElasticsearchClient.mockClear(); + }); + describe('auth', () => { let root: ReturnType; beforeEach(async () => { @@ -200,7 +218,7 @@ describe('http service', () => { }, 30000); afterEach(async () => { - clusterClientMock.mockClear(); + MockLegacyScopedClusterClient.mockClear(); await root.shutdown(); }); @@ -363,7 +381,7 @@ describe('http service', () => { }, 30000); afterEach(async () => { - clusterClientMock.mockClear(); + MockLegacyScopedClusterClient.mockClear(); await root.shutdown(); }); @@ -386,7 +404,7 @@ describe('http service', () => { await kbnTestServer.request.get(root, '/new-platform/').expect(200); // client contains authHeaders for BWC with legacy platform. - const [client] = clusterClientMock.mock.calls; + const [client] = MockLegacyScopedClusterClient.mock.calls; const [, , clientHeaders] = client; expect(clientHeaders).toEqual(authHeaders); }); @@ -410,7 +428,7 @@ describe('http service', () => { .set('Authorization', authorizationHeader) .expect(200); - const [client] = clusterClientMock.mock.calls; + const [client] = MockLegacyScopedClusterClient.mock.calls; const [, , clientHeaders] = client; expect(clientHeaders).toEqual({ authorization: authorizationHeader }); }); @@ -426,7 +444,7 @@ describe('http service', () => { }) ); - clusterClientInstanceMock.callAsCurrentUser.mockRejectedValue(authenticationError); + legacyClusterClientInstanceMock.callAsCurrentUser.mockRejectedValue(authenticationError); const router = createRouter('/new-platform'); router.get({ path: '/', validate: false }, async (context, req, res) => { @@ -441,4 +459,91 @@ describe('http service', () => { expect(response.header['www-authenticate']).toEqual('authenticate header'); }); }); + + describe('elasticsearch client', () => { + let root: ReturnType; + + beforeEach(async () => { + root = kbnTestServer.createRoot({ plugins: { initialize: false } }); + }, 30000); + + afterEach(async () => { + MockElasticsearchClient.mockClear(); + await root.shutdown(); + }); + + it('forwards unauthorized errors from elasticsearch', async () => { + const { http } = await root.setup(); + const { createRouter } = http; + // eslint-disable-next-line prefer-const + let elasticsearch: InternalElasticsearchServiceStart; + + esClient.ping.mockImplementation(() => + elasticsearchClientMock.createClientError( + new ResponseError({ + statusCode: 401, + body: { + error: { + type: 'Unauthorized', + }, + }, + warnings: [], + headers: { + 'WWW-Authenticate': 'content', + }, + meta: {} as any, + }) + ) + ); + + const router = createRouter('/new-platform'); + router.get({ path: '/', validate: false }, async (context, req, res) => { + await elasticsearch.client.asScoped(req).asInternalUser.ping(); + return res.ok(); + }); + + const coreStart = await root.start(); + elasticsearch = coreStart.elasticsearch; + + const { header } = await kbnTestServer.request.get(root, '/new-platform/').expect(401); + + expect(header['www-authenticate']).toEqual('content'); + }); + + it('uses a default value for `www-authenticate` header when ES 401 does not specify it', async () => { + const { http } = await root.setup(); + const { createRouter } = http; + // eslint-disable-next-line prefer-const + let elasticsearch: InternalElasticsearchServiceStart; + + esClient.ping.mockImplementation(() => + elasticsearchClientMock.createClientError( + new ResponseError({ + statusCode: 401, + body: { + error: { + type: 'Unauthorized', + }, + }, + warnings: [], + headers: {}, + meta: {} as any, + }) + ) + ); + + const router = createRouter('/new-platform'); + router.get({ path: '/', validate: false }, async (context, req, res) => { + await elasticsearch.client.asScoped(req).asInternalUser.ping(); + return res.ok(); + }); + + const coreStart = await root.start(); + elasticsearch = coreStart.elasticsearch; + + const { header } = await kbnTestServer.request.get(root, '/new-platform/').expect(401); + + expect(header['www-authenticate']).toEqual('Basic realm="Authorization Required"'); + }); + }); }); diff --git a/src/core/server/http/router/router.ts b/src/core/server/http/router/router.ts index 35eec746163ce..cc5279a396163 100644 --- a/src/core/server/http/router/router.ts +++ b/src/core/server/http/router/router.ts @@ -23,8 +23,17 @@ import Boom from 'boom'; import { isConfigSchema } from '@kbn/config-schema'; import { Logger } from '../../logging'; import { LegacyElasticsearchErrorHelpers } from '../../elasticsearch/legacy/errors'; +import { + isUnauthorizedError as isElasticsearchUnauthorizedError, + UnauthorizedError as EsNotAuthorizedError, +} from '../../elasticsearch/client/errors'; import { KibanaRequest } from './request'; -import { KibanaResponseFactory, kibanaResponseFactory, IKibanaResponse } from './response'; +import { + KibanaResponseFactory, + kibanaResponseFactory, + IKibanaResponse, + ErrorHttpResponseOptions, +} from './response'; import { RouteConfig, RouteConfigOptions, RouteMethod, validBodyOutput } from './route'; import { HapiResponseAdapter } from './response_adapter'; import { RequestHandlerContext } from '../../../server'; @@ -264,7 +273,13 @@ export class Router implements IRouter { return hapiResponseAdapter.handle(kibanaResponse); } catch (e) { this.log.error(e); - // forward 401 (boom) error from ES + // forward 401 errors from ES client + if (isElasticsearchUnauthorizedError(e)) { + return hapiResponseAdapter.handle( + kibanaResponseFactory.unauthorized(convertEsUnauthorized(e)) + ); + } + // forward 401 (boom) errors from legacy ES client if (LegacyElasticsearchErrorHelpers.isNotAuthorizedError(e)) { return e; } @@ -273,6 +288,21 @@ export class Router implements IRouter { } } +const convertEsUnauthorized = (e: EsNotAuthorizedError): ErrorHttpResponseOptions => { + const getAuthenticateHeaderValue = () => { + const header = Object.entries(e.headers).find( + ([key]) => key.toLowerCase() === 'www-authenticate' + ); + return header ? header[1] : 'Basic realm="Authorization Required"'; + }; + return { + body: e.message, + headers: { + 'www-authenticate': getAuthenticateHeaderValue(), + }, + }; +}; + type WithoutHeadArgument = T extends (first: any, ...rest: infer Params) => infer Return ? (...rest: Params) => Return : never; From c5073f4849409437bf73b8ec87616c8c98e2b59e Mon Sep 17 00:00:00 2001 From: cachedout Date: Tue, 21 Jul 2020 12:08:54 +0200 Subject: [PATCH 37/77] Archive e2e test results in ES (#72575) * Archive e2e test results in ES * Disable flaky comment feature and PR notifications * Update .ci/end2end.groovy Co-authored-by: Victor Martinez Co-authored-by: Victor Martinez --- .ci/end2end.groovy | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.ci/end2end.groovy b/.ci/end2end.groovy index 97099c6f87448..ee117d362d59b 100644 --- a/.ci/end2end.groovy +++ b/.ci/end2end.groovy @@ -110,6 +110,9 @@ pipeline { archiveArtifacts(allowEmptyArchive: true, artifacts: "${E2E_DIR}/kibana.log") } } + cleanup { + notifyBuildResult(notifyPRComment: false, analyzeFlakey: false, shouldNotify: false) + } } } From 81cbd13db49888d72ba75723d4c41947a0733e3e Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 21 Jul 2020 12:17:01 +0100 Subject: [PATCH 38/77] chore(NA): fix grunt task for test:coverage (#72539) --- tasks/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/test.js b/tasks/test.js index 96ec4d91db325..09821b97fe2e8 100644 --- a/tasks/test.js +++ b/tasks/test.js @@ -48,7 +48,7 @@ module.exports = function (grunt) { grunt.task.run(['run:karmaTestServer', ...ciShardTasks]); }); - grunt.registerTask('test:coverage', ['run:testCoverageServer', 'karma:coverage']); + grunt.registerTask('test:coverage', ['run:karmaTestCoverageServer', 'karma:coverage']); grunt.registerTask('test:quick', [ 'checkPlugins', From e1ffcccb9681e24c92d2048b90b3d38da9e3980e Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Tue, 21 Jul 2020 14:45:51 +0300 Subject: [PATCH 39/77] Add inspector for VEGA (#70941) * [WIP] Add inspector for VEGA Closes: #31189 * view -> dataset * cleanup * add spec viewer * cleanup code * use rx to retrieve data from adapters * Make custom inspector adapters registerable from the visType * fix flex-box size * cleanup * remove visTypesWithoutInspector from visualize_embeddable * fix PR comments * add vega folder to sass-lint * fix jest * Update src/plugins/vis_type_vega/public/vega_inspector/components/data_viewer.tsx Co-authored-by: Wylie Conlon * use addSignalListener * cleanup * add onColumnResize handler * EuiCodeEditor -> CodeEditor * fix type_check * fix issue with pagination * fix extra vertical scroll * add area-label for EuiButtonIcon * add area-label for EuiComboBox * Design Commit - Fixing up layout trying to remove any `.eui` classes and uses flex instead of percentage - Fixing text to use `Sentence case` not `Title Case` * Wrapper around signal viewer table * fix Jest snapshot Co-authored-by: Elastic Machine Co-authored-by: Wylie Conlon Co-authored-by: cchaos --- .sass-lint.yml | 1 + src/plugins/data/public/public.api.md | 3 +- .../data/public/search/aggs/buckets/terms.ts | 2 +- .../data/public/search/expressions/esaggs.ts | 2 +- .../utils/courier_inspector_stats.ts | 7 +- src/plugins/data/server/server.api.md | 1 - .../public/application/angular/discover.js | 2 +- .../embeddable/search_embeddable.ts | 2 +- .../expressions/common/execution/execution.ts | 4 +- .../expressions/common/execution/types.ts | 6 +- src/plugins/expressions/public/loader.ts | 5 +- .../public/input_control_vis_type.ts | 1 + .../inspector/common/adapters/index.ts | 9 +- .../common/adapters/request/index.ts | 1 + .../inspector/common/adapters/types.ts | 25 +++ src/plugins/inspector/public/index.scss | 2 +- src/plugins/inspector/public/plugin.tsx | 3 +- src/plugins/inspector/public/types.ts | 12 +- .../inspector_panel.test.tsx.snap | 6 +- .../inspector/public/ui/inspector_panel.scss | 12 ++ .../public/ui/inspector_panel.test.tsx | 3 +- .../inspector/public/ui/inspector_panel.tsx | 8 +- .../inspector/public/view_registry.test.ts | 2 +- src/plugins/inspector/public/view_registry.ts | 3 +- .../views/data/components/data_view.tsx | 3 +- .../inspector/public/views/data/index.tsx | 3 +- .../inspector/public/views/requests/index.ts | 3 +- .../vis_type_markdown/public/markdown_vis.ts | 1 + .../public/timelion_vis_type.tsx | 1 + .../public/metrics_type.ts | 1 + src/plugins/vis_type_vega/kibana.json | 2 +- .../vis_type_vega/public/_vega_vis.scss | 42 ++--- .../public/data_model/search_api.ts | 36 ++++- .../public/data_model/vega_parser.test.js | 1 + .../public/data_model/vega_parser.ts | 6 +- src/plugins/vis_type_vega/public/plugin.ts | 17 +- src/plugins/vis_type_vega/public/vega_fn.ts | 18 ++- .../vega_inspector/components/data_viewer.tsx | 114 ++++++++++++++ .../public/vega_inspector/components/index.ts | 22 +++ .../components/inspector_data_grid.tsx | 144 +++++++++++++++++ .../components/signal_viewer.tsx | 72 +++++++++ .../vega_inspector/components/spec_viewer.tsx | 97 ++++++++++++ .../public/vega_inspector/index.ts | 24 +++ .../public/vega_inspector/vega_adapter.ts | 148 ++++++++++++++++++ .../vega_inspector/vega_data_inspector.scss | 18 +++ .../vega_inspector/vega_data_inspector.tsx | 74 +++++++++ .../public/vega_inspector/vega_inspector.tsx | 57 +++++++ .../public/vega_request_handler.ts | 11 +- src/plugins/vis_type_vega/public/vega_type.ts | 4 +- .../public/vega_view/vega_base_view.js | 5 + .../public/vega_view/vega_map_view.js | 2 +- .../public/vega_view/vega_view.js | 2 +- .../public/embeddable/visualize_embeddable.ts | 14 +- .../public/vis_types/base_vis_type.ts | 4 + test/functional/apps/visualize/_vega_chart.js | 5 - x-pack/plugins/maps/public/kibana_services.js | 2 +- 56 files changed, 992 insertions(+), 83 deletions(-) create mode 100644 src/plugins/inspector/common/adapters/types.ts create mode 100644 src/plugins/inspector/public/ui/inspector_panel.scss create mode 100644 src/plugins/vis_type_vega/public/vega_inspector/components/data_viewer.tsx create mode 100644 src/plugins/vis_type_vega/public/vega_inspector/components/index.ts create mode 100644 src/plugins/vis_type_vega/public/vega_inspector/components/inspector_data_grid.tsx create mode 100644 src/plugins/vis_type_vega/public/vega_inspector/components/signal_viewer.tsx create mode 100644 src/plugins/vis_type_vega/public/vega_inspector/components/spec_viewer.tsx create mode 100644 src/plugins/vis_type_vega/public/vega_inspector/index.ts create mode 100644 src/plugins/vis_type_vega/public/vega_inspector/vega_adapter.ts create mode 100644 src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.scss create mode 100644 src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.tsx create mode 100644 src/plugins/vis_type_vega/public/vega_inspector/vega_inspector.tsx diff --git a/.sass-lint.yml b/.sass-lint.yml index 50cbe81cc7da2..d6eaaf391de1a 100644 --- a/.sass-lint.yml +++ b/.sass-lint.yml @@ -3,6 +3,7 @@ files: - 'src/legacy/core_plugins/metrics/**/*.s+(a|c)ss' - 'src/plugins/timelion/**/*.s+(a|c)ss' - 'src/plugins/vis_type_vislib/**/*.s+(a|c)ss' + - 'src/plugins/vis_type_vega/**/*.s+(a|c)ss' - 'src/plugins/vis_type_xy/**/*.s+(a|c)ss' - 'x-pack/plugins/canvas/**/*.s+(a|c)ss' - 'x-pack/plugins/triggers_actions_ui/**/*.s+(a|c)ss' diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 38e0416233e25..a8868c07061c3 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -52,7 +52,6 @@ import { EuiButtonEmptyProps } from '@elastic/eui'; import { EuiComboBoxProps } from '@elastic/eui'; import { EuiConfirmModalProps } from '@elastic/eui'; import { EuiGlobalToastListToast } from '@elastic/eui'; -import { EventEmitter } from 'events'; import { ExclusiveUnion } from '@elastic/eui'; import { ExistsParams } from 'elasticsearch'; import { ExplainParams } from 'elasticsearch'; @@ -148,7 +147,7 @@ import { ReindexRethrottleParams } from 'elasticsearch'; import { RenderSearchTemplateParams } from 'elasticsearch'; import { Reporter } from '@kbn/analytics'; import { RequestAdapter } from 'src/plugins/inspector/common'; -import { RequestStatistics as RequestStatistics_2 } from 'src/plugins/inspector/common'; +import { RequestStatistics } from 'src/plugins/inspector/common'; import { Required } from '@kbn/utility-types'; import * as Rx from 'rxjs'; import { SavedObject } from 'src/core/server'; diff --git a/src/plugins/data/public/search/aggs/buckets/terms.ts b/src/plugins/data/public/search/aggs/buckets/terms.ts index d3acd33d73d01..5c8483cf21369 100644 --- a/src/plugins/data/public/search/aggs/buckets/terms.ts +++ b/src/plugins/data/public/search/aggs/buckets/terms.ts @@ -129,7 +129,7 @@ export const getTermsBucketAgg = () => const response = await nestedSearchSource.fetch({ abortSignal }); request - .stats(getResponseInspectorStats(nestedSearchSource, response)) + .stats(getResponseInspectorStats(response, nestedSearchSource)) .ok({ json: response }); resp = mergeOtherBucketAggResponse(aggConfigs, resp, response, aggConfig, filterAgg()); } diff --git a/src/plugins/data/public/search/expressions/esaggs.ts b/src/plugins/data/public/search/expressions/esaggs.ts index b01f17762b2be..690f6b1df11c3 100644 --- a/src/plugins/data/public/search/expressions/esaggs.ts +++ b/src/plugins/data/public/search/expressions/esaggs.ts @@ -160,7 +160,7 @@ const handleCourierRequest = async ({ (searchSource as any).lastQuery = queryHash; - request.stats(getResponseInspectorStats(searchSource, response)).ok({ json: response }); + request.stats(getResponseInspectorStats(response, searchSource)).ok({ json: response }); (searchSource as any).rawResponse = response; } catch (e) { diff --git a/src/plugins/data/public/search/expressions/utils/courier_inspector_stats.ts b/src/plugins/data/public/search/expressions/utils/courier_inspector_stats.ts index 96d0aaa16f6ba..c933e8cd3e961 100644 --- a/src/plugins/data/public/search/expressions/utils/courier_inspector_stats.ts +++ b/src/plugins/data/public/search/expressions/utils/courier_inspector_stats.ts @@ -61,10 +61,11 @@ export function getRequestInspectorStats(searchSource: ISearchSource) { /** @public */ export function getResponseInspectorStats( - searchSource: ISearchSource, - resp: SearchResponse + resp: SearchResponse, + searchSource?: ISearchSource ) { - const lastRequest = searchSource.history && searchSource.history[searchSource.history.length - 1]; + const lastRequest = + searchSource?.history && searchSource.history[searchSource.history.length - 1]; const stats: RequestStatistics = {}; if (resp && resp.took) { diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index c5d19fef9531e..99a77ff9aeb10 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -39,7 +39,6 @@ import { DeleteTemplateParams } from 'elasticsearch'; import { DetailedPeerCertificate } from 'tls'; import { Duration } from 'moment'; import { ErrorToastOptions } from 'src/core/public/notifications'; -import { EventEmitter } from 'events'; import { ExistsParams } from 'elasticsearch'; import { ExplainParams } from 'elasticsearch'; import { FieldStatsParams } from 'elasticsearch'; diff --git a/src/plugins/discover/public/application/angular/discover.js b/src/plugins/discover/public/application/angular/discover.js index 9b8b32b51cfd8..c791bdd850151 100644 --- a/src/plugins/discover/public/application/angular/discover.js +++ b/src/plugins/discover/public/application/angular/discover.js @@ -874,7 +874,7 @@ function discoverController( } function onResults(resp) { - inspectorRequest.stats(getResponseInspectorStats($scope.searchSource, resp)).ok({ json: resp }); + inspectorRequest.stats(getResponseInspectorStats(resp, $scope.searchSource)).ok({ json: resp }); if (getTimeField()) { const tabifiedData = tabifyAggResponse($scope.vis.data.aggs, resp); diff --git a/src/plugins/discover/public/application/embeddable/search_embeddable.ts b/src/plugins/discover/public/application/embeddable/search_embeddable.ts index 9a3dd0d310ff7..b621017677c58 100644 --- a/src/plugins/discover/public/application/embeddable/search_embeddable.ts +++ b/src/plugins/discover/public/application/embeddable/search_embeddable.ts @@ -307,7 +307,7 @@ export class SearchEmbeddable extends Embeddable this.updateOutput({ loading: false, error: undefined }); // Log response to inspector - inspectorRequest.stats(getResponseInspectorStats(searchSource, resp)).ok({ json: resp }); + inspectorRequest.stats(getResponseInspectorStats(resp, searchSource)).ok({ json: resp }); // Apply the changes to the angular scope this.searchScope.$apply(() => { diff --git a/src/plugins/expressions/common/execution/execution.ts b/src/plugins/expressions/common/execution/execution.ts index f42ee18965309..3533500a2fbc5 100644 --- a/src/plugins/expressions/common/execution/execution.ts +++ b/src/plugins/expressions/common/execution/execution.ts @@ -23,7 +23,7 @@ import { createExecutionContainer, ExecutionContainer } from './container'; import { createError } from '../util'; import { Defer, now } from '../../../kibana_utils/common'; import { toPromise } from '../../../data/common/utils/abort_utils'; -import { RequestAdapter, DataAdapter } from '../../../inspector/common'; +import { RequestAdapter, DataAdapter, Adapters } from '../../../inspector/common'; import { isExpressionValueError, ExpressionValueError } from '../expression_types/specs/error'; import { ExpressionAstExpression, @@ -70,7 +70,7 @@ export class Execution< ExtraContext extends Record = Record, Input = unknown, Output = unknown, - InspectorAdapters = ExtraContext['inspectorAdapters'] extends object + InspectorAdapters extends Adapters = ExtraContext['inspectorAdapters'] extends object ? ExtraContext['inspectorAdapters'] : DefaultInspectorAdapters > { diff --git a/src/plugins/expressions/common/execution/types.ts b/src/plugins/expressions/common/execution/types.ts index 51538394cd125..7c26e586fb790 100644 --- a/src/plugins/expressions/common/execution/types.ts +++ b/src/plugins/expressions/common/execution/types.ts @@ -18,7 +18,7 @@ */ import { ExpressionType } from '../expression_types'; -import { DataAdapter, RequestAdapter } from '../../../inspector/common'; +import { Adapters, DataAdapter, RequestAdapter } from '../../../inspector/common'; import { TimeRange, Query, Filter } from '../../../data/common'; import { SavedObject, SavedObjectAttributes } from '../../../../core/public'; @@ -26,7 +26,7 @@ import { SavedObject, SavedObjectAttributes } from '../../../../core/public'; * `ExecutionContext` is an object available to all functions during a single execution; * it provides various methods to perform side-effects. */ -export interface ExecutionContext { +export interface ExecutionContext { /** * Get initial input with which execution started. */ @@ -75,7 +75,7 @@ export interface ExecutionContext { /** * Adapters used to open the inspector. */ - adapters: Adapters; + adapters: TAdapters; /** * The title that the inspector is currently using e.g. a visualization name. */ diff --git a/src/plugins/inspector/public/ui/__snapshots__/inspector_panel.test.tsx.snap b/src/plugins/inspector/public/ui/__snapshots__/inspector_panel.test.tsx.snap index 0e9560cbd7962..9ed4e60cac519 100644 --- a/src/plugins/inspector/public/ui/__snapshots__/inspector_panel.test.tsx.snap +++ b/src/plugins/inspector/public/ui/__snapshots__/inspector_panel.test.tsx.snap @@ -306,9 +306,11 @@ exports[`InspectorPanel should render as expected 1`] = `
- +
div { + display: flex; + flex-direction: column; + + > div { + flex-grow: 1; + } + } +} diff --git a/src/plugins/inspector/public/ui/inspector_panel.test.tsx b/src/plugins/inspector/public/ui/inspector_panel.test.tsx index c482b6fa8033b..23f698c23793b 100644 --- a/src/plugins/inspector/public/ui/inspector_panel.test.tsx +++ b/src/plugins/inspector/public/ui/inspector_panel.test.tsx @@ -20,7 +20,8 @@ import React from 'react'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; import { InspectorPanel } from './inspector_panel'; -import { Adapters, InspectorViewDescription } from '../types'; +import { InspectorViewDescription } from '../types'; +import { Adapters } from '../../common'; describe('InspectorPanel', () => { let adapters: Adapters; diff --git a/src/plugins/inspector/public/ui/inspector_panel.tsx b/src/plugins/inspector/public/ui/inspector_panel.tsx index 85705b6b74f55..37a51257112d6 100644 --- a/src/plugins/inspector/public/ui/inspector_panel.tsx +++ b/src/plugins/inspector/public/ui/inspector_panel.tsx @@ -17,11 +17,13 @@ * under the License. */ +import './inspector_panel.scss'; import { i18n } from '@kbn/i18n'; import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { EuiFlexGroup, EuiFlexItem, EuiFlyoutHeader, EuiTitle, EuiFlyoutBody } from '@elastic/eui'; -import { Adapters, InspectorViewDescription } from '../types'; +import { InspectorViewDescription } from '../types'; +import { Adapters } from '../../common'; import { InspectorViewChooser } from './inspector_view_chooser'; function hasAdaptersChanged(oldAdapters: Adapters, newAdapters: Adapters) { @@ -122,7 +124,9 @@ export class InspectorPanel extends Component - {this.renderSelectedPanel()} + + {this.renderSelectedPanel()} + ); } diff --git a/src/plugins/inspector/public/view_registry.test.ts b/src/plugins/inspector/public/view_registry.test.ts index 542328d4f48da..13e109f50243c 100644 --- a/src/plugins/inspector/public/view_registry.test.ts +++ b/src/plugins/inspector/public/view_registry.test.ts @@ -20,7 +20,7 @@ import { InspectorViewRegistry } from './view_registry'; import { InspectorViewDescription } from './types'; -import { Adapters } from './types'; +import { Adapters } from '../common'; function createMockView( params: { diff --git a/src/plugins/inspector/public/view_registry.ts b/src/plugins/inspector/public/view_registry.ts index 800d917af28ca..be84a62a11712 100644 --- a/src/plugins/inspector/public/view_registry.ts +++ b/src/plugins/inspector/public/view_registry.ts @@ -18,7 +18,8 @@ */ import { EventEmitter } from 'events'; -import { Adapters, InspectorViewDescription } from './types'; +import { InspectorViewDescription } from './types'; +import { Adapters } from '../common'; /** * @callback viewShouldShowFunc diff --git a/src/plugins/inspector/public/views/data/components/data_view.tsx b/src/plugins/inspector/public/views/data/components/data_view.tsx index e03c165d96a27..1a2b6f9922d2d 100644 --- a/src/plugins/inspector/public/views/data/components/data_view.tsx +++ b/src/plugins/inspector/public/views/data/components/data_view.tsx @@ -30,7 +30,8 @@ import { } from '@elastic/eui'; import { DataTableFormat } from './data_table'; -import { InspectorViewProps, Adapters } from '../../../types'; +import { InspectorViewProps } from '../../../types'; +import { Adapters } from '../../../../common'; import { TabularLoaderOptions, TabularData, diff --git a/src/plugins/inspector/public/views/data/index.tsx b/src/plugins/inspector/public/views/data/index.tsx index 0cd88442bf8f8..b02e02bbe6b6b 100644 --- a/src/plugins/inspector/public/views/data/index.tsx +++ b/src/plugins/inspector/public/views/data/index.tsx @@ -20,7 +20,8 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { DataViewComponent } from './components/data_view'; -import { Adapters, InspectorViewDescription, InspectorViewProps } from '../../types'; +import { InspectorViewDescription, InspectorViewProps } from '../../types'; +import { Adapters } from '../../../common'; import { IUiSettingsClient } from '../../../../../core/public'; export const getDataViewDescription = ( diff --git a/src/plugins/inspector/public/views/requests/index.ts b/src/plugins/inspector/public/views/requests/index.ts index 741da76872710..00a223e1e30fa 100644 --- a/src/plugins/inspector/public/views/requests/index.ts +++ b/src/plugins/inspector/public/views/requests/index.ts @@ -19,7 +19,8 @@ import { i18n } from '@kbn/i18n'; import { RequestsViewComponent } from './components/requests_view'; -import { Adapters, InspectorViewDescription } from '../../types'; +import { InspectorViewDescription } from '../../types'; +import { Adapters } from '../../../common'; export const getRequestsViewDescription = (): InspectorViewDescription => ({ title: i18n.translate('inspector.requests.requestsTitle', { diff --git a/src/plugins/vis_type_markdown/public/markdown_vis.ts b/src/plugins/vis_type_markdown/public/markdown_vis.ts index 3309330d7527c..089e00bb44937 100644 --- a/src/plugins/vis_type_markdown/public/markdown_vis.ts +++ b/src/plugins/vis_type_markdown/public/markdown_vis.ts @@ -66,4 +66,5 @@ export const markdownVisDefinition = { }, requestHandler: 'none', responseHandler: 'none', + inspectorAdapters: {}, }; diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx b/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx index 52addb3c2d9d2..b4c90700b160f 100644 --- a/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx +++ b/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx @@ -62,6 +62,7 @@ export function getTimelionVisDefinition(dependencies: TimelionVisDependencies) }, requestHandler: timelionRequestHandler, responseHandler: 'none', + inspectorAdapters: {}, options: { showIndexSelection: false, showQueryBar: false, diff --git a/src/plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts index 649ee765cc642..44b0334a37871 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_type.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts @@ -78,5 +78,6 @@ export const metricsVisDefinition = { showIndexSelection: false, }, requestHandler: metricsRequestHandler, + inspectorAdapters: {}, responseHandler: 'none', }; diff --git a/src/plugins/vis_type_vega/kibana.json b/src/plugins/vis_type_vega/kibana.json index d7a92de627a99..7ba5f23f10564 100644 --- a/src/plugins/vis_type_vega/kibana.json +++ b/src/plugins/vis_type_vega/kibana.json @@ -3,6 +3,6 @@ "version": "kibana", "server": true, "ui": true, - "requiredPlugins": ["data", "visualizations", "mapsLegacy", "expressions"], + "requiredPlugins": ["data", "visualizations", "mapsLegacy", "expressions", "inspector"], "requiredBundles": ["kibanaUtils", "kibanaReact"] } diff --git a/src/plugins/vis_type_vega/public/_vega_vis.scss b/src/plugins/vis_type_vega/public/_vega_vis.scss index 4fc6fbc326ec1..f9468d677eeed 100644 --- a/src/plugins/vis_type_vega/public/_vega_vis.scss +++ b/src/plugins/vis_type_vega/public/_vega_vis.scss @@ -17,6 +17,7 @@ // BUG #23514: Make sure Vega doesn't display the controls in two places .vega-bindings { + // sass-lint:disable no-important display: none !important; } } @@ -47,7 +48,7 @@ width: $euiSizeM * 10 - $euiSize; } - input[type="range"] { + input[type='range'] { width: $euiSizeM * 10; display: inline-block; vertical-align: middle; @@ -74,7 +75,7 @@ top: 0; width: 100%; margin: auto; - opacity: 0.8; + opacity: .8; z-index: 1; list-style: none; } @@ -115,25 +116,30 @@ @include euiTextTruncate; padding-top: $euiSizeXS; padding-bottom: $euiSizeXS; - } - td.key { - color: $euiColorMediumShade; - max-width: $euiSize * 10; - text-align: right; - padding-right: $euiSizeXS; - } - td.value { - max-width: $euiSizeL * 10; - text-align: left; - } + &.key { + color: $euiColorMediumShade; + max-width: $euiSize * 10; + text-align: right; + padding-right: $euiSizeXS; + } - @media only screen and (max-width: map-get($euiBreakpoints, 'm')){ - td.key { - max-width: $euiSize * 6; + &.value { + max-width: $euiSizeL * 10; + text-align: left; } - td.value { - max-width: $euiSize * 10; + } + + + @media only screen and (max-width: map-get($euiBreakpoints, 'm')) { + td { + &.key { + max-width: $euiSize * 6; + } + + &.value { + max-width: $euiSize * 10; + } } } } diff --git a/src/plugins/vis_type_vega/public/data_model/search_api.ts b/src/plugins/vis_type_vega/public/data_model/search_api.ts index c2eecf13c2d51..18387a6ab0876 100644 --- a/src/plugins/vis_type_vega/public/data_model/search_api.ts +++ b/src/plugins/vis_type_vega/public/data_model/search_api.ts @@ -18,13 +18,17 @@ */ import { combineLatest } from 'rxjs'; -import { map } from 'rxjs/operators'; +import { map, tap } from 'rxjs/operators'; import { CoreStart, IUiSettingsClient } from 'kibana/public'; import { getSearchParamsFromRequest, SearchRequest, DataPublicPluginStart, + IEsSearchResponse, } from '../../../data/public'; +import { search as dataPluginSearch } from '../../../data/public'; +import { VegaInspectorAdapters } from '../vega_inspector'; +import { RequestResponder } from '../../../inspector/public'; export interface SearchAPIDependencies { uiSettings: IUiSettingsClient; @@ -35,26 +39,52 @@ export interface SearchAPIDependencies { export class SearchAPI { constructor( private readonly dependencies: SearchAPIDependencies, - private readonly abortSignal?: AbortSignal + private readonly abortSignal?: AbortSignal, + public readonly inspectorAdapters?: VegaInspectorAdapters ) {} search(searchRequests: SearchRequest[]) { const { search } = this.dependencies.search; + const requestResponders: any = {}; return combineLatest( searchRequests.map((request, index) => { + const requestId: number = index; const params = getSearchParamsFromRequest(request, { uiSettings: this.dependencies.uiSettings, injectedMetadata: this.dependencies.injectedMetadata, }); + if (this.inspectorAdapters) { + requestResponders[requestId] = this.inspectorAdapters.requests.start( + `#${requestId}`, + request + ); + requestResponders[requestId].json(params.body); + } + return search({ params }, { signal: this.abortSignal }).pipe( + tap((data) => this.inspectSearchResult(data, requestResponders[requestId])), map((data) => ({ - id: index, + id: requestId, rawResponse: data.rawResponse, })) ); }) ); } + + public resetSearchStats() { + if (this.inspectorAdapters) { + this.inspectorAdapters.requests.reset(); + } + } + + private inspectSearchResult(response: IEsSearchResponse, requestResponder: RequestResponder) { + if (requestResponder) { + requestResponder + .stats(dataPluginSearch.getResponseInspectorStats(response.rawResponse)) + .ok({ json: response.rawResponse }); + } + } } diff --git a/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js b/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js index 51aa4313a97b5..e29e16e3212f4 100644 --- a/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js +++ b/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js @@ -97,6 +97,7 @@ describe('VegaParser._resolveEsQueries', () => { search: jest.fn(() => ({ toPromise: jest.fn(() => Promise.resolve(data)), })), + resetSearchStats: jest.fn(), }; }); diff --git a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts index 17166e1540755..c867523d2b3b3 100644 --- a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts +++ b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts @@ -79,6 +79,7 @@ export class VegaParser { paddingHeight?: number; containerDir?: ControlsLocation | ControlsDirection; controlsDir?: ControlsLocation; + searchAPI: SearchAPI; constructor( spec: VegaSpec | string, @@ -92,10 +93,11 @@ export class VegaParser { this.error = undefined; this.warnings = []; + this.searchAPI = searchAPI; const onWarn = this._onWarning.bind(this); this._urlParsers = { - elasticsearch: new EsQueryParser(timeCache, searchAPI, filters, onWarn), + elasticsearch: new EsQueryParser(timeCache, this.searchAPI, filters, onWarn), emsfile: new EmsFileParser(serviceSettings), url: new UrlParser(onWarn), }; @@ -541,6 +543,8 @@ export class VegaParser { async _resolveDataUrls() { const pending: PendingType = {}; + this.searchAPI.resetSearchStats(); + this._findObjectDataUrls(this.spec!, (obj: Data) => { const url = obj.url; delete obj.url; diff --git a/src/plugins/vis_type_vega/public/plugin.ts b/src/plugins/vis_type_vega/public/plugin.ts index c20a104736291..00c6b2e3c8d5b 100644 --- a/src/plugins/vis_type_vega/public/plugin.ts +++ b/src/plugins/vis_type_vega/public/plugin.ts @@ -18,8 +18,10 @@ */ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '../../../core/public'; import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; -import { Plugin as DataPublicPlugin } from '../../data/public'; +import { DataPublicPluginSetup, DataPublicPluginStart } from '../../data/public'; import { VisualizationsSetup } from '../../visualizations/public'; +import { Setup as InspectorSetup } from '../../inspector/public'; + import { setNotifications, setData, @@ -37,11 +39,13 @@ import { IServiceSettings } from '../../maps_legacy/public'; import './index.scss'; import { ConfigSchema } from '../config'; +import { getVegaInspectorView } from './vega_inspector'; + /** @internal */ export interface VegaVisualizationDependencies { core: CoreSetup; plugins: { - data: ReturnType; + data: DataPublicPluginSetup; }; serviceSettings: IServiceSettings; } @@ -50,13 +54,14 @@ export interface VegaVisualizationDependencies { export interface VegaPluginSetupDependencies { expressions: ReturnType; visualizations: VisualizationsSetup; - data: ReturnType; + inspector: InspectorSetup; + data: DataPublicPluginSetup; mapsLegacy: any; } /** @internal */ export interface VegaPluginStartDependencies { - data: ReturnType; + data: DataPublicPluginStart; } /** @internal */ @@ -69,7 +74,7 @@ export class VegaPlugin implements Plugin, void> { public async setup( core: CoreSetup, - { data, expressions, visualizations, mapsLegacy }: VegaPluginSetupDependencies + { inspector, data, expressions, visualizations, mapsLegacy }: VegaPluginSetupDependencies ) { setInjectedVars({ enableExternalUrls: this.initializerContext.config.get().enableExternalUrls, @@ -88,6 +93,8 @@ export class VegaPlugin implements Plugin, void> { serviceSettings: mapsLegacy.serviceSettings, }; + inspector.registerView(getVegaInspectorView({ uiSettings: core.uiSettings })); + expressions.registerFunction(() => createVegaFn(visualizationDependencies)); visualizations.createBaseVisualization(createVegaTypeDefinition(visualizationDependencies)); diff --git a/src/plugins/vis_type_vega/public/vega_fn.ts b/src/plugins/vis_type_vega/public/vega_fn.ts index d077aa7aee004..c109bb3c6e90c 100644 --- a/src/plugins/vis_type_vega/public/vega_fn.ts +++ b/src/plugins/vis_type_vega/public/vega_fn.ts @@ -19,9 +19,15 @@ import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { ExpressionFunctionDefinition, KibanaContext, Render } from '../../expressions/public'; +import { + ExecutionContext, + ExpressionFunctionDefinition, + KibanaContext, + Render, +} from '../../expressions/public'; import { VegaVisualizationDependencies } from './plugin'; import { createVegaRequestHandler } from './vega_request_handler'; +import { VegaInspectorAdapters } from './vega_inspector/index'; import { TimeRange, Query } from '../../data/public'; import { VegaParser } from './data_model/vega_parser'; @@ -42,7 +48,13 @@ interface RenderValue { export const createVegaFn = ( dependencies: VegaVisualizationDependencies -): ExpressionFunctionDefinition<'vega', Input, Arguments, Output> => ({ +): ExpressionFunctionDefinition< + 'vega', + Input, + Arguments, + Output, + ExecutionContext +> => ({ name: 'vega', type: 'render', inputTypes: ['kibana_context', 'null'], @@ -57,7 +69,7 @@ export const createVegaFn = ( }, }, async fn(input, args, context) { - const vegaRequestHandler = createVegaRequestHandler(dependencies, context.abortSignal); + const vegaRequestHandler = createVegaRequestHandler(dependencies, context); const response = await vegaRequestHandler({ timeRange: get(input, 'timeRange') as TimeRange, diff --git a/src/plugins/vis_type_vega/public/vega_inspector/components/data_viewer.tsx b/src/plugins/vis_type_vega/public/vega_inspector/components/data_viewer.tsx new file mode 100644 index 0000000000000..9b09a09eb05e0 --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_inspector/components/data_viewer.tsx @@ -0,0 +1,114 @@ +/* + * 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, { useState, useCallback, useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiComboBox, + EuiFlexGroup, + EuiComboBoxProps, + EuiFlexItem, + EuiSpacer, + CommonProps, +} from '@elastic/eui'; +import { VegaAdapter, InspectDataSets } from '../vega_adapter'; +import { InspectorDataGrid } from './inspector_data_grid'; + +interface DataViewerProps extends CommonProps { + vegaAdapter: VegaAdapter; +} + +const getDataGridArialabel = (view: InspectDataSets) => + i18n.translate('visTypeVega.inspector.dataViewer.gridAriaLabel', { + defaultMessage: '{name} data grid', + values: { + name: view.id, + }, + }); + +const dataSetAriaLabel = i18n.translate('visTypeVega.inspector.dataViewer.dataSetAriaLabel', { + defaultMessage: 'Data set', +}); + +export const DataViewer = ({ vegaAdapter, ...rest }: DataViewerProps) => { + const [inspectDataSets, setInspectDataSets] = useState([]); + const [selectedView, setSelectedView] = useState(); + const [dataGridAriaLabel, setDataGridAriaLabel] = useState(''); + + const onViewChange: EuiComboBoxProps['onChange'] = useCallback( + (selectedOptions) => { + const newView = inspectDataSets!.find((view) => view.id === selectedOptions[0].label); + + if (newView) { + setDataGridAriaLabel(getDataGridArialabel(newView)); + setSelectedView(newView); + } + }, + [inspectDataSets] + ); + + useEffect(() => { + const subscription = vegaAdapter.getDataSetsSubscription().subscribe((dataSets) => { + setInspectDataSets(dataSets); + }); + + return () => { + subscription.unsubscribe(); + }; + }, [vegaAdapter]); + + useEffect(() => { + if (inspectDataSets) { + if (!selectedView) { + setSelectedView(inspectDataSets[0]); + } else { + setDataGridAriaLabel(getDataGridArialabel(selectedView)); + } + } + }, [selectedView, inspectDataSets]); + + if (!selectedView) { + return null; + } + + return ( + + + + ({ + label: item.id, + }))} + aria-label={dataSetAriaLabel} + onChange={onViewChange} + isClearable={false} + singleSelection={{ asPlainText: true }} + selectedOptions={[{ label: selectedView.id }]} + /> + + + + + + ); +}; diff --git a/src/plugins/vis_type_vega/public/vega_inspector/components/index.ts b/src/plugins/vis_type_vega/public/vega_inspector/components/index.ts new file mode 100644 index 0000000000000..76e631f9ecd94 --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_inspector/components/index.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +export { DataViewer } from './data_viewer'; +export { SignalViewer } from './signal_viewer'; +export { SpecViewer } from './spec_viewer'; diff --git a/src/plugins/vis_type_vega/public/vega_inspector/components/inspector_data_grid.tsx b/src/plugins/vis_type_vega/public/vega_inspector/components/inspector_data_grid.tsx new file mode 100644 index 0000000000000..00f24e03d8196 --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_inspector/components/inspector_data_grid.tsx @@ -0,0 +1,144 @@ +/* + * 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, { useState, useCallback, useMemo, useEffect } from 'react'; +import { EuiDataGrid, EuiDataGridSorting, EuiDataGridProps } from '@elastic/eui'; +import { VegaRuntimeData } from '../vega_adapter'; + +const DEFAULT_PAGE_SIZE = 15; + +interface InspectorDataGridProps extends VegaRuntimeData { + dataGridAriaLabel: string; +} + +export const InspectorDataGrid = ({ columns, data, dataGridAriaLabel }: InspectorDataGridProps) => { + const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: DEFAULT_PAGE_SIZE }); + const onChangeItemsPerPage = useCallback( + (pageSize) => setPagination((p) => ({ ...p, pageSize, pageIndex: 0 })), + [setPagination] + ); + + const onChangePage = useCallback((pageIndex) => setPagination((p) => ({ ...p, pageIndex })), [ + setPagination, + ]); + + // Column visibility + const [visibleColumns, setVisibleColumns] = useState([]); + + useEffect( + () => { + setPagination({ + ...pagination, + pageIndex: 0, + }); + setVisibleColumns(columns.map((column) => column.id)); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [dataGridAriaLabel] + ); + + // Sorting + const [sortingColumns, setSortingColumns] = useState([]); + + const onSort = useCallback( + (newSortingColumns: EuiDataGridSorting['columns']) => { + setSortingColumns(newSortingColumns); + }, + [setSortingColumns] + ); + + let gridData = useMemo(() => { + return [...data].sort((a, b) => { + for (let i = 0; i < sortingColumns.length; i++) { + const column = sortingColumns[i]; + const aValue = a[column.id]; + const bValue = b[column.id]; + + if (aValue < bValue) return column.direction === 'asc' ? -1 : 1; + if (aValue > bValue) return column.direction === 'asc' ? 1 : -1; + } + return 0; + }); + }, [data, sortingColumns]); + + const renderCellValue = useMemo(() => { + return (({ rowIndex, columnId }) => { + let adjustedRowIndex = rowIndex; + + // If we are doing the pagination (instead of leaving that to the grid) + // then the row index must be adjusted as `data` has already been pruned to the page size + adjustedRowIndex = rowIndex - pagination.pageIndex * pagination.pageSize; + + return gridData.hasOwnProperty(adjustedRowIndex) + ? gridData[adjustedRowIndex][columnId] || null + : null; + }) as EuiDataGridProps['renderCellValue']; + }, [gridData, pagination.pageIndex, pagination.pageSize]); + + // Pagination + gridData = useMemo(() => { + const rowStart = pagination.pageIndex * pagination.pageSize; + const rowEnd = Math.min(rowStart + pagination.pageSize, gridData.length); + return gridData.slice(rowStart, rowEnd); + }, [gridData, pagination]); + + // Resize + const [columnsWidth, setColumnsWidth] = useState>({}); + + const onColumnResize: EuiDataGridProps['onColumnResize'] = useCallback( + ({ columnId, width }) => { + setColumnsWidth({ + ...columnsWidth, + [columnId]: width, + }); + }, + [columnsWidth] + ); + + return ( + { + if (columnsWidth[column.id]) { + return { + ...column, + initialWidth: columnsWidth[column.id], + }; + } + return column; + })} + columnVisibility={{ + visibleColumns, + setVisibleColumns, + }} + rowCount={data.length} + renderCellValue={renderCellValue} + sorting={{ columns: sortingColumns, onSort }} + toolbarVisibility={{ + showFullScreenSelector: false, + }} + onColumnResize={onColumnResize} + pagination={{ + ...pagination, + pageSizeOptions: [DEFAULT_PAGE_SIZE, 25, 50], + onChangeItemsPerPage, + onChangePage, + }} + /> + ); +}; diff --git a/src/plugins/vis_type_vega/public/vega_inspector/components/signal_viewer.tsx b/src/plugins/vis_type_vega/public/vega_inspector/components/signal_viewer.tsx new file mode 100644 index 0000000000000..39df004f327a4 --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_inspector/components/signal_viewer.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, { useEffect, useState } from 'react'; + +import { EuiSpacer } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { VegaAdapter, InspectSignalsSets } from '../vega_adapter'; +import { InspectorDataGrid } from './inspector_data_grid'; + +interface SignalViewerProps { + vegaAdapter: VegaAdapter; +} + +const initialSignalColumnWidth = 150; + +const signalDataGridAriaLabel = i18n.translate('visTypeVega.inspector.signalViewer.gridAriaLabel', { + defaultMessage: 'Signal values data grid', +}); + +export const SignalViewer = ({ vegaAdapter }: SignalViewerProps) => { + const [inspectSignalsSets, setInspectSignalsSets] = useState(); + + useEffect(() => { + const subscription = vegaAdapter.getSignalsSetsSubscription().subscribe((signalSets) => { + if (signalSets) { + setInspectSignalsSets(signalSets); + } + }); + return () => { + subscription.unsubscribe(); + }; + }, [vegaAdapter]); + + if (!inspectSignalsSets) { + return null; + } + + return ( +
+ + { + if (index === 0) { + return { + ...column, + initialWidth: initialSignalColumnWidth, + }; + } + return column; + })} + data={inspectSignalsSets.data} + dataGridAriaLabel={signalDataGridAriaLabel} + /> +
+ ); +}; diff --git a/src/plugins/vis_type_vega/public/vega_inspector/components/spec_viewer.tsx b/src/plugins/vis_type_vega/public/vega_inspector/components/spec_viewer.tsx new file mode 100644 index 0000000000000..54f7974960aa2 --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_inspector/components/spec_viewer.tsx @@ -0,0 +1,97 @@ +/* + * 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, { useEffect, useState } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { + EuiFlexItem, + EuiFlexGroup, + EuiCopy, + EuiButtonEmpty, + EuiSpacer, + CommonProps, +} from '@elastic/eui'; +import { VegaAdapter } from '../vega_adapter'; +import { CodeEditor } from '../../../../kibana_react/public'; + +interface SpecViewerProps extends CommonProps { + vegaAdapter: VegaAdapter; +} + +const copyToClipboardLabel = i18n.translate( + 'visTypeVega.inspector.specViewer.copyToClipboardLabel', + { + defaultMessage: 'Copy to clipboard', + } +); + +export const SpecViewer = ({ vegaAdapter, ...rest }: SpecViewerProps) => { + const [spec, setSpec] = useState(); + + useEffect(() => { + const subscription = vegaAdapter.getSpecSubscription().subscribe((data) => { + if (data) { + setSpec(data); + } + }); + return () => { + subscription.unsubscribe(); + }; + }, [vegaAdapter]); + + if (!spec) { + return null; + } + + return ( + + + +
+ + {(copy) => ( + + {copyToClipboardLabel} + + )} + +
+
+ + {}} + options={{ + readOnly: true, + lineNumbers: 'off', + fontSize: 12, + minimap: { + enabled: false, + }, + scrollBeyondLastLine: false, + wordWrap: 'on', + wrappingIndent: 'indent', + automaticLayout: true, + }} + /> + +
+ ); +}; diff --git a/src/plugins/vis_type_vega/public/vega_inspector/index.ts b/src/plugins/vis_type_vega/public/vega_inspector/index.ts new file mode 100644 index 0000000000000..24da27d2d742d --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_inspector/index.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +export { + createInspectorAdapters, + getVegaInspectorView, + VegaInspectorAdapters, +} from './vega_inspector'; diff --git a/src/plugins/vis_type_vega/public/vega_inspector/vega_adapter.ts b/src/plugins/vis_type_vega/public/vega_inspector/vega_adapter.ts new file mode 100644 index 0000000000000..e4c536af40591 --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_inspector/vega_adapter.ts @@ -0,0 +1,148 @@ +/* + * 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 { Observable, ReplaySubject, fromEventPattern, merge, timer } from 'rxjs'; +import { map, switchMap, filter, debounce } from 'rxjs/operators'; +import { View, Runtime, Spec } from 'vega'; +import { i18n } from '@kbn/i18n'; +import { Assign } from '@kbn/utility-types'; + +interface DebugValues { + view: View; + spec: Spec; +} + +export interface VegaRuntimeData { + columns: Array<{ + id: string; + }>; + data: Array>; +} + +export type InspectDataSets = Assign; +export type InspectSignalsSets = VegaRuntimeData; + +const vegaAdapterSignalLabel = i18n.translate('visTypeVega.inspector.vegaAdapter.signal', { + defaultMessage: 'Signal', +}); + +const vegaAdapterValueLabel = i18n.translate('visTypeVega.inspector.vegaAdapter.value', { + defaultMessage: 'Value', +}); + +/** Get Runtime Scope for Vega View + * @link https://vega.github.io/vega/docs/api/debugging/#scope + **/ +const getVegaRuntimeScope = (debugValues: DebugValues) => + (debugValues.view as any)._runtime as Runtime; + +const serializeColumns = (item: Record, columns: string[]) => { + const nonSerializableFieldLabel = '(..)'; + + return columns.reduce((row: Record, column) => { + try { + const cell = item[column]; + row[column] = typeof cell === 'object' ? JSON.stringify(cell) : `${cell}`; + } catch (e) { + row[column] = nonSerializableFieldLabel; + } + return row; + }, {}); +}; + +export class VegaAdapter { + private debugValuesSubject = new ReplaySubject(); + + bindInspectValues(debugValues: DebugValues) { + this.debugValuesSubject.next(debugValues); + } + + getDataSetsSubscription(): Observable { + return this.debugValuesSubject.pipe( + filter((debugValues) => Boolean(debugValues)), + map((debugValues) => { + const runtimeScope = getVegaRuntimeScope(debugValues); + + return Object.keys(runtimeScope.data || []).reduce((acc: InspectDataSets[], key) => { + const value = runtimeScope.data[key].values.value; + + if (value && value[0]) { + const columns = Object.keys(value[0]); + acc.push({ + id: key, + columns: columns.map((column) => ({ id: column, schema: 'json' })), + data: value.map((item: Record) => serializeColumns(item, columns)), + }); + } + return acc; + }, []); + }) + ); + } + + getSignalsSetsSubscription(): Observable { + const signalsListener = this.debugValuesSubject.pipe( + filter((debugValues) => Boolean(debugValues)), + switchMap((debugValues) => { + const runtimeScope = getVegaRuntimeScope(debugValues); + + return merge( + ...Object.keys(runtimeScope.signals).map((key: string) => + fromEventPattern( + (handler) => debugValues.view.addSignalListener(key, handler), + (handler) => debugValues.view.removeSignalListener(key, handler) + ) + ) + ).pipe( + debounce((val) => timer(350)), + map(() => debugValues) + ); + }) + ); + + return merge(this.debugValuesSubject, signalsListener).pipe( + filter((debugValues) => Boolean(debugValues)), + map((debugValues) => { + const runtimeScope = getVegaRuntimeScope(debugValues); + + return { + columns: [ + { id: vegaAdapterSignalLabel, schema: 'text' }, + { id: vegaAdapterValueLabel, schema: 'json' }, + ], + data: Object.keys(runtimeScope.signals).map((key: string) => + serializeColumns( + { + [vegaAdapterSignalLabel]: key, + [vegaAdapterValueLabel]: runtimeScope.signals[key].value, + }, + [vegaAdapterSignalLabel, vegaAdapterValueLabel] + ) + ), + }; + }) + ); + } + + getSpecSubscription(): Observable { + return this.debugValuesSubject.pipe( + filter((debugValues) => Boolean(debugValues)), + map((debugValues) => JSON.stringify(debugValues.spec, null, 2)) + ); + } +} diff --git a/src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.scss b/src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.scss new file mode 100644 index 0000000000000..487f505657d3b --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.scss @@ -0,0 +1,18 @@ +.vgaVegaDataInspector, +.vgaVegaDataInspector__specViewer { + height: 100%; +} + +.vgaVegaDataInspector { + // TODO: EUI needs to provide props to pass down from EuiTabbedContent to tabs and content + display: flex; + flex-direction: column; + + [role='tablist'] { + flex-shrink: 0; + } + + [role='tabpanel'] { + flex-grow: 1; + } +} diff --git a/src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.tsx b/src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.tsx new file mode 100644 index 0000000000000..3b9427c96e62a --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_inspector/vega_data_inspector.tsx @@ -0,0 +1,74 @@ +/* + * 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 './vega_data_inspector.scss'; + +import React from 'react'; +import { EuiTabbedContent } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; +import { VegaInspectorAdapters } from './vega_inspector'; +import { DataViewer, SignalViewer, SpecViewer } from './components'; +import { InspectorViewProps } from '../../../inspector/public'; + +export type VegaDataInspectorProps = InspectorViewProps; + +const dataSetsLabel = i18n.translate('visTypeVega.inspector.dataSetsLabel', { + defaultMessage: 'Data sets', +}); + +const signalValuesLabel = i18n.translate('visTypeVega.inspector.signalValuesLabel', { + defaultMessage: 'Signal values', +}); + +const specLabel = i18n.translate('visTypeVega.inspector.specLabel', { + defaultMessage: 'Spec', +}); + +export const VegaDataInspector = ({ adapters }: VegaDataInspectorProps) => { + const tabs = [ + { + id: 'data-viewer--id', + name: dataSetsLabel, + content: , + }, + { + id: 'signal-viewer--id', + name: signalValuesLabel, + content: , + }, + { + id: 'spec-viewer--id', + name: specLabel, + content: ( + + ), + }, + ]; + + return ( + + ); +}; diff --git a/src/plugins/vis_type_vega/public/vega_inspector/vega_inspector.tsx b/src/plugins/vis_type_vega/public/vega_inspector/vega_inspector.tsx new file mode 100644 index 0000000000000..83d9e467646a6 --- /dev/null +++ b/src/plugins/vis_type_vega/public/vega_inspector/vega_inspector.tsx @@ -0,0 +1,57 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { IUiSettingsClient } from 'kibana/public'; +import { VegaAdapter } from './vega_adapter'; +import { VegaDataInspector, VegaDataInspectorProps } from './vega_data_inspector'; +import { KibanaContextProvider } from '../../../kibana_react/public'; +import { Adapters, RequestAdapter, InspectorViewDescription } from '../../../inspector/public'; + +export interface VegaInspectorAdapters extends Adapters { + requests: RequestAdapter; + vega: VegaAdapter; +} + +const vegaDebugLabel = i18n.translate('visTypeVega.inspector.vegaDebugLabel', { + defaultMessage: 'Vega debug', +}); + +interface VegaInspectorViewDependencies { + uiSettings: IUiSettingsClient; +} + +export const getVegaInspectorView = (dependencies: VegaInspectorViewDependencies) => + ({ + title: vegaDebugLabel, + shouldShow(adapters) { + return Boolean(adapters.vega); + }, + component: (props) => ( + + + + ), + } as InspectorViewDescription); + +export const createInspectorAdapters = (): VegaInspectorAdapters => ({ + requests: new RequestAdapter(), + vega: new VegaAdapter(), +}); diff --git a/src/plugins/vis_type_vega/public/vega_request_handler.ts b/src/plugins/vis_type_vega/public/vega_request_handler.ts index 997b1982d749a..c09a9466df602 100644 --- a/src/plugins/vis_type_vega/public/vega_request_handler.ts +++ b/src/plugins/vis_type_vega/public/vega_request_handler.ts @@ -25,6 +25,7 @@ import { TimeCache } from './data_model/time_cache'; import { VegaVisualizationDependencies } from './plugin'; import { VisParams } from './vega_fn'; import { getData, getInjectedMetadata } from './services'; +import { VegaInspectorAdapters } from './vega_inspector'; interface VegaRequestHandlerParams { query: Query; @@ -33,9 +34,14 @@ interface VegaRequestHandlerParams { visParams: VisParams; } +interface VegaRequestHandlerContext { + abortSignal?: AbortSignal; + inspectorAdapters?: VegaInspectorAdapters; +} + export function createVegaRequestHandler( { plugins: { data }, core: { uiSettings }, serviceSettings }: VegaVisualizationDependencies, - abortSignal?: AbortSignal + context: VegaRequestHandlerContext = {} ) { let searchAPI: SearchAPI; const { timefilter } = data.query.timefilter; @@ -54,7 +60,8 @@ export function createVegaRequestHandler( search: getData().search, injectedMetadata: getInjectedMetadata(), }, - abortSignal + context.abortSignal, + context.inspectorAdapters ); } diff --git a/src/plugins/vis_type_vega/public/vega_type.ts b/src/plugins/vis_type_vega/public/vega_type.ts index 5825661f9001c..d69eb3cfba282 100644 --- a/src/plugins/vis_type_vega/public/vega_type.ts +++ b/src/plugins/vis_type_vega/public/vega_type.ts @@ -23,9 +23,10 @@ import { VegaVisualizationDependencies } from './plugin'; import { VegaVisEditor } from './components'; import { createVegaRequestHandler } from './vega_request_handler'; -// @ts-ignore +// @ts-expect-error import { createVegaVisualization } from './vega_visualization'; import { getDefaultSpec } from './default_spec'; +import { createInspectorAdapters } from './vega_inspector'; export const createVegaTypeDefinition = (dependencies: VegaVisualizationDependencies) => { const requestHandler = createVegaRequestHandler(dependencies); @@ -54,5 +55,6 @@ export const createVegaTypeDefinition = (dependencies: VegaVisualizationDependen showFilterBar: true, }, stage: 'experimental', + inspectorAdapters: createInspectorAdapters, }; }; diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js b/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js index 55c3606bf5e45..8f88d5c5b2056 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js +++ b/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js @@ -364,6 +364,11 @@ export class VegaBaseView { * Set global debug variable to simplify vega debugging in console. Show info message first time */ setDebugValues(view, spec, vlspec) { + this._parser.searchAPI.inspectorAdapters?.vega.bindInspectValues({ + view, + spec: vlspec || spec, + }); + if (window) { if (window.VEGA_DEBUG === undefined && console) { console.log('%cWelcome to Kibana Vega Plugin!', 'font-size: 16px; font-weight: bold;'); diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js b/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js index 6908fd13a9ca1..78ae2efdbdda5 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js +++ b/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js @@ -142,7 +142,7 @@ export class VegaMapView extends VegaBaseView { }); const vegaView = vegaMapLayer.getVegaView(); - this.setDebugValues(vegaView, this._parser.spec, this._parser.vlspec); await this.setView(vegaView); + this.setDebugValues(vegaView, this._parser.spec, this._parser.vlspec); } } diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_view.js b/src/plugins/vis_type_vega/public/vega_view/vega_view.js index e3455b97b7fe2..98c972ef84ccb 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_view.js +++ b/src/plugins/vis_type_vega/public/vega_view/vega_view.js @@ -26,7 +26,6 @@ export class VegaView extends VegaBaseView { if (!this._$container) return; const view = new vega.View(vega.parse(this._parser.spec), this._vegaViewConfig); - this.setDebugValues(view, this._parser.spec, this._parser.vlspec); view.warn = this.onWarn.bind(this); view.error = this.onError.bind(this); @@ -36,5 +35,6 @@ export class VegaView extends VegaBaseView { if (this._parser.useHover) view.hover(); await this.setView(view); + this.setDebugValues(view, this._parser.spec, this._parser.vlspec); } } diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts index 2f9cda32fccdc..749926e1abd00 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -34,6 +34,7 @@ import { EmbeddableOutput, Embeddable, IContainer, + Adapters, } from '../../../../plugins/embeddable/public'; import { dispatchRenderComplete } from '../../../../plugins/kibana_utils/public'; import { @@ -78,8 +79,6 @@ export interface VisualizeOutput extends EmbeddableOutput { type ExpressionLoader = InstanceType; -const visTypesWithoutInspector = ['markdown', 'input_control_vis', 'metrics', 'vega', 'timelion']; - export class VisualizeEmbeddable extends Embeddable { private handler?: ExpressionLoader; private timefilter: TimefilterContract; @@ -96,6 +95,7 @@ export class VisualizeEmbeddable extends Embeddable { - if (!this.handler || visTypesWithoutInspector.includes(this.vis.type.name)) { + if (!this.handler || (this.inspectorAdapters && !Object.keys(this.inspectorAdapters).length)) { return undefined; } return this.handler.inspect(); @@ -349,6 +356,7 @@ export class VisualizeEmbeddable extends Embeddable Adapters); } export class BaseVisType { @@ -63,6 +65,7 @@ export class BaseVisType { hierarchicalData: boolean | unknown; setup?: unknown; useCustomNoDataScreen: boolean; + inspectorAdapters?: Adapters | (() => Adapters); constructor(opts: BaseVisTypeOptions) { if (!opts.icon && !opts.image) { @@ -98,6 +101,7 @@ export class BaseVisType { this.requiresSearch = this.requestHandler !== 'none'; this.hierarchicalData = opts.hierarchicalData || false; this.useCustomNoDataScreen = opts.useCustomNoDataScreen || false; + this.inspectorAdapters = opts.inspectorAdapters; } public get schemas() { diff --git a/test/functional/apps/visualize/_vega_chart.js b/test/functional/apps/visualize/_vega_chart.js index 4442e1f969b4b..c530c6f823133 100644 --- a/test/functional/apps/visualize/_vega_chart.js +++ b/test/functional/apps/visualize/_vega_chart.js @@ -22,7 +22,6 @@ import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['timePicker', 'visualize', 'visChart', 'vegaChart']); const filterBar = getService('filterBar'); - const inspector = getService('inspector'); const log = getService('log'); describe('vega chart in visualize app', () => { @@ -35,10 +34,6 @@ export default function ({ getService, getPageObjects }) { describe('vega chart', () => { describe('initial render', () => { - it('should not have inspector enabled', async function () { - await inspector.expectIsNotEnabled(); - }); - it.skip('should have some initial vega spec text', async function () { const vegaSpec = await PageObjects.vegaChart.getSpec(); expect(vegaSpec).to.contain('{').and.to.contain('data'); diff --git a/x-pack/plugins/maps/public/kibana_services.js b/x-pack/plugins/maps/public/kibana_services.js index 53e128f94dfb6..89d578f27b118 100644 --- a/x-pack/plugins/maps/public/kibana_services.js +++ b/x-pack/plugins/maps/public/kibana_services.js @@ -80,7 +80,7 @@ export async function fetchSearchSourceAndRecordWithInspector({ inspectorRequest.json(body); }); resp = await searchSource.fetch({ abortSignal }); - inspectorRequest.stats(getResponseInspectorStats(searchSource, resp)).ok({ json: resp }); + inspectorRequest.stats(getResponseInspectorStats(resp, searchSource)).ok({ json: resp }); } catch (error) { inspectorRequest.error({ error }); throw error; From c74b214fe3815e4ebe7e12cfc804651033fd2fa2 Mon Sep 17 00:00:00 2001 From: Gil Raphaelli Date: Tue, 21 Jul 2020 08:14:12 -0400 Subject: [PATCH 40/77] allow some env settings for ingest manager (#72544) --- .../os_packages/docker_generator/resources/bin/kibana-docker | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker index 745a3d1f0c830..0913d4ba4e83a 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker @@ -174,6 +174,8 @@ kibana_vars=( xpack.infra.sources.default.fields.timestamp xpack.infra.sources.default.logAlias xpack.infra.sources.default.metricAlias + xpack.ingestManager.fleet.tlsCheckDisabled + xpack.ingestManager.registryUrl xpack.license_management.enabled xpack.ml.enabled xpack.reporting.capture.browser.autoDownload From 8fdebc9e822af030aa949554d00c69f3143f41ed Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Tue, 21 Jul 2020 14:08:29 +0100 Subject: [PATCH 41/77] [Task Manager] Batches the update operations in Task Manager (#71470) This PR attempts to batch update tasks in Task Manager in order to avoid overloading the Elasticsearch queue. This is the 1st PR addressing https://github.com/elastic/kibana/issues/65551 Under the hood we now use a Reactive buffer accumulates all calls to the `update` api in the TaskStore and flushes after 50ms or when as many operations as there are workers have been buffered (whichever comes first). --- .../server/buffered_task_store.test.ts | 82 +++++ .../server/buffered_task_store.ts | 39 +++ .../server/lib/bulk_operation_buffer.test.ts | 288 ++++++++++++++++++ .../server/lib/bulk_operation_buffer.ts | 129 ++++++++ .../server/lib/result_type.test.ts | 27 ++ .../task_manager/server/lib/result_type.ts | 19 ++ .../task_manager/server/task_manager.ts | 10 +- .../task_manager/server/task_runner.ts | 2 +- .../task_manager/server/task_store.mock.ts | 31 ++ .../plugins/task_manager/server/task_store.ts | 65 +++- 10 files changed, 685 insertions(+), 7 deletions(-) create mode 100644 x-pack/plugins/task_manager/server/buffered_task_store.test.ts create mode 100644 x-pack/plugins/task_manager/server/buffered_task_store.ts create mode 100644 x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts create mode 100644 x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.ts create mode 100644 x-pack/plugins/task_manager/server/lib/result_type.test.ts create mode 100644 x-pack/plugins/task_manager/server/task_store.mock.ts diff --git a/x-pack/plugins/task_manager/server/buffered_task_store.test.ts b/x-pack/plugins/task_manager/server/buffered_task_store.test.ts new file mode 100644 index 0000000000000..8e18405c79ed2 --- /dev/null +++ b/x-pack/plugins/task_manager/server/buffered_task_store.test.ts @@ -0,0 +1,82 @@ +/* + * 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 uuid from 'uuid'; +import { taskStoreMock } from './task_store.mock'; +import { BufferedTaskStore } from './buffered_task_store'; +import { asErr, asOk } from './lib/result_type'; +import { TaskStatus } from './task'; + +describe('Buffered Task Store', () => { + test('proxies the TaskStore for `maxAttempts` and `remove`', async () => { + const taskStore = taskStoreMock.create({ maxAttempts: 10 }); + taskStore.bulkUpdate.mockResolvedValue([]); + const bufferedStore = new BufferedTaskStore(taskStore, {}); + + expect(bufferedStore.maxAttempts).toEqual(10); + + bufferedStore.remove('1'); + expect(taskStore.remove).toHaveBeenCalledWith('1'); + }); + + describe('update', () => { + test("proxies the TaskStore's `bulkUpdate`", async () => { + const taskStore = taskStoreMock.create({ maxAttempts: 10 }); + const bufferedStore = new BufferedTaskStore(taskStore, {}); + + const task = mockTask(); + + taskStore.bulkUpdate.mockResolvedValue([asOk(task)]); + + expect(await bufferedStore.update(task)).toMatchObject(task); + expect(taskStore.bulkUpdate).toHaveBeenCalledWith([task]); + }); + + test('handles partially successfull bulkUpdates resolving each call appropriately', async () => { + const taskStore = taskStoreMock.create({ maxAttempts: 10 }); + const bufferedStore = new BufferedTaskStore(taskStore, {}); + + const tasks = [mockTask(), mockTask(), mockTask()]; + + taskStore.bulkUpdate.mockResolvedValueOnce([ + asOk(tasks[0]), + asErr({ entity: tasks[1], error: new Error('Oh no, something went terribly wrong') }), + asOk(tasks[2]), + ]); + + const results = [ + bufferedStore.update(tasks[0]), + bufferedStore.update(tasks[1]), + bufferedStore.update(tasks[2]), + ]; + expect(await results[0]).toMatchObject(tasks[0]); + expect(results[1]).rejects.toMatchInlineSnapshot( + `[Error: Oh no, something went terribly wrong]` + ); + expect(await results[2]).toMatchObject(tasks[2]); + }); + }); +}); + +function mockTask() { + return { + id: `task_${uuid.v4()}`, + attempts: 0, + schedule: undefined, + params: { hello: 'world' }, + retryAt: null, + runAt: new Date(), + scheduledAt: new Date(), + scope: undefined, + startedAt: null, + state: { foo: 'bar' }, + status: TaskStatus.Idle, + taskType: 'report', + user: undefined, + version: '123', + ownerId: '123', + }; +} diff --git a/x-pack/plugins/task_manager/server/buffered_task_store.ts b/x-pack/plugins/task_manager/server/buffered_task_store.ts new file mode 100644 index 0000000000000..e1e5f802204c1 --- /dev/null +++ b/x-pack/plugins/task_manager/server/buffered_task_store.ts @@ -0,0 +1,39 @@ +/* + * 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 { TaskStore } from './task_store'; +import { ConcreteTaskInstance } from './task'; +import { Updatable } from './task_runner'; +import { createBuffer, Operation, BufferOptions } from './lib/bulk_operation_buffer'; +import { unwrapPromise } from './lib/result_type'; + +// by default allow updates to be buffered for up to 50ms +const DEFAULT_BUFFER_MAX_DURATION = 50; + +export class BufferedTaskStore implements Updatable { + private bufferedUpdate: Operation; + constructor(private readonly taskStore: TaskStore, options: BufferOptions) { + this.bufferedUpdate = createBuffer( + (docs) => taskStore.bulkUpdate(docs), + { + bufferMaxDuration: DEFAULT_BUFFER_MAX_DURATION, + ...options, + } + ); + } + + public get maxAttempts(): number { + return this.taskStore.maxAttempts; + } + + public async update(doc: ConcreteTaskInstance): Promise { + return unwrapPromise(this.bufferedUpdate(doc)); + } + + public async remove(id: string): Promise { + return this.taskStore.remove(id); + } +} diff --git a/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts b/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts new file mode 100644 index 0000000000000..9293656233026 --- /dev/null +++ b/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.test.ts @@ -0,0 +1,288 @@ +/* + * 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 { createBuffer, Entity, OperationError, BulkOperation } from './bulk_operation_buffer'; +import { mapErr, asOk, asErr, Ok, Err } from './result_type'; + +interface TaskInstance extends Entity { + attempts: number; +} + +const createTask = (function (): () => TaskInstance { + let counter = 0; + return () => ({ + id: `task ${++counter}`, + attempts: 1, + }); +})(); + +function incrementAttempts(task: TaskInstance): Ok { + return asOk({ + ...task, + attempts: task.attempts + 1, + }); +} + +function errorAttempts(task: TaskInstance): Err> { + return asErr({ + entity: incrementAttempts(task).value, + error: { name: '', message: 'Oh no, something went terribly wrong', statusCode: 500 }, + }); +} + +describe('Bulk Operation Buffer', () => { + describe('createBuffer()', () => { + test('batches up multiple Operation calls', async () => { + const bulkUpdate: jest.Mocked> = jest.fn( + ([task1, task2]) => { + return Promise.resolve([incrementAttempts(task1), incrementAttempts(task2)]); + } + ); + + const bufferedUpdate = createBuffer(bulkUpdate); + + const task1 = createTask(); + const task2 = createTask(); + + expect(await Promise.all([bufferedUpdate(task1), bufferedUpdate(task2)])).toMatchObject([ + incrementAttempts(task1), + incrementAttempts(task2), + ]); + expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); + }); + + test('batch updates are executed at most by the next Event Loop tick by default', async () => { + const bulkUpdate: jest.Mocked> = jest.fn((tasks) => { + return Promise.resolve(tasks.map(incrementAttempts)); + }); + + const bufferedUpdate = createBuffer(bulkUpdate); + + const task1 = createTask(); + const task2 = createTask(); + const task3 = createTask(); + const task4 = createTask(); + const task5 = createTask(); + const task6 = createTask(); + + return new Promise((resolve) => { + Promise.all([bufferedUpdate(task1), bufferedUpdate(task2)]).then((_) => { + expect(bulkUpdate).toHaveBeenCalledTimes(1); + expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); + expect(bulkUpdate).not.toHaveBeenCalledWith([task3, task4]); + }); + + setTimeout(() => { + // on next tick + setTimeout(() => { + // on next tick + expect(bulkUpdate).toHaveBeenCalledTimes(2); + Promise.all([bufferedUpdate(task5), bufferedUpdate(task6)]).then((_) => { + expect(bulkUpdate).toHaveBeenCalledTimes(3); + expect(bulkUpdate).toHaveBeenCalledWith([task5, task6]); + resolve(); + }); + }, 0); + + expect(bulkUpdate).toHaveBeenCalledTimes(1); + Promise.all([bufferedUpdate(task3), bufferedUpdate(task4)]).then((_) => { + expect(bulkUpdate).toHaveBeenCalledTimes(2); + expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); + }); + }, 0); + }); + }); + + test('batch updates can be customised to execute after a certain period', async () => { + const bulkUpdate: jest.Mocked> = jest.fn((tasks) => { + return Promise.resolve(tasks.map(incrementAttempts)); + }); + + const bufferMaxDuration = 50; + const bufferedUpdate = createBuffer(bulkUpdate, { bufferMaxDuration }); + + const task1 = createTask(); + const task2 = createTask(); + const task3 = createTask(); + const task4 = createTask(); + const task5 = createTask(); + const task6 = createTask(); + + return new Promise((resolve) => { + Promise.all([bufferedUpdate(task1), bufferedUpdate(task2)]).then((_) => { + expect(bulkUpdate).toHaveBeenCalledTimes(1); + expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); + expect(bulkUpdate).not.toHaveBeenCalledWith([task3, task4]); + }); + + setTimeout(() => { + // on next tick + setTimeout(() => { + // on next tick + expect(bulkUpdate).toHaveBeenCalledTimes(2); + Promise.all([bufferedUpdate(task5), bufferedUpdate(task6)]).then((_) => { + expect(bulkUpdate).toHaveBeenCalledTimes(3); + expect(bulkUpdate).toHaveBeenCalledWith([task5, task6]); + resolve(); + }); + }, bufferMaxDuration + 1); + + expect(bulkUpdate).toHaveBeenCalledTimes(1); + Promise.all([bufferedUpdate(task3), bufferedUpdate(task4)]).then((_) => { + expect(bulkUpdate).toHaveBeenCalledTimes(2); + expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); + }); + }, bufferMaxDuration + 1); + }); + }); + + test('batch updates are executed once queue hits a certain bound', async () => { + const bulkUpdate: jest.Mocked> = jest.fn((tasks) => { + return Promise.resolve(tasks.map(incrementAttempts)); + }); + + const bufferedUpdate = createBuffer(bulkUpdate, { + bufferMaxDuration: 100, + bufferMaxOperations: 2, + }); + + const task1 = createTask(); + const task2 = createTask(); + const task3 = createTask(); + const task4 = createTask(); + const task5 = createTask(); + + return new Promise((resolve) => { + bufferedUpdate(task1); + bufferedUpdate(task2); + bufferedUpdate(task3); + bufferedUpdate(task4); + + setTimeout(() => { + expect(bulkUpdate).toHaveBeenCalledTimes(2); + expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); + expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); + + setTimeout(() => { + expect(bulkUpdate).toHaveBeenCalledTimes(2); + bufferedUpdate(task5).then((_) => { + expect(bulkUpdate).toHaveBeenCalledTimes(3); + expect(bulkUpdate).toHaveBeenCalledWith([task5]); + resolve(); + }); + }, 50); + }, 50); + }); + }); + + test('queue upper bound is reset after each flush', async () => { + const bulkUpdate: jest.Mocked> = jest.fn((tasks) => { + return Promise.resolve(tasks.map(incrementAttempts)); + }); + + const bufferMaxDuration = 100; + const bufferedUpdate = createBuffer(bulkUpdate, { + bufferMaxDuration, + bufferMaxOperations: 3, + }); + + const task1 = createTask(); + const task2 = createTask(); + const task3 = createTask(); + const task4 = createTask(); + + return new Promise((resolve) => { + bufferedUpdate(task1); + bufferedUpdate(task2); + + setTimeout(() => { + expect(bulkUpdate).toHaveBeenCalledTimes(1); + expect(bulkUpdate).toHaveBeenCalledWith([task1, task2]); + + bufferedUpdate(task3); + bufferedUpdate(task4); + + setTimeout(() => { + expect(bulkUpdate).toHaveBeenCalledTimes(1); + + setTimeout(() => { + expect(bulkUpdate).toHaveBeenCalledTimes(2); + expect(bulkUpdate).toHaveBeenCalledWith([task3, task4]); + resolve(); + }, bufferMaxDuration / 2); + }, bufferMaxDuration / 2); + }, bufferMaxDuration + 1); + }); + }); + test('handles both resolutions and rejections at individual task level', async (done) => { + const bulkUpdate: jest.Mocked> = jest.fn( + ([task1, task2, task3]) => { + return Promise.resolve([ + incrementAttempts(task1), + errorAttempts(task2), + incrementAttempts(task3), + ]); + } + ); + + const bufferedUpdate = createBuffer(bulkUpdate); + + const task1 = createTask(); + const task2 = createTask(); + const task3 = createTask(); + + return Promise.all([ + expect(bufferedUpdate(task1)).resolves.toMatchObject(incrementAttempts(task1)), + expect(bufferedUpdate(task2)).rejects.toMatchObject( + mapErr( + (err: OperationError) => asErr(err.error), + errorAttempts(task2) + ) + ), + expect(bufferedUpdate(task3)).resolves.toMatchObject(incrementAttempts(task3)), + ]).then(() => { + expect(bulkUpdate).toHaveBeenCalledTimes(1); + done(); + }); + }); + + test('handles bulkUpdate failure', async (done) => { + const bulkUpdate: jest.Mocked> = jest.fn(() => { + return Promise.reject(new Error('bulkUpdate is an illusion')); + }); + + const bufferedUpdate = createBuffer(bulkUpdate); + + const task1 = createTask(); + const task2 = createTask(); + const task3 = createTask(); + + return Promise.all([ + expect(bufferedUpdate(task1)).rejects.toMatchInlineSnapshot(` + Object { + "error": [Error: bulkUpdate is an illusion], + "tag": "err", + } + `), + expect(bufferedUpdate(task2)).rejects.toMatchInlineSnapshot(` + Object { + "error": [Error: bulkUpdate is an illusion], + "tag": "err", + } + `), + expect(bufferedUpdate(task3)).rejects.toMatchInlineSnapshot(` + Object { + "error": [Error: bulkUpdate is an illusion], + "tag": "err", + } + `), + ]).then(() => { + expect(bulkUpdate).toHaveBeenCalledTimes(1); + done(); + }); + }); + }); +}); diff --git a/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.ts b/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.ts new file mode 100644 index 0000000000000..fca7ce02e0cd7 --- /dev/null +++ b/x-pack/plugins/task_manager/server/lib/bulk_operation_buffer.ts @@ -0,0 +1,129 @@ +/* + * 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 { keyBy, map } from 'lodash'; +import { Subject, race, from } from 'rxjs'; +import { bufferWhen, filter, bufferCount, flatMap, mapTo, first } from 'rxjs/operators'; +import { either, Result, asOk, asErr, Ok, Err } from './result_type'; + +export interface BufferOptions { + bufferMaxDuration?: number; + bufferMaxOperations?: number; +} + +export interface Entity { + id: string; +} + +export interface OperationError { + entity: Input; + error: ErrorOutput; +} + +export type OperationResult = Result< + Output, + OperationError +>; + +export type Operation = ( + entity: Input +) => Promise>; + +export type BulkOperation = ( + entities: Input[] +) => Promise>>; + +const DONT_FLUSH = false; +const FLUSH = true; + +export function createBuffer( + bulkOperation: BulkOperation, + { bufferMaxDuration = 0, bufferMaxOperations = Number.MAX_VALUE }: BufferOptions = {} +): Operation { + const flushBuffer = new Subject(); + + const storeUpdateBuffer = new Subject<{ + entity: Input; + onSuccess: (entity: Ok) => void; + onFailure: (error: Err) => void; + }>(); + + storeUpdateBuffer + .pipe( + bufferWhen(() => flushBuffer), + filter((tasks) => tasks.length > 0) + ) + .subscribe((entities) => { + const entityById = keyBy(entities, ({ entity: { id } }) => id); + bulkOperation(map(entities, 'entity')) + .then((results) => { + results.forEach((result) => + either( + result, + (entity) => { + entityById[entity.id].onSuccess(asOk(entity)); + }, + ({ entity, error }: OperationError) => { + entityById[entity.id].onFailure(asErr(error)); + } + ) + ); + }) + .catch((ex) => { + entities.forEach(({ onFailure }) => onFailure(asErr(ex))); + }); + }); + + let countInBuffer = 0; + const flushAndResetCounter = () => { + countInBuffer = 0; + flushBuffer.next(); + }; + storeUpdateBuffer + .pipe( + // complete once the buffer has either filled to `bufferMaxOperations` or + // a `bufferMaxDuration` has passed. Default to `bufferMaxDuration` being the + // current event loop tick rather than a fixed duration + flatMap(() => { + return ++countInBuffer === 1 + ? race([ + // the race is started in response to the first operation into the buffer + // so we flush once the remaining operations come in (which is `bufferMaxOperations - 1`) + storeUpdateBuffer.pipe(bufferCount(bufferMaxOperations - 1)), + bufferMaxDuration + ? // if theres a max duration, flush buffer based on that + from(resolveIn(bufferMaxDuration)) + : // ensure we flush by the end of the "current" event loop tick + from(resolveImmediate()), + ]).pipe(first(), mapTo(FLUSH)) + : from([DONT_FLUSH]); + }), + filter((shouldFlush) => shouldFlush) + ) + .subscribe({ + next: flushAndResetCounter, + // As this stream is just trying to decide when to flush + // there's no data to lose, so in the case that an error + // is thrown, lets just flush + error: flushAndResetCounter, + }); + + return async function (entity: Input) { + return new Promise((resolve, reject) => { + storeUpdateBuffer.next({ entity, onSuccess: resolve, onFailure: reject }); + }); + }; +} + +function resolveImmediate() { + return new Promise(setImmediate); +} + +function resolveIn(ms: number) { + return new Promise((resolve) => { + setTimeout(resolve, ms); + }); +} diff --git a/x-pack/plugins/task_manager/server/lib/result_type.test.ts b/x-pack/plugins/task_manager/server/lib/result_type.test.ts new file mode 100644 index 0000000000000..480a732f1f617 --- /dev/null +++ b/x-pack/plugins/task_manager/server/lib/result_type.test.ts @@ -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. + */ + +import uuid from 'uuid'; +import { unwrapPromise, asOk, asErr } from './result_type'; + +describe(`Result`, () => { + describe(`unwrapPromise`, () => { + test(`unwraps OKs from the result`, async () => { + const uniqueId = uuid.v4(); + expect(await unwrapPromise(Promise.resolve(asOk(uniqueId)))).toEqual(uniqueId); + }); + + test(`unwraps Errs from the result`, async () => { + const uniqueId = uuid.v4(); + expect(unwrapPromise(Promise.resolve(asErr(uniqueId)))).rejects.toEqual(uniqueId); + }); + + test(`unwraps Errs from the result when promise rejects`, async () => { + const uniqueId = uuid.v4(); + expect(unwrapPromise(Promise.reject(asErr(uniqueId)))).rejects.toEqual(uniqueId); + }); + }); +}); diff --git a/x-pack/plugins/task_manager/server/lib/result_type.ts b/x-pack/plugins/task_manager/server/lib/result_type.ts index edf4d84dd226d..d21c17d3bb5b3 100644 --- a/x-pack/plugins/task_manager/server/lib/result_type.ts +++ b/x-pack/plugins/task_manager/server/lib/result_type.ts @@ -47,6 +47,25 @@ export async function promiseResult(future: Promise): Promise(future: Promise>): Promise { + return future + .catch( + // catch rejection as we expect the result of the rejected promise + // to be wrapped in a Result - sadly there's no way to "Type" this + // requirment in Typescript as Promises do not enfore a type on their + // rejection + // The `then` will then unwrap the Result from around `ex` for us + (ex: Err) => ex + ) + .then((result: Result) => + map( + result, + (value: T) => Promise.resolve(value), + (err: E) => Promise.reject(err) + ) + ); +} + export function unwrap(result: Result): T | E { return isOk(result) ? result.value : result.error; } diff --git a/x-pack/plugins/task_manager/server/task_manager.ts b/x-pack/plugins/task_manager/server/task_manager.ts index 23cb33cfac6c2..35ca439bb9130 100644 --- a/x-pack/plugins/task_manager/server/task_manager.ts +++ b/x-pack/plugins/task_manager/server/task_manager.ts @@ -57,6 +57,7 @@ import { } from './task_store'; import { identifyEsError } from './lib/identify_es_error'; import { ensureDeprecatedFieldsAreCorrected } from './lib/correct_deprecated_fields'; +import { BufferedTaskStore } from './buffered_task_store'; const VERSION_CONFLICT_STATUS = 409; @@ -90,7 +91,10 @@ export type TaskLifecycleEvent = TaskMarkRunning | TaskRun | TaskClaim | TaskRun */ export class TaskManager { private definitions: TaskDictionary = {}; + private store: TaskStore; + private bufferedStore: BufferedTaskStore; + private logger: Logger; private pool: TaskPool; // all task related events (task claimed, task marked as running, etc.) are emitted through events$ @@ -139,6 +143,10 @@ export class TaskManager { // pipe store events into the TaskManager's event stream this.store.events.subscribe((event) => this.events$.next(event)); + this.bufferedStore = new BufferedTaskStore(this.store, { + bufferMaxOperations: opts.config.max_workers, + }); + this.pool = new TaskPool({ logger: this.logger, maxWorkers: opts.config.max_workers, @@ -165,7 +173,7 @@ export class TaskManager { return new TaskManagerRunner({ logger: this.logger, instance, - store: this.store, + store: this.bufferedStore, definitions: this.definitions, beforeRun: this.middleware.beforeRun, beforeMarkRunning: this.middleware.beforeMarkRunning, diff --git a/x-pack/plugins/task_manager/server/task_runner.ts b/x-pack/plugins/task_manager/server/task_runner.ts index 4c690a5675f61..ebf13fac2f311 100644 --- a/x-pack/plugins/task_manager/server/task_runner.ts +++ b/x-pack/plugins/task_manager/server/task_runner.ts @@ -49,7 +49,7 @@ export interface TaskRunner { toString: () => string; } -interface Updatable { +export interface Updatable { readonly maxAttempts: number; update(doc: ConcreteTaskInstance): Promise; remove(id: string): Promise; diff --git a/x-pack/plugins/task_manager/server/task_store.mock.ts b/x-pack/plugins/task_manager/server/task_store.mock.ts new file mode 100644 index 0000000000000..86db695bc5e2c --- /dev/null +++ b/x-pack/plugins/task_manager/server/task_store.mock.ts @@ -0,0 +1,31 @@ +/* + * 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 { TaskStore } from './task_store'; + +interface TaskStoreOptions { + maxAttempts?: number; + index?: string; + taskManagerId?: string; +} +export const taskStoreMock = { + create({ maxAttempts = 0, index = '', taskManagerId = '' }: TaskStoreOptions) { + const mocked = ({ + update: jest.fn(), + remove: jest.fn(), + schedule: jest.fn(), + claimAvailableTasks: jest.fn(), + bulkUpdate: jest.fn(), + get: jest.fn(), + getLifecycle: jest.fn(), + fetch: jest.fn(), + maxAttempts, + index, + taskManagerId, + } as unknown) as jest.Mocked; + return mocked; + }, +}; diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts index 4a691e17011e8..7ec3db5c99aa7 100644 --- a/x-pack/plugins/task_manager/server/task_store.ts +++ b/x-pack/plugins/task_manager/server/task_store.ts @@ -17,9 +17,10 @@ import { SavedObjectsSerializer, SavedObjectsRawDoc, ISavedObjectsRepository, + SavedObjectsUpdateResponse, } from '../../../../src/core/server'; -import { asOk, asErr } from './lib/result_type'; +import { asOk, asErr, Result } from './lib/result_type'; import { ConcreteTaskInstance, @@ -98,10 +99,10 @@ export interface ClaimOwnershipResult { docs: ConcreteTaskInstance[]; } -export interface BulkUpdateTaskFailureResult { - error: NonNullable; - task: ConcreteTaskInstance; -} +export type BulkUpdateResult = Result< + ConcreteTaskInstance, + { entity: ConcreteTaskInstance; error: Error } +>; export interface UpdateByQueryResult { updated: number; @@ -332,6 +333,54 @@ export class TaskStore { ); } + /** + * Updates the specified docs in the index, returning the docs + * with their versions up to date. + * + * @param {Array} docs + * @returns {Promise>} + */ + public async bulkUpdate(docs: ConcreteTaskInstance[]): Promise { + const attributesByDocId = docs.reduce((attrsById, doc) => { + attrsById.set(doc.id, taskInstanceToAttributes(doc)); + return attrsById; + }, new Map()); + + const updatedSavedObjects: Array = ( + await this.savedObjectsRepository.bulkUpdate( + docs.map((doc) => ({ + type: 'task', + id: doc.id, + options: { version: doc.version }, + attributes: attributesByDocId.get(doc.id)!, + })), + { + refresh: false, + } + ) + ).saved_objects; + + return updatedSavedObjects.map((updatedSavedObject, index) => + isSavedObjectsUpdateResponse(updatedSavedObject) + ? asOk( + savedObjectToConcreteTaskInstance({ + ...updatedSavedObject, + attributes: defaults( + updatedSavedObject.attributes, + attributesByDocId.get(updatedSavedObject.id)! + ), + }) + ) + : asErr({ + // The SavedObjectsRepository maintains the order of the docs + // so we can rely on the index in the `docs` to match an error + // on the same index in the `bulkUpdate` result + entity: docs[index], + error: updatedSavedObject, + }) + ); + } + /** * Removes the specified task from the index. * @@ -468,3 +517,9 @@ function ensureQueryOnlyReturnsTaskObjects(opts: SearchOpts): SearchOpts { query, }; } + +function isSavedObjectsUpdateResponse( + result: SavedObjectsUpdateResponse | Error +): result is SavedObjectsUpdateResponse { + return result && typeof (result as SavedObjectsUpdateResponse).id === 'string'; +} From c63ab91c7bfc574a563a5e0be3bab67156b8ddaa Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Tue, 21 Jul 2020 09:12:50 -0400 Subject: [PATCH 42/77] [Monitoring] Fix the messaging around needing TLS enabled (#72310) * Fix the copy * Fix type issues * PR feedback * Add missing code --- .../public/alerts/lib/security_toasts.tsx | 82 ++----------------- 1 file changed, 5 insertions(+), 77 deletions(-) diff --git a/x-pack/plugins/monitoring/public/alerts/lib/security_toasts.tsx b/x-pack/plugins/monitoring/public/alerts/lib/security_toasts.tsx index 918c0b5c9b609..2850a5b772c32 100644 --- a/x-pack/plugins/monitoring/public/alerts/lib/security_toasts.tsx +++ b/x-pack/plugins/monitoring/public/alerts/lib/security_toasts.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiSpacer, EuiLink, EuiCode, EuiText } from '@elastic/eui'; +import { EuiSpacer, EuiLink } from '@elastic/eui'; import { Legacy } from '../../legacy_shims'; import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public'; @@ -30,11 +30,10 @@ const showTlsAndEncryptionError = () => {

{i18n.translate('xpack.monitoring.healthCheck.tlsAndEncryptionError', { - defaultMessage: `You must enable Transport Layer Security between Kibana and Elasticsearch - and configure an encryption key in your kibana.yml file to use the Alerting feature.`, + defaultMessage: `Stack monitoring alerts require Transport Layer Security between Kibana and Elasticsearch, and an encryption key in your kibana.yml file.`, })}

- + { }); }; -const showEncryptionError = () => { - const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = Legacy.shims.docLinks; - - Legacy.shims.toastNotifications.addWarning( - { - title: toMountPoint( - - ), - text: toMountPoint( -
- {i18n.translate('xpack.monitoring.healthCheck.encryptionErrorBeforeKey', { - defaultMessage: 'To create an alert, set a value for ', - })} - - {'xpack.encryptedSavedObjects.encryptionKey'} - - {i18n.translate('xpack.monitoring.healthCheck.encryptionErrorAfterKey', { - defaultMessage: ' in your kibana.yml file. ', - })} - - {i18n.translate('xpack.monitoring.healthCheck.encryptionErrorAction', { - defaultMessage: 'Learn how.', - })} - -
- ), - }, - {} - ); -}; - -const showTlsError = () => { - const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = Legacy.shims.docLinks; - - Legacy.shims.toastNotifications.addWarning({ - title: toMountPoint( - - ), - text: toMountPoint( -
- {i18n.translate('xpack.monitoring.healthCheck.tlsError', { - defaultMessage: - 'Alerting relies on API keys, which require TLS between Elasticsearch and Kibana. ', - })} - - {i18n.translate('xpack.monitoring.healthCheck.tlsErrorAction', { - defaultMessage: 'Learn how to enable TLS.', - })} - -
- ), - }); -}; - export const showSecurityToast = (alertingHealth: AlertingFrameworkHealth) => { const { isSufficientlySecure, hasPermanentEncryptionKey } = alertingHealth; + if ( Array.isArray(alertingHealth) || (!alertingHealth.hasOwnProperty('isSufficientlySecure') && @@ -127,11 +59,7 @@ export const showSecurityToast = (alertingHealth: AlertingFrameworkHealth) => { return; } - if (!isSufficientlySecure && !hasPermanentEncryptionKey) { + if (!isSufficientlySecure || !hasPermanentEncryptionKey) { showTlsAndEncryptionError(); - } else if (!isSufficientlySecure) { - showTlsError(); - } else if (!hasPermanentEncryptionKey) { - showEncryptionError(); } }; From fbf41e53795abf257caf5b44636d2ad35c4a364c Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 21 Jul 2020 14:28:10 +0100 Subject: [PATCH 43/77] [ML] Handling data recognizer saved object errors (#72447) * [ML] Handling data recognizer saved object errors * adding text for unknown errors * fixing typos --- .../plugins/ml/common/types/capabilities.ts | 2 +- x-pack/plugins/ml/common/types/modules.ts | 1 + .../recognize/components/kibana_objects.tsx | 7 ++++- .../models/data_recognizer/data_recognizer.ts | 30 +++++++++++++++++-- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/ml/common/types/capabilities.ts b/x-pack/plugins/ml/common/types/capabilities.ts index b46dd87eec15f..f2177b0a3572f 100644 --- a/x-pack/plugins/ml/common/types/capabilities.ts +++ b/x-pack/plugins/ml/common/types/capabilities.ts @@ -81,7 +81,7 @@ export function getPluginPrivileges() { catalogue: [PLUGIN_ID], savedObject: { all: [], - read: ['index-pattern', 'search'], + read: ['index-pattern', 'dashboard', 'search', 'visualization'], }, }; diff --git a/x-pack/plugins/ml/common/types/modules.ts b/x-pack/plugins/ml/common/types/modules.ts index b476762f6efca..bfa7e38332c1b 100644 --- a/x-pack/plugins/ml/common/types/modules.ts +++ b/x-pack/plugins/ml/common/types/modules.ts @@ -30,6 +30,7 @@ export interface KibanaObject { title: string; config: KibanaObjectConfig; exists?: boolean; + error?: any; } export interface KibanaObjects { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/components/kibana_objects.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/components/kibana_objects.tsx index 4954b44bf8842..f8ca7926ad7d6 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/components/kibana_objects.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/components/kibana_objects.tsx @@ -46,7 +46,7 @@ export const KibanaObjects: FC = memo(
    - {kibanaObjects.map(({ id, title, success, exists }, i) => ( + {kibanaObjects.map(({ id, title, success, exists, error }, i) => (
  • @@ -55,6 +55,11 @@ export const KibanaObjects: FC = memo( {title} + {success === false && error !== undefined && ( + + {error.message} + + )} {exists && ( diff --git a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts index 521d04159ca7a..21e178dcc7e76 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts @@ -93,6 +93,7 @@ export interface RecognizeResult { interface ObjectExistResult { id: string; type: string; + exists?: boolean; } interface ObjectExistResponse { @@ -493,7 +494,13 @@ export class DataRecognizer { // update the exists flag in the results this.updateKibanaResults(results.kibana, savedObjects); // create the savedObjects - saveResults.savedObjects = await this.saveKibanaObjects(savedObjects); + try { + saveResults.savedObjects = await this.saveKibanaObjects(savedObjects); + } catch (error) { + // only one error is returned for the bulk create saved object request + // so populate every saved object with the same error. + this.populateKibanaResultErrors(results.kibana, error.output?.payload); + } } // merge all the save results this.updateResults(results, saveResults); @@ -610,7 +617,26 @@ export class DataRecognizer { (type) => { kibanaSaveResults[type].forEach((resultItem) => { const i = objectExistResults.find((o) => o.id === resultItem.id && o.type === type); - resultItem.exists = i !== undefined; + resultItem.exists = i !== undefined && i.exists; + }); + } + ); + } + + // add an error object to every kibana saved object, + // if it doesn't already exist. + populateKibanaResultErrors( + kibanaSaveResults: DataRecognizerConfigResponse['kibana'], + error: any + ) { + const errorObj = + error === undefined ? { message: 'Unknown error when creating saved object' } : error; + (Object.keys(kibanaSaveResults) as Array).forEach( + (type) => { + kibanaSaveResults[type].forEach((resultItem) => { + if (resultItem.exists === false) { + resultItem.error = errorObj; + } }); } ); From 98478b49e046c6e667eed569972dfad40e9c34b9 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Tue, 21 Jul 2020 16:51:29 +0300 Subject: [PATCH 44/77] Migrated fixed_scroll karma tests to jest (#72258) Co-authored-by: Elastic Machine --- .../public/__tests__/discover/fixed_scroll.js | 202 ------------- .../angular/directives/fixed_scroll.test.js | 268 ++++++++++++++++++ 2 files changed, 268 insertions(+), 202 deletions(-) delete mode 100644 src/legacy/core_plugins/kibana/public/__tests__/discover/fixed_scroll.js create mode 100644 src/plugins/discover/public/application/angular/directives/fixed_scroll.test.js diff --git a/src/legacy/core_plugins/kibana/public/__tests__/discover/fixed_scroll.js b/src/legacy/core_plugins/kibana/public/__tests__/discover/fixed_scroll.js deleted file mode 100644 index 9bb0ebc76474d..0000000000000 --- a/src/legacy/core_plugins/kibana/public/__tests__/discover/fixed_scroll.js +++ /dev/null @@ -1,202 +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. - */ - -/* eslint-disable @kbn/eslint/no-restricted-paths */ - -import angular from 'angular'; -import expect from '@kbn/expect'; -import ngMock from 'ng_mock'; -import $ from 'jquery'; -import sinon from 'sinon'; - -import { PrivateProvider } from '../../../../../../plugins/kibana_legacy/public'; -import { FixedScrollProvider } from '../../../../../../plugins/discover/public/application/angular/directives/fixed_scroll'; -import { DebounceProviderTimeout } from '../../../../../../plugins/discover/public/application/angular/directives/debounce/debounce'; - -const testModuleName = 'fixedScroll'; - -angular - .module(testModuleName, []) - .provider('Private', PrivateProvider) - .service('debounce', ['$timeout', DebounceProviderTimeout]) - .directive('fixedScroll', FixedScrollProvider); - -describe('FixedScroll directive', function () { - const sandbox = sinon.createSandbox(); - - let compile; - let flushPendingTasks; - const trash = []; - beforeEach(ngMock.module(testModuleName)); - beforeEach( - ngMock.inject(function ($compile, $rootScope, $timeout) { - flushPendingTasks = function flushPendingTasks() { - $rootScope.$digest(); - $timeout.flush(); - }; - - compile = function (ratioY, ratioX) { - if (ratioX == null) ratioX = ratioY; - - // since the directive works at the sibling level we create a - // parent for everything to happen in - const $parent = $('
    ').css({ - position: 'fixed', - top: 0, - left: 0, - right: 0, - bottom: 0, - }); - - $parent.appendTo(document.body); - trash.push($parent); - - const $el = $('
    ') - .css({ - 'overflow-x': 'auto', - width: $parent.width(), - }) - .appendTo($parent); - - const $content = $('
    ') - .css({ - width: $parent.width() * ratioX, - height: $parent.height() * ratioY, - }) - .appendTo($el); - - $compile($parent)($rootScope); - flushPendingTasks(); - - return { - $container: $el, - $content: $content, - $scroller: $parent.find('.fixed-scroll-scroller'), - }; - }; - }) - ); - - afterEach(function () { - trash.splice(0).forEach(function ($el) { - $el.remove(); - }); - - sandbox.restore(); - }); - - it('does nothing when not needed', function () { - let els = compile(0.5, 1.5); - expect(els.$scroller).to.have.length(0); - - els = compile(1.5, 0.5); - expect(els.$scroller).to.have.length(0); - }); - - it('attaches a scroller below the element when the content is larger then the container', function () { - const els = compile(1.5); - expect(els.$scroller).to.have.length(1); - }); - - it('copies the width of the container', function () { - const els = compile(1.5); - expect(els.$scroller.width()).to.be(els.$container.width()); - }); - - it('mimics the scrollWidth of the element', function () { - const els = compile(1.5); - expect(els.$scroller.prop('scrollWidth')).to.be(els.$container.prop('scrollWidth')); - }); - - describe('scroll event handling / tug of war prevention', function () { - it('listens when needed, unlistens when not needed', function () { - const on = sandbox.spy($.fn, 'on'); - const off = sandbox.spy($.fn, 'off'); - - const els = compile(1.5); - expect(on.callCount).to.be(2); - checkThisVals('$.fn.on', on); - - expect(off.callCount).to.be(0); - els.$container.width(els.$container.prop('scrollWidth')); - flushPendingTasks(); - expect(off.callCount).to.be(2); - checkThisVals('$.fn.off', off); - - function checkThisVals(name, spy) { - // the this values should be different - expect(spy.thisValues[0].is(spy.thisValues[1])).to.be(false); - // but they should be either $scroller or $container - spy.thisValues.forEach(function ($this) { - if ($this.is(els.$scroller) || $this.is(els.$container)) return; - expect.fail('expected ' + name + ' to be called with $scroller or $container'); - }); - } - }); - - [ - { from: '$container', to: '$scroller' }, - { from: '$scroller', to: '$container' }, - ].forEach(function (names) { - describe('scroll events ' + JSON.stringify(names), function () { - let spy; - let els; - let $from; - let $to; - - beforeEach(function () { - spy = sandbox.spy($.fn, 'scrollLeft'); - els = compile(1.5); - $from = els[names.from]; - $to = els[names.to]; - }); - - it('transfers the scrollLeft', function () { - expect(spy.callCount).to.be(0); - $from.scroll(); - expect(spy.callCount).to.be(2); - - // first call should read the scrollLeft from the $container - const firstCall = spy.getCall(0); - expect(firstCall.thisValue.is($from)).to.be(true); - expect(firstCall.args).to.eql([]); - - // second call should be setting the scrollLeft on the $scroller - const secondCall = spy.getCall(1); - expect(secondCall.thisValue.is($to)).to.be(true); - expect(secondCall.args).to.eql([firstCall.returnValue]); - }); - - /** - * In practice, calling $el.scrollLeft() causes the "scroll" event to trigger, - * but the browser seems to be very careful about triggering the event too much - * and I can't reliably recreate the browsers behavior in a test. So... faking it! - */ - it('prevents tug of war by ignoring echo scroll events', function () { - $from.scroll(); - expect(spy.callCount).to.be(2); - - spy.resetHistory(); - $to.scroll(); - expect(spy.callCount).to.be(0); - }); - }); - }); - }); -}); diff --git a/src/plugins/discover/public/application/angular/directives/fixed_scroll.test.js b/src/plugins/discover/public/application/angular/directives/fixed_scroll.test.js new file mode 100644 index 0000000000000..16293ca621e05 --- /dev/null +++ b/src/plugins/discover/public/application/angular/directives/fixed_scroll.test.js @@ -0,0 +1,268 @@ +/* + * 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 angular from 'angular'; +import 'angular-mocks'; +import $ from 'jquery'; + +import sinon from 'sinon'; + +import { PrivateProvider, initAngularBootstrap } from '../../../../../kibana_legacy/public'; +import { FixedScrollProvider } from './fixed_scroll'; +import { DebounceProviderTimeout } from './debounce/debounce'; + +const testModuleName = 'fixedScroll'; + +angular + .module(testModuleName, []) + .provider('Private', PrivateProvider) + .service('debounce', ['$timeout', DebounceProviderTimeout]) + .directive('fixedScroll', FixedScrollProvider); + +describe('FixedScroll directive', function () { + const sandbox = sinon.createSandbox(); + let mockWidth; + let mockHeight; + let currentWidth = 120; + let currentHeight = 120; + let currentJqLiteWidth = 120; + let spyScrollWidth; + + let compile; + let flushPendingTasks; + const trash = []; + + beforeAll(() => { + mockWidth = jest.spyOn($.prototype, 'width').mockImplementation(function (width) { + if (width === undefined) { + return currentWidth; + } else { + currentWidth = width; + return this; + } + }); + mockHeight = jest.spyOn($.prototype, 'height').mockImplementation(function (height) { + if (height === undefined) { + return currentHeight; + } else { + currentHeight = height; + return this; + } + }); + angular.element.prototype.width = jest.fn(function (width) { + if (width === undefined) { + return currentJqLiteWidth; + } else { + currentJqLiteWidth = width; + return this; + } + }); + angular.element.prototype.offset = jest.fn(() => ({ top: 0 })); + }); + + beforeEach(() => { + currentJqLiteWidth = 120; + initAngularBootstrap(); + + angular.mock.module(testModuleName); + angular.mock.inject(($compile, $rootScope, $timeout) => { + flushPendingTasks = function flushPendingTasks() { + $rootScope.$digest(); + $timeout.flush(); + }; + + compile = function (ratioY, ratioX) { + if (ratioX == null) ratioX = ratioY; + + // since the directive works at the sibling level we create a + // parent for everything to happen in + const $parent = $('
    ').css({ + position: 'fixed', + top: 0, + left: 0, + right: 0, + bottom: 0, + }); + + $parent.appendTo(document.body); + trash.push($parent); + + const $el = $('
    ') + .css({ + 'overflow-x': 'auto', + width: $parent.width(), + }) + .appendTo($parent); + + spyScrollWidth = jest.spyOn(window.HTMLElement.prototype, 'scrollWidth', 'get'); + spyScrollWidth.mockReturnValue($parent.width() * ratioX); + angular.element.prototype.height = jest.fn(() => $parent.height() * ratioY); + + const $content = $('
    ') + .css({ + width: $parent.width() * ratioX, + height: $parent.height() * ratioY, + }) + .appendTo($el); + + $compile($parent)($rootScope); + flushPendingTasks(); + + return { + $container: $el, + $content: $content, + $scroller: $parent.find('.fixed-scroll-scroller'), + }; + }; + }); + }); + + afterEach(function () { + trash.splice(0).forEach(function ($el) { + $el.remove(); + }); + + sandbox.restore(); + spyScrollWidth.mockRestore(); + }); + + afterAll(() => { + mockWidth.mockRestore(); + mockHeight.mockRestore(); + delete angular.element.prototype.width; + delete angular.element.prototype.height; + delete angular.element.prototype.offset; + }); + + test('does nothing when not needed', function () { + let els = compile(0.5, 1.5); + expect(els.$scroller).toHaveLength(0); + + els = compile(1.5, 0.5); + expect(els.$scroller).toHaveLength(0); + }); + + test('attaches a scroller below the element when the content is larger then the container', function () { + const els = compile(1.5); + expect(els.$scroller.length).toBe(1); + }); + + test('copies the width of the container', function () { + const els = compile(1.5); + expect(els.$scroller.width()).toBe(els.$container.width()); + }); + + test('mimics the scrollWidth of the element', function () { + const els = compile(1.5); + expect(els.$scroller.prop('scrollWidth')).toBe(els.$container.prop('scrollWidth')); + }); + + describe('scroll event handling / tug of war prevention', function () { + test('listens when needed, unlistens when not needed', function (done) { + const on = sandbox.spy($.fn, 'on'); + const off = sandbox.spy($.fn, 'off'); + const jqLiteOn = sandbox.spy(angular.element.prototype, 'on'); + const jqLiteOff = sandbox.spy(angular.element.prototype, 'off'); + + const els = compile(1.5); + expect(on.callCount).toBe(1); + expect(jqLiteOn.callCount).toBe(1); + checkThisVals('$.fn.on', on, jqLiteOn); + + expect(off.callCount).toBe(0); + expect(jqLiteOff.callCount).toBe(0); + currentJqLiteWidth = els.$container.prop('scrollWidth'); + flushPendingTasks(); + expect(off.callCount).toBe(1); + expect(jqLiteOff.callCount).toBe(1); + checkThisVals('$.fn.off', off, jqLiteOff); + done(); + + function checkThisVals(namejQueryFn, spyjQueryFn, spyjqLiteFn) { + // the this values should be different + expect(spyjQueryFn.thisValues[0].is(spyjqLiteFn.thisValues[0])).toBeFalsy(); + // but they should be either $scroller or $container + const el = spyjQueryFn.thisValues[0]; + + if (el.is(els.$scroller) || el.is(els.$container)) return; + + done.fail('expected ' + namejQueryFn + ' to be called with $scroller or $container'); + } + }); + + // Turn off this row because tests failed. + // Scroll event is not catched in fixed_scroll. + // As container is jquery element in test but inside fixed_scroll it's a jqLite element. + // it would need jquery in jest to make this work. + [ + //{ from: '$container', to: '$scroller' }, + { from: '$scroller', to: '$container' }, + ].forEach(function (names) { + describe('scroll events ' + JSON.stringify(names), function () { + let spyJQueryScrollLeft; + let spyJQLiteScrollLeft; + let els; + let $from; + let $to; + + beforeEach(function () { + spyJQueryScrollLeft = sandbox.spy($.fn, 'scrollLeft'); + spyJQLiteScrollLeft = sandbox.stub(); + angular.element.prototype.scrollLeft = spyJQLiteScrollLeft; + els = compile(1.5); + $from = els[names.from]; + $to = els[names.to]; + }); + + test('transfers the scrollLeft', function () { + expect(spyJQueryScrollLeft.callCount).toBe(0); + expect(spyJQLiteScrollLeft.callCount).toBe(0); + $from.scroll(); + expect(spyJQueryScrollLeft.callCount).toBe(1); + expect(spyJQLiteScrollLeft.callCount).toBe(1); + + // first call should read the scrollLeft from the $container + const firstCall = spyJQueryScrollLeft.getCall(0); + expect(firstCall.args).toEqual([]); + + // second call should be setting the scrollLeft on the $scroller + const secondCall = spyJQLiteScrollLeft.getCall(0); + expect(secondCall.args).toEqual([firstCall.returnValue]); + }); + + /** + * In practice, calling $el.scrollLeft() causes the "scroll" event to trigger, + * but the browser seems to be very careful about triggering the event too much + * and I can't reliably recreate the browsers behavior in a test. So... faking it! + */ + test('prevents tug of war by ignoring echo scroll events', function () { + $from.scroll(); + expect(spyJQueryScrollLeft.callCount).toBe(1); + expect(spyJQLiteScrollLeft.callCount).toBe(1); + + spyJQueryScrollLeft.resetHistory(); + spyJQLiteScrollLeft.resetHistory(); + $to.scroll(); + expect(spyJQueryScrollLeft.callCount).toBe(0); + expect(spyJQLiteScrollLeft.callCount).toBe(0); + }); + }); + }); + }); +}); From 5d4827f14f25a017b5a7681d687d2dcadf08c9dc Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Tue, 21 Jul 2020 09:54:13 -0400 Subject: [PATCH 45/77] [Security Solution] Add margin (#72542) --- .../public/resolver/view/process_event_dot.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx index aab4193bf031d..503fd3d3dcef9 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx @@ -410,7 +410,7 @@ const UnstyledProcessEventDot = React.memo( alignSelf: 'flex-start', background: colorMap.resolverBackground, display: `${isShowingEventActions ? 'flex' : 'none'}`, - margin: 0, + margin: '2px 0 0 0', padding: 0, }} > From 2fc7112ec27a9f8ded0e2f9e097613721f1179dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Tue, 21 Jul 2020 15:55:43 +0200 Subject: [PATCH 46/77] [APM] Update script with new roles/users (#72599) * [APM] Update script with new roles/users * add log * Add validation for http prefix --- .../setup-custom-kibana-user-role.ts | 111 ++++++++++-------- 1 file changed, 64 insertions(+), 47 deletions(-) diff --git a/x-pack/plugins/apm/scripts/kibana-security/setup-custom-kibana-user-role.ts b/x-pack/plugins/apm/scripts/kibana-security/setup-custom-kibana-user-role.ts index 29acdb3e2a5cf..b0083da69cf85 100644 --- a/x-pack/plugins/apm/scripts/kibana-security/setup-custom-kibana-user-role.ts +++ b/x-pack/plugins/apm/scripts/kibana-security/setup-custom-kibana-user-role.ts @@ -6,27 +6,21 @@ /* eslint-disable no-console */ -import yaml from 'js-yaml'; import axios, { AxiosRequestConfig, AxiosError } from 'axios'; -import fs from 'fs'; import { union, difference, once } from 'lodash'; -import path from 'path'; import { argv } from 'yargs'; -const config = yaml.safeLoad( - fs.readFileSync( - path.join(__filename, '../../../../../../config/kibana.dev.yml'), - 'utf8' - ) -); - -const KIBANA_INDEX = config['kibana.index'] as string; -const TASK_MANAGER_INDEX = config['xpack.task_manager.index'] as string; -const KIBANA_ROLE_SUFFIX = argv.roleSuffix as string; +const KIBANA_ROLE_SUFFIX = argv.roleSuffix as string | undefined; const ELASTICSEARCH_USERNAME = (argv.username as string) || 'elastic'; -const ELASTICSEARCH_PASSWORD = (argv.password || - config['elasticsearch.password']) as string; -const KIBANA_BASE_URL = (argv.kibanaUrl as string) || 'http://localhost:5601'; +const ELASTICSEARCH_PASSWORD = argv.password as string | undefined; +const KIBANA_BASE_URL = argv.kibanaUrl as string | undefined; + +console.log({ + KIBANA_ROLE_SUFFIX, + ELASTICSEARCH_USERNAME, + ELASTICSEARCH_PASSWORD, + KIBANA_BASE_URL, +}); interface User { username: string; @@ -76,33 +70,26 @@ init().catch((e) => { }); async function init() { - const version = await getKibanaVersion(); - console.log(`Connected to Kibana ${version}`); - - const isKibanaLocal = KIBANA_BASE_URL.startsWith('http://localhost'); - - // kibana.index must be different from `.kibana` - if (isKibanaLocal && KIBANA_INDEX === '.kibana') { + if (!ELASTICSEARCH_PASSWORD) { console.log( - 'kibana.dev.yml: Please use a custom "kibana.index". Example: "kibana.index: .kibana-john"' + 'Please specify credentials for elasticsearch: `--username elastic --password abcd` ' ); return; } - if (isKibanaLocal && !KIBANA_INDEX.startsWith('.kibana')) { + if (!KIBANA_BASE_URL) { console.log( - 'kibana.dev.yml: "kibana.index" must be prefixed with `.kibana`. Example: "kibana.index: .kibana-john"' + 'Please specify the url for Kibana: `--kibana-url http://localhost:5601` ' ); return; } if ( - isKibanaLocal && - TASK_MANAGER_INDEX && - !TASK_MANAGER_INDEX.startsWith('.kibana') + !KIBANA_BASE_URL.startsWith('https://') && + !KIBANA_BASE_URL.startsWith('http://') ) { console.log( - 'kibana.dev.yml: "xpack.task_manager.index" must be prefixed with `.kibana`. Example: "xpack.task_manager.index: .kibana-task-manager-john"' + 'Kibana url must be prefixed with http(s):// `--kibana-url http://localhost:5601`' ); return; } @@ -114,35 +101,50 @@ async function init() { return; } + const version = await getKibanaVersion(); + console.log(`Connected to Kibana ${version}`); + const isEnabled = await isSecurityEnabled(); if (!isEnabled) { console.log('Security must be enabled!'); return; } + const APM_READ_ROLE = `apm_read_${KIBANA_ROLE_SUFFIX}`; const KIBANA_READ_ROLE = `kibana_read_${KIBANA_ROLE_SUFFIX}`; const KIBANA_WRITE_ROLE = `kibana_write_${KIBANA_ROLE_SUFFIX}`; + const APM_USER_ROLE = 'apm_user'; // create roles - await createRole({ roleName: KIBANA_READ_ROLE, privilege: 'read' }); - await createRole({ roleName: KIBANA_WRITE_ROLE, privilege: 'all' }); + await createRole({ + roleName: APM_READ_ROLE, + kibanaPrivileges: { feature: { apm: ['read'] } }, + }); + await createRole({ + roleName: KIBANA_READ_ROLE, + kibanaPrivileges: { base: ['read'] }, + }); + await createRole({ + roleName: KIBANA_WRITE_ROLE, + kibanaPrivileges: { base: ['all'] }, + }); - // read/write access to all apps + apm index access + // read access only to APM + apm index access await createOrUpdateUser({ - username: 'apm_write_user', - roles: ['apm_user', KIBANA_WRITE_ROLE], + username: 'apm_read_user', + roles: [APM_USER_ROLE, APM_READ_ROLE], }); // read access to all apps + apm index access await createOrUpdateUser({ - username: 'apm_read_user', - roles: ['apm_user', KIBANA_READ_ROLE], + username: 'kibana_read_user', + roles: [APM_USER_ROLE, KIBANA_READ_ROLE], }); - // read/write access to all apps (no apm index access) + // read/write access to all apps + apm index access await createOrUpdateUser({ username: 'kibana_write_user', - roles: [KIBANA_WRITE_ROLE], + roles: [APM_USER_ROLE, KIBANA_WRITE_ROLE], }); } @@ -159,7 +161,12 @@ async function isSecurityEnabled() { async function callKibana(options: AxiosRequestConfig): Promise { const kibanaBasePath = await getKibanaBasePath(); - const reqOptions = { + + if (!ELASTICSEARCH_PASSWORD) { + throw new Error('Missing `--password`'); + } + + const { data } = await axios.request({ ...options, baseURL: KIBANA_BASE_URL + kibanaBasePath, auth: { @@ -167,18 +174,18 @@ async function callKibana(options: AxiosRequestConfig): Promise { password: ELASTICSEARCH_PASSWORD, }, headers: { 'kbn-xsrf': 'true', ...options.headers }, - }; - - const { data } = await axios.request(reqOptions); + }); return data; } +type Privilege = [] | ['read'] | ['all']; + async function createRole({ roleName, - privilege, + kibanaPrivileges, }: { roleName: string; - privilege: 'read' | 'all'; + kibanaPrivileges: { base?: Privilege; feature?: Record }; }) { const role = await getRole(roleName); if (role) { @@ -192,11 +199,21 @@ async function createRole({ data: { metadata: { version: 1 }, elasticsearch: { cluster: [], indices: [] }, - kibana: [{ base: [privilege], feature: {}, spaces: ['*'] }], + kibana: [ + { + base: kibanaPrivileges.base ?? [], + feature: kibanaPrivileges.feature ?? {}, + spaces: ['*'], + }, + ], }, }); - console.log(`Created role "${roleName}" with privilege "${privilege}"`); + console.log( + `Created role "${roleName}" with privilege "${JSON.stringify( + kibanaPrivileges + )}"` + ); } async function createOrUpdateUser(newUser: User) { From 9facf416f5ce4dc6a818fa2de45242986ce1b836 Mon Sep 17 00:00:00 2001 From: Devon Thomson Date: Tue, 21 Jul 2020 09:56:13 -0400 Subject: [PATCH 47/77] Applying tiny fix from 72532 to main branch (#72533) --- .../editor_frame_service/embeddable/embeddable_factory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts index f9685dac32e23..9a901d3631ec3 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts @@ -102,7 +102,7 @@ export class EmbeddableFactory implements EmbeddableFactoryDefinition { { savedVis, editPath: getEditPath(savedObjectId), - editUrl: coreHttp.basePath.prepend(`app/lens${getEditPath(savedObjectId)}`), + editUrl: coreHttp.basePath.prepend(`/app/lens${getEditPath(savedObjectId)}`), editable: await this.isEditable(), indexPatterns, }, From 05ee3da80db34ccf93e7424aa2704c098a1b49fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Tue, 21 Jul 2020 15:56:43 +0200 Subject: [PATCH 48/77] =?UTF-8?q?[APM]=20Disable=20flaky=20rum=20e2e?= =?UTF-8?q?=E2=80=99s=20(#72614)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{rum_dashboard.feature => rum_dashboard.feature.disabled} | 0 x-pack/plugins/apm/e2e/run-e2e.sh | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename x-pack/plugins/apm/e2e/cypress/integration/{rum_dashboard.feature => rum_dashboard.feature.disabled} (100%) diff --git a/x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature b/x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature.disabled similarity index 100% rename from x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature rename to x-pack/plugins/apm/e2e/cypress/integration/rum_dashboard.feature.disabled diff --git a/x-pack/plugins/apm/e2e/run-e2e.sh b/x-pack/plugins/apm/e2e/run-e2e.sh index bc64f2b009d52..6cdae93aec63b 100755 --- a/x-pack/plugins/apm/e2e/run-e2e.sh +++ b/x-pack/plugins/apm/e2e/run-e2e.sh @@ -18,8 +18,8 @@ normal=$(tput sgr0) # paths E2E_DIR="${0%/*}" -TMP_DIR="./tmp" -APM_IT_DIR="./tmp/apm-integration-testing" +TMP_DIR="tmp" +APM_IT_DIR="tmp/apm-integration-testing" cd ${E2E_DIR} From 1cde692ab71297a4cc8f2240a3e744efc1ff2f8d Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Tue, 21 Jul 2020 07:04:06 -0700 Subject: [PATCH 49/77] Add Upgrade Assistant API integration test to ensure the reindex operation saved object can handle immense error messages (#72347) --- x-pack/test/api_integration/apis/index.js | 1 + .../apis/upgrade_assistant/index.ts | 13 +++++++ ...ndex_operation_with_large_error_message.ts | 21 ++++++++++++ .../upgrade_assistant/upgrade_assistant.ts | 34 +++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 x-pack/test/api_integration/apis/upgrade_assistant/index.ts create mode 100644 x-pack/test/api_integration/apis/upgrade_assistant/reindex_operation_with_large_error_message.ts create mode 100644 x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts diff --git a/x-pack/test/api_integration/apis/index.js b/x-pack/test/api_integration/apis/index.js index aeea062bdb85d..ce0e534d8a750 100644 --- a/x-pack/test/api_integration/apis/index.js +++ b/x-pack/test/api_integration/apis/index.js @@ -32,5 +32,6 @@ export default function ({ loadTestFile }) { loadTestFile(require.resolve('./endpoint')); loadTestFile(require.resolve('./ingest_manager')); loadTestFile(require.resolve('./lists')); + loadTestFile(require.resolve('./upgrade_assistant')); }); } diff --git a/x-pack/test/api_integration/apis/upgrade_assistant/index.ts b/x-pack/test/api_integration/apis/upgrade_assistant/index.ts new file mode 100644 index 0000000000000..6dfb32327b184 --- /dev/null +++ b/x-pack/test/api_integration/apis/upgrade_assistant/index.ts @@ -0,0 +1,13 @@ +/* + * 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 { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('Upgrade Assistant', () => { + loadTestFile(require.resolve('./upgrade_assistant')); + }); +} diff --git a/x-pack/test/api_integration/apis/upgrade_assistant/reindex_operation_with_large_error_message.ts b/x-pack/test/api_integration/apis/upgrade_assistant/reindex_operation_with_large_error_message.ts new file mode 100644 index 0000000000000..4664295c0a4a1 --- /dev/null +++ b/x-pack/test/api_integration/apis/upgrade_assistant/reindex_operation_with_large_error_message.ts @@ -0,0 +1,21 @@ +/* + * 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 const reindexOperationWithLargeErrorMessage = { + 'upgrade-assistant-reindex-operation': { + indexName: 'filebeat-2019', + newIndexName: 'reindexed-v7-filebeat-2019', + status: 2, + lastCompletedStep: 40, + locked: null, + reindexTaskId: 'MrzNyPknSyCk6WnmIJeLyQ:151888', + reindexTaskPercComplete: 0, + // eslint-disable-next-line + errorMessage: 'Error: Reindexing failed: {\"completed\":true,\"task\":{\"node\":\"MrzNyPknSyCk6WnmIJeLyQ\",\"id\":151888,\"type\":\"transport\",\"action\":\"indices:data/write/reindex\",\"status\":{\"total\":12031,\"updated\":0,\"created\":0,\"deleted\":0,\"batches\":1,\"version_conflicts\":0,\"noops\":0,\"retries\":{\"bulk\":0,\"search\":0},\"throttled_millis\":0,\"requests_per_second\":-1,\"throttled_until_millis\":0},\"description\":\"reindex from [filebeat-2019] to [reindexed-v7-filebeat-2019][_doc]\",\"start_time_in_millis\":1565576543962,\"running_time_in_nanos\":139827660,\"cancellable\":true,\"headers\":{}},\"response\":{\"took\":139,\"timed_out\":false,\"total\":12031,\"updated\":0,\"created\":0,\"deleted\":0,\"batches\":1,\"version_conflicts\":0,\"noops\":0,\"retries\":{\"bulk\":0,\"search\":0},\"throttled\":\"0s\",\"throttled_millis\":0,\"requests_per_second\":-1,\"throttled_until\":\"0s\",\"throttled_until_millis\":0,\"failures\":[{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"WWcIB2gBP1edM8bXWzIA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'WWcIB2gBP1edM8bXWzIA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T01:30:08,792] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ub6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ub6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,712] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"WmcIB2gBP1edM8bXWzIA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'WmcIB2gBP1edM8bXWzIA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T01:30:10,143] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ur6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ur6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,715] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"yWcIB2gBP1edM8bXbTI3\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'yWcIB2gBP1edM8bXbTI3\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T01:30:10,144] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"u76zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'u76zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,716] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xmuoCGgBP1edM8bXjNTs\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xmuoCGgBP1edM8bXjNTs\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:04:44,179] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vL6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vL6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,717] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"x2uoCGgBP1edM8bXjNTs\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'x2uoCGgBP1edM8bXjNTs\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:04:44,180] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vb6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vb6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,727] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Y2umCGgBP1edM8bXCM1f\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Y2umCGgBP1edM8bXCM1f\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:02:04,196] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vr6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vr6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,728] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ZGumCGgBP1edM8bXCM1f\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ZGumCGgBP1edM8bXCM1f\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:02:04,197] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"v76zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'v76zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,728] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"zGuoCGgBP1edM8bXoNR0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'zGuoCGgBP1edM8bXoNR0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:04:44,180] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"wL6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'wL6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,729] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xmuqCGgBP1edM8bX_dvy\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xmuqCGgBP1edM8bX_dvy\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:07:24,176] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"wb6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'wb6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,715] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"y2urCGgBP1edM8bXEdt8\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'y2urCGgBP1edM8bXEdt8\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:07:24,177] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"wr6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'wr6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,731] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0GumCGgBP1edM8bXG83n\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0GumCGgBP1edM8bXG83n\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:02:04,197] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"w76zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'w76zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,732] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EmulCGgBP1edM8bXk8wr\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EmulCGgBP1edM8bXk8wr\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:01:24,172] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xL6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xL6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,735] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3WupCGgBP1edM8bXsdfn\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3WupCGgBP1edM8bXsdfn\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:06:04,163] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xb6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xb6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,735] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"SmupCGgBP1edM8bXxdhv\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'SmupCGgBP1edM8bXxdhv\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:06:04,164] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xr6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xr6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,739] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"KGuwCGgBP1edM8bXaOvE\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'KGuwCGgBP1edM8bXaOvE\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:13:24,170] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"x76zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'x76zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,740] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"KWuwCGgBP1edM8bXaOvE\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'KWuwCGgBP1edM8bXaOvE\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:13:24,171] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"yL6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'yL6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,743] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0WuvCGgBP1edM8bX4OkJ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0WuvCGgBP1edM8bX4OkJ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:12:44,182] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"yb6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'yb6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,744] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1muvCGgBP1edM8bX8-mR\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1muvCGgBP1edM8bX8-mR\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:12:44,183] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"yr6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'yr6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,744] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lWuwCGgBP1edM8bXfOtL\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lWuwCGgBP1edM8bXfOtL\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:13:24,171] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"y76zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'y76zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,747] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UGuuCGgBP1edM8bXp-aj\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UGuuCGgBP1edM8bXp-aj\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:11:24,189] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"zL6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'zL6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,748] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"VWuuCGgBP1edM8bXu-YM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'VWuuCGgBP1edM8bXu-YM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:11:24,190] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"zb6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'zb6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,751] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"8GuvCGgBP1edM8bXkejm\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'8GuvCGgBP1edM8bXkejm\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:12:24,178] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"zr6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'zr6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,752] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kGuuCGgBP1edM8bXC-RA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kGuuCGgBP1edM8bXC-RA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:10:44,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"z76zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'z76zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,755] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hGuvCGgBP1edM8bXfuhe\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hGuvCGgBP1edM8bXfuhe\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:12:24,177] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0L6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0L6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,756] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0WzHCGgBP1edM8bXXyzY\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0WzHCGgBP1edM8bXXyzY\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:38:24,178] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0b6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0b6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,759] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0mzHCGgBP1edM8bXXyzY\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0mzHCGgBP1edM8bXXyzY\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:38:24,179] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0r6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0r6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,763] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"12zHCGgBP1edM8bXcyxh\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'12zHCGgBP1edM8bXcyxh\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:38:24,181] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"076zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'076zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,764] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"x2zDCGgBP1edM8bX8SKV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'x2zDCGgBP1edM8bX8SKV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:34:44,233] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1L6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1L6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,764] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"M2zECGgBP1edM8bXBCNx\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'M2zECGgBP1edM8bXBCNx\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:34:44,234] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1b6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1b6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,767] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"MmzGCGgBP1edM8bXdSp1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'MmzGCGgBP1edM8bXdSp1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:37:24,168] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1r6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1r6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,768] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xmzGCGgBP1edM8bXYSnu\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xmzGCGgBP1edM8bXYSnu\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:37:24,168] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"176zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'176zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,771] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cGzFCGgBP1edM8bX2Sg0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cGzFCGgBP1edM8bX2Sg0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:36:44,171] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"2L6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'2L6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,775] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dWzFCGgBP1edM8bX7Ci8\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dWzFCGgBP1edM8bX7Ci8\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:36:44,172] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"2b6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'2b6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,776] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"SWzHCGgBP1edM8bXmi1y\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'SWzHCGgBP1edM8bXmi1y\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T09:38:44,228] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"2r6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'2r6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,777] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"WGzwCGgBP1edM8bXk6IO\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'WGzwCGgBP1edM8bXk6IO\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:23:24,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"276zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'276zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,779] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"WWzwCGgBP1edM8bXk6IO\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'WWzwCGgBP1edM8bXk6IO\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:23:24,205] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3L6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3L6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,783] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0WzwCGgBP1edM8bXzaKs\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0WzwCGgBP1edM8bXzaKs\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:23:44,215] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3b6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3b6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,787] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0mzwCGgBP1edM8bXzaKs\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0mzwCGgBP1edM8bXzaKs\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:23:44,216] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3r6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3r6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,788] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1mzvCGgBP1edM8bXWp6K\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1mzvCGgBP1edM8bXWp6K\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:22:04,200] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"376zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'376zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,733] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"PmzwCGgBP1edM8bX4aMx\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'PmzwCGgBP1edM8bX4aMx\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:23:44,217] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4L6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4L6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,791] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"22zvCGgBP1edM8bXbp4T\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'22zvCGgBP1edM8bXbp4T\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:22:04,201] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4b6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4b6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,797] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"XmzwCGgBP1edM8bXpqKY\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'XmzwCGgBP1edM8bXpqKY\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:23:24,205] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4r6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4r6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,798] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"FmzuCGgBP1edM8bXvp1I\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'FmzuCGgBP1edM8bXvp1I\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:21:24,223] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"476zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'476zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,792] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"CWzwCGgBP1edM8bXMaFn\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'CWzwCGgBP1edM8bXMaFn\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:23:04,193] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5L6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5L6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,799] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dmzwCGgBP1edM8bXRKHz\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dmzwCGgBP1edM8bXRKHz\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:23:04,194] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5b6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5b6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,800] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EGz2CGgBP1edM8bXEbJo\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EGz2CGgBP1edM8bXEbJo\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:29:24,224] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5r6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5r6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,803] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EWz2CGgBP1edM8bXEbJo\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EWz2CGgBP1edM8bXEbJo\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:29:24,225] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"576zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'576zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,804] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Z2z2CGgBP1edM8bXmrMV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Z2z2CGgBP1edM8bXmrMV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:30:04,202] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"6L6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'6L6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,805] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"aGz2CGgBP1edM8bXmrMV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'aGz2CGgBP1edM8bXmrMV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:30:04,203] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"6b6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'6b6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,806] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"imzzCGgBP1edM8bX2qvw\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'imzzCGgBP1edM8bX2qvw\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:27:04,210] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"6r6zJWgBP1edM8bXctF2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'6r6zJWgBP1edM8bXctF2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,813] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"i2zzCGgBP1edM8bX2qvw\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'i2zzCGgBP1edM8bX2qvw\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:27:04,211] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"676zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'676zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:40,626] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1Wz2CGgBP1edM8bXrbOd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1Wz2CGgBP1edM8bXrbOd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:30:04,203] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"7L6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'7L6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,088] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Fmz2CGgBP1edM8bXJLLl\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Fmz2CGgBP1edM8bXJLLl\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:29:24,225] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"7b6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'7b6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,592] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4WzxCGgBP1edM8bX36Ue\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4WzxCGgBP1edM8bX36Ue\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:24:44,215] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"7r6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'7r6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,590] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lGz3CGgBP1edM8bXSbXe\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lGz3CGgBP1edM8bXSbXe\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:30:44,193] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"776zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'776zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,605] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3GzxCGgBP1edM8bXy6WU\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3GzxCGgBP1edM8bXy6WU\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:24:44,214] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"8L6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'8L6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,605] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-GzzCGgBP1edM8bX7qt5\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-GzzCGgBP1edM8bX7qt5\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T10:27:04,212] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"8b6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'8b6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,611] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fnrGDWgBP1edM8bX9nN0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fnrGDWgBP1edM8bX9nN0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T08:56:04,203] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"8r6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'8r6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,613] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"f3rGDWgBP1edM8bX9nN0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'f3rGDWgBP1edM8bX9nN0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T08:56:04,203] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"876zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'876zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,617] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AXq6DWgBP1edM8bXS0_E\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AXq6DWgBP1edM8bXS0_E\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T08:42:09,899] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9L6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9L6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,617] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_Xq6DWgBP1edM8bXOE47\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_Xq6DWgBP1edM8bXOE47\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T08:42:09,166] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9b6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9b6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,647] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"rHq5DWgBP1edM8bXw00K\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'rHq5DWgBP1edM8bXw00K\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T08:41:31,488] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9r6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9r6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,648] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"V3GLCmgBP1edM8bXgjTB\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'V3GLCmgBP1edM8bXgjTB\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-01T17:52:15,311] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"976zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'976zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,649] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"g3rHDWgBP1edM8bXCXO3\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'g3rHDWgBP1edM8bXCXO3\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T08:56:04,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-L6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-L6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,649] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"THUeDGgBP1edM8bX-bs8\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'THUeDGgBP1edM8bX-bs8\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T01:12:56,601] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-b6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-b6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,650] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4HUeDGgBP1edM8bX5rpU\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4HUeDGgBP1edM8bX5rpU\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T01:12:56,466] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-r6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-r6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,647] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"qHq5DWgBP1edM8bXsE0Y\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'qHq5DWgBP1edM8bXsE0Y\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T08:41:31,487] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-76zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-76zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,651] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"NnrYDWgBP1edM8bXDqRl\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'NnrYDWgBP1edM8bXDqRl\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:14:44,217] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_L6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_L6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,653] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"N3rYDWgBP1edM8bXDqRl\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'N3rYDWgBP1edM8bXDqRl\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:14:44,218] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_b6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_b6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,655] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UXrZDWgBP1edM8bXRaf5\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UXrZDWgBP1edM8bXRaf5\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:16:04,193] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_r6zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_r6zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,656] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UnrZDWgBP1edM8bXRaf5\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UnrZDWgBP1edM8bXRaf5\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:16:04,194] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_76zJWgBP1edM8bXctH1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_76zJWgBP1edM8bXctH1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,652] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"QHraDWgBP1edM8bXfqt9\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'QHraDWgBP1edM8bXfqt9\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:17:24,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AL6zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AL6zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,661] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"QXraDWgBP1edM8bXfqt9\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'QXraDWgBP1edM8bXfqt9\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:17:24,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Ab6zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Ab6zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,662] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"O3rYDWgBP1edM8bXIKT8\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'O3rYDWgBP1edM8bXIKT8\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:14:44,218] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Ar6zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Ar6zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,665] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_3rYDWgBP1edM8bX0KXG\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_3rYDWgBP1edM8bX0KXG\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:15:24,164] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"A76zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'A76zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,665] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ZHraDWgBP1edM8bXV6pr\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ZHraDWgBP1edM8bXV6pr\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:17:04,192] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"BL6zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'BL6zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,666] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-3rYDWgBP1edM8bXvaU9\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-3rYDWgBP1edM8bXvaU9\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:15:24,163] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Bb6zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Bb6zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,671] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"YHraDWgBP1edM8bXQ6rj\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'YHraDWgBP1edM8bXQ6rj\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:17:04,191] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Br6zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Br6zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,672] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"v3rZDWgBP1edM8bXWaeA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'v3rZDWgBP1edM8bXWaeA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:16:04,194] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"B76zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'B76zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,663] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3XrlDWgBP1edM8bXQMmM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3XrlDWgBP1edM8bXQMmM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:29:04,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"CL6zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'CL6zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,674] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3nrlDWgBP1edM8bXQMmM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3nrlDWgBP1edM8bXQMmM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:29:04,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Cb6zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Cb6zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,676] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lnsBDmgBP1edM8bX3Ru0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lnsBDmgBP1edM8bX3Ru0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:00:24,333] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Cr6zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Cr6zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,678] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"l3sBDmgBP1edM8bX3Ru0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'l3sBDmgBP1edM8bX3Ru0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:00:24,334] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"C76zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'C76zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,683] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AnriDWgBP1edM8bXgcJl\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AnriDWgBP1edM8bXgcJl\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:26:04,195] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"DL6zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'DL6zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,684] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"BnriDWgBP1edM8bXlMLt\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'BnriDWgBP1edM8bXlMLt\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:26:04,196] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Db6zJWgBP1edM8bXctL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Db6zJWgBP1edM8bXctL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,684] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4nrlDWgBP1edM8bXVMkU\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4nrlDWgBP1edM8bXVMkU\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:29:04,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Dr6zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Dr6zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,685] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"W3sCDmgBP1edM8bXjB3u\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'W3sCDmgBP1edM8bXjB3u\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:01:04,179] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"D76zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'D76zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,677] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5XriDWgBP1edM8bXz8KI\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5XriDWgBP1edM8bXz8KI\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:26:24,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EL6zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EL6zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,686] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"eHriDWgBP1edM8bXu8L_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'eHriDWgBP1edM8bXu8L_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T09:26:24,184] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Eb6zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Eb6zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,687] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"m3sBDmgBP1edM8bX8Rse\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'m3sBDmgBP1edM8bX8Rse\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:00:24,334] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Er6zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Er6zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,691] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"GnsIDmgBP1edM8bXCy09\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'GnsIDmgBP1edM8bXCy09\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:07:04,171] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"E76zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'E76zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,695] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"G3sIDmgBP1edM8bXCy09\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'G3sIDmgBP1edM8bXCy09\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:07:04,172] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"FL6zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'FL6zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,696] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"tHsLDmgBP1edM8bXUzYg\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'tHsLDmgBP1edM8bXUzYg\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:10:44,174] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Fb6zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Fb6zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,697] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"tXsLDmgBP1edM8bXUzYg\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'tXsLDmgBP1edM8bXUzYg\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:10:44,175] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Fr6zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Fr6zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,699] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"D3sKDmgBP1edM8bXaDS6\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'D3sKDmgBP1edM8bXaDS6\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:09:44,335] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"F76zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'F76zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,700] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EHsKDmgBP1edM8bXaDS6\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EHsKDmgBP1edM8bXaDS6\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:09:44,335] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"GL6zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'GL6zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,703] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"iHsIDmgBP1edM8bXHi3G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'iHsIDmgBP1edM8bXHi3G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:07:04,172] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Gb6zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Gb6zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,705] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"WXsHDmgBP1edM8bXbysD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'WXsHDmgBP1edM8bXbysD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:06:24,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Gr6zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Gr6zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,705] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"FHsKDmgBP1edM8bXfDRC\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'FHsKDmgBP1edM8bXfDRC\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:09:44,336] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"G76zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'G76zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,688] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Y3sKDmgBP1edM8bX3TXu\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Y3sKDmgBP1edM8bX3TXu\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:10:04,162] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"HL6zJWgBP1edM8bXctL2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'HL6zJWgBP1edM8bXctL2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,707] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9nsKDmgBP1edM8bXyjRm\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9nsKDmgBP1edM8bXyjRm\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:10:04,161] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Hb6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Hb6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,799] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"VXsHDmgBP1edM8bXWytz\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'VXsHDmgBP1edM8bXWytz\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:06:24,184] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Hr6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Hr6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,815] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"BHsPDmgBP1edM8bXrEN3\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'BHsPDmgBP1edM8bXrEN3\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:15:24,196] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"H76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'H76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,817] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"BXsPDmgBP1edM8bXrEN3\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'BXsPDmgBP1edM8bXrEN3\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:15:24,197] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"IL6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'IL6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,818] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"LnsNDmgBP1edM8bX6z45\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'LnsNDmgBP1edM8bX6z45\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:13:24,177] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Ib6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Ib6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,823] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"PHsfDmgBP1edM8bXeHBQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'PHsfDmgBP1edM8bXeHBQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:32:44,306] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Ir6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Ir6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,814] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"QHsfDmgBP1edM8bXi3At\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'QHsfDmgBP1edM8bXi3At\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:32:44,307] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"I76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'I76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,837] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cnsPDmgBP1edM8bXwEMA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cnsPDmgBP1edM8bXwEMA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:15:24,197] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"JL6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'JL6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,838] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AHsgDmgBP1edM8bXJ3Jv\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AHsgDmgBP1edM8bXJ3Jv\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:33:24,188] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Jb6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Jb6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,837] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"oHsODmgBP1edM8bXEj5M\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'oHsODmgBP1edM8bXEj5M\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:13:44,177] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Jr6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Jr6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,839] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"pHsODmgBP1edM8bXJT7T\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'pHsODmgBP1edM8bXJT7T\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:13:44,177] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"J76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'J76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,840] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"wXsNDmgBP1edM8bX1z2y\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'wXsNDmgBP1edM8bX1z2y\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:13:24,176] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"KL6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'KL6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,844] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"X3smDmgBP1edM8bXm4Te\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'X3smDmgBP1edM8bXm4Te\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:40:24,175] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Kb6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Kb6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,846] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"YHsmDmgBP1edM8bXm4Te\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'YHsmDmgBP1edM8bXm4Te\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:40:36,621] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Kr6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Kr6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,847] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_HsnDmgBP1edM8bXcoa5\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_HsnDmgBP1edM8bXcoa5\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:41:24,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"K76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'K76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,855] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_XsnDmgBP1edM8bXcoa5\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_XsnDmgBP1edM8bXcoa5\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:41:24,206] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"LL6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'LL6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,856] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"WnsmDmgBP1edM8bXkIQm\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'WnsmDmgBP1edM8bXkIQm\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:40:24,174] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Lb6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Lb6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,857] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"W3smDmgBP1edM8bXkIQm\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'W3smDmgBP1edM8bXkIQm\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:40:24,175] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Lr6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Lr6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,858] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dXsnDmgBP1edM8bXrYdU\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dXsnDmgBP1edM8bXrYdU\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:41:44,189] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"L76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'L76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,846] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dnsnDmgBP1edM8bXrYdU\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dnsnDmgBP1edM8bXrYdU\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:41:44,190] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ML6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ML6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,867] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"zHsmDmgBP1edM8bXr4Rm\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'zHsmDmgBP1edM8bXr4Rm\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:40:36,622] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Mb6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Mb6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,863] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AnsnDmgBP1edM8bXhodB\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AnsnDmgBP1edM8bXhodB\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:41:24,207] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Mr6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Mr6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,882] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dHsmDmgBP1edM8bXLoN8\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dHsmDmgBP1edM8bXLoN8\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:40:04,171] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"M76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'M76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,884] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"eHsmDmgBP1edM8bXQoME\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'eHsmDmgBP1edM8bXQoME\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:40:04,172] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"NL6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'NL6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,886] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4nsnDmgBP1edM8bXwIfb\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4nsnDmgBP1edM8bXwIfb\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-02T10:41:44,190] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Nb6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Nb6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,888] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"QYc4EmgBP1edM8bXKyWs\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'QYc4EmgBP1edM8bXKyWs\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-03T05:38:05,730] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Nr6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Nr6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,891] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"yJToFmgBP1edM8bXBIlI\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'yJToFmgBP1edM8bXBIlI\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T03:28:44,660] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"N76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'N76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,884] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xJTnFmgBP1edM8bX8Ym-\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xJTnFmgBP1edM8bX8Ym-\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T03:28:44,479] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"OL6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'OL6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,893] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ZI8WFWgBP1edM8bXYFDI\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ZI8WFWgBP1edM8bXYFDI\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-03T19:00:07,762] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Ob6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Ob6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,899] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"aI8WFWgBP1edM8bXc1Dn\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'aI8WFWgBP1edM8bXc1Dn\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-03T19:00:07,763] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Or6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Or6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,902] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hpCnFWgBP1edM8bXavHK\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hpCnFWgBP1edM8bXavHK\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-03T21:38:25,222] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"O76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'O76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,903] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"co2NFGgBP1edM8bX4ss3\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'co2NFGgBP1edM8bX4ss3\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-03T16:31:00,752] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"PL6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'PL6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,904] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hJCnFWgBP1edM8bXWPEZ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hJCnFWgBP1edM8bXWPEZ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-03T21:38:25,221] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Pb6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Pb6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,906] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kYdOEmgBP1edM8bXwWXL\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kYdOEmgBP1edM8bXwWXL\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-03T06:02:43,588] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Pr6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Pr6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,911] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"RpVOF2gBP1edM8bX8a_D\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'RpVOF2gBP1edM8bX8a_D\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T05:21:11,967] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"P76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'P76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,914] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"R5VOF2gBP1edM8bX8a_D\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'R5VOF2gBP1edM8bX8a_D\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T05:21:13,240] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"QL6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'QL6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,902] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"SJVOF2gBP1edM8bX8a_D\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'SJVOF2gBP1edM8bX8a_D\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T05:21:13,241] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Qb6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Qb6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,923] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"e5fMF2gBP1edM8bXYBR0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'e5fMF2gBP1edM8bXYBR0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T07:38:10,221] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Qr6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Qr6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,925] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fJfMF2gBP1edM8bXYBR0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fJfMF2gBP1edM8bXYBR0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T07:38:10,222] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Q76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Q76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,926] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fZfMF2gBP1edM8bXYBR0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fZfMF2gBP1edM8bXYBR0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T07:38:10,222] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"RL6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'RL6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,924] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"OpcXGGgBP1edM8bXweua\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'OpcXGGgBP1edM8bXweua\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:00:24,173] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Rb6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Rb6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,927] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ypcXGGgBP1edM8bXruoP\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ypcXGGgBP1edM8bXruoP\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:00:24,173] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Rr6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Rr6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,928] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"TJVPF2gBP1edM8bXBK-g\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'TJVPF2gBP1edM8bXBK-g\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T05:21:13,241] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"R76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'R76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,935] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fpfMF2gBP1edM8bXcxRp\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fpfMF2gBP1edM8bXcxRp\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T07:38:10,330] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"SL6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'SL6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,936] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"d5cXGGgBP1edM8bXJenY\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'d5cXGGgBP1edM8bXJenY\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T08:59:51,298] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Sb6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Sb6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,939] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"eZcXGGgBP1edM8bXOOnd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'eZcXGGgBP1edM8bXOOnd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T08:59:51,299] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Sr6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Sr6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,940] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"D5VCF2gBP1edM8bXqYwC\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'D5VCF2gBP1edM8bXqYwC\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T05:07:44,837] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"S76zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'S76zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,947] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lJcaGGgBP1edM8bXp_PR\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lJcaGGgBP1edM8bXp_PR\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:03:44,177] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"TL6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'TL6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,948] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lZcaGGgBP1edM8bXp_PR\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lZcaGGgBP1edM8bXp_PR\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:03:44,178] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Tb6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Tb6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,951] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"rZcXGGgBP1edM8bX6Ouo\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'rZcXGGgBP1edM8bX6Ouo\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:00:44,194] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Tr6zJWgBP1edM8bXc9Id\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Tr6zJWgBP1edM8bXc9Id\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,959] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"rpcXGGgBP1edM8bX6Ouo\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'rpcXGGgBP1edM8bX6Ouo\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:00:44,195] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"T76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'T76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,961] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"35cYGGgBP1edM8bXq-39\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'35cYGGgBP1edM8bXq-39\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:01:24,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,963] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"b5cYGGgBP1edM8bXmO1y\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'b5cYGGgBP1edM8bXmO1y\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:01:24,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Ub6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Ub6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,928] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"r5cXGGgBP1edM8bX_Osx\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'r5cXGGgBP1edM8bX_Osx\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:00:44,195] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Ur6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Ur6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,975] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9JcZGGgBP1edM8bX0PD3\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9JcZGGgBP1edM8bX0PD3\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:02:44,191] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"U76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'U76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,976] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ZJcZGGgBP1edM8bX5PGH\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ZJcZGGgBP1edM8bX5PGH\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:02:44,192] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"VL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'VL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,976] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UZcYGGgBP1edM8bX0-4k\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UZcYGGgBP1edM8bX0-4k\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:01:44,174] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Vb6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Vb6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,983] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UpcYGGgBP1edM8bX5u6V\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UpcYGGgBP1edM8bX5u6V\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:01:44,174] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Vr6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Vr6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,984] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1pghGGgBP1edM8bXcgYu\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1pghGGgBP1edM8bXcgYu\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:11:04,172] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"V76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'V76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,985] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"15ghGGgBP1edM8bXcgYu\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'15ghGGgBP1edM8bXcgYu\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:11:04,173] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"WL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'WL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,987] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"2pcfGGgBP1edM8bXAf8o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'2pcfGGgBP1edM8bXAf8o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:08:24,196] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Wb6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Wb6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,988] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"SpgfGGgBP1edM8bXFACx\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'SpgfGGgBP1edM8bXFACx\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:08:24,197] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Wr6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Wr6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,992] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"R5ghGGgBP1edM8bXhQe7\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'R5ghGGgBP1edM8bXhQe7\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:11:04,173] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"W76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'W76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,995] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"m5giGGgBP1edM8bXDghw\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'m5giGGgBP1edM8bXDghw\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:11:44,187] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"XL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'XL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,999] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vJgfGGgBP1edM8bXOwDC\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vJgfGGgBP1edM8bXOwDC\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:08:44,182] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Xb6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Xb6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,000] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vZgfGGgBP1edM8bXTwBK\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vZgfGGgBP1edM8bXTwBK\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:08:44,183] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Xr6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Xr6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,003] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"uZghGGgBP1edM8bXrAfK\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'uZghGGgBP1edM8bXrAfK\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:11:24,178] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"X76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'X76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,004] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"upghGGgBP1edM8bXwAdP\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'upghGGgBP1edM8bXwAdP\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:11:24,179] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"YL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'YL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:43,975] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"tZg3GGgBP1edM8bXHURQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'tZg3GGgBP1edM8bXHURQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:34:44,181] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Yb6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Yb6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,026] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"tpg3GGgBP1edM8bXHURQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'tpg3GGgBP1edM8bXHURQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:34:44,182] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Yr6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Yr6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,032] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kJg5GGgBP1edM8bX3Ex1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kJg5GGgBP1edM8bX3Ex1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:37:44,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Y76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Y76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,032] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kZg5GGgBP1edM8bX3Ex1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kZg5GGgBP1edM8bX3Ex1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:37:44,187] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ZL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ZL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,033] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"OJg1GGgBP1edM8bX5EHK\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'OJg1GGgBP1edM8bX5EHK\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:33:24,176] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Zb6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Zb6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,034] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"N5g1GGgBP1edM8bX0UFG\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'N5g1GGgBP1edM8bX0UFG\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:33:24,176] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Zr6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Zr6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,011] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dpg1GGgBP1edM8bXSD-I\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dpg1GGgBP1edM8bXSD-I\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:32:44,166] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Z76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Z76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,039] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5pg1GGgBP1edM8bXXD8R\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5pg1GGgBP1edM8bXXD8R\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:32:44,167] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"aL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'aL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,041] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Jpg3GGgBP1edM8bXMEXX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Jpg3GGgBP1edM8bXMEXX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:34:44,182] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ab6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ab6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,044] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mZg3GGgBP1edM8bXV0Xo\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mZg3GGgBP1edM8bXV0Xo\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:35:04,172] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ar6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ar6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,046] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mpg3GGgBP1edM8bXa0Vw\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mpg3GGgBP1edM8bXa0Vw\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:35:04,173] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"a76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'a76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,040] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Wpg8GGgBP1edM8bX6VXC\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Wpg8GGgBP1edM8bX6VXC\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:41:04,169] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"bL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'bL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,070] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"W5g8GGgBP1edM8bX6VXC\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'W5g8GGgBP1edM8bX6VXC\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:41:04,170] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"bb6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'bb6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,074] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Xpg_GGgBP1edM8bXR1xA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Xpg_GGgBP1edM8bXR1xA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:43:44,182] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"br6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'br6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,079] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"X5g_GGgBP1edM8bXR1xA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'X5g_GGgBP1edM8bXR1xA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:43:44,182] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"b76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'b76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,080] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"e5g_GGgBP1edM8bXDFuz\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'e5g_GGgBP1edM8bXDFuz\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:43:24,166] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,081] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"65g_GGgBP1edM8bXIFsw\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'65g_GGgBP1edM8bXIFsw\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:43:24,167] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cb6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cb6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,082] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"y5g8GGgBP1edM8bX_VVL\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'y5g8GGgBP1edM8bX_VVL\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:41:04,170] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cr6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cr6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,083] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mJg8GGgBP1edM8bXOVP4\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mJg8GGgBP1edM8bXOVP4\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:40:24,197] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"c76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'c76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,087] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mZg8GGgBP1edM8bXTVN-\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mZg8GGgBP1edM8bXTVN-\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:40:24,198] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,091] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-pg9GGgBP1edM8bXwFeb\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-pg9GGgBP1edM8bXwFeb\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:42:04,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"db6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'db6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,092] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-5g9GGgBP1edM8bX1Fcl\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-5g9GGgBP1edM8bX1Fcl\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:42:04,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dr6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dr6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,093] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"KJhCGGgBP1edM8bXaGUV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'KJhCGGgBP1edM8bXaGUV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:47:04,196] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"d76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'d76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,094] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"KZhCGGgBP1edM8bXaGUV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'KZhCGGgBP1edM8bXaGUV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:47:04,197] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"eL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'eL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,094] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hJhUGGgBP1edM8bXaZil\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hJhUGGgBP1edM8bXaZil\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:06:44,224] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"eb6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'eb6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,097] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hZhUGGgBP1edM8bXaZil\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hZhUGGgBP1edM8bXaZil\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:06:44,225] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"er6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'er6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,099] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mZhCGGgBP1edM8bXe2Wc\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mZhCGGgBP1edM8bXe2Wc\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:47:04,197] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"e76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'e76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,103] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Z5hUGGgBP1edM8bXpJk_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Z5hUGGgBP1edM8bXpJk_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:07:04,167] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,104] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"C5hCGGgBP1edM8bXomaw\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'C5hCGGgBP1edM8bXomaw\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:47:24,173] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fb6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fb6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,105] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9ZhUGGgBP1edM8bXfZgu\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9ZhUGGgBP1edM8bXfZgu\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:06:44,225] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fr6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fr6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,106] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"DJhCGGgBP1edM8bXtmY2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'DJhCGGgBP1edM8bXtmY2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T09:47:24,173] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"f76zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'f76zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,111] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"oZhUGGgBP1edM8bXCJfp\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'oZhUGGgBP1edM8bXCJfp\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:06:24,214] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gL6zJWgBP1edM8bXc9I_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gL6zJWgBP1edM8bXc9I_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,112] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ophUGGgBP1edM8bXG5eD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ophUGGgBP1edM8bXG5eD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:06:24,215] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gb6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gb6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,112] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EJhYGGgBP1edM8bXE6Mt\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EJhYGGgBP1edM8bXE6Mt\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:10:44,195] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gr6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gr6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,113] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"FJhYGGgBP1edM8bXGqP9\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'FJhYGGgBP1edM8bXGqP9\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:10:50,727] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"g76zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'g76zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,114] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"K5hXGGgBP1edM8bXxaIL\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'K5hXGGgBP1edM8bXxaIL\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:10:24,200] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hL6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hL6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,114] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"m5hXGGgBP1edM8bX2KKV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'m5hXGGgBP1edM8bX2KKV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:10:24,201] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hb6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hb6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,115] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lphZGGgBP1edM8bXU6Z_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lphZGGgBP1edM8bXU6Z_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:12:04,180] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hr6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hr6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,116] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"A5hZGGgBP1edM8bXZ6cI\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'A5hZGGgBP1edM8bXZ6cI\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:12:04,181] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"h76zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'h76zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,116] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"DZhXGGgBP1edM8bX_6Ou\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'DZhXGGgBP1edM8bX_6Ou\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:10:44,194] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"iL6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'iL6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,119] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gZhYGGgBP1edM8bXLqOG\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gZhYGGgBP1edM8bXLqOG\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:10:50,728] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ib6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ib6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,120] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"sJhYGGgBP1edM8bX8aXW\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'sJhYGGgBP1edM8bX8aXW\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:11:44,190] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ir6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ir6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,121] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"tJhZGGgBP1edM8bXBaVe\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'tJhZGGgBP1edM8bXBaVe\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:11:44,191] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"i76zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'i76zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,124] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"85hfGGgBP1edM8bXqLih\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'85hfGGgBP1edM8bXqLih\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:19:04,215] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"jL6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'jL6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,128] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9JhfGGgBP1edM8bXqLih\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9JhfGGgBP1edM8bXqLih\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:19:04,215] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"jb6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'jb6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,129] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"MZhfGGgBP1edM8bXH7fp\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'MZhfGGgBP1edM8bXH7fp\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:18:24,208] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"jr6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'jr6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,131] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xphyGGgBP1edM8bX3O8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xphyGGgBP1edM8bX3O8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:40:04,210] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"j76zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'j76zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,132] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"x5hyGGgBP1edM8bX7u92\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'x5hyGGgBP1edM8bX7u92\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:40:04,210] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kL6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kL6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,133] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EphfGGgBP1edM8bXbrgH\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EphfGGgBP1edM8bXbrgH\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:18:44,201] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kb6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kb6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,135] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"f5hfGGgBP1edM8bXgbiQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'f5hfGGgBP1edM8bXgbiQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:18:44,202] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kr6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kr6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,136] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dJhgGGgBP1edM8bX9Lyr\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dJhgGGgBP1edM8bX9Lyr\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:20:24,192] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"k76zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'k76zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,139] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4ZhhGGgBP1edM8bXCLwy\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4ZhhGGgBP1edM8bXCLwy\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:20:24,193] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lL6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lL6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,141] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-JhfGGgBP1edM8bXvLgp\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-JhfGGgBP1edM8bXvLgp\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:19:04,216] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lb6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lb6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,143] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"k5h4GGgBP1edM8bXbP_Q\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'k5h4GGgBP1edM8bXbP_Q\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:46:04,184] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lr6zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lr6zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,144] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lJh4GGgBP1edM8bXbP_Q\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lJh4GGgBP1edM8bXbP_Q\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:46:04,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"l76zJWgBP1edM8bXc9JX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'l76zJWgBP1edM8bXc9JX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:44,147] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_5h2GGgBP1edM8bXD_hO\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_5h2GGgBP1edM8bXD_hO\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:43:24,192] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mb6zJWgBP1edM8bXg9KN\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mb6zJWgBP1edM8bXg9KN\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-07T00:24:46,435] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"BJl4GGgBP1edM8bXgABZ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'BJl4GGgBP1edM8bXgABZ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:46:04,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ZtC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ZtC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,295] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gJh3GGgBP1edM8bXR_zS\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gJh3GGgBP1edM8bXR_zS\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:44:44,174] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Z9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Z9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,295] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"T5h2GGgBP1edM8bXhPp-\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'T5h2GGgBP1edM8bXhPp-\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:44:04,187] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"aNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'aNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,295] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UZh2GGgBP1edM8bXmPoG\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UZh2GGgBP1edM8bXmPoG\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:44:04,188] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"adC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'adC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,296] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"85h3GGgBP1edM8bXbvzk\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'85h3GGgBP1edM8bXbvzk\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:45:04,177] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"atC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'atC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,296] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9Jh3GGgBP1edM8bXgvxs\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9Jh3GGgBP1edM8bXgvxs\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:45:04,178] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"a9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'a9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,296] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EJh3GGgBP1edM8bXNPxI\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EJh3GGgBP1edM8bXNPxI\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:44:44,173] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"bNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'bNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,297] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"epl9GGgBP1edM8bXnQ4C\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'epl9GGgBP1edM8bXnQ4C\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:51:44,191] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"bdC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'bdC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,297] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"e5l9GGgBP1edM8bXnQ4C\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'e5l9GGgBP1edM8bXnQ4C\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:51:44,192] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"btC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'btC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,298] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4Jl_GGgBP1edM8bXEBIj\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4Jl_GGgBP1edM8bXEBIj\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:53:24,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"b9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'b9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,299] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4Zl_GGgBP1edM8bXEBIj\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4Zl_GGgBP1edM8bXEBIj\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:53:24,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,299] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_pl-GGgBP1edM8bX1RGG\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_pl-GGgBP1edM8bX1RGG\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:53:04,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cdC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cdC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,300] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"bZl-GGgBP1edM8bX6RIP\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'bZl-GGgBP1edM8bX6RIP\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:53:04,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ctC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ctC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,300] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"6pl9GGgBP1edM8bXsA6L\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'6pl9GGgBP1edM8bXsA6L\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:51:44,192] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"c9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'c9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,300] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"25l8GGgBP1edM8bXsgue\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'25l8GGgBP1edM8bXsgue\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:50:44,176] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,300] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"XZl9GGgBP1edM8bX1w-k\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'XZl9GGgBP1edM8bX1w-k\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:52:04,193] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ddC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ddC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,303] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"X5l9GGgBP1edM8bX6w8l\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'X5l9GGgBP1edM8bX6w8l\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:52:04,194] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dtC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dtC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,303] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"45l_GGgBP1edM8bXIxKr\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'45l_GGgBP1edM8bXIxKr\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-04T10:53:24,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"d9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'d9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,303] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"MqW9HGgBP1edM8bXOzPd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'MqW9HGgBP1edM8bXOzPd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:39:44,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"eNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'eNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,303] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"NKW9HGgBP1edM8bXTzNl\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'NKW9HGgBP1edM8bXTzNl\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:39:44,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"edC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'edC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,311] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"rqW8HGgBP1edM8bXFy9k\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'rqW8HGgBP1edM8bXFy9k\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:38:24,322] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"etC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'etC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,311] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"HaW8HGgBP1edM8bXKjBk\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'HaW8HGgBP1edM8bXKjBk\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:38:24,326] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"e9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'e9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,311] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"daW6HGgBP1edM8bXQioX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'daW6HGgBP1edM8bXQioX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:36:24,240] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,312] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"bqW8HGgBP1edM8bXnzGY\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'bqW8HGgBP1edM8bXnzGY\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:39:04,213] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fdC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fdC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,312] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cKW8HGgBP1edM8bXszEh\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cKW8HGgBP1edM8bXszEh\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:39:04,213] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ftC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ftC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,312] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4qW8HGgBP1edM8bX2jFE\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4qW8HGgBP1edM8bX2jFE\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:39:24,196] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"f9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'f9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,313] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UaW8HGgBP1edM8bX7TLF\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UaW8HGgBP1edM8bX7TLF\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:39:24,197] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,313] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"CaW-HGgBP1edM8bX_Tgd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'CaW-HGgBP1edM8bX_Tgd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:41:44,217] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gdC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gdC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,313] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"CqW-HGgBP1edM8bX_Tgd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'CqW-HGgBP1edM8bX_Tgd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:41:44,217] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gtC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gtC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,313] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hqW9HGgBP1edM8bXxDSY\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hqW9HGgBP1edM8bXxDSY\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:40:24,195] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"g9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'g9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,314] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"h6W9HGgBP1edM8bXxDSY\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'h6W9HGgBP1edM8bXxDSY\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:40:24,196] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,314] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"a6XAHGgBP1edM8bXgzzD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'a6XAHGgBP1edM8bXgzzD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:43:24,198] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hdC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hdC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,314] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"bKXAHGgBP1edM8bXgzzD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'bKXAHGgBP1edM8bXgzzD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:43:24,199] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"htC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'htC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,314] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"eaW_HGgBP1edM8bXEDil\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'eaW_HGgBP1edM8bXEDil\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:41:44,218] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"h9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'h9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,315] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lKW-HGgBP1edM8bXwjeF\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lKW-HGgBP1edM8bXwjeF\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:41:24,188] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"iNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'iNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,315] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lqW-HGgBP1edM8bX1jcN\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lqW-HGgBP1edM8bX1jcN\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:41:24,189] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"idC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'idC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,315] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"W6W_HGgBP1edM8bXXjnH\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'W6W_HGgBP1edM8bXXjnH\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:42:04,198] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"itC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'itC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,316] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"XaW_HGgBP1edM8bXcjlP\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'XaW_HGgBP1edM8bXcjlP\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:42:04,199] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"i9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'i9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,316] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9qW9HGgBP1edM8bX2DQf\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9qW9HGgBP1edM8bX2DQf\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:40:24,196] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"jNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'jNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,316] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"YqXBHGgBP1edM8bXz0DU\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'YqXBHGgBP1edM8bXz0DU\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:44:44,206] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"jdC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'jdC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,316] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Y6XBHGgBP1edM8bXz0DU\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Y6XBHGgBP1edM8bXz0DU\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:44:44,207] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"jtC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'jtC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,317] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vaXAHGgBP1edM8bX5T1s\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vaXAHGgBP1edM8bX5T1s\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:43:44,209] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"j9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'j9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,317] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vqXAHGgBP1edM8bX5T1s\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vqXAHGgBP1edM8bX5T1s\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:43:44,210] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,319] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ZaXBHGgBP1edM8bX40Ba\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ZaXBHGgBP1edM8bX40Ba\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:44:44,207] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kdC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kdC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,320] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"26XAHGgBP1edM8bXlzxL\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'26XAHGgBP1edM8bXlzxL\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:43:24,199] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ktC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ktC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,320] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EaXBHGgBP1edM8bXbj8n\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EaXBHGgBP1edM8bXbj8n\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:44:24,187] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"k9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'k9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,320] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gKXBHGgBP1edM8bXgT-w\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gKXBHGgBP1edM8bXgT-w\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:44:24,188] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lNC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lNC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,320] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"tqXCHGgBP1edM8bXWEGO\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'tqXCHGgBP1edM8bXWEGO\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:45:24,191] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ldC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ldC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,322] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"JaXCHGgBP1edM8bXbEIV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'JaXCHGgBP1edM8bXbEIV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:45:24,191] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ltC1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ltC1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,323] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"wKXAHGgBP1edM8bX-D30\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'wKXAHGgBP1edM8bX-D30\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:43:44,210] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"l9C1K2gBP1edM8bXby--\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'l9C1K2gBP1edM8bXby--\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,323] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"PaXEHGgBP1edM8bXj0gD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'PaXEHGgBP1edM8bXj0gD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:47:44,199] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mNC1K2gBP1edM8bXby_o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mNC1K2gBP1edM8bXby_o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,323] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"P6XEHGgBP1edM8bXokiN\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'P6XEHGgBP1edM8bXokiN\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:47:44,199] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mdC1K2gBP1edM8bXby_o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mdC1K2gBP1edM8bXby_o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,324] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"x6XFHGgBP1edM8bXx0uL\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'x6XFHGgBP1edM8bXx0uL\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:49:04,207] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mtC1K2gBP1edM8bXby_o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mtC1K2gBP1edM8bXby_o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,324] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AqXFHGgBP1edM8bXK0pF\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AqXFHGgBP1edM8bXK0pF\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:48:24,195] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"m9C1K2gBP1edM8bXby_o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'m9C1K2gBP1edM8bXby_o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,324] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"saXEHGgBP1edM8bXyUic\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'saXEHGgBP1edM8bXyUic\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:48:04,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"nNC1K2gBP1edM8bXby_o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'nNC1K2gBP1edM8bXby_o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,325] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"IaXEHGgBP1edM8bX3Ukl\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'IaXEHGgBP1edM8bX3Ukl\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:48:04,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ndC1K2gBP1edM8bXby_o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ndC1K2gBP1edM8bXby_o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,325] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dqXFHGgBP1edM8bXZUri\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dqXFHGgBP1edM8bXZUri\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:48:44,202] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ntC1K2gBP1edM8bXby_o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ntC1K2gBP1edM8bXby_o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,325] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5aXFHGgBP1edM8bXeUpq\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5aXFHGgBP1edM8bXeUpq\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:48:44,202] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"n9C1K2gBP1edM8bXby_o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'n9C1K2gBP1edM8bXby_o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,325] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"BKXFHGgBP1edM8bXPkrP\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'BKXFHGgBP1edM8bXPkrP\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:48:24,196] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"oNC1K2gBP1edM8bXby_o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'oNC1K2gBP1edM8bXby_o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,326] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"yaXFHGgBP1edM8bX20sT\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'yaXFHGgBP1edM8bX20sT\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:49:04,208] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"odC1K2gBP1edM8bXby_o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'odC1K2gBP1edM8bXby_o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,327] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_6XGHGgBP1edM8bXnk1r\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_6XGHGgBP1edM8bXnk1r\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:50:04,182] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"otC1K2gBP1edM8bXby_o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'otC1K2gBP1edM8bXby_o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,327] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"b6XGHGgBP1edM8bXsU7z\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'b6XGHGgBP1edM8bXsU7z\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:50:04,183] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"o9C1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'o9C1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,327] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"i6XGHGgBP1edM8bXY03P\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'i6XGHGgBP1edM8bXY03P\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:49:44,177] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"pNC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'pNC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,328] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"jaXGHGgBP1edM8bXd01X\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'jaXGHGgBP1edM8bXd01X\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:49:44,178] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"pdC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'pdC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,330] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AqXYHGgBP1edM8bXKoDS\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AqXYHGgBP1edM8bXKoDS\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T07:09:04,378] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ptC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ptC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,331] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"qqXGHGgBP1edM8bXFUyt\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'qqXGHGgBP1edM8bXFUyt\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:49:24,172] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"p9C1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'p9C1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,331] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"O6XGHGgBP1edM8bXAkwm\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'O6XGHGgBP1edM8bXAkwm\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T06:49:24,171] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"qNC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'qNC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,331] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AKXYHGgBP1edM8bXF4D_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AKXYHGgBP1edM8bXF4D_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T07:09:04,377] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"qdC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'qdC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,332] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1aUCHWgBP1edM8bXIfd-\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1aUCHWgBP1edM8bXIfd-\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T07:55:04,167] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"qtC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'qtC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,332] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"caXjHGgBP1edM8bXdaCh\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'caXjHGgBP1edM8bXdaCh\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T07:21:24,191] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"q9C1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'q9C1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,332] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"paUBHWgBP1edM8bXS_Wj\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'paUBHWgBP1edM8bXS_Wj\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T07:54:04,199] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"rNC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'rNC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,333] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"BKUCHWgBP1edM8bX5PrT\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'BKUCHWgBP1edM8bX5PrT\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T07:55:44,169] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"rdC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'rdC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,333] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"46XjHGgBP1edM8bXnKCw\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'46XjHGgBP1edM8bXnKCw\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T07:21:44,177] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"rtC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'rtC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,333] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UqXjHGgBP1edM8bXsKE5\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UqXjHGgBP1edM8bXsKE5\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T07:21:44,178] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"r9C1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'r9C1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,333] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"RaUCHWgBP1edM8bXNfgF\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'RaUCHWgBP1edM8bXNfgF\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T07:55:04,168] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"sNC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'sNC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,334] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"8KUEHWgBP1edM8bXRP1o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'8KUEHWgBP1edM8bXRP1o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T07:57:24,175] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"sdC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'sdC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,451] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"p6UBHWgBP1edM8bXXvUs\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'p6UBHWgBP1edM8bXXvUs\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T07:54:04,200] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"stC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'stC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,451] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"pKYIHWgBP1edM8bXnQrD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'pKYIHWgBP1edM8bXnQrD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:02:04,179] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"s9C1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'s9C1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,451] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"paYIHWgBP1edM8bXnQrD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'paYIHWgBP1edM8bXnQrD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:02:04,180] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"tNC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'tNC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,452] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"GKYLHWgBP1edM8bXSRJe\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'GKYLHWgBP1edM8bXSRJe\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:05:04,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"tdC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'tdC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,452] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"GaYLHWgBP1edM8bXSRJe\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'GaYLHWgBP1edM8bXSRJe\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:05:04,185] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ttC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ttC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,452] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-KYJHWgBP1edM8bXJgt8\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-KYJHWgBP1edM8bXJgt8\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:02:44,175] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"t9C1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'t9C1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,453] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-aYJHWgBP1edM8bXJgt8\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-aYJHWgBP1edM8bXJgt8\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:02:44,175] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"uNC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'uNC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,453] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"S6YJHWgBP1edM8bXiA0l\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'S6YJHWgBP1edM8bXiA0l\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:03:04,187] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"udC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'udC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,453] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"TKYJHWgBP1edM8bXiA0l\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'TKYJHWgBP1edM8bXiA0l\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:03:04,188] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"utC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'utC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,453] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"J6YMHWgBP1edM8bXRxVH\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'J6YMHWgBP1edM8bXRxVH\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:06:04,194] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"u9C1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'u9C1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,454] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"KKYMHWgBP1edM8bXRxVH\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'KKYMHWgBP1edM8bXRxVH\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:06:04,195] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vNC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vNC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,454] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"p6YIHWgBP1edM8bXsQpJ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'p6YIHWgBP1edM8bXsQpJ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:02:04,180] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vdC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vdC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,454] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"TqYJHWgBP1edM8bXmw2v\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'TqYJHWgBP1edM8bXmw2v\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:03:04,188] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vtC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vtC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,455] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Z6YJHWgBP1edM8bXOgwE\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Z6YJHWgBP1edM8bXOgwE\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:02:44,176] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"v9C1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'v9C1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,455] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"iaYLHWgBP1edM8bXXBLn\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'iaYLHWgBP1edM8bXXBLn\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:05:04,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"wNC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'wNC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,455] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"b6YhHWgBP1edM8bXB1Dh\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'b6YhHWgBP1edM8bXB1Dh\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:28:46,868] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"wdC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'wdC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,455] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cKYhHWgBP1edM8bXB1Dh\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cKYhHWgBP1edM8bXB1Dh\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:28:46,869] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"wtC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'wtC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,456] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cqYhHWgBP1edM8bXC1DK\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cqYhHWgBP1edM8bXC1DK\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:28:46,869] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"w9C1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'w9C1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,456] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"c6YhHWgBP1edM8bXC1DK\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'c6YhHWgBP1edM8bXC1DK\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:28:50,023] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xNC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xNC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,456] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Y6YlHWgBP1edM8bX6l5k\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Y6YlHWgBP1edM8bX6l5k\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:33:59,840] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xdC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xdC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,456] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ZKYlHWgBP1edM8bX6l5k\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ZKYlHWgBP1edM8bX6l5k\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:33:59,841] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xtC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xtC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,457] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ZaYlHWgBP1edM8bX6l5k\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ZaYlHWgBP1edM8bX6l5k\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:34:00,157] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"x9C1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'x9C1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,457] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"KKYfHWgBP1edM8bXM0sa\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'KKYfHWgBP1edM8bXM0sa\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:26:44,209] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"yNC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'yNC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,457] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"KaYfHWgBP1edM8bXM0sa\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'KaYfHWgBP1edM8bXM0sa\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:26:44,210] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ydC1K2gBP1edM8bXby_p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ydC1K2gBP1edM8bXby_p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,458] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1qYeHWgBP1edM8bX0Ulx\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1qYeHWgBP1edM8bX0Ulx\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:26:24,210] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ytC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ytC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,458] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"16YeHWgBP1edM8bX0Ulx\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'16YeHWgBP1edM8bX0Ulx\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:26:24,210] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"y9C1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'y9C1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,458] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"faYfHWgBP1edM8bXu0zV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'faYfHWgBP1edM8bXu0zV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:27:24,183] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"zNC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'zNC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,458] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fqYfHWgBP1edM8bXu0zV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fqYfHWgBP1edM8bXu0zV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:27:24,184] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"zdC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'zdC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,459] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"K6YfHWgBP1edM8bXRkuj\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'K6YfHWgBP1edM8bXRkuj\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:26:44,210] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ztC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ztC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,459] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"RaYeHWgBP1edM8bX5Er4\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'RaYeHWgBP1edM8bX5Er4\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:26:24,211] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"z9C1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'z9C1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,459] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"7aYfHWgBP1edM8bXz0xd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'7aYfHWgBP1edM8bXz0xd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:27:24,184] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0NC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0NC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,459] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"d6YhHWgBP1edM8bXH1BQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'d6YhHWgBP1edM8bXH1BQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T08:28:50,262] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0dC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0dC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,460] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"7aZWHWgBP1edM8bXIudC\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'7aZWHWgBP1edM8bXIudC\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:26:44,179] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0tC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0tC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,460] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"7qZWHWgBP1edM8bXIudC\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'7qZWHWgBP1edM8bXIudC\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:26:44,180] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"09C1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'09C1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,460] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"wKZVHWgBP1edM8bXcuV4\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'wKZVHWgBP1edM8bXcuV4\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:26:04,178] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1NC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1NC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,461] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"waZVHWgBP1edM8bXcuV4\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'waZVHWgBP1edM8bXcuV4\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:26:04,179] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1dC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1dC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,461] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"KaZSHWgBP1edM8bXF9wR\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'KaZSHWgBP1edM8bXF9wR\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:22:24,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1tC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1tC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,461] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"KqZSHWgBP1edM8bXF9wR\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'KqZSHWgBP1edM8bXF9wR\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:22:24,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"19C1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'19C1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,461] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"LaZVHWgBP1edM8bXhuYA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'LaZVHWgBP1edM8bXhuYA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:26:04,179] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"2NC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'2NC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,462] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"tqZRHWgBP1edM8bX79v8\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'tqZRHWgBP1edM8bX79v8\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:22:04,211] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"2dC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'2dC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,462] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fKZSHWgBP1edM8bXjN1B\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fKZSHWgBP1edM8bXjN1B\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:22:44,168] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"2tC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'2tC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,462] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9KZWHWgBP1edM8bXNefJ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9KZWHWgBP1edM8bXNefJ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:26:44,180] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"29C1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'29C1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,463] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dqZSHWgBP1edM8bXeN25\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dqZSHWgBP1edM8bXeN25\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:22:44,168] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3NC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3NC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,463] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"laZSHWgBP1edM8bXKtyX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'laZSHWgBP1edM8bXKtyX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T09:22:24,187] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3dC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3dC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,463] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Jqd4HWgBP1edM8bX7EvJ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Jqd4HWgBP1edM8bX7EvJ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:04:44,211] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3tC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3tC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,463] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"J6d4HWgBP1edM8bX7EvJ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'J6d4HWgBP1edM8bX7EvJ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:04:44,212] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"39C1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'39C1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,464] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"2Kd4HWgBP1edM8bXi0ke\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'2Kd4HWgBP1edM8bXi0ke\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:04:24,213] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4NC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4NC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,464] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"2ad4HWgBP1edM8bXi0ke\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'2ad4HWgBP1edM8bXi0ke\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:04:24,214] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4dC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4dC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,464] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"oKd5HWgBP1edM8bXJ0tl\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'oKd5HWgBP1edM8bXJ0tl\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:05:04,206] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4tC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4tC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,464] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"oad5HWgBP1edM8bXJ0tl\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'oad5HWgBP1edM8bXJ0tl\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:05:04,207] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"49C1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'49C1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,465] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Lad5HWgBP1edM8bXAEtR\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Lad5HWgBP1edM8bXAEtR\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:04:44,212] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5NC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5NC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,465] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"zKd5HWgBP1edM8bX100v\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'zKd5HWgBP1edM8bX100v\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:05:44,190] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5dC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5dC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,465] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0qd5HWgBP1edM8bX6k23\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0qd5HWgBP1edM8bX6k23\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:05:44,190] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5tC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5tC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,466] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Zad4HWgBP1edM8bXZEkM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Zad4HWgBP1edM8bXZEkM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:04:04,203] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"59C1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'59C1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,466] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"RKd4HWgBP1edM8bXnkqn\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'RKd4HWgBP1edM8bXnkqn\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:04:24,214] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"6NC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'6NC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,466] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Dad5HWgBP1edM8bXOkzs\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Dad5HWgBP1edM8bXOkzs\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:05:04,207] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"6dC1K2gBP1edM8bXcC8G\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'6dC1K2gBP1edM8bXcC8G\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,466] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"z6eAHWgBP1edM8bXLF9i\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'z6eAHWgBP1edM8bXLF9i\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:12:42,992] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"79C1K2gBP1edM8bXgi-L\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'79C1K2gBP1edM8bXgi-L\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T04:25:34,467] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0KeAHWgBP1edM8bXLF9i\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0KeAHWgBP1edM8bXLF9i\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:12:42,992] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"OtKvLGgBP1edM8bXif-0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'OtKvLGgBP1edM8bXif-0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T08:58:44,251] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0aeAHWgBP1edM8bXLF9i\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0aeAHWgBP1edM8bXLF9i\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:12:44,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"O9KvLGgBP1edM8bXif-0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'O9KvLGgBP1edM8bXif-0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T08:58:44,252] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"d6d9HWgBP1edM8bXMlef\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'d6d9HWgBP1edM8bXMlef\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:09:24,188] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"JdOvLGgBP1edM8bX6gCw\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'JdOvLGgBP1edM8bX6gCw\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T08:59:04,299] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"eKd9HWgBP1edM8bXMlef\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'eKd9HWgBP1edM8bXMlef\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:09:24,189] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"JtOvLGgBP1edM8bX6gCw\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'JtOvLGgBP1edM8bX6gCw\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T08:59:04,300] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"PKeAHWgBP1edM8bXP2Dp\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'PKeAHWgBP1edM8bXP2Dp\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:12:44,205] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"QdKvLGgBP1edM8bXnP-P\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'QdKvLGgBP1edM8bXnP-P\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T08:58:44,255] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fqd9HWgBP1edM8bXRlco\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fqd9HWgBP1edM8bXRlco\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:09:24,189] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Z9DXK2gBP1edM8bX65OO\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Z9DXK2gBP1edM8bX65OO\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T05:03:04,971] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lKd_HWgBP1edM8bXVV2E\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lKd_HWgBP1edM8bXVV2E\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:11:44,208] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ktOvLGgBP1edM8bX_gA5\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ktOvLGgBP1edM8bX_gA5\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T08:59:04,300] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mqd_HWgBP1edM8bXaV0M\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mqd_HWgBP1edM8bXaV0M\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:11:44,209] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-tDXK2gBP1edM8bX2JIF\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-tDXK2gBP1edM8bX2JIF\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T05:03:04,819] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lad8HWgBP1edM8bX5FZ-\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lad8HWgBP1edM8bX5FZ-\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:09:04,189] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gtDXK2gBP1edM8bXnpJS\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gtDXK2gBP1edM8bXnpJS\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T05:02:53,938] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"8Kd9HWgBP1edM8bXbVc4\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'8Kd9HWgBP1edM8bXbVc4\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:09:44,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"h9DXK2gBP1edM8bXsJL1\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'h9DXK2gBP1edM8bXsJL1\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T05:02:55,438] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"W6d9HWgBP1edM8bXgFjB\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'W6d9HWgBP1edM8bXgFjB\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:09:44,205] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"x9OwLGgBP1edM8bXwQKM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'x9OwLGgBP1edM8bXwQKM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:00:04,208] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0qeVHWgBP1edM8bXiZxB\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0qeVHWgBP1edM8bXiZxB\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:36:04,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"yNOwLGgBP1edM8bXwQKM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'yNOwLGgBP1edM8bXwQKM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:00:04,209] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"06eVHWgBP1edM8bXiZxB\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'06eVHWgBP1edM8bXiZxB\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:36:04,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"G9OyLGgBP1edM8bXlghR\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'G9OyLGgBP1edM8bXlghR\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:02:04,206] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"LaeUHWgBP1edM8bXnprd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'LaeUHWgBP1edM8bXnprd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:35:04,208] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"HNOyLGgBP1edM8bXlghR\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'HNOyLGgBP1edM8bXlghR\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:02:04,207] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"LqeUHWgBP1edM8bXnprd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'LqeUHWgBP1edM8bXnprd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:35:04,209] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"O9OyLGgBP1edM8bXWwe5\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'O9OyLGgBP1edM8bXWwe5\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:01:44,223] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"P6eVHWgBP1edM8bXnJ3I\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'P6eVHWgBP1edM8bXnJ3I\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:36:04,205] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"p9OyLGgBP1edM8bXbwdA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'p9OyLGgBP1edM8bXbwdA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:01:44,224] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"oqeEHWgBP1edM8bXS2sl\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'oqeEHWgBP1edM8bXS2sl\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:17:04,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ztOwLGgBP1edM8bX1QIW\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ztOwLGgBP1edM8bX1QIW\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:00:04,209] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"WaeVHWgBP1edM8bXTpyn\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'WaeVHWgBP1edM8bXTpyn\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:35:44,187] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"sdOxLGgBP1edM8bXIwM0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'sdOxLGgBP1edM8bXIwM0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:00:24,195] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"X6eVHWgBP1edM8bXYpwv\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'X6eVHWgBP1edM8bXYpwv\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:35:44,188] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"HdOxLGgBP1edM8bXNgTr\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'HdOxLGgBP1edM8bXNgTr\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:00:24,196] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mqeUHWgBP1edM8bXsppm\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mqeUHWgBP1edM8bXsppm\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:35:04,209] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UdOxLGgBP1edM8bX-gYO\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UdOxLGgBP1edM8bX-gYO\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:01:24,208] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"tKeUHWgBP1edM8bXZJmu\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'tKeUHWgBP1edM8bXZJmu\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:34:44,366] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"V9OyLGgBP1edM8bXDQac\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'V9OyLGgBP1edM8bXDQac\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:01:24,211] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"uqeUHWgBP1edM8bXd5nP\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'uqeUHWgBP1edM8bXd5nP\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:34:44,367] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"v9O2LGgBP1edM8bXPxLd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'v9O2LGgBP1edM8bXPxLd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:06:04,230] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"X6ebHWgBP1edM8bXo67s\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'X6ebHWgBP1edM8bXo67s\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:42:44,171] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"wNO2LGgBP1edM8bXPxLd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'wNO2LGgBP1edM8bXPxLd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:06:04,231] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"YKebHWgBP1edM8bXo67s\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'YKebHWgBP1edM8bXo67s\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:42:44,172] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xtO2LGgBP1edM8bXUxJm\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xtO2LGgBP1edM8bXUxJm\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:06:04,231] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"B6ebHWgBP1edM8bXG60w\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'B6ebHWgBP1edM8bXG60w\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:42:04,205] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kNO5LGgBP1edM8bXYBur\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kNO5LGgBP1edM8bXYBur\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:09:24,218] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"CKebHWgBP1edM8bXG60w\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'CKebHWgBP1edM8bXG60w\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:42:04,206] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"39O2LGgBP1edM8bXBRFD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'39O2LGgBP1edM8bXBRFD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:05:44,215] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"2qeaHWgBP1edM8bXa6pn\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'2qeaHWgBP1edM8bXa6pn\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:41:24,202] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"S9O2LGgBP1edM8bXGBLN\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'S9O2LGgBP1edM8bXGBLN\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:05:44,216] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"26eaHWgBP1edM8bXa6pn\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'26eaHWgBP1edM8bXa6pn\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:41:24,203] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_NO5LGgBP1edM8bXdBs0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_NO5LGgBP1edM8bXdBs0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:09:24,219] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"y6ebHWgBP1edM8bXt650\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'y6ebHWgBP1edM8bXt650\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:42:44,172] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"WdO5LGgBP1edM8bX_B3v\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'WdO5LGgBP1edM8bX_B3v\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:10:04,199] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"s6ecHWgBP1edM8bXGa8g\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'s6ecHWgBP1edM8bXGa8g\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:43:04,336] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dtO5LGgBP1edM8bXrhzN\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dtO5LGgBP1edM8bXrhzN\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:09:44,225] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"DqebHWgBP1edM8bXLq24\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'DqebHWgBP1edM8bXLq24\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:42:04,206] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cNO5LGgBP1edM8bXmxxc\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cNO5LGgBP1edM8bXmxxc\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:09:44,224] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"raecHWgBP1edM8bXBa-Y\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'raecHWgBP1edM8bXBa-Y\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:43:04,335] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-tO6LGgBP1edM8bX0x_K\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-tO6LGgBP1edM8bX0x_K\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:11:04,219] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"RqeaHWgBP1edM8bXfqvs\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'RqeaHWgBP1edM8bXfqvs\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:41:24,203] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-9O6LGgBP1edM8bX0x_K\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-9O6LGgBP1edM8bX0x_K\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:11:04,220] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"iKeZHWgBP1edM8bX9qkt\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'iKeZHWgBP1edM8bX9qkt\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:40:44,186] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5dO7LGgBP1edM8bXNSB0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5dO7LGgBP1edM8bXNSB0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:11:24,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3aefHWgBP1edM8bXTbiD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3aefHWgBP1edM8bXTbiD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:46:44,278] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5tO7LGgBP1edM8bXNSB0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5tO7LGgBP1edM8bXNSB0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:11:24,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3qefHWgBP1edM8bXTbiD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3qefHWgBP1edM8bXTbiD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:46:44,279] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xdO6LGgBP1edM8bXEB13\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xdO6LGgBP1edM8bXEB13\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:10:04,199] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"wKedHWgBP1edM8bXKrKX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'wKedHWgBP1edM8bXKrKX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:44:24,182] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AdO6LGgBP1edM8bX5yBS\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AdO6LGgBP1edM8bX5yBS\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:11:04,220] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"K6edHWgBP1edM8bXPrMr\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'K6edHWgBP1edM8bXPrMr\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:44:24,183] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UtO7LGgBP1edM8bXSCH7\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UtO7LGgBP1edM8bXSCH7\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:11:24,205] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"DKedHWgBP1edM8bXjLRE\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'DKedHWgBP1edM8bXjLRE\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:44:44,181] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"htO8LGgBP1edM8bXDCNP\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'htO8LGgBP1edM8bXDCNP\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:12:24,211] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EqedHWgBP1edM8bXn7TM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EqedHWgBP1edM8bXn7TM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:44:44,181] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gtPNLGgBP1edM8bXcVX7\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gtPNLGgBP1edM8bXcVX7\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:31:24,378] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"CaefHWgBP1edM8bX_btQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'CaefHWgBP1edM8bX_btQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:47:24,170] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"iNPNLGgBP1edM8bXhVUe\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'iNPNLGgBP1edM8bXhVUe\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:31:24,379] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"D6egHWgBP1edM8bXELvY\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'D6egHWgBP1edM8bXELvY\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:47:24,171] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"jNO8LGgBP1edM8bXHyPV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'jNO8LGgBP1edM8bXHyPV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:12:24,212] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"SaefHWgBP1edM8bXYbkM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'SaefHWgBP1edM8bXYbkM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T10:46:44,279] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"etPPLGgBP1edM8bXPlqZ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'etPPLGgBP1edM8bXPlqZ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:33:24,202] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"R6jJHWgBP1edM8bXkjGL\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'R6jJHWgBP1edM8bXkjGL\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T11:32:44,970] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"e9PPLGgBP1edM8bXPlqZ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'e9PPLGgBP1edM8bXPlqZ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:33:24,203] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"u6gRHmgBP1edM8bX-v8g\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'u6gRHmgBP1edM8bX-v8g\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:51:53,494] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ddPQLGgBP1edM8bXil6n\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ddPQLGgBP1edM8bXil6n\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:34:44,248] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vKgRHmgBP1edM8bX-v8g\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vKgRHmgBP1edM8bX-v8g\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:51:53,495] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dtPQLGgBP1edM8bXil6n\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dtPQLGgBP1edM8bXil6n\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:34:44,249] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"vagRHmgBP1edM8bX-v8g\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'vagRHmgBP1edM8bX-v8g\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:51:58,622] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"w9PSLGgBP1edM8bXX2Nr\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'w9PSLGgBP1edM8bXX2Nr\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:36:44,225] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"y6jSHWgBP1edM8bXzUuQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'y6jSHWgBP1edM8bXzUuQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T11:42:53,918] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xNPSLGgBP1edM8bXX2Nr\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xNPSLGgBP1edM8bXX2Nr\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:36:44,226] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"zKjSHWgBP1edM8bXzUuQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'zKjSHWgBP1edM8bXzUuQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T11:42:53,919] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"4tPTLGgBP1edM8bXhGZo\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'4tPTLGgBP1edM8bXhGZo\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:38:04,224] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"zajSHWgBP1edM8bXzUuQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'zajSHWgBP1edM8bXzUuQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T11:42:54,044] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"49PTLGgBP1edM8bXhGZo\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'49PTLGgBP1edM8bXhGZo\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:38:04,225] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1KjSHWgBP1edM8bX4UsI\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1KjSHWgBP1edM8bX4UsI\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T11:42:54,044] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"sNPRLGgBP1edM8bXYWCB\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'sNPRLGgBP1edM8bXYWCB\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:35:44,235] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xagSHmgBP1edM8bXDf-p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xagSHmgBP1edM8bXDf-p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:51:58,622] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"sdPRLGgBP1edM8bXYWCB\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'sdPRLGgBP1edM8bXYWCB\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:35:44,236] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"e6gQHmgBP1edM8bXJfrr\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'e6gQHmgBP1edM8bXJfrr\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:49:55,044] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ydPSLGgBP1edM8bXcmPz\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ydPSLGgBP1edM8bXcmPz\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:36:44,226] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"g6gQHmgBP1edM8bXOPri\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'g6gQHmgBP1edM8bXOPri\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:49:55,044] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"e9PQLGgBP1edM8bXnl4u\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'e9PQLGgBP1edM8bXnl4u\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:34:44,249] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"3agRHmgBP1edM8bXv_6F\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'3agRHmgBP1edM8bXv_6F\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:51:38,804] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"6NPPLGgBP1edM8bXUloh\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'6NPPLGgBP1edM8bXUloh\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:33:24,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"R6gRHmgBP1edM8bX0_8N\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'R6gRHmgBP1edM8bX0_8N\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:51:38,915] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"HtPRLGgBP1edM8bXdWEI\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'HtPRLGgBP1edM8bXdWEI\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T09:35:44,236] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"RKkTHmgBP1edM8bXRgMv\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'RKkTHmgBP1edM8bXRgMv\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:53:23,512] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"LdP5LGgBP1edM8bXxdXD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'LdP5LGgBP1edM8bXxdXD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:19:44,232] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_6k7HmgBP1edM8bXfHVM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_6k7HmgBP1edM8bXfHVM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T13:37:18,162] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"LtP5LGgBP1edM8bXxdXD\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'LtP5LGgBP1edM8bXxdXD\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:19:44,234] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AKk7HmgBP1edM8bXfHZM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AKk7HmgBP1edM8bXfHZM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T13:37:18,163] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"f9P9LGgBP1edM8bX-OEE\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'f9P9LGgBP1edM8bX-OEE\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:24:24,204] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Aak7HmgBP1edM8bXfHZM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Aak7HmgBP1edM8bXfHZM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T13:37:18,163] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gNP9LGgBP1edM8bX-OEE\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gNP9LGgBP1edM8bX-OEE\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:24:24,205] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mKqHHmgBP1edM8bXK03_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mKqHHmgBP1edM8bXK03_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T14:59:55,728] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mtP5LGgBP1edM8bX2dVL\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mtP5LGgBP1edM8bX2dVL\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:19:44,234] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"maqHHmgBP1edM8bXK03_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'maqHHmgBP1edM8bXK03_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T14:59:55,729] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"1dP9LGgBP1edM8bXDd6g\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'1dP9LGgBP1edM8bXDd6g\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:23:24,180] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mqqHHmgBP1edM8bXK03_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mqqHHmgBP1edM8bXK03_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T14:59:55,729] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"29P9LGgBP1edM8bXId4o\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'29P9LGgBP1edM8bXId4o\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:23:24,180] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Oqk8HmgBP1edM8bXUnh7\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Oqk8HmgBP1edM8bXUnh7\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T13:38:08,956] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"K9P9LGgBP1edM8bXguDS\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'K9P9LGgBP1edM8bXguDS\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:23:44,193] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"pak8HmgBP1edM8bXZXj6\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'pak8HmgBP1edM8bXZXj6\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T13:38:08,957] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"aNP5LGgBP1edM8bXKdN_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'aNP5LGgBP1edM8bXKdN_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:19:04,247] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"oqqHHmgBP1edM8bXPk27\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'oqqHHmgBP1edM8bXPk27\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T14:59:55,942] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"htP-LGgBP1edM8bXC-GN\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'htP-LGgBP1edM8bXC-GN\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:24:24,206] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"B6k7HmgBP1edM8bXj3Yd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'B6k7HmgBP1edM8bXj3Yd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T13:37:18,270] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"v9P9LGgBP1edM8bXb99L\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'v9P9LGgBP1edM8bXb99L\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:23:44,192] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"8qkWHmgBP1edM8bXPwvq\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'8qkWHmgBP1edM8bXPwvq\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:56:33,750] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"htwiMGgBP1edM8bXffV7\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'htwiMGgBP1edM8bXffV7\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:08,778] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-akWHmgBP1edM8bXUwtz\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-akWHmgBP1edM8bXUwtz\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:56:33,751] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"h9wiMGgBP1edM8bXffV7\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'h9wiMGgBP1edM8bXffV7\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:11,461] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"r6kTHmgBP1edM8bXWQOz\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'r6kTHmgBP1edM8bXWQOz\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T12:53:23,512] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"iNwiMGgBP1edM8bXffV7\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'iNwiMGgBP1edM8bXffV7\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:11,773] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"KqsWH2gBP1edM8bXdOZj\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'KqsWH2gBP1edM8bXdOZj\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T17:36:20,633] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"idwiMGgBP1edM8bXffV7\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'idwiMGgBP1edM8bXffV7\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:11,942] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"j6sSH2gBP1edM8bXG9kS\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'j6sSH2gBP1edM8bXG9kS\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T17:31:33,746] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"itwiMGgBP1edM8bXffV7\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'itwiMGgBP1edM8bXffV7\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:12,064] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"k6xpH2gBP1edM8bXd9Lh\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'k6xpH2gBP1edM8bXd9Lh\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T19:07:07,037] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"jdwiMGgBP1edM8bXgfVk\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'jdwiMGgBP1edM8bXgfVk\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:12,212] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"l6xpH2gBP1edM8bXitLH\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'l6xpH2gBP1edM8bXitLH\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T19:07:07,038] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"jtwiMGgBP1edM8bXgfVk\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'jtwiMGgBP1edM8bXgfVk\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:12,401] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"uqxsH2gBP1edM8bXv9sd\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'uqxsH2gBP1edM8bXv9sd\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T19:10:36,342] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"j9wiMGgBP1edM8bXgfVk\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'j9wiMGgBP1edM8bXgfVk\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:12,582] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"JqxsH2gBP1edM8bX0tyl\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'JqxsH2gBP1edM8bX0tyl\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T19:10:37,978] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kNwiMGgBP1edM8bXgfVk\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kNwiMGgBP1edM8bXgfVk\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:12,722] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"aa4RIGgBP1edM8bXjLRA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'aa4RIGgBP1edM8bXjLRA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T22:10:34,083] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kdwiMGgBP1edM8bXgfVk\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kdwiMGgBP1edM8bXgfVk\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:12,899] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Za4RIGgBP1edM8bXebQt\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Za4RIGgBP1edM8bXebQt\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T22:10:34,082] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"d9wiMGgBP1edM8bXbfXX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'d9wiMGgBP1edM8bXbfXX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:03,716] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"La7jH2gBP1edM8bXdzGV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'La7jH2gBP1edM8bXdzGV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-05T21:20:15,922] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"eNwiMGgBP1edM8bXcfXA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'eNwiMGgBP1edM8bXcfXA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:06,493] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"f7J9IWgBP1edM8bXGsfv\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'f7J9IWgBP1edM8bXGsfv\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T04:47:45,189] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"edwiMGgBP1edM8bXcfXA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'edwiMGgBP1edM8bXcfXA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:08,379] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gLJ9IWgBP1edM8bXGsfv\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gLJ9IWgBP1edM8bXGsfv\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T04:47:45,195] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AtwiMGgBP1edM8bXVvVo\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AtwiMGgBP1edM8bXVvVo\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:02:57,261] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gbJ9IWgBP1edM8bXGsfv\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gbJ9IWgBP1edM8bXGsfv\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T04:47:47,198] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"A9wiMGgBP1edM8bXVvVo\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'A9wiMGgBP1edM8bXVvVo\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:00,367] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"TbPIIWgBP1edM8bXLp3Z\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'TbPIIWgBP1edM8bXLp3Z\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:09:44,205] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"CNwiMGgBP1edM8bXYvUm\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'CNwiMGgBP1edM8bXYvUm\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:03:02,154] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UrPIIWgBP1edM8bXQZ2m\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UrPIIWgBP1edM8bXQZ2m\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:09:44,206] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"qdQZLWgBP1edM8bXIi9Q\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'qdQZLWgBP1edM8bXIi9Q\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:53:58,795] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EbJdIWgBP1edM8bXcG21\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EbJdIWgBP1edM8bXcG21\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T04:13:05,036] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"qtQZLWgBP1edM8bXIi9Q\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'qtQZLWgBP1edM8bXIi9Q\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:53:58,796] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"8rJdIWgBP1edM8bXvm3S\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'8rJdIWgBP1edM8bXvm3S\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T04:13:36,215] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"q9QZLWgBP1edM8bXIi9Q\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'q9QZLWgBP1edM8bXIi9Q\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:53:58,988] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"XrJdIWgBP1edM8bX0m5b\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'XrJdIWgBP1edM8bX0m5b\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T04:13:36,216] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"SNMGLWgBP1edM8bXNfl_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'SNMGLWgBP1edM8bXNfl_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:33:24,291] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"a7JeIWgBP1edM8bX43HP\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'a7JeIWgBP1edM8bX43HP\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T04:14:42,656] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"SdMGLWgBP1edM8bXNfl_\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'SdMGLWgBP1edM8bXNfl_\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:33:24,292] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"cLJeIWgBP1edM8bX93Fa\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'cLJeIWgBP1edM8bX93Fa\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T04:14:42,657] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"M9MFLWgBP1edM8bXJPYM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'M9MFLWgBP1edM8bXJPYM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:32:04,194] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"hrJ9IWgBP1edM8bXLscM\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'hrJ9IWgBP1edM8bXLscM\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T04:47:49,811] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"sdQZLWgBP1edM8bXNS8E\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'sdQZLWgBP1edM8bXNS8E\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:53:58,989] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Y7POIWgBP1edM8bXNa4l\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Y7POIWgBP1edM8bXNa4l\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:16:24,161] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"T9MGLWgBP1edM8bXSfkH\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'T9MGLWgBP1edM8bXSfkH\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-08T10:33:24,292] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ZLPOIWgBP1edM8bXNa4l\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ZLPOIWgBP1edM8bXNa4l\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:16:24,162] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_twiMGgBP1edM8bXS_Rg\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_twiMGgBP1edM8bXS_Rg\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T01:02:55,896] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"srPOIWgBP1edM8bXlq_O\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'srPOIWgBP1edM8bXlq_O\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:16:44,153] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"8N1bMGgBP1edM8bX-ZsE\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'8N1bMGgBP1edM8bX-ZsE\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:56,320] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"s7POIWgBP1edM8bXlq_O\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'s7POIWgBP1edM8bXlq_O\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:16:44,153] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9d1bMGgBP1edM8bX_Jvp\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9d1bMGgBP1edM8bX_Jvp\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:58,337] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"LrPNIWgBP1edM8bXXqxK\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'LrPNIWgBP1edM8bXXqxK\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:15:24,167] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9t1bMGgBP1edM8bX_Jvp\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9t1bMGgBP1edM8bX_Jvp\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:59,493] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"M7PNIWgBP1edM8bXcazS\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'M7PNIWgBP1edM8bXcazS\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:15:24,168] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-d1cMGgBP1edM8bXAJvT\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-d1cMGgBP1edM8bXAJvT\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:00,382] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"0LPOIWgBP1edM8bXSK6t\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'0LPOIWgBP1edM8bXSK6t\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:16:24,162] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-91cMGgBP1edM8bXBJu4\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-91cMGgBP1edM8bXBJu4\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:01,278] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"uLPOIWgBP1edM8bXqq9X\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'uLPOIWgBP1edM8bXqq9X\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:16:44,154] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_N1cMGgBP1edM8bXBJu4\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_N1cMGgBP1edM8bXBJu4\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:02,129] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"pbPQIWgBP1edM8bXCbPp\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'pbPQIWgBP1edM8bXCbPp\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:18:24,159] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"AN1cMGgBP1edM8bXCJyh\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'AN1cMGgBP1edM8bXCJyh\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:02,130] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EbPQIWgBP1edM8bXHbRx\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EbPQIWgBP1edM8bXHbRx\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:18:24,160] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"bd1bMGgBP1edM8bX1ZvQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'bd1bMGgBP1edM8bX1ZvQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:47,031] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"kLPMIWgBP1edM8bXc6no\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'kLPMIWgBP1edM8bXc6no\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:14:24,293] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"dt1bMGgBP1edM8bX4ZuQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'dt1bMGgBP1edM8bX4ZuQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:48,514] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"GLPUIWgBP1edM8bX_8KA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'GLPUIWgBP1edM8bX_8KA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:23:44,174] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"d91bMGgBP1edM8bX4ZuQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'d91bMGgBP1edM8bX4ZuQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:51,596] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"GbPUIWgBP1edM8bX_8KA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'GbPUIWgBP1edM8bX_8KA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:23:44,175] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"eN1bMGgBP1edM8bX4ZuQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'eN1bMGgBP1edM8bX4ZuQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:51,596] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"krPVIWgBP1edM8bXOsIY\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'krPVIWgBP1edM8bXOsIY\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:24:04,141] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ed1bMGgBP1edM8bX4ZuQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ed1bMGgBP1edM8bX4ZuQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:51,597] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"k7PVIWgBP1edM8bXOsIY\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'k7PVIWgBP1edM8bXOsIY\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:24:04,142] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"et1bMGgBP1edM8bX4ZuQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'et1bMGgBP1edM8bX4ZuQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:51,597] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"xrPoIWgBP1edM8bXiPmJ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'xrPoIWgBP1edM8bXiPmJ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:45:04,187] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"e91bMGgBP1edM8bX4ZuQ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'e91bMGgBP1edM8bX4ZuQ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:51,597] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"x7PoIWgBP1edM8bXiPmJ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'x7PoIWgBP1edM8bXiPmJ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:45:04,188] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fN1bMGgBP1edM8bXl5pN\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fN1bMGgBP1edM8bXl5pN\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:30,365] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"k7PSIWgBP1edM8bXybsW\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'k7PSIWgBP1edM8bXybsW\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:21:24,141] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"fd1bMGgBP1edM8bXl5pN\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'fd1bMGgBP1edM8bXl5pN\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:30,365] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"lLPSIWgBP1edM8bXybsW\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'lLPSIWgBP1edM8bXybsW\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:21:24,142] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ft1bMGgBP1edM8bXm5o-\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ft1bMGgBP1edM8bXm5o-\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:31,892] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"zLPoIWgBP1edM8bXm_k0\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'zLPoIWgBP1edM8bXm_k0\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:45:04,188] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"7t1bMGgBP1edM8bXppru\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'7t1bMGgBP1edM8bXppru\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:34,730] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_7PVIWgBP1edM8bXTcKg\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_7PVIWgBP1edM8bXTcKg\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:24:04,142] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"8N1bMGgBP1edM8bXqprW\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'8N1bMGgBP1edM8bXqprW\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:36,576] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"HrPVIWgBP1edM8bXE8II\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'HrPVIWgBP1edM8bXE8II\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:23:44,176] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"9N1bMGgBP1edM8bXrpq-\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'9N1bMGgBP1edM8bXrpq-\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:38,524] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ILPSIWgBP1edM8bXorsB\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ILPSIWgBP1edM8bXorsB\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:21:04,164] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"-N1bMGgBP1edM8bXupp4\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'-N1bMGgBP1edM8bXupp4\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:40,174] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ALPSIWgBP1edM8bX3Lya\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ALPSIWgBP1edM8bX3Lya\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:21:24,142] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_N1bMGgBP1edM8bXxpox\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_N1bMGgBP1edM8bXxpox\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:43,187] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ILQPImgBP1edM8bX5mrS\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ILQPImgBP1edM8bX5mrS\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:28:04,240] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"_t1bMGgBP1edM8bXypoY\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'_t1bMGgBP1edM8bXypoY\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:45,157] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"IbQPImgBP1edM8bX5mrS\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'IbQPImgBP1edM8bX5mrS\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:28:04,241] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ft1bMGgBP1edM8bX6Ztc\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ft1bMGgBP1edM8bX6Ztc\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:53,693] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"5rQQImgBP1edM8bXgmtA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'5rQQImgBP1edM8bXgmtA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:28:44,212] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"gN1bMGgBP1edM8bX7ZtF\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'gN1bMGgBP1edM8bX7ZtF\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:55,250] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"57QQImgBP1edM8bXgmtA\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'57QQImgBP1edM8bXgmtA\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:28:44,212] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"q91aMGgBP1edM8bX55iB\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'q91aMGgBP1edM8bX55iB\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:04:38,035] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"TLTxIWgBP1edM8bXExIu\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'TLTxIWgBP1edM8bXExIu\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:54:24,161] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Ad1bMGgBP1edM8bXXJqz\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Ad1bMGgBP1edM8bXXJqz\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:09,704] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"UrTxIWgBP1edM8bXJhK2\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'UrTxIWgBP1edM8bXJhK2\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:54:24,162] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Bt1bMGgBP1edM8bXcJo7\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Bt1bMGgBP1edM8bXcJo7\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:05:10,891] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"J7QPImgBP1edM8bX-WqG\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'J7QPImgBP1edM8bX-WqG\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:28:04,241] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mN1cMGgBP1edM8bXwJ5I\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mN1cMGgBP1edM8bXwJ5I\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:46,924] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"o7TxIWgBP1edM8bXmxPq\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'o7TxIWgBP1edM8bXmxPq\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:55:04,387] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"md1cMGgBP1edM8bXwJ5I\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'md1cMGgBP1edM8bXwJ5I\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:48,727] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"DrTxIWgBP1edM8bXrxRw\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'DrTxIWgBP1edM8bXrxRw\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T06:55:04,388] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mt1cMGgBP1edM8bXxJ4x\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mt1cMGgBP1edM8bXxJ4x\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:50,422] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"BLQQImgBP1edM8bXNGsi\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'BLQQImgBP1edM8bXNGsi\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:28:24,214] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"m91cMGgBP1edM8bXxJ4x\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'m91cMGgBP1edM8bXxJ4x\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:50,566] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"mbQQImgBP1edM8bXIGqX\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'mbQQImgBP1edM8bXIGqX\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:28:24,213] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"nN1cMGgBP1edM8bXxJ4x\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'nN1cMGgBP1edM8bXxJ4x\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:51,055] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"LrQSImgBP1edM8bXV3EI\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'LrQSImgBP1edM8bXV3EI\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:30:44,206] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"nd1cMGgBP1edM8bXxJ4x\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'nd1cMGgBP1edM8bXxJ4x\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:51,249] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"L7QSImgBP1edM8bXV3EI\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'L7QSImgBP1edM8bXV3EI\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:30:44,207] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"o91cMGgBP1edM8bXz57p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'o91cMGgBP1edM8bXz57p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:51,249] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"NbQSImgBP1edM8bXanGU\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'NbQSImgBP1edM8bXanGU\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:30:44,207] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"pN1cMGgBP1edM8bXz57p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'pN1cMGgBP1edM8bXz57p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:52,620] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"YLQQImgBP1edM8bXvGza\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'YLQQImgBP1edM8bXvGza\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:29:04,199] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"pd1cMGgBP1edM8bXz57p\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'pd1cMGgBP1edM8bXz57p\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:53,920] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"y7QQImgBP1edM8bX0Gxh\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'y7QQImgBP1edM8bX0Gxh\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:29:04,200] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Lt1cMGgBP1edM8bX-p_l\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Lt1cMGgBP1edM8bX-p_l\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:03,717] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"rLQRImgBP1edM8bXHm2C\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'rLQRImgBP1edM8bXHm2C\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:29:24,207] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"MN1cMGgBP1edM8bX_p_N\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'MN1cMGgBP1edM8bX_p_N\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:05,375] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"srQRImgBP1edM8bXMm0L\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'srQRImgBP1edM8bXMm0L\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:29:24,208] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Md1cMGgBP1edM8bX_p_N\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Md1cMGgBP1edM8bX_p_N\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:06,058] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"7bQQImgBP1edM8bXlWvJ\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'7bQQImgBP1edM8bXlWvJ\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:28:44,213] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ot1dMGgBP1edM8bXCp-I\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ot1dMGgBP1edM8bXCp-I\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:06,292] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"j7QRImgBP1edM8bXbG6l\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'j7QRImgBP1edM8bXbG6l\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:29:44,214] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"o91dMGgBP1edM8bXCp-I\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'o91dMGgBP1edM8bXCp-I\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:07,782] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"JLQRImgBP1edM8bXWW4e\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'JLQRImgBP1edM8bXWW4e\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:29:44,213] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"pN1dMGgBP1edM8bXCp-I\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'pN1dMGgBP1edM8bXCp-I\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:08,180] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"uLQWImgBP1edM8bXAHuV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'uLQWImgBP1edM8bXAHuV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:34:44,209] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"pd1dMGgBP1edM8bXCp-I\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'pd1dMGgBP1edM8bXCp-I\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:09,433] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ubQWImgBP1edM8bXAHuV\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ubQWImgBP1edM8bXAHuV\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:34:44,209] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"IN1cMGgBP1edM8bX559b\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'IN1cMGgBP1edM8bX559b\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:59,267] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"EbQWImgBP1edM8bXiX1P\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'EbQWImgBP1edM8bXiX1P\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:35:24,217] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"It1cMGgBP1edM8bX659D\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'It1cMGgBP1edM8bX659D\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:06:59,732] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"ErQWImgBP1edM8bXiX1P\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'ErQWImgBP1edM8bXiX1P\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:35:24,218] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"I91cMGgBP1edM8bX659D\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'I91cMGgBP1edM8bX659D\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:00,679] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"frQZImgBP1edM8bXDYTb\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'frQZImgBP1edM8bXDYTb\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:38:04,210] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Jd1cMGgBP1edM8bX758r\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Jd1cMGgBP1edM8bX758r\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:01,299] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"f7QZImgBP1edM8bXDYTb\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'f7QZImgBP1edM8bXDYTb\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:38:04,211] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Kd1cMGgBP1edM8bX858T\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Kd1cMGgBP1edM8bX858T\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:01,781] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"HLQXImgBP1edM8bXh4A4\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'HLQXImgBP1edM8bXh4A4\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:36:24,228] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"K91cMGgBP1edM8bX9p_7\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'K91cMGgBP1edM8bX9p_7\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:02,962] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"HbQXImgBP1edM8bXh4A4\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'HbQXImgBP1edM8bXh4A4\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-06T07:36:24,229] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400},{\"index\":\"reindexed-v7-filebeat-2019\",\"type\":\"_doc\",\"id\":\"Nt1dMGgBP1edM8bXTKDy\",\"cause\":{\"type\":\"mapper_parsing_exception\",\"reason\":\"failed to parse field [@timestamp] of type [date] in document with id \'Nt1dMGgBP1edM8bXTKDy\'\",\"caused_by\":{\"type\":\"illegal_argument_exception\",\"reason\":\"failed to parse date field [2019-01-09T02:07:23,126] with format [strict_date_optional_time||epoch_millis]\",\"caused_by\":{\"type\":\"date_time_parse_exception\",\"reason\":\"Failed to parse with all enclosed parsers\"}}},\"status\":400}]}}', + runningReindexCount: null, + }, + type: 'upgrade-assistant-reindex-operation', +}; diff --git a/x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts b/x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts new file mode 100644 index 0000000000000..daeb71ef12382 --- /dev/null +++ b/x-pack/test/api_integration/apis/upgrade_assistant/upgrade_assistant.ts @@ -0,0 +1,34 @@ +/* + * 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 expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../ftr_provider_context'; +import { reindexOperationWithLargeErrorMessage } from './reindex_operation_with_large_error_message'; + +export default function ({ getService }: FtrProviderContext) { + const es = getService('legacyEs'); + + describe('Reindex operation saved object', function () { + const dotKibanaIndex = '.kibana'; + const fakeSavedObjectId = 'fakeSavedObjectId'; + + after(async () => { + // Clean up the fake saved object we created. This will error if the test failed. + return await es.delete({ index: dotKibanaIndex, id: fakeSavedObjectId }); + }); + + it('is indexed successfully with immense error message', async () => { + // Guards against regression of https://github.com/elastic/kibana/pull/71710. + const result = await es.create({ + index: dotKibanaIndex, // In normal operation this would be the .kibana-n index. + id: fakeSavedObjectId, + body: reindexOperationWithLargeErrorMessage, + }); + expect(result).to.be.ok(); + }); + }); +} From a540cafb85eb92640e4d3963ba0bef6ce95a8cb6 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Tue, 21 Jul 2020 07:04:40 -0700 Subject: [PATCH 50/77] Add doc titles to ES UI apps (#71045) * Add doc titles to CCR, ILM, Index Management, Ingest Node Pipelines, License Management, Remote Clusters, Rollup Jobs, Watcher, and Upgrade Assistant. Clear doc title when leaving Dev Tools. * Refactor Watcher boot file to follow index-oriented pattern of other plugins. --- src/plugins/dev_tools/public/application.tsx | 1 + .../public/plugin.ts | 10 +++++- .../public/plugin.tsx | 10 +++++- .../application/mount_management_section.ts | 18 +++++++++-- .../plugins/ingest_pipelines/public/plugin.ts | 24 +++++++++++--- .../license_management/public/plugin.ts | 17 +++++++--- .../plugins/remote_clusters/public/plugin.ts | 16 +++++++++- x-pack/plugins/rollup/public/plugin.ts | 28 ++++++++++------ .../application/mount_management_section.ts | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - .../upgrade_assistant/public/plugin.ts | 27 +++++++++++++--- .../application/{boot.tsx => index.tsx} | 3 +- x-pack/plugins/watcher/public/plugin.ts | 32 ++++++++++++++----- 14 files changed, 149 insertions(+), 40 deletions(-) rename x-pack/plugins/watcher/public/application/{boot.tsx => index.tsx} (94%) diff --git a/src/plugins/dev_tools/public/application.tsx b/src/plugins/dev_tools/public/application.tsx index 788ec1f145e2a..46f09a8ebb879 100644 --- a/src/plugins/dev_tools/public/application.tsx +++ b/src/plugins/dev_tools/public/application.tsx @@ -203,6 +203,7 @@ export function renderApp( }); return () => { + chrome.docTitle.reset(); ReactDOM.unmountComponentAtNode(element); unlisten(); }; diff --git a/x-pack/plugins/cross_cluster_replication/public/plugin.ts b/x-pack/plugins/cross_cluster_replication/public/plugin.ts index 7aa0d19fa976f..80e67110c20c7 100644 --- a/x-pack/plugins/cross_cluster_replication/public/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/public/plugin.ts @@ -45,12 +45,15 @@ export class CrossClusterReplicationPlugin implements Plugin { const [coreStart] = await getStartServices(); const { + chrome: { docTitle }, i18n: { Context: I18nContext }, docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, application: { getUrlForApp }, } = coreStart; - return mountApp({ + docTitle.change(PLUGIN.TITLE); + + const unmountAppCallback = await mountApp({ element, setBreadcrumbs, I18nContext, @@ -59,6 +62,11 @@ export class CrossClusterReplicationPlugin implements Plugin { history, getUrlForApp, }); + + return () => { + docTitle.reset(); + unmountAppCallback(); + }; }, }); diff --git a/x-pack/plugins/index_lifecycle_management/public/plugin.tsx b/x-pack/plugins/index_lifecycle_management/public/plugin.tsx index 832d066dfa33b..1d26aa53752a9 100644 --- a/x-pack/plugins/index_lifecycle_management/public/plugin.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/plugin.tsx @@ -44,18 +44,26 @@ export class IndexLifecycleManagementPlugin { mount: async ({ element, history }) => { const [coreStart] = await getStartServices(); const { + chrome: { docTitle }, i18n: { Context: I18nContext }, docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, application: { navigateToApp }, } = coreStart; + docTitle.change(PLUGIN.TITLE); + // Initialize additional services. initDocumentation( `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/` ); const { renderApp } = await import('./application'); - return renderApp(element, I18nContext, history, navigateToApp); + const unmountAppCallback = renderApp(element, I18nContext, history, navigateToApp); + + return () => { + docTitle.reset(); + unmountAppCallback(); + }; }, }); diff --git a/x-pack/plugins/index_management/public/application/mount_management_section.ts b/x-pack/plugins/index_management/public/application/mount_management_section.ts index 6145ea410b0e8..6257b68430cf0 100644 --- a/x-pack/plugins/index_management/public/application/mount_management_section.ts +++ b/x-pack/plugins/index_management/public/application/mount_management_section.ts @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import { i18n } from '@kbn/i18n'; import { CoreSetup } from 'src/core/public'; import { ManagementAppMountParams } from 'src/plugins/management/public/'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; import { IngestManagerSetup } from '../../../ingest_manager/public'; +import { PLUGIN } from '../../common/constants'; import { ExtensionsService } from '../services'; import { IndexMgmtMetricsType } from '../types'; import { AppDependencies } from './app_context'; @@ -34,7 +36,14 @@ export async function mountManagementSection( ) { const { element, setBreadcrumbs, history } = params; const [core] = await coreSetup.getStartServices(); - const { docLinks, fatalErrors, application } = core; + const { + docLinks, + fatalErrors, + application, + chrome: { docTitle }, + } = core; + + docTitle.change(PLUGIN.getI18nName(i18n)); breadcrumbService.setup(setBreadcrumbs); documentationService.setup(docLinks); @@ -53,5 +62,10 @@ export async function mountManagementSection( setBreadcrumbs, }; - return renderApp(element, { core, dependencies: appDependencies }); + const unmountAppCallback = renderApp(element, { core, dependencies: appDependencies }); + + return () => { + docTitle.reset(); + unmountAppCallback(); + }; } diff --git a/x-pack/plugins/ingest_pipelines/public/plugin.ts b/x-pack/plugins/ingest_pipelines/public/plugin.ts index 945e825c88fbd..339068f185d1d 100644 --- a/x-pack/plugins/ingest_pipelines/public/plugin.ts +++ b/x-pack/plugins/ingest_pipelines/public/plugin.ts @@ -14,22 +14,36 @@ import { Dependencies } from './types'; export class IngestPipelinesPlugin implements Plugin { public setup(coreSetup: CoreSetup, plugins: Dependencies): void { const { management, usageCollection } = plugins; - const { http } = coreSetup; + const { http, getStartServices } = coreSetup; // Initialize services uiMetricService.setup(usageCollection); apiService.setup(http, uiMetricService); + const pluginName = i18n.translate('xpack.ingestPipelines.appTitle', { + defaultMessage: 'Ingest Node Pipelines', + }); + management.sections.section.ingest.registerApp({ id: PLUGIN_ID, order: 1, - title: i18n.translate('xpack.ingestPipelines.appTitle', { - defaultMessage: 'Ingest Node Pipelines', - }), + title: pluginName, mount: async (params) => { + const [coreStart] = await getStartServices(); + + const { + chrome: { docTitle }, + } = coreStart; + + docTitle.change(pluginName); + const { mountManagementSection } = await import('./application/mount_management_section'); + const unmountAppCallback = await mountManagementSection(coreSetup, params); - return await mountManagementSection(coreSetup, params); + return () => { + docTitle.reset(); + unmountAppCallback(); + }; }, }); } diff --git a/x-pack/plugins/license_management/public/plugin.ts b/x-pack/plugins/license_management/public/plugin.ts index b99ea387121ee..27e31726f9a19 100644 --- a/x-pack/plugins/license_management/public/plugin.ts +++ b/x-pack/plugins/license_management/public/plugin.ts @@ -55,22 +55,27 @@ export class LicenseManagementUIPlugin title: PLUGIN.title, order: 0, mount: async ({ element, setBreadcrumbs, history }) => { - const [core, { telemetry }] = await getStartServices(); + const [coreStart, { telemetry }] = await getStartServices(); const initialLicense = await plugins.licensing.license$.pipe(first()).toPromise(); // Setup documentation links - const { docLinks } = core; + const { + docLinks, + chrome: { docTitle }, + } = coreStart; const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = docLinks; const esBase = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}`; const appDocLinks = { security: `${esBase}/security-settings.html`, }; + docTitle.change(PLUGIN.title); + // Setup services this.breadcrumbService.setup(setBreadcrumbs); const appDependencies: AppDependencies = { - core, + core: coreStart, config, plugins: { licensing, @@ -87,8 +92,12 @@ export class LicenseManagementUIPlugin }; const { renderApp } = await import('./application'); + const unmountAppCallback = renderApp(element, appDependencies); - return renderApp(element, appDependencies); + return () => { + docTitle.reset(); + unmountAppCallback(); + }; }, }); diff --git a/x-pack/plugins/remote_clusters/public/plugin.ts b/x-pack/plugins/remote_clusters/public/plugin.ts index 33222dd7052e9..24cb148d24d84 100644 --- a/x-pack/plugins/remote_clusters/public/plugin.ts +++ b/x-pack/plugins/remote_clusters/public/plugin.ts @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import { CoreSetup, Plugin, CoreStart, PluginInitializerContext } from 'kibana/public'; +import { PLUGIN } from '../common/constants'; import { init as initBreadcrumbs } from './application/services/breadcrumb'; import { init as initDocumentation } from './application/services/documentation'; import { init as initHttp } from './application/services/http'; @@ -43,11 +44,14 @@ export class RemoteClustersUIPlugin mount: async ({ element, setBreadcrumbs, history }) => { const [core] = await getStartServices(); const { + chrome: { docTitle }, i18n: { Context: i18nContext }, docLinks, fatalErrors, } = core; + docTitle.change(PLUGIN.getI18nName()); + // Initialize services initBreadcrumbs(setBreadcrumbs); initDocumentation(docLinks); @@ -58,7 +62,17 @@ export class RemoteClustersUIPlugin const isCloudEnabled = Boolean(cloud?.isCloudEnabled); const { renderApp } = await import('./application'); - return renderApp(element, i18nContext, { isCloudEnabled }, history); + const unmountAppCallback = await renderApp( + element, + i18nContext, + { isCloudEnabled }, + history + ); + + return () => { + docTitle.reset(); + unmountAppCallback(); + }; }, }); } diff --git a/x-pack/plugins/rollup/public/plugin.ts b/x-pack/plugins/rollup/public/plugin.ts index 73ee675b089c8..49545f090d923 100644 --- a/x-pack/plugins/rollup/public/plugin.ts +++ b/x-pack/plugins/rollup/public/plugin.ts @@ -75,21 +75,31 @@ export class RollupPlugin implements Plugin { }); } + const pluginName = i18n.translate('xpack.rollupJobs.appTitle', { + defaultMessage: 'Rollup Jobs', + }); + management.sections.section.data.registerApp({ id: 'rollup_jobs', - title: i18n.translate('xpack.rollupJobs.appTitle', { defaultMessage: 'Rollup Jobs' }), + title: pluginName, order: 4, async mount(params) { - params.setBreadcrumbs([ - { - text: i18n.translate('xpack.rollupJobs.breadcrumbsTitle', { - defaultMessage: 'Rollup Jobs', - }), - }, - ]); + const [coreStart] = await core.getStartServices(); + + const { + chrome: { docTitle }, + } = coreStart; + + docTitle.change(pluginName); + params.setBreadcrumbs([{ text: pluginName }]); + const { renderApp } = await import('./application'); + const unmountAppCallback = await renderApp(core, params); - return renderApp(core, params); + return () => { + docTitle.reset(); + unmountAppCallback(); + }; }, }); } diff --git a/x-pack/plugins/snapshot_restore/public/application/mount_management_section.ts b/x-pack/plugins/snapshot_restore/public/application/mount_management_section.ts index b06a60a5c830f..eb2046f065e17 100644 --- a/x-pack/plugins/snapshot_restore/public/application/mount_management_section.ts +++ b/x-pack/plugins/snapshot_restore/public/application/mount_management_section.ts @@ -48,7 +48,6 @@ export async function mountManagementSection( const unmountAppCallback = renderApp(element, appDependencies); return () => { - // Change tab label back to Kibana. docTitle.reset(); unmountAppCallback(); }; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index c1f0dc4c0c60c..4175f76ad7ba8 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -12332,7 +12332,6 @@ "xpack.reporting.shareContextMenu.pdfReportsButtonLabel": "PDF レポート", "xpack.reporting.shareContextMenu.pngReportsButtonLabel": "PNG レポート", "xpack.rollupJobs.appTitle": "ロールアップジョブ", - "xpack.rollupJobs.breadcrumbsTitle": "ロールアップジョブ", "xpack.rollupJobs.create.backButton.label": "戻る", "xpack.rollupJobs.create.dateTypeField": "日付", "xpack.rollupJobs.create.errors.dateHistogramFieldMissing": "日付フィールドが必要です。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 0f2a51c8ff889..33d60dbd17700 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -12338,7 +12338,6 @@ "xpack.reporting.shareContextMenu.pdfReportsButtonLabel": "PDF 报告", "xpack.reporting.shareContextMenu.pngReportsButtonLabel": "PNG 报告", "xpack.rollupJobs.appTitle": "汇总/打包作业", - "xpack.rollupJobs.breadcrumbsTitle": "汇总/打包作业", "xpack.rollupJobs.create.backButton.label": "上一步", "xpack.rollupJobs.create.dateTypeField": "日期", "xpack.rollupJobs.create.errors.dateHistogramFieldMissing": "“日期”字段必填。", diff --git a/x-pack/plugins/upgrade_assistant/public/plugin.ts b/x-pack/plugins/upgrade_assistant/public/plugin.ts index 01c1a6a4659d5..98f1b8351b88b 100644 --- a/x-pack/plugins/upgrade_assistant/public/plugin.ts +++ b/x-pack/plugins/upgrade_assistant/public/plugin.ts @@ -3,6 +3,7 @@ * 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'; import { Plugin, CoreSetup, PluginInitializerContext } from 'src/core/public'; @@ -21,22 +22,38 @@ export class UpgradeAssistantUIPlugin implements Plugin { constructor(private ctx: PluginInitializerContext) {} setup(coreSetup: CoreSetup, { cloud, management }: Dependencies) { const { enabled } = this.ctx.config.get(); + if (!enabled) { return; } + const appRegistrar = management.sections.section.stack; const isCloudEnabled = Boolean(cloud?.isCloudEnabled); + const pluginName = i18n.translate('xpack.upgradeAssistant.appTitle', { + defaultMessage: '{version} Upgrade Assistant', + values: { version: `${NEXT_MAJOR_VERSION}.0` }, + }); + appRegistrar.registerApp({ id: 'upgrade_assistant', - title: i18n.translate('xpack.upgradeAssistant.appTitle', { - defaultMessage: '{version} Upgrade Assistant', - values: { version: `${NEXT_MAJOR_VERSION}.0` }, - }), + title: pluginName, order: 1, async mount(params) { + const [coreStart] = await coreSetup.getStartServices(); + + const { + chrome: { docTitle }, + } = coreStart; + + docTitle.change(pluginName); const { mountManagementSection } = await import('./application/mount_management_section'); - return mountManagementSection(coreSetup, isCloudEnabled, params); + const unmountAppCallback = await mountManagementSection(coreSetup, isCloudEnabled, params); + + return () => { + docTitle.reset(); + unmountAppCallback(); + }; }, }); } diff --git a/x-pack/plugins/watcher/public/application/boot.tsx b/x-pack/plugins/watcher/public/application/index.tsx similarity index 94% rename from x-pack/plugins/watcher/public/application/boot.tsx rename to x-pack/plugins/watcher/public/application/index.tsx index 8461bd65bbd5e..70a63e6a04dd6 100644 --- a/x-pack/plugins/watcher/public/application/boot.tsx +++ b/x-pack/plugins/watcher/public/application/index.tsx @@ -17,7 +17,7 @@ interface BootDeps extends AppDeps { I18nContext: any; } -export const boot = (bootDeps: BootDeps) => { +export const renderApp = (bootDeps: BootDeps) => { const { I18nContext, element, savedObjects, ...appDeps } = bootDeps; setHttpClient(appDeps.http); @@ -29,6 +29,7 @@ export const boot = (bootDeps: BootDeps) => { , element ); + return () => { unmountComponentAtNode(element); }; diff --git a/x-pack/plugins/watcher/public/plugin.ts b/x-pack/plugins/watcher/public/plugin.ts index 6b66c341497b7..98b49af15019b 100644 --- a/x-pack/plugins/watcher/public/plugin.ts +++ b/x-pack/plugins/watcher/public/plugin.ts @@ -30,20 +30,31 @@ export class WatcherUIPlugin implements Plugin { ) { const esSection = management.sections.section.insightsAndAlerting; + const pluginName = i18n.translate( + 'xpack.watcher.sections.watchList.managementSection.watcherDisplayName', + { defaultMessage: 'Watcher' } + ); + const watcherESApp = esSection.registerApp({ id: 'watcher', - title: i18n.translate( - 'xpack.watcher.sections.watchList.managementSection.watcherDisplayName', - { defaultMessage: 'Watcher' } - ), + title: pluginName, order: 3, mount: async ({ element, setBreadcrumbs, history }) => { - const [core] = await getStartServices(); - const { i18n: i18nDep, docLinks, savedObjects, application } = core; - const { boot } = await import('./application/boot'); + const [coreStart] = await getStartServices(); + const { + chrome: { docTitle }, + i18n: i18nDep, + docLinks, + savedObjects, + application, + } = coreStart; + + docTitle.change(pluginName); + + const { renderApp } = await import('./application'); const { TimeBuckets } = await import('./legacy'); - return boot({ + const unmountAppCallback = renderApp({ // Skip the first license status, because that's already been used to determine // whether to include Watcher. licenseStatus$: licensing.license$.pipe(skip(1), map(licenseToLicenseStatus)), @@ -60,6 +71,11 @@ export class WatcherUIPlugin implements Plugin { history, getUrlForApp: application.getUrlForApp, }); + + return () => { + docTitle.reset(); + unmountAppCallback(); + }; }, }); From 245940ac11153f00825be947d86b7b145a6fdc94 Mon Sep 17 00:00:00 2001 From: Jonathan Buttner <56361221+jonathan-buttner@users.noreply.github.com> Date: Tue, 21 Jul 2020 10:56:06 -0400 Subject: [PATCH 51/77] Only check that the event ids are the same in arrays (#72624) --- x-pack/test/api_integration/apis/endpoint/resolver.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/x-pack/test/api_integration/apis/endpoint/resolver.ts b/x-pack/test/api_integration/apis/endpoint/resolver.ts index c8217f2b6872a..fa980aed30502 100644 --- a/x-pack/test/api_integration/apis/endpoint/resolver.ts +++ b/x-pack/test/api_integration/apis/endpoint/resolver.ts @@ -17,7 +17,10 @@ import { ResolverNodeStats, ResolverRelatedAlerts, } from '../../../../plugins/security_solution/common/endpoint/types'; -import { parentEntityId } from '../../../../plugins/security_solution/common/endpoint/models/event'; +import { + parentEntityId, + eventId, +} from '../../../../plugins/security_solution/common/endpoint/models/event'; import { FtrProviderContext } from '../../ftr_provider_context'; import { Event, @@ -167,10 +170,14 @@ const compareArrays = ( if (lengthCheck) { expect(expected.length).to.eql(toTest.length); } + toTest.forEach((toTestEvent) => { expect( expected.find((arrEvent) => { - return JSON.stringify(arrEvent) === JSON.stringify(toTestEvent); + // we're only checking that the event ids are the same here. The reason we can't check the entire document + // is because ingest pipelines are used to add fields to the document when it is received by elasticsearch, + // therefore it will not be the same as the document created by the generator + return eventId(toTestEvent) === eventId(arrEvent); }) ).to.be.ok(); }); From 42d2b7def5d48c40faf9eaa92db33f4fa8914c55 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Tue, 21 Jul 2020 16:16:47 +0100 Subject: [PATCH 52/77] [ci][apm-ui] fix argument name for disabling pr comments (#72633) --- .ci/end2end.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/end2end.groovy b/.ci/end2end.groovy index ee117d362d59b..2cdc6d1c297cd 100644 --- a/.ci/end2end.groovy +++ b/.ci/end2end.groovy @@ -111,7 +111,7 @@ pipeline { } } cleanup { - notifyBuildResult(notifyPRComment: false, analyzeFlakey: false, shouldNotify: false) + notifyBuildResult(prComment: false, analyzeFlakey: false, shouldNotify: false) } } } From a7a2b7cb4c58e9d9228580e907dcbd1c88781006 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 21 Jul 2020 09:26:05 -0600 Subject: [PATCH 53/77] [docs] remove references to tile map visualization in supported aggregations (#72493) --- docs/visualize/aggregations.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/visualize/aggregations.asciidoc b/docs/visualize/aggregations.asciidoc index 868e66d0f4e36..ef38f716f2303 100644 --- a/docs/visualize/aggregations.asciidoc +++ b/docs/visualize/aggregations.asciidoc @@ -85,9 +85,9 @@ Bucket aggregations sort documents into buckets, depending on the contents of th {ref}/search-aggregations-bucket-filter-aggregation.html[Filter]:: Each filter creates a bucket of documents. You can specify a filter as a <> or <> query string. -{ref}/search-aggregations-bucket-geohashgrid-aggregation.html[Geohash]:: Displays points based on a geohash. Supported by the tile map and data table visualizations. +{ref}/search-aggregations-bucket-geohashgrid-aggregation.html[Geohash]:: Displays points based on a geohash. Supported by data table visualizations and <>. -{ref}/search-aggregations-bucket-geotilegrid-aggregation.html[Geotile]:: Groups points based on web map tiling. Supported by the tile map and data table visualizations. +{ref}/search-aggregations-bucket-geotilegrid-aggregation.html[Geotile]:: Groups points based on web map tiling. Supported by data table visualizations and <>. {ref}/search-aggregations-bucket-histogram-aggregation.html[Histogram]:: Builds from a numeric field. From 98fabd46907287dff533f435ffb2195bac63521a Mon Sep 17 00:00:00 2001 From: Tre Date: Tue, 21 Jul 2020 09:58:21 -0600 Subject: [PATCH 54/77] [QA][Code Coverage] Fixup Team Assignment (#72467) --- .../__tests__/mocks/team_assign_mock.json | 3 ++ .../__tests__/team_assignment.test.js | 45 +++++++++++++++++++ .../ingest_coverage/constants.js | 2 +- .../team_assignment/get_data.js | 14 +++--- .../ingest_coverage/team_assignment/index.js | 32 ++++++++----- .../team_assignment/update_ingest_pipeline.js | 4 +- .../shell_scripts/assign_teams.sh | 2 +- 7 files changed, 81 insertions(+), 21 deletions(-) create mode 100644 src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.json create mode 100644 src/dev/code_coverage/ingest_coverage/__tests__/team_assignment.test.js diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.json b/src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.json new file mode 100644 index 0000000000000..355c484a84fa3 --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.json @@ -0,0 +1,3 @@ +{ + "abc": "123" +} diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/team_assignment.test.js b/src/dev/code_coverage/ingest_coverage/__tests__/team_assignment.test.js new file mode 100644 index 0000000000000..e597ffb5d2f4b --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/__tests__/team_assignment.test.js @@ -0,0 +1,45 @@ +/* + * 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 expect from '@kbn/expect'; +import { fetch } from '../team_assignment/get_data'; +import { noop } from '../utils'; + +describe(`Team Assignment`, () => { + const mockPath = 'src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.json'; + describe(`fetch fn`, () => { + it(`should be a fn`, () => { + expect(typeof fetch).to.be('function'); + }); + describe(`applied to a path that exists`, () => { + it(`should return the contents of the path`, () => { + const sut = fetch(mockPath); + expect(sut.chain(JSON.parse)).to.have.property('abc'); + }); + }); + describe(`applied to an non-existing path`, () => { + it(`should return a Left with the error message within`, () => { + const expectLeft = (err) => + expect(err.message).to.contain('ENOENT: no such file or directory'); + + fetch('fake_path.json').fold(expectLeft, noop); + }); + }); + }); +}); diff --git a/src/dev/code_coverage/ingest_coverage/constants.js b/src/dev/code_coverage/ingest_coverage/constants.js index ae3079afd911d..f2f467e461ae5 100644 --- a/src/dev/code_coverage/ingest_coverage/constants.js +++ b/src/dev/code_coverage/ingest_coverage/constants.js @@ -32,4 +32,4 @@ export const TEAM_ASSIGNMENT_PIPELINE_NAME = process.env.PIPELINE_NAME || 'team_ export const CODE_COVERAGE_CI_JOB_NAME = 'elastic+kibana+code-coverage'; export const RESEARCH_CI_JOB_NAME = 'elastic+kibana+qa-research'; export const CI_JOB_NAME = process.env.COVERAGE_JOB_NAME || RESEARCH_CI_JOB_NAME; -export const RESEARCH_CLUSTER_ES_HOST = process.env.ES_HOST || 'http://localhost:9200'; +export const ES_HOST = process.env.ES_HOST || 'http://localhost:9200'; diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/get_data.js b/src/dev/code_coverage/ingest_coverage/team_assignment/get_data.js index d9fbf5690d8a4..34526a2f79302 100644 --- a/src/dev/code_coverage/ingest_coverage/team_assignment/get_data.js +++ b/src/dev/code_coverage/ingest_coverage/team_assignment/get_data.js @@ -19,13 +19,15 @@ import { readFileSync } from 'fs'; import { resolve } from 'path'; -import { fromNullable } from '../either'; +import { tryCatch as tc } from '../either'; const ROOT = resolve(__dirname, '../../../../..'); + const resolveFromRoot = resolve.bind(null, ROOT); -const path = ` -src/dev/code_coverage/ingest_coverage/team_assignment/ingestion_pipeline_painless.json`; -const resolved = resolveFromRoot(path.trimStart()); -const getContents = (scriptPath) => readFileSync(scriptPath, 'utf8'); -export const fetch = () => fromNullable(resolved).map(getContents); +const resolved = (path) => () => resolveFromRoot(path); + +const getContents = (path) => tc(() => readFileSync(path, 'utf8')); + +// fetch :: String -> Left | Right +export const fetch = (path) => tc(resolved(path)).chain(getContents); diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/index.js b/src/dev/code_coverage/ingest_coverage/team_assignment/index.js index 301f7fb2dee2f..11f9748708283 100644 --- a/src/dev/code_coverage/ingest_coverage/team_assignment/index.js +++ b/src/dev/code_coverage/ingest_coverage/team_assignment/index.js @@ -20,29 +20,39 @@ import { run } from '@kbn/dev-utils'; import { TEAM_ASSIGNMENT_PIPELINE_NAME } from '../constants'; import { fetch } from './get_data'; -import { noop } from '../utils'; import { update } from './update_ingest_pipeline'; -export const uploadTeamAssignmentJson = () => run(execute, { description }); - const updatePipeline = update(TEAM_ASSIGNMENT_PIPELINE_NAME); -function execute({ flags, log }) { +const execute = ({ flags, log }) => { if (flags.verbose) log.verbose(`### Verbose logging enabled`); - fetch().fold(noop, updatePipeline(log)); + const logLeft = handleErr(log); + const updateAndLog = updatePipeline(log); + + const { path } = flags; + + fetch(path).fold(logLeft, updateAndLog); +}; + +function handleErr(log) { + return (msg) => log.error(msg); } -function description() { - return ` +const description = ` Upload the latest team assignment pipeline def from src, to the cluster. + `; -Examples: +const flags = { + string: ['path', 'verbose'], + help: ` +--path Required, path to painless definition for team assignment. + `, +}; -node scripts/load_team_assignment.js --verbose +const usage = 'node scripts/load_team_assignment.js --verbose --path PATH_TO_PAINLESS_SCRIPT.json'; - `; -} +export const uploadTeamAssignmentJson = () => run(execute, { description, flags, usage }); diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/update_ingest_pipeline.js b/src/dev/code_coverage/ingest_coverage/team_assignment/update_ingest_pipeline.js index 03844b2a5dd32..22a9d0a461ebf 100644 --- a/src/dev/code_coverage/ingest_coverage/team_assignment/update_ingest_pipeline.js +++ b/src/dev/code_coverage/ingest_coverage/team_assignment/update_ingest_pipeline.js @@ -18,12 +18,12 @@ */ import { createFailError } from '@kbn/dev-utils'; -import { RESEARCH_CLUSTER_ES_HOST } from '../constants'; +import { ES_HOST } from '../constants'; import { pretty, green } from '../utils'; const { Client } = require('@elastic/elasticsearch'); -const node = RESEARCH_CLUSTER_ES_HOST; +const node = ES_HOST; const client = new Client({ node }); export const update = (id) => (log) => async (body) => { diff --git a/src/dev/code_coverage/shell_scripts/assign_teams.sh b/src/dev/code_coverage/shell_scripts/assign_teams.sh index 186cbecb436e9..aaa14655a9a26 100644 --- a/src/dev/code_coverage/shell_scripts/assign_teams.sh +++ b/src/dev/code_coverage/shell_scripts/assign_teams.sh @@ -9,7 +9,7 @@ export PIPELINE_NAME ES_HOST="https://${USER_FROM_VAULT}:${PASS_FROM_VAULT}@${HOST_FROM_VAULT}" export ES_HOST -node scripts/load_team_assignment.js --verbose +node scripts/load_team_assignment.js --verbose --path src/dev/code_coverage/ingest_coverage/team_assignment/ingestion_pipeline_painless.json echo "### Code Coverage Team Assignment - Complete" echo "" From c3bd7ae9df5bf69a10013355763638c33e0cb80f Mon Sep 17 00:00:00 2001 From: Madison Caldwell Date: Tue, 21 Jul 2020 12:22:53 -0400 Subject: [PATCH 55/77] Move manifest packageConfig mocks into security_solution plugin (#72527) --- x-pack/plugins/ingest_manager/common/mocks.ts | 87 ------------------ .../server/endpoint/lib/artifacts/mocks.ts | 89 +++++++++++++++++++ .../manifest_manager/manifest_manager.mock.ts | 6 +- 3 files changed, 91 insertions(+), 91 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/mocks.ts b/x-pack/plugins/ingest_manager/common/mocks.ts index 236324b11c580..e85364f2bb672 100644 --- a/x-pack/plugins/ingest_manager/common/mocks.ts +++ b/x-pack/plugins/ingest_manager/common/mocks.ts @@ -44,90 +44,3 @@ export const createPackageConfigMock = (): PackageConfig => { ], }; }; - -export const createPackageConfigWithInitialManifestMock = (): PackageConfig => { - const packageConfig = createPackageConfigMock(); - packageConfig.inputs[0].config!.artifact_manifest = { - value: { - artifacts: { - 'endpoint-exceptionlist-linux-v1': { - compression_algorithm: 'zlib', - encryption_algorithm: 'none', - decoded_sha256: 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - encoded_sha256: 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - decoded_size: 14, - encoded_size: 22, - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - }, - 'endpoint-exceptionlist-macos-v1': { - compression_algorithm: 'zlib', - encryption_algorithm: 'none', - decoded_sha256: 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - encoded_sha256: 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - decoded_size: 14, - encoded_size: 22, - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-macos-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - }, - 'endpoint-exceptionlist-windows-v1': { - compression_algorithm: 'zlib', - encryption_algorithm: 'none', - decoded_sha256: 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - encoded_sha256: 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - decoded_size: 14, - encoded_size: 22, - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - }, - }, - manifest_version: 'a9b7ef358a363f327f479e31efc4f228b2277a7fb4d1914ca9b4e7ca9ffcf537', - schema_version: 'v1', - }, - }; - return packageConfig; -}; - -export const createPackageConfigWithManifestMock = (): PackageConfig => { - const packageConfig = createPackageConfigMock(); - packageConfig.inputs[0].config!.artifact_manifest = { - value: { - artifacts: { - 'endpoint-exceptionlist-linux-v1': { - compression_algorithm: 'zlib', - encryption_algorithm: 'none', - decoded_sha256: '0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', - encoded_sha256: '57941169bb2c5416f9bd7224776c8462cb9a2be0fe8b87e6213e77a1d29be824', - decoded_size: 292, - encoded_size: 131, - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', - }, - 'endpoint-exceptionlist-macos-v1': { - compression_algorithm: 'zlib', - encryption_algorithm: 'none', - decoded_sha256: '96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', - encoded_sha256: '975382ab55d019cbab0bbac207a54e2a7d489fad6e8f6de34fc6402e5ef37b1e', - decoded_size: 432, - encoded_size: 147, - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-macos-v1/96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', - }, - 'endpoint-exceptionlist-windows-v1': { - compression_algorithm: 'zlib', - encryption_algorithm: 'none', - decoded_sha256: '96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', - encoded_sha256: '975382ab55d019cbab0bbac207a54e2a7d489fad6e8f6de34fc6402e5ef37b1e', - decoded_size: 432, - encoded_size: 147, - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', - }, - }, - manifest_version: '520f6cf88b3f36a065c6ca81058d5f8690aadadf6fe857f8dec4cc37589e7283', - schema_version: 'v1', - }, - }; - - return packageConfig; -}; diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/mocks.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/mocks.ts index 097151ee835ba..0ec6cb2bd61b3 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/mocks.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/mocks.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { PackageConfig } from '../../../../../ingest_manager/common'; +import { createPackageConfigMock } from '../../../../../ingest_manager/common/mocks'; import { InternalArtifactCompleteSchema } from '../../schemas/artifacts'; import { getInternalArtifactMock, @@ -66,3 +68,90 @@ export const getEmptyMockManifest = async (opts?: { compress: boolean }) => { artifacts.forEach((artifact) => manifest.addEntry(artifact)); return manifest; }; + +export const createPackageConfigWithInitialManifestMock = (): PackageConfig => { + const packageConfig = createPackageConfigMock(); + packageConfig.inputs[0].config!.artifact_manifest = { + value: { + artifacts: { + 'endpoint-exceptionlist-linux-v1': { + compression_algorithm: 'zlib', + encryption_algorithm: 'none', + decoded_sha256: 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + encoded_sha256: 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', + decoded_size: 14, + encoded_size: 22, + relative_url: + '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + }, + 'endpoint-exceptionlist-macos-v1': { + compression_algorithm: 'zlib', + encryption_algorithm: 'none', + decoded_sha256: 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + encoded_sha256: 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', + decoded_size: 14, + encoded_size: 22, + relative_url: + '/api/endpoint/artifacts/download/endpoint-exceptionlist-macos-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + }, + 'endpoint-exceptionlist-windows-v1': { + compression_algorithm: 'zlib', + encryption_algorithm: 'none', + decoded_sha256: 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + encoded_sha256: 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', + decoded_size: 14, + encoded_size: 22, + relative_url: + '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + }, + }, + manifest_version: 'a9b7ef358a363f327f479e31efc4f228b2277a7fb4d1914ca9b4e7ca9ffcf537', + schema_version: 'v1', + }, + }; + return packageConfig; +}; + +export const createPackageConfigWithManifestMock = (): PackageConfig => { + const packageConfig = createPackageConfigMock(); + packageConfig.inputs[0].config!.artifact_manifest = { + value: { + artifacts: { + 'endpoint-exceptionlist-linux-v1': { + compression_algorithm: 'zlib', + encryption_algorithm: 'none', + decoded_sha256: '0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', + encoded_sha256: '57941169bb2c5416f9bd7224776c8462cb9a2be0fe8b87e6213e77a1d29be824', + decoded_size: 292, + encoded_size: 131, + relative_url: + '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', + }, + 'endpoint-exceptionlist-macos-v1': { + compression_algorithm: 'zlib', + encryption_algorithm: 'none', + decoded_sha256: '96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', + encoded_sha256: '975382ab55d019cbab0bbac207a54e2a7d489fad6e8f6de34fc6402e5ef37b1e', + decoded_size: 432, + encoded_size: 147, + relative_url: + '/api/endpoint/artifacts/download/endpoint-exceptionlist-macos-v1/96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', + }, + 'endpoint-exceptionlist-windows-v1': { + compression_algorithm: 'zlib', + encryption_algorithm: 'none', + decoded_sha256: '96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', + encoded_sha256: '975382ab55d019cbab0bbac207a54e2a7d489fad6e8f6de34fc6402e5ef37b1e', + decoded_size: 432, + encoded_size: 147, + relative_url: + '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', + }, + }, + manifest_version: '520f6cf88b3f36a065c6ca81058d5f8690aadadf6fe857f8dec4cc37589e7283', + schema_version: 'v1', + }, + }; + + return packageConfig; +}; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.mock.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.mock.ts index 08cdb9816a1c1..2ebffa6fb3ad8 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.mock.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.mock.ts @@ -6,10 +6,6 @@ import { savedObjectsClientMock, loggingSystemMock } from 'src/core/server/mocks'; import { Logger } from 'src/core/server'; -import { - createPackageConfigWithManifestMock, - createPackageConfigWithInitialManifestMock, -} from '../../../../../../ingest_manager/common/mocks'; import { PackageConfigServiceInterface } from '../../../../../../ingest_manager/server'; import { createPackageConfigServiceMock } from '../../../../../../ingest_manager/server/mocks'; import { listMock } from '../../../../../../lists/server/mocks'; @@ -18,6 +14,8 @@ import { getArtifactClientMock } from '../artifact_client.mock'; import { getManifestClientMock } from '../manifest_client.mock'; import { ManifestManager } from './manifest_manager'; import { + createPackageConfigWithManifestMock, + createPackageConfigWithInitialManifestMock, getMockManifest, getMockArtifactsWithDiff, getEmptyMockArtifacts, From 3f5f9b7669fe160ba0d9de5e6e0b499342d7e9ed Mon Sep 17 00:00:00 2001 From: Kevin Qualters <56408403+kqualters-elastic@users.noreply.github.com> Date: Tue, 21 Jul 2020 13:07:40 -0400 Subject: [PATCH 56/77] [Security Solution][Resolver] Show process detail panel when clicking a process node (#72563) --- .../public/resolver/view/process_event_dot.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx index 503fd3d3dcef9..1f4952f15119d 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/process_event_dot.tsx @@ -252,7 +252,7 @@ const UnstyledProcessEventDot = React.memo( selectedProcessId: nodeID, }, }); - pushToQueryParams({ crumbId: nodeID, crumbEvent: 'all' }); + pushToQueryParams({ crumbId: nodeID, crumbEvent: '' }); }, [animationTarget, dispatch, pushToQueryParams, nodeID, nodeHTMLID]); /** From 4b06a4eb410654c304541fa9d10a047815d8751f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= Date: Tue, 21 Jul 2020 19:15:27 +0200 Subject: [PATCH 57/77] [Security Solution][Timeline] Add Empty view to the Timelines page (#72576) --- .../timelines/pages/timelines_page.test.tsx | 10 ++ .../public/timelines/pages/timelines_page.tsx | 108 ++++++++++-------- 2 files changed, 70 insertions(+), 48 deletions(-) diff --git a/x-pack/plugins/security_solution/public/timelines/pages/timelines_page.test.tsx b/x-pack/plugins/security_solution/public/timelines/pages/timelines_page.test.tsx index 2e59dbb72233f..f9097ddef6490 100644 --- a/x-pack/plugins/security_solution/public/timelines/pages/timelines_page.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/pages/timelines_page.test.tsx @@ -21,6 +21,16 @@ jest.mock('react-router-dom', () => { }; }); jest.mock('../../overview/components/events_by_dataset'); +jest.mock('../../common/containers/source', () => { + const originalModule = jest.requireActual('../../common/containers/source'); + + return { + ...originalModule, + useWithSource: jest.fn().mockReturnValue({ + indicesExist: true, + }), + }; +}); jest.mock('../../common/lib/kibana', () => { const originalModule = jest.requireActual('../../common/lib/kibana'); diff --git a/x-pack/plugins/security_solution/public/timelines/pages/timelines_page.tsx b/x-pack/plugins/security_solution/public/timelines/pages/timelines_page.tsx index 56aff3ec8aaac..b59f9e90f8e74 100644 --- a/x-pack/plugins/security_solution/public/timelines/pages/timelines_page.tsx +++ b/x-pack/plugins/security_solution/public/timelines/pages/timelines_page.tsx @@ -15,6 +15,8 @@ import { WrapperPage } from '../../common/components/wrapper_page'; import { useKibana } from '../../common/lib/kibana'; import { SpyRoute } from '../../common/utils/route/spy_routes'; import { useApolloClient } from '../../common/utils/apollo_context'; +import { useWithSource } from '../../common/containers/source'; +import { OverviewEmpty } from '../../overview/components/overview_empty'; import { StatefulOpenTimeline } from '../components/open_timeline'; import { NEW_TEMPLATE_TIMELINE } from '../components/timeline/properties/translations'; @@ -36,61 +38,71 @@ export const TimelinesPageComponent: React.FC = () => { const onImportTimelineBtnClick = useCallback(() => { setImportDataModalToggle(true); }, [setImportDataModalToggle]); + const { indicesExist } = useWithSource(); const apolloClient = useApolloClient(); - const uiCapabilities = useKibana().services.application.capabilities; - const capabilitiesCanUserCRUD: boolean = !!uiCapabilities.siem.crud; + const capabilitiesCanUserCRUD: boolean = !!useKibana().services.application.capabilities.siem + .crud; return ( <> - - - - - {capabilitiesCanUserCRUD && ( - - {i18n.ALL_TIMELINES_IMPORT_TIMELINE_TITLE} - - )} - - {tabName === TimelineType.default ? ( - - {capabilitiesCanUserCRUD && ( - + {indicesExist ? ( + <> + + + + + {capabilitiesCanUserCRUD && ( + + {i18n.ALL_TIMELINES_IMPORT_TIMELINE_TITLE} + + )} + + {tabName === TimelineType.default ? ( + + {capabilitiesCanUserCRUD && ( + + )} + + ) : ( + + + )} - - ) : ( - - - - )} - - + + - - - - + + + + + + ) : ( + + + + + )} From eb71e599ce2dbdb2062389257d64f7761e9e6e08 Mon Sep 17 00:00:00 2001 From: Clint Andrew Hall Date: Tue, 21 Jul 2020 14:12:56 -0400 Subject: [PATCH 58/77] [pre-req] Convert Page Manager, Page Preview, DOM Preview (#70370) Co-authored-by: Elastic Machine Co-authored-by: Corey Robertson --- x-pack/plugins/canvas/i18n/components.ts | 16 ++ .../{dom_preview.js => dom_preview.tsx} | 53 +++++-- .../public/components/dom_preview/index.js | 9 -- .../index.js => dom_preview/index.ts} | 2 +- .../components/link/{index.js => index.ts} | 0 .../canvas/public/components/link/link.js | 63 -------- .../canvas/public/components/link/link.tsx | 72 +++++++++ .../public/components/page_manager/index.js | 37 ----- .../public/components/page_manager/index.ts | 31 ++++ .../{page_manager.js => page_manager.tsx} | 148 ++++++++++-------- .../public/components/page_preview/index.ts | 24 +++ .../{page_controls.js => page_controls.tsx} | 21 ++- .../{page_preview.js => page_preview.tsx} | 35 ++--- .../public/components/toolbar/toolbar.tsx | 3 +- .../canvas/public/lib/create_handlers.ts | 2 +- 15 files changed, 292 insertions(+), 224 deletions(-) rename x-pack/plugins/canvas/public/components/dom_preview/{dom_preview.js => dom_preview.tsx} (71%) delete mode 100644 x-pack/plugins/canvas/public/components/dom_preview/index.js rename x-pack/plugins/canvas/public/components/{page_preview/index.js => dom_preview/index.ts} (84%) rename x-pack/plugins/canvas/public/components/link/{index.js => index.ts} (100%) delete mode 100644 x-pack/plugins/canvas/public/components/link/link.js create mode 100644 x-pack/plugins/canvas/public/components/link/link.tsx delete mode 100644 x-pack/plugins/canvas/public/components/page_manager/index.js create mode 100644 x-pack/plugins/canvas/public/components/page_manager/index.ts rename x-pack/plugins/canvas/public/components/page_manager/{page_manager.js => page_manager.tsx} (63%) create mode 100644 x-pack/plugins/canvas/public/components/page_preview/index.ts rename x-pack/plugins/canvas/public/components/page_preview/{page_controls.js => page_controls.tsx} (75%) rename x-pack/plugins/canvas/public/components/page_preview/{page_preview.js => page_preview.tsx} (56%) diff --git a/x-pack/plugins/canvas/i18n/components.ts b/x-pack/plugins/canvas/i18n/components.ts index 78083f26a38b1..acc55d50ae19a 100644 --- a/x-pack/plugins/canvas/i18n/components.ts +++ b/x-pack/plugins/canvas/i18n/components.ts @@ -567,6 +567,22 @@ export const ComponentStrings = { pageNumber, }, }), + getAddPageTooltip: () => + i18n.translate('xpack.canvas.pageManager.addPageTooltip', { + defaultMessage: 'Add a new page to this workpad', + }), + getConfirmRemoveTitle: () => + i18n.translate('xpack.canvas.pageManager.confirmRemoveTitle', { + defaultMessage: 'Remove Page', + }), + getConfirmRemoveDescription: () => + i18n.translate('xpack.canvas.pageManager.confirmRemoveDescription', { + defaultMessage: 'Are you sure you want to remove this page?', + }), + getConfirmRemoveButtonLabel: () => + i18n.translate('xpack.canvas.pageManager.removeButtonLabel', { + defaultMessage: 'Remove', + }), }, PagePreviewPageControls: { getClonePageAriaLabel: () => diff --git a/x-pack/plugins/canvas/public/components/dom_preview/dom_preview.js b/x-pack/plugins/canvas/public/components/dom_preview/dom_preview.tsx similarity index 71% rename from x-pack/plugins/canvas/public/components/dom_preview/dom_preview.js rename to x-pack/plugins/canvas/public/components/dom_preview/dom_preview.tsx index f74862af8d105..6ec0276c2f49f 100644 --- a/x-pack/plugins/canvas/public/components/dom_preview/dom_preview.js +++ b/x-pack/plugins/canvas/public/components/dom_preview/dom_preview.tsx @@ -4,30 +4,38 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { debounce } from 'lodash'; -export class DomPreview extends React.Component { +interface Props { + elementId: string; + height: number; +} + +export class DomPreview extends PureComponent { static propTypes = { elementId: PropTypes.string.isRequired, height: PropTypes.number.isRequired, }; + _container: HTMLDivElement | null = null; + _content: HTMLDivElement | null = null; + _observer: MutationObserver | null = null; + _original: Element | null = null; + _updateTimeout: number = 0; + componentDidMount() { this.update(); } componentWillUnmount() { clearTimeout(this._updateTimeout); - this._observer && this._observer.disconnect(); // observer not guaranteed to exist - } - _container = null; - _content = null; - _observer = null; - _original = null; - _updateTimeout = null; + if (this._observer) { + this._observer.disconnect(); // observer not guaranteed to exist + } + } update = () => { if (!this._content || !this._container) { @@ -38,7 +46,10 @@ export class DomPreview extends React.Component { const originalChanged = currentOriginal !== this._original; if (originalChanged) { - this._observer && this._observer.disconnect(); + if (this._observer) { + this._observer.disconnect(); + } + this._original = currentOriginal; if (this._original) { @@ -50,12 +61,16 @@ export class DomPreview extends React.Component { this._observer.observe(this._original, config); } else { clearTimeout(this._updateTimeout); // to avoid the assumption that we fully control when `update` is called - this._updateTimeout = setTimeout(this.update, 30); + this._updateTimeout = window.setTimeout(this.update, 30); return; } } - const thumb = this._original.cloneNode(true); + if (!this._original) { + return; + } + + const thumb = this._original.cloneNode(true) as HTMLDivElement; thumb.id += '-thumb'; const originalStyle = window.getComputedStyle(this._original, null); @@ -66,9 +81,10 @@ export class DomPreview extends React.Component { const scale = thumbHeight / originalHeight; const thumbWidth = originalWidth * scale; - if (this._content.hasChildNodes()) { + if (this._content.firstChild) { this._content.removeChild(this._content.firstChild); } + this._content.appendChild(thumb); this._content.style.cssText = `transform: scale(${scale}); transform-origin: top left;`; @@ -76,13 +92,16 @@ export class DomPreview extends React.Component { // Copy canvas data const originalCanvas = this._original.querySelectorAll('canvas'); - const thumbCanvas = thumb.querySelectorAll('canvas'); + const thumbCanvas = (thumb as Element).querySelectorAll('canvas'); // Cloned canvas elements are blank and need to be explicitly redrawn if (originalCanvas.length > 0) { - Array.from(originalCanvas).map((img, i) => - thumbCanvas[i].getContext('2d').drawImage(img, 0, 0) - ); + Array.from(originalCanvas).map((img, i) => { + const context = thumbCanvas[i].getContext('2d'); + if (context) { + context.drawImage(img, 0, 0); + } + }); } }; diff --git a/x-pack/plugins/canvas/public/components/dom_preview/index.js b/x-pack/plugins/canvas/public/components/dom_preview/index.js deleted file mode 100644 index 283f92c7ecd9b..0000000000000 --- a/x-pack/plugins/canvas/public/components/dom_preview/index.js +++ /dev/null @@ -1,9 +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 { DomPreview as Component } from './dom_preview'; - -export const DomPreview = Component; diff --git a/x-pack/plugins/canvas/public/components/page_preview/index.js b/x-pack/plugins/canvas/public/components/dom_preview/index.ts similarity index 84% rename from x-pack/plugins/canvas/public/components/page_preview/index.js rename to x-pack/plugins/canvas/public/components/dom_preview/index.ts index d72d6403dd5be..19980b7c2cfe5 100644 --- a/x-pack/plugins/canvas/public/components/page_preview/index.js +++ b/x-pack/plugins/canvas/public/components/dom_preview/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { PagePreview } from './page_preview'; +export { DomPreview } from './dom_preview'; diff --git a/x-pack/plugins/canvas/public/components/link/index.js b/x-pack/plugins/canvas/public/components/link/index.ts similarity index 100% rename from x-pack/plugins/canvas/public/components/link/index.js rename to x-pack/plugins/canvas/public/components/link/index.ts diff --git a/x-pack/plugins/canvas/public/components/link/link.js b/x-pack/plugins/canvas/public/components/link/link.js deleted file mode 100644 index d973164190592..0000000000000 --- a/x-pack/plugins/canvas/public/components/link/link.js +++ /dev/null @@ -1,63 +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 React from 'react'; -import PropTypes from 'prop-types'; -import { EuiLink } from '@elastic/eui'; - -import { ComponentStrings } from '../../../i18n'; - -const { Link: strings } = ComponentStrings; - -const isModifiedEvent = (ev) => !!(ev.metaKey || ev.altKey || ev.ctrlKey || ev.shiftKey); - -export class Link extends React.PureComponent { - static propTypes = { - target: PropTypes.string, - onClick: PropTypes.func, - name: PropTypes.string.isRequired, - params: PropTypes.object, - children: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.node]).isRequired, - }; - - static contextTypes = { - router: PropTypes.object, - }; - - navigateTo = (name, params) => (ev) => { - if (this.props.onClick) { - this.props.onClick(ev); - } - - if ( - !ev.defaultPrevented && // onClick prevented default - ev.button === 0 && // ignore everything but left clicks - !this.props.target && // let browser handle "target=_blank" etc. - !isModifiedEvent(ev) // ignore clicks with modifier keys - ) { - ev.preventDefault(); - this.context.router.navigateTo(name, params); - } - }; - - render() { - try { - const { name, params, children, ...linkArgs } = this.props; - const { router } = this.context; - const href = router.getFullPath(router.create(name, params)); - const props = { - ...linkArgs, - href, - onClick: this.navigateTo(name, params), - }; - - return {children}; - } catch (e) { - console.error(e); - return
    {strings.getErrorMessage(e.message)}
    ; - } - } -} diff --git a/x-pack/plugins/canvas/public/components/link/link.tsx b/x-pack/plugins/canvas/public/components/link/link.tsx new file mode 100644 index 0000000000000..b0289fba842d1 --- /dev/null +++ b/x-pack/plugins/canvas/public/components/link/link.tsx @@ -0,0 +1,72 @@ +/* + * 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, { FC, MouseEvent, useContext } from 'react'; +import PropTypes from 'prop-types'; +import { EuiLink, EuiLinkProps } from '@elastic/eui'; +import { RouterContext } from '../router'; + +import { ComponentStrings } from '../../../i18n'; + +const { Link: strings } = ComponentStrings; + +const isModifiedEvent = (ev: MouseEvent) => + !!(ev.metaKey || ev.altKey || ev.ctrlKey || ev.shiftKey); + +interface Props { + name: string; + params: Record; +} + +export const Link: FC = ({ + onClick, + target, + name, + params, + children, + ...linkArgs +}) => { + const router = useContext(RouterContext); + + if (router) { + const navigateTo = (ev: MouseEvent) => { + if (onClick) { + onClick(ev); + } + + if ( + !ev.defaultPrevented && // onClick prevented default + ev.button === 0 && // ignore everything but left clicks + !target && // let browser handle "target=_blank" etc. + !isModifiedEvent(ev) // ignore clicks with modifier keys + ) { + ev.preventDefault(); + router.navigateTo(name, params); + } + }; + + try { + return ( + + {children} + + ); + } catch (e) { + return
    {strings.getErrorMessage(e.message)}
    ; + } + } + + return
    {strings.getErrorMessage('Router Undefined')}
    ; +}; + +Link.contextTypes = { + router: PropTypes.object, +}; + +Link.propTypes = { + name: PropTypes.string.isRequired, + params: PropTypes.object, +}; diff --git a/x-pack/plugins/canvas/public/components/page_manager/index.js b/x-pack/plugins/canvas/public/components/page_manager/index.js deleted file mode 100644 index a198b7b8c3d8c..0000000000000 --- a/x-pack/plugins/canvas/public/components/page_manager/index.js +++ /dev/null @@ -1,37 +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 { connect } from 'react-redux'; -import { compose, withState } from 'recompose'; -import * as pageActions from '../../state/actions/pages'; -import { canUserWrite } from '../../state/selectors/app'; -import { getSelectedPage, getWorkpad, getPages, isWriteable } from '../../state/selectors/workpad'; -import { DEFAULT_WORKPAD_CSS } from '../../../common/lib/constants'; -import { PageManager as Component } from './page_manager'; - -const mapStateToProps = (state) => { - const { id, css } = getWorkpad(state); - - return { - isWriteable: isWriteable(state) && canUserWrite(state), - pages: getPages(state), - selectedPage: getSelectedPage(state), - workpadId: id, - workpadCSS: css || DEFAULT_WORKPAD_CSS, - }; -}; - -const mapDispatchToProps = (dispatch) => ({ - addPage: () => dispatch(pageActions.addPage()), - movePage: (id, position) => dispatch(pageActions.movePage(id, position)), - duplicatePage: (id) => dispatch(pageActions.duplicatePage(id)), - removePage: (id) => dispatch(pageActions.removePage(id)), -}); - -export const PageManager = compose( - connect(mapStateToProps, mapDispatchToProps), - withState('deleteId', 'setDeleteId', null) -)(Component); diff --git a/x-pack/plugins/canvas/public/components/page_manager/index.ts b/x-pack/plugins/canvas/public/components/page_manager/index.ts new file mode 100644 index 0000000000000..d19540cd6a687 --- /dev/null +++ b/x-pack/plugins/canvas/public/components/page_manager/index.ts @@ -0,0 +1,31 @@ +/* + * 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 { Dispatch } from 'redux'; +import { connect } from 'react-redux'; +// @ts-expect-error untyped local +import * as pageActions from '../../state/actions/pages'; +import { canUserWrite } from '../../state/selectors/app'; +import { getSelectedPage, getWorkpad, getPages, isWriteable } from '../../state/selectors/workpad'; +import { DEFAULT_WORKPAD_CSS } from '../../../common/lib/constants'; +import { PageManager as Component } from './page_manager'; +import { State } from '../../../types'; + +const mapStateToProps = (state: State) => ({ + isWriteable: isWriteable(state) && canUserWrite(state), + pages: getPages(state), + selectedPage: getSelectedPage(state), + workpadId: getWorkpad(state).id, + workpadCSS: getWorkpad(state).css || DEFAULT_WORKPAD_CSS, +}); + +const mapDispatchToProps = (dispatch: Dispatch) => ({ + onAddPage: () => dispatch(pageActions.addPage()), + onMovePage: (id: string, position: number) => dispatch(pageActions.movePage(id, position)), + onRemovePage: (id: string) => dispatch(pageActions.removePage(id)), +}); + +export const PageManager = connect(mapStateToProps, mapDispatchToProps)(Component); diff --git a/x-pack/plugins/canvas/public/components/page_manager/page_manager.js b/x-pack/plugins/canvas/public/components/page_manager/page_manager.tsx similarity index 63% rename from x-pack/plugins/canvas/public/components/page_manager/page_manager.js rename to x-pack/plugins/canvas/public/components/page_manager/page_manager.tsx index 3e2ff9dfe2b22..edc0d6201495b 100644 --- a/x-pack/plugins/canvas/public/components/page_manager/page_manager.js +++ b/x-pack/plugins/canvas/public/components/page_manager/page_manager.tsx @@ -4,38 +4,63 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment } from 'react'; +import React, { Fragment, Component } from 'react'; import PropTypes from 'prop-types'; import { EuiIcon, EuiFlexGroup, EuiFlexItem, EuiText, EuiToolTip } from '@elastic/eui'; -import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'; +import { DragDropContext, Droppable, Draggable, DragDropContextProps } from 'react-beautiful-dnd'; +// @ts-expect-error untyped dependency import Style from 'style-it'; + import { ConfirmModal } from '../confirm_modal'; import { Link } from '../link'; import { PagePreview } from '../page_preview'; import { ComponentStrings } from '../../../i18n'; +import { CanvasPage } from '../../../types'; const { PageManager: strings } = ComponentStrings; -export class PageManager extends React.PureComponent { +export interface Props { + isWriteable: boolean; + onAddPage: () => void; + onMovePage: (pageId: string, position: number) => void; + onPreviousPage: () => void; + onRemovePage: (pageId: string) => void; + pages: CanvasPage[]; + selectedPage?: string; + workpadCSS?: string; + workpadId: string; +} + +interface State { + showTrayPop: boolean; + removeId: string | null; +} + +export class PageManager extends Component { static propTypes = { isWriteable: PropTypes.bool.isRequired, + onAddPage: PropTypes.func.isRequired, + onMovePage: PropTypes.func.isRequired, + onPreviousPage: PropTypes.func.isRequired, + onRemovePage: PropTypes.func.isRequired, pages: PropTypes.array.isRequired, - workpadId: PropTypes.string.isRequired, - addPage: PropTypes.func.isRequired, - movePage: PropTypes.func.isRequired, - previousPage: PropTypes.func.isRequired, - duplicatePage: PropTypes.func.isRequired, - removePage: PropTypes.func.isRequired, selectedPage: PropTypes.string, - deleteId: PropTypes.string, - setDeleteId: PropTypes.func.isRequired, workpadCSS: PropTypes.string, + workpadId: PropTypes.string.isRequired, }; - state = { - showTrayPop: true, - }; + constructor(props: Props) { + super(props); + this.state = { + showTrayPop: true, + removeId: null, + }; + } + + _isMounted: boolean = false; + _activePageRef: HTMLDivElement | null = null; + _pageListRef: HTMLDivElement | null = null; componentDidMount() { // keep track of whether or not the component is mounted, to prevent rogue setState calls @@ -44,11 +69,13 @@ export class PageManager extends React.PureComponent { // gives the tray pop animation time to finish setTimeout(() => { this.scrollToActivePage(); - this._isMounted && this.setState({ showTrayPop: false }); + if (this._isMounted) { + this.setState({ showTrayPop: false }); + } }, 1000); } - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: Props) { // scrolls to the active page on the next tick, otherwise new pages don't scroll completely into view if (prevProps.selectedPage !== this.props.selectedPage) { setTimeout(this.scrollToActivePage, 0); @@ -60,33 +87,33 @@ export class PageManager extends React.PureComponent { } scrollToActivePage = () => { - if (this.activePageRef && this.pageListRef) { + if (this._activePageRef && this._pageListRef) { // not all target browsers support element.scrollTo // TODO: replace this with something more cross-browser, maybe scrollIntoView - if (!this.pageListRef.scrollTo) { + if (!this._pageListRef.scrollTo) { return; } - const pageOffset = this.activePageRef.offsetLeft; + const pageOffset = this._activePageRef.offsetLeft; const { left: pageLeft, right: pageRight, width: pageWidth, - } = this.activePageRef.getBoundingClientRect(); + } = this._activePageRef.getBoundingClientRect(); const { left: listLeft, right: listRight, width: listWidth, - } = this.pageListRef.getBoundingClientRect(); + } = this._pageListRef.getBoundingClientRect(); if (pageLeft < listLeft) { - this.pageListRef.scrollTo({ + this._pageListRef.scrollTo({ left: pageOffset, behavior: 'smooth', }); } if (pageRight > listRight) { - this.pageListRef.scrollTo({ + this._pageListRef.scrollTo({ left: pageOffset - listWidth + pageWidth, behavior: 'smooth', }); @@ -94,22 +121,29 @@ export class PageManager extends React.PureComponent { } }; - confirmDelete = (pageId) => { - this._isMounted && this.props.setDeleteId(pageId); + onConfirmRemove = (removeId: string) => { + if (this._isMounted) { + this.setState({ removeId }); + } }; - resetDelete = () => this._isMounted && this.props.setDeleteId(null); + resetRemove = () => this._isMounted && this.setState({ removeId: null }); + + doRemove = () => { + const { onPreviousPage, onRemovePage, selectedPage } = this.props; + const { removeId } = this.state; + this.resetRemove(); + + if (removeId === selectedPage) { + onPreviousPage(); + } - doDelete = () => { - const { previousPage, removePage, deleteId, selectedPage } = this.props; - this.resetDelete(); - if (deleteId === selectedPage) { - previousPage(); + if (removeId !== null) { + onRemovePage(removeId); } - removePage(deleteId); }; - onDragEnd = ({ draggableId: pageId, source, destination }) => { + onDragEnd: DragDropContextProps['onDragEnd'] = ({ draggableId: pageId, source, destination }) => { // dropped outside the list if (!destination) { return; @@ -117,18 +151,11 @@ export class PageManager extends React.PureComponent { const position = destination.index - source.index; - this.props.movePage(pageId, position); + this.props.onMovePage(pageId, position); }; - renderPage = (page, i) => { - const { - isWriteable, - selectedPage, - workpadId, - movePage, - duplicatePage, - workpadCSS, - } = this.props; + renderPage = (page: CanvasPage, i: number) => { + const { isWriteable, selectedPage, workpadId, workpadCSS } = this.props; const pageNumber = i + 1; return ( @@ -141,7 +168,7 @@ export class PageManager extends React.PureComponent { }`} ref={(el) => { if (page.id === selectedPage) { - this.activePageRef = el; + this._activePageRef = el; } provided.innerRef(el); }} @@ -163,16 +190,7 @@ export class PageManager extends React.PureComponent { {Style.it( workpadCSS,
    - +
    )} @@ -185,8 +203,8 @@ export class PageManager extends React.PureComponent { }; render() { - const { pages, addPage, deleteId, isWriteable } = this.props; - const { showTrayPop } = this.state; + const { pages, onAddPage, isWriteable } = this.props; + const { showTrayPop, removeId } = this.state; return ( @@ -200,7 +218,7 @@ export class PageManager extends React.PureComponent { showTrayPop ? 'canvasPageManager--trayPop' : '' }`} ref={(el) => { - this.pageListRef = el; + this._pageListRef = el; provided.innerRef(el); }} {...provided.droppableProps} @@ -216,11 +234,11 @@ export class PageManager extends React.PureComponent {
    `; + +exports[`Storyshots components/Assets/Asset redux 1`] = ` +
    +
    +
    +
    +
    + Asset thumbnail +
    +
    +
    +
    +

    + + airplane + +
    + + + ( + 1 + kb) + + +

    +
    +
    +
    +
    + + + +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +`; diff --git a/x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset_manager.stories.storyshot b/x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset_manager.stories.storyshot index 1b8f1480759f6..11c5681ebf79e 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset_manager.stories.storyshot +++ b/x-pack/plugins/canvas/public/components/asset_manager/__examples__/__snapshots__/asset_manager.stories.storyshot @@ -229,6 +229,545 @@ Array [ ] `; +exports[`Storyshots components/Assets/AssetManager redux 1`] = ` +Array [ +
    , +
    , +
    +
    + +
    +
    +
    + Manage workpad assets +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    + Below are the image assets in this workpad. Any assets that are currently in use cannot be determined at this time. To reclaim space, delete assets. +

    +
    +
    +
    +
    +
    +
    +
    +
    + Asset thumbnail +
    +
    +
    +
    +

    + + airplane + +
    + + + ( + 1 + kb) + + +

    +
    +
    +
    +
    + + + +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    + Asset thumbnail +
    +
    +
    +
    +

    + + marker + +
    + + + ( + 1 + kb) + + +

    +
    +
    +
    +
    + + + +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    + 0% space used +
    +
    +
    + +
    +
    +
    +
    , +
    , +] +`; + exports[`Storyshots components/Assets/AssetManager two assets 1`] = ` Array [
    {story()}
    ) - .add('airplane', () => ( - - )) - .add('marker', () => ( - - )); diff --git a/x-pack/plugins/canvas/public/components/asset_manager/__examples__/asset_manager.stories.tsx b/x-pack/plugins/canvas/public/components/asset_manager/__examples__/asset_manager.stories.tsx index cb42823ccab7b..1434ef60cf0d8 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/__examples__/asset_manager.stories.tsx +++ b/x-pack/plugins/canvas/public/components/asset_manager/__examples__/asset_manager.stories.tsx @@ -7,42 +7,32 @@ import { action } from '@storybook/addon-actions'; import { storiesOf } from '@storybook/react'; import React from 'react'; -import { AssetType } from '../../../../types'; -import { AssetManager } from '../asset_manager'; -const AIRPLANE: AssetType = { - '@created': '2018-10-13T16:44:44.648Z', - id: 'airplane', - type: 'dataurl', - value: - 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1Ni4zMSA1Ni4zMSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNmZmY7c3Ryb2tlOiMwMDc4YTA7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlLXdpZHRoOjJweDt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPlBsYW5lIEljb248L3RpdGxlPjxnIGlkPSJMYXllcl8yIiBkYXRhLW5hbWU9IkxheWVyIDIiPjxnIGlkPSJMYXllcl8xLTIiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNNDkuNTEsNDguOTMsNDEuMjYsMjIuNTIsNTMuNzYsMTBhNS4yOSw1LjI5LDAsMCwwLTcuNDgtNy40N2wtMTIuNSwxMi41TDcuMzgsNi43OUEuNy43LDAsMCwwLDYuNjksN0wxLjIsMTIuNDVhLjcuNywwLDAsMCwwLDFMMTkuODUsMjlsLTcuMjQsNy4yNC03Ljc0LS42YS43MS43MSwwLDAsMC0uNTMuMkwxLjIxLDM5YS42Ny42NywwLDAsMCwuMDgsMUw5LjQ1LDQ2bC4wNywwYy4xMS4xMy4yMi4yNi4zNC4zOHMuMjUuMjMuMzguMzRhLjM2LjM2LDAsMCwwLDAsLjA3TDE2LjMzLDU1YS42OC42OCwwLDAsMCwxLC4wN0wyMC40OSw1MmEuNjcuNjcsMCwwLDAsLjE5LS41NGwtLjU5LTcuNzQsNy4yNC03LjI0TDQyLjg1LDU1LjA2YS42OC42OCwwLDAsMCwxLDBsNS41LTUuNUEuNjYuNjYsMCwwLDAsNDkuNTEsNDguOTNaIi8+PC9nPjwvZz48L3N2Zz4=', -}; +import { AssetManager, AssetManagerComponent } from '../'; -const MARKER: AssetType = { - '@created': '2018-10-13T16:44:44.648Z', - id: 'marker', - type: 'dataurl', - value: - 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzOC4zOSA1Ny41NyI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNmZmY7c3Ryb2tlOiMwMTliOGY7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlLXdpZHRoOjJweDt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPkxvY2F0aW9uIEljb248L3RpdGxlPjxnIGlkPSJMYXllcl8yIiBkYXRhLW5hbWU9IkxheWVyIDIiPjxnIGlkPSJMYXllcl8xLTIiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMTkuMTksMUExOC4xOSwxOC4xOSwwLDAsMCwyLjk0LDI3LjM2aDBhMTkuNTEsMTkuNTEsMCwwLDAsMSwxLjc4TDE5LjE5LDU1LjU3LDM0LjM4LDI5LjIxQTE4LjE5LDE4LjE5LDAsMCwwLDE5LjE5LDFabTAsMjMuMjlhNS41Myw1LjUzLDAsMSwxLDUuNTMtNS41M0E1LjUzLDUuNTMsMCwwLDEsMTkuMTksMjQuMjlaIi8+PC9nPjwvZz48L3N2Zz4=', -}; +import { Provider, AIRPLANE, MARKER } from './provider'; storiesOf('components/Assets/AssetManager', module) + .add('redux: AssetManager', () => ( + + + + )) .add('no assets', () => ( - + + + )) .add('two assets', () => ( - + + + )); diff --git a/x-pack/plugins/canvas/public/components/asset_manager/__examples__/provider.tsx b/x-pack/plugins/canvas/public/components/asset_manager/__examples__/provider.tsx new file mode 100644 index 0000000000000..1cd7562b59c47 --- /dev/null +++ b/x-pack/plugins/canvas/public/components/asset_manager/__examples__/provider.tsx @@ -0,0 +1,110 @@ +/* + * 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. + */ + +/* eslint-disable no-console */ + +/* + This Provider is temporary. See https://github.com/elastic/kibana/pull/69357 +*/ + +import React, { FC } from 'react'; +import { applyMiddleware, createStore, Dispatch, Store } from 'redux'; +import thunkMiddleware from 'redux-thunk'; +import { Provider as ReduxProvider } from 'react-redux'; + +// @ts-expect-error untyped local +import { appReady } from '../../../../public/state/middleware/app_ready'; +// @ts-expect-error untyped local +import { resolvedArgs } from '../../../../public/state/middleware/resolved_args'; + +// @ts-expect-error untyped local +import { getRootReducer } from '../../../../public/state/reducers'; + +// @ts-expect-error Untyped local +import { getDefaultWorkpad } from '../../../../public/state/defaults'; +import { State, AssetType } from '../../../../types'; + +export const AIRPLANE: AssetType = { + '@created': '2018-10-13T16:44:44.648Z', + id: 'airplane', + type: 'dataurl', + value: + 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1Ni4zMSA1Ni4zMSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNmZmY7c3Ryb2tlOiMwMDc4YTA7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlLXdpZHRoOjJweDt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPlBsYW5lIEljb248L3RpdGxlPjxnIGlkPSJMYXllcl8yIiBkYXRhLW5hbWU9IkxheWVyIDIiPjxnIGlkPSJMYXllcl8xLTIiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNNDkuNTEsNDguOTMsNDEuMjYsMjIuNTIsNTMuNzYsMTBhNS4yOSw1LjI5LDAsMCwwLTcuNDgtNy40N2wtMTIuNSwxMi41TDcuMzgsNi43OUEuNy43LDAsMCwwLDYuNjksN0wxLjIsMTIuNDVhLjcuNywwLDAsMCwwLDFMMTkuODUsMjlsLTcuMjQsNy4yNC03Ljc0LS42YS43MS43MSwwLDAsMC0uNTMuMkwxLjIxLDM5YS42Ny42NywwLDAsMCwuMDgsMUw5LjQ1LDQ2bC4wNywwYy4xMS4xMy4yMi4yNi4zNC4zOHMuMjUuMjMuMzguMzRhLjM2LjM2LDAsMCwwLDAsLjA3TDE2LjMzLDU1YS42OC42OCwwLDAsMCwxLC4wN0wyMC40OSw1MmEuNjcuNjcsMCwwLDAsLjE5LS41NGwtLjU5LTcuNzQsNy4yNC03LjI0TDQyLjg1LDU1LjA2YS42OC42OCwwLDAsMCwxLDBsNS41LTUuNUEuNjYuNjYsMCwwLDAsNDkuNTEsNDguOTNaIi8+PC9nPjwvZz48L3N2Zz4=', +}; + +export const MARKER: AssetType = { + '@created': '2018-10-13T16:44:44.648Z', + id: 'marker', + type: 'dataurl', + value: + 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzOC4zOSA1Ny41NyI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNmZmY7c3Ryb2tlOiMwMTliOGY7c3Ryb2tlLW1pdGVybGltaXQ6MTA7c3Ryb2tlLXdpZHRoOjJweDt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPkxvY2F0aW9uIEljb248L3RpdGxlPjxnIGlkPSJMYXllcl8yIiBkYXRhLW5hbWU9IkxheWVyIDIiPjxnIGlkPSJMYXllcl8xLTIiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMTkuMTksMUExOC4xOSwxOC4xOSwwLDAsMCwyLjk0LDI3LjM2aDBhMTkuNTEsMTkuNTEsMCwwLDAsMSwxLjc4TDE5LjE5LDU1LjU3LDM0LjM4LDI5LjIxQTE4LjE5LDE4LjE5LDAsMCwwLDE5LjE5LDFabTAsMjMuMjlhNS41Myw1LjUzLDAsMSwxLDUuNTMtNS41M0E1LjUzLDUuNTMsMCwwLDEsMTkuMTksMjQuMjlaIi8+PC9nPjwvZz48L3N2Zz4=', +}; + +export const state: State = { + app: { + basePath: '/', + ready: true, + serverFunctions: [], + }, + assets: { + AIRPLANE, + MARKER, + }, + transient: { + canUserWrite: true, + zoomScale: 1, + elementStats: { + total: 0, + ready: 0, + pending: 0, + error: 0, + }, + inFlight: false, + fullScreen: false, + selectedTopLevelNodes: [], + resolvedArgs: {}, + refresh: { + interval: 0, + }, + autoplay: { + enabled: false, + interval: 10000, + }, + }, + persistent: { + schemaVersion: 2, + workpad: getDefaultWorkpad(), + }, +}; + +// @ts-expect-error untyped local +import { elementsRegistry } from '../../../lib/elements_registry'; +import { image } from '../../../../canvas_plugin_src/elements/image'; +elementsRegistry.register(image); + +export const patchDispatch: (store: Store, dispatch: Dispatch) => Dispatch = (store, dispatch) => ( + action +) => { + const previousState = store.getState(); + const returnValue = dispatch(action); + const newState = store.getState(); + + console.group(action.type || '(thunk)'); + console.log('Previous State', previousState); + console.log('New State', newState); + console.groupEnd(); + + return returnValue; +}; + +export const Provider: FC = ({ children }) => { + const middleware = applyMiddleware(thunkMiddleware); + const reducer = getRootReducer(state); + const store = createStore(reducer, state, middleware); + store.dispatch = patchDispatch(store, store.dispatch); + + return {children}; +}; diff --git a/x-pack/plugins/canvas/public/components/asset_manager/asset.component.tsx b/x-pack/plugins/canvas/public/components/asset_manager/asset.component.tsx new file mode 100644 index 0000000000000..a04d37cf7f9fc --- /dev/null +++ b/x-pack/plugins/canvas/public/components/asset_manager/asset.component.tsx @@ -0,0 +1,147 @@ +/* + * 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, { FC, useState } from 'react'; +import { + EuiButtonIcon, + EuiFlexGroup, + EuiFlexItem, + EuiImage, + EuiPanel, + EuiSpacer, + EuiText, + EuiTextColor, + EuiToolTip, +} from '@elastic/eui'; + +import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; + +import { ConfirmModal } from '../confirm_modal'; +import { Clipboard } from '../clipboard'; +import { Download } from '../download'; +import { AssetType } from '../../../types'; + +import { ComponentStrings } from '../../../i18n'; + +const { Asset: strings } = ComponentStrings; + +interface Props { + /** The asset to be rendered */ + asset: AssetType; + /** The function to execute when the user clicks 'Create' */ + onCreate: (assetId: string) => void; + /** The function to execute when the user clicks 'Delete' */ + onDelete: (asset: AssetType) => void; +} + +export const Asset: FC = ({ asset, onCreate, onDelete }) => { + const { services } = useKibana(); + const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false); + + const onCopy = (result: boolean) => + result && services.canvas.notify.success(`Copied '${asset.id}' to clipboard`); + + const confirmModal = ( + { + setIsConfirmModalVisible(false); + onDelete(asset); + }} + onCancel={() => setIsConfirmModalVisible(false)} + /> + ); + + const createImage = ( + + + onCreate(asset.id)} + /> + + + ); + + const downloadAsset = ( + + + + + + + + ); + + const copyAsset = ( + + + + + + + + ); + + const deleteAsset = ( + + + setIsConfirmModalVisible(true)} + /> + + + ); + + const thumbnail = ( +
    + +
    + ); + + const assetLabel = ( + +

    + {asset.id} +
    + + ({Math.round(asset.value.length / 1024)} kb) + +

    +
    + ); + + return ( + + + {thumbnail} + + {assetLabel} + + + {createImage} + {downloadAsset} + {copyAsset} + {deleteAsset} + + + {isConfirmModalVisible ? confirmModal : null} + + ); +}; diff --git a/x-pack/plugins/canvas/public/components/asset_manager/asset.tsx b/x-pack/plugins/canvas/public/components/asset_manager/asset.tsx index b0eaecc7b5203..1a3ce8419aff6 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/asset.tsx +++ b/x-pack/plugins/canvas/public/components/asset_manager/asset.tsx @@ -3,124 +3,59 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { - EuiButtonIcon, - EuiFlexGroup, - EuiFlexItem, - EuiImage, - EuiPanel, - EuiSpacer, - EuiText, - EuiTextColor, - EuiToolTip, -} from '@elastic/eui'; -import React, { FunctionComponent } from 'react'; - -import { ComponentStrings } from '../../../i18n'; - -import { Clipboard } from '../clipboard'; -import { Download } from '../download'; -import { AssetType } from '../../../types'; - -const { Asset: strings } = ComponentStrings; - -interface Props { - /** The asset to be rendered */ - asset: AssetType; - /** The function to execute when the user clicks 'Create' */ - onCreate: (asset: AssetType) => void; - /** The function to execute when the user clicks 'Copy' */ - onCopy: (asset: AssetType) => void; - /** The function to execute when the user clicks 'Delete' */ - onDelete: (asset: AssetType) => void; -} - -export const Asset: FunctionComponent = (props) => { - const { asset, onCreate, onCopy, onDelete } = props; - - const createImage = ( - - - onCreate(asset)} - /> - - - ); - - const downloadAsset = ( - - - - - - - - ); - - const copyAsset = ( - - - result && onCopy(asset)}> - - - - - ); - - const deleteAsset = ( - - - onDelete(asset)} - /> - - - ); - - const thumbnail = ( -
    - -
    - ); - - const assetLabel = ( - -

    - {asset.id} -
    - - ({Math.round(asset.value.length / 1024)} kb) - -

    -
    - ); - - return ( - - - {thumbnail} - - {assetLabel} - - - {createImage} - {downloadAsset} - {copyAsset} - {deleteAsset} - - - - ); -}; +import { Dispatch } from 'redux'; +import { connect } from 'react-redux'; +import { set } from '@elastic/safer-lodash-set'; + +import { fromExpression, toExpression } from '@kbn/interpreter/common'; + +// @ts-expect-error untyped local +import { elementsRegistry } from '../../lib/elements_registry'; +// @ts-expect-error untyped local +import { addElement } from '../../state/actions/elements'; +import { getSelectedPage } from '../../state/selectors/workpad'; +// @ts-expect-error untyped local +import { removeAsset } from '../../state/actions/assets'; +import { State, ExpressionAstExpression, AssetType } from '../../../types'; + +import { Asset as Component } from './asset.component'; + +export const Asset = connect( + (state: State) => ({ + selectedPage: getSelectedPage(state), + }), + (dispatch: Dispatch) => ({ + onCreate: (pageId: string) => (assetId: string) => { + const imageElement = elementsRegistry.get('image'); + const elementAST = fromExpression(imageElement.expression); + const selector = ['chain', '0', 'arguments', 'dataurl']; + const subExp: ExpressionAstExpression[] = [ + { + type: 'expression', + chain: [ + { + type: 'function', + function: 'asset', + arguments: { + _: [assetId], + }, + }, + ], + }, + ]; + const newAST = set(elementAST, selector, subExp); + imageElement.expression = toExpression(newAST); + dispatch(addElement(pageId, imageElement)); + }, + onDelete: (asset: AssetType) => dispatch(removeAsset(asset.id)), + }), + (stateProps, dispatchProps, ownProps) => { + const { onCreate, onDelete } = dispatchProps; + + return { + ...ownProps, + onCreate: onCreate(stateProps.selectedPage), + onDelete, + }; + } +)(Component); diff --git a/x-pack/plugins/canvas/public/components/asset_manager/asset_modal.tsx b/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.component.tsx similarity index 69% rename from x-pack/plugins/canvas/public/components/asset_manager/asset_modal.tsx rename to x-pack/plugins/canvas/public/components/asset_manager/asset_manager.component.tsx index cb61bf1dc26c4..98f3d8b48829d 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/asset_modal.tsx +++ b/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.component.tsx @@ -3,6 +3,9 @@ * 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, { FC, useState } from 'react'; +import PropTypes from 'prop-types'; import { EuiButton, EuiEmptyPrompt, @@ -21,48 +24,29 @@ import { EuiSpacer, EuiText, } from '@elastic/eui'; -import PropTypes from 'prop-types'; -import React, { FunctionComponent } from 'react'; - -import { ComponentStrings } from '../../../i18n'; import { ASSET_MAX_SIZE } from '../../../common/lib/constants'; import { Loading } from '../loading'; import { Asset } from './asset'; import { AssetType } from '../../../types'; +import { ComponentStrings } from '../../../i18n'; -const { AssetModal: strings } = ComponentStrings; +const { AssetManager: strings } = ComponentStrings; interface Props { /** The assets to display within the modal */ - assetValues: AssetType[]; - /** Indicates if assets are being loaded */ - isLoading: boolean; + assets: AssetType[]; /** Function to invoke when the modal is closed */ onClose: () => void; - /** Function to invoke when a file is uploaded */ - onFileUpload: (assets: FileList | null) => void; - /** Function to invoke when an asset is copied */ - onAssetCopy: (asset: AssetType) => void; - /** Function to invoke when an asset is created */ - onAssetCreate: (asset: AssetType) => void; - /** Function to invoke when an asset is deleted */ - onAssetDelete: (asset: AssetType) => void; + onAddAsset: (file: File) => void; } -export const AssetModal: FunctionComponent = (props) => { - const { - assetValues, - isLoading, - onAssetCopy, - onAssetCreate, - onAssetDelete, - onClose, - onFileUpload, - } = props; +export const AssetManager: FC = (props) => { + const { assets, onClose, onAddAsset } = props; + const [isLoading, setIsLoading] = useState(false); const assetsTotal = Math.round( - assetValues.reduce((total, { value }) => total + value.length, 0) / 1024 + assets.reduce((total, { value }) => total + value.length, 0) / 1024 ); const percentageUsed = Math.round((assetsTotal / ASSET_MAX_SIZE) * 100); @@ -77,10 +61,22 @@ export const AssetModal: FunctionComponent = (props) => { ); + const onFileUpload = (files: FileList | null) => { + if (files === null) { + return; + } + + setIsLoading(true); + + Promise.all(Array.from(files).map((file) => onAddAsset(file))).finally(() => { + setIsLoading(false); + }); + }; + return ( onClose()} className="canvasAssetManager canvasModal--fixedSize" maxWidth="1000px" > @@ -110,16 +106,10 @@ export const AssetModal: FunctionComponent = (props) => {

    {strings.getDescription()}

    - {assetValues.length ? ( + {assets.length ? ( - {assetValues.map((asset) => ( - + {assets.map((asset) => ( + ))} ) : ( @@ -143,7 +133,7 @@ export const AssetModal: FunctionComponent = (props) => { - + onClose()}> {strings.getModalCloseButtonLabel()} @@ -152,12 +142,8 @@ export const AssetModal: FunctionComponent = (props) => { ); }; -AssetModal.propTypes = { - assetValues: PropTypes.array, - isLoading: PropTypes.bool, +AssetManager.propTypes = { + assets: PropTypes.arrayOf(PropTypes.object).isRequired, onClose: PropTypes.func.isRequired, - onFileUpload: PropTypes.func.isRequired, - onAssetCopy: PropTypes.func.isRequired, - onAssetCreate: PropTypes.func.isRequired, - onAssetDelete: PropTypes.func.isRequired, + onAddAsset: PropTypes.func.isRequired, }; diff --git a/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.ts b/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.ts new file mode 100644 index 0000000000000..f9bcfb266006c --- /dev/null +++ b/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.ts @@ -0,0 +1,70 @@ +/* + * 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 { Dispatch } from 'redux'; +import { connect } from 'react-redux'; +import { get } from 'lodash'; + +import { getId } from '../../lib/get_id'; +// @ts-expect-error untyped local +import { findExistingAsset } from '../../lib/find_existing_asset'; +import { VALID_IMAGE_TYPES } from '../../../common/lib/constants'; +import { encode } from '../../../common/lib/dataurl'; +// @ts-expect-error untyped local +import { elementsRegistry } from '../../lib/elements_registry'; +// @ts-expect-error untyped local +import { addElement } from '../../state/actions/elements'; +import { getAssets } from '../../state/selectors/assets'; +// @ts-expect-error untyped local +import { removeAsset, createAsset } from '../../state/actions/assets'; +import { State, AssetType } from '../../../types'; + +import { AssetManager as Component } from './asset_manager.component'; + +export const AssetManager = connect( + (state: State) => ({ + assets: getAssets(state), + }), + (dispatch: Dispatch) => ({ + onAddAsset: (type: string, content: string) => { + // make the ID here and pass it into the action + const assetId = getId('asset'); + dispatch(createAsset(type, content, assetId)); + + // then return the id, so the caller knows the id that will be created + return assetId; + }, + }), + (stateProps, dispatchProps, ownProps) => { + const { assets } = stateProps; + const { onAddAsset } = dispatchProps; + + // pull values out of assets object + // have to cast to AssetType[] because TS doesn't know about filtering + const assetValues = Object.values(assets).filter((asset) => !!asset) as AssetType[]; + + return { + ...ownProps, + assets: assetValues, + onAddAsset: (file: File) => { + const [type, subtype] = get(file, 'type', '').split('/'); + if (type === 'image' && VALID_IMAGE_TYPES.indexOf(subtype) >= 0) { + return encode(file).then((dataurl) => { + const dataurlType = 'dataurl'; + const existingId = findExistingAsset(dataurlType, dataurl, assetValues); + + if (existingId) { + return existingId; + } + + return onAddAsset(dataurlType, dataurl); + }); + } + + return false; + }, + }; + } +)(Component); diff --git a/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.tsx b/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.tsx deleted file mode 100644 index cb177591fd650..0000000000000 --- a/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.tsx +++ /dev/null @@ -1,111 +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 PropTypes from 'prop-types'; -import React, { Fragment, PureComponent } from 'react'; - -import { ComponentStrings } from '../../../i18n'; - -import { ConfirmModal } from '../confirm_modal'; -import { AssetType } from '../../../types'; -import { AssetModal } from './asset_modal'; - -const { AssetManager: strings } = ComponentStrings; - -export interface Props { - /** A list of assets, if available */ - assetValues: AssetType[]; - /** Function to invoke when an asset is selected to be added as an element to the workpad */ - onAddImageElement: (id: string) => void; - /** Function to invoke when an asset is deleted */ - onAssetDelete: (id: string | null) => void; - /** Function to invoke when an asset is copied */ - onAssetCopy: () => void; - /** Function to invoke when an asset is added */ - onAssetAdd: (asset: File) => void; - /** Function to invoke when an asset modal is closed */ - onClose: () => void; -} - -interface State { - /** The id of the asset to delete, if applicable. Is set if the viewer clicks the delete icon */ - deleteId: string | null; - /** Indicates if the modal is currently loading */ - isLoading: boolean; -} - -export class AssetManager extends PureComponent { - public static propTypes = { - assetValues: PropTypes.array, - onAddImageElement: PropTypes.func.isRequired, - onAssetAdd: PropTypes.func.isRequired, - onAssetCopy: PropTypes.func.isRequired, - onAssetDelete: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - }; - - public static defaultProps = { - assetValues: [], - }; - - public state = { - deleteId: null, - isLoading: false, - }; - - public render() { - const { isLoading } = this.state; - const { assetValues, onAssetCopy, onAddImageElement, onClose } = this.props; - - const assetModal = ( - { - onAddImageElement(createdAsset.id); - onClose(); - }} - onAssetDelete={(asset: AssetType) => this.setState({ deleteId: asset.id })} - onClose={onClose} - onFileUpload={this.handleFileUpload} - /> - ); - - const confirmModal = ( - - ); - - return ( - - {assetModal} - {confirmModal} - - ); - } - - private resetDelete = () => this.setState({ deleteId: null }); - - private doDelete = () => { - this.resetDelete(); - this.props.onAssetDelete(this.state.deleteId); - }; - - private handleFileUpload = (files: FileList | null) => { - if (files == null) return; - this.setState({ isLoading: true }); - Promise.all(Array.from(files).map((file) => this.props.onAssetAdd(file))).finally(() => { - this.setState({ isLoading: false }); - }); - }; -} diff --git a/x-pack/plugins/canvas/public/components/asset_manager/index.ts b/x-pack/plugins/canvas/public/components/asset_manager/index.ts index 9b4406f607867..5d586c07f4e4e 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/index.ts +++ b/x-pack/plugins/canvas/public/components/asset_manager/index.ts @@ -4,107 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { connect } from 'react-redux'; -import { compose, withProps } from 'recompose'; -import { set } from '@elastic/safer-lodash-set'; -import { get } from 'lodash'; -import { fromExpression, toExpression } from '@kbn/interpreter/common'; -import { getAssets } from '../../state/selectors/assets'; -// @ts-expect-error untyped local -import { removeAsset, createAsset } from '../../state/actions/assets'; -// @ts-expect-error untyped local -import { elementsRegistry } from '../../lib/elements_registry'; -// @ts-expect-error untyped local -import { addElement } from '../../state/actions/elements'; -import { getSelectedPage } from '../../state/selectors/workpad'; -import { encode } from '../../../common/lib/dataurl'; -import { getId } from '../../lib/get_id'; -// @ts-expect-error untyped local -import { findExistingAsset } from '../../lib/find_existing_asset'; -import { VALID_IMAGE_TYPES } from '../../../common/lib/constants'; -import { withKibana } from '../../../../../../src/plugins/kibana_react/public'; -import { WithKibanaProps } from '../../'; -import { AssetManager as Component, Props as AssetManagerProps } from './asset_manager'; - -import { State, ExpressionAstExpression, AssetType } from '../../../types'; - -const mapStateToProps = (state: State) => ({ - assets: getAssets(state), - selectedPage: getSelectedPage(state), -}); - -const mapDispatchToProps = (dispatch: (action: any) => void) => ({ - onAddImageElement: (pageId: string) => (assetId: string) => { - const imageElement = elementsRegistry.get('image'); - const elementAST = fromExpression(imageElement.expression); - const selector = ['chain', '0', 'arguments', 'dataurl']; - const subExp: ExpressionAstExpression[] = [ - { - type: 'expression', - chain: [ - { - type: 'function', - function: 'asset', - arguments: { - _: [assetId], - }, - }, - ], - }, - ]; - const newAST = set(elementAST, selector, subExp); - imageElement.expression = toExpression(newAST); - dispatch(addElement(pageId, imageElement)); - }, - onAssetAdd: (type: string, content: string) => { - // make the ID here and pass it into the action - const assetId = getId('asset'); - dispatch(createAsset(type, content, assetId)); - - // then return the id, so the caller knows the id that will be created - return assetId; - }, - onAssetDelete: (assetId: string) => dispatch(removeAsset(assetId)), -}); - -const mergeProps = ( - stateProps: ReturnType, - dispatchProps: ReturnType, - ownProps: AssetManagerProps -) => { - const { assets, selectedPage } = stateProps; - const { onAssetAdd } = dispatchProps; - const assetValues = Object.values(assets); // pull values out of assets object - - return { - ...ownProps, - ...dispatchProps, - onAddImageElement: dispatchProps.onAddImageElement(stateProps.selectedPage), - selectedPage, - assetValues, - onAssetAdd: (file: File) => { - const [type, subtype] = get(file, 'type', '').split('/'); - if (type === 'image' && VALID_IMAGE_TYPES.indexOf(subtype) >= 0) { - return encode(file).then((dataurl) => { - const dataurlType = 'dataurl'; - const existingId = findExistingAsset(dataurlType, dataurl, assetValues); - if (existingId) { - return existingId; - } - return onAssetAdd(dataurlType, dataurl); - }); - } - - return false; - }, - }; -}; - -export const AssetManager = compose( - connect(mapStateToProps, mapDispatchToProps, mergeProps), - withKibana, - withProps(({ kibana }: WithKibanaProps) => ({ - onAssetCopy: (asset: AssetType) => - kibana.services.canvas.notify.success(`Copied '${asset.id}' to clipboard`), - })) -)(Component); +export { Asset } from './asset'; +export { Asset as AssetComponent } from './asset.component'; +export { AssetManager } from './asset_manager'; +export { AssetManager as AssetManagerComponent } from './asset_manager.component'; diff --git a/x-pack/plugins/canvas/storybook/storyshots.test.js b/x-pack/plugins/canvas/storybook/storyshots.test.js index ba4013f7cc816..e3a9654bb49fa 100644 --- a/x-pack/plugins/canvas/storybook/storyshots.test.js +++ b/x-pack/plugins/canvas/storybook/storyshots.test.js @@ -94,4 +94,5 @@ addSerializer(styleSheetSerializer); initStoryshots({ configPath: path.resolve(__dirname, './../storybook'), test: multiSnapshotWithOptions({}), + storyNameRegex: /^((?!.*?redux).)*$/, }); diff --git a/x-pack/plugins/canvas/storybook/webpack.config.js b/x-pack/plugins/canvas/storybook/webpack.config.js index 1e0e36f796128..927f71b832ba0 100644 --- a/x-pack/plugins/canvas/storybook/webpack.config.js +++ b/x-pack/plugins/canvas/storybook/webpack.config.js @@ -47,6 +47,12 @@ module.exports = async ({ config }) => { ], }); + config.module.rules.push({ + test: /\.mjs$/, + include: /node_modules/, + type: 'javascript/auto', + }); + // Parse props data for .tsx files // This is notoriously slow, and is making Storybook unusable. Disabling for now. // See: https://github.com/storybookjs/storybook/issues/7998 @@ -117,6 +123,15 @@ module.exports = async ({ config }) => { ], }); + // Exclude large-dependency modules that need not be included in Storybook. + config.module.rules.push({ + test: [ + path.resolve(__dirname, '../public/components/embeddable_flyout'), + path.resolve(__dirname, '../../reporting/public'), + ], + use: 'null-loader', + }); + // Ensure jQuery is global for Storybook, specifically for the runtime. config.plugins.push( new webpack.ProvidePlugin({ @@ -216,5 +231,7 @@ module.exports = async ({ config }) => { config.resolve.alias.ui = path.resolve(KIBANA_ROOT, 'src/legacy/ui/public'); config.resolve.alias.ng_mock$ = path.resolve(KIBANA_ROOT, 'src/test_utils/public/ng_mock'); + config.resolve.extensions.push('.mjs'); + return config; }; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 4175f76ad7ba8..451557ff93092 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -4685,14 +4685,14 @@ "xpack.canvas.argFormArgSimpleForm.requiredTooltip": "この引数は必須です。数値を入力してください。", "xpack.canvas.argFormPendingArgValue.loadingMessage": "読み込み中", "xpack.canvas.argFormSimpleFailure.failureTooltip": "この引数のインターフェースが値を解析できなかったため、フォールバックインプットが使用されています", + "xpack.canvas.asset.confirmModalButtonLabel": "削除", + "xpack.canvas.asset.confirmModalDetail": "このアセットを削除してよろしいですか?", + "xpack.canvas.asset.confirmModalTitle": "アセットの削除", "xpack.canvas.asset.copyAssetTooltip": "ID をクリップボードにコピー", "xpack.canvas.asset.createImageTooltip": "画像エレメントを作成", "xpack.canvas.asset.deleteAssetTooltip": "削除", "xpack.canvas.asset.downloadAssetTooltip": "ダウンロード", "xpack.canvas.asset.thumbnailAltText": "アセットのサムネイル", - "xpack.canvas.assetManager.confirmModalButtonLabel": "削除", - "xpack.canvas.assetManager.confirmModalDetail": "このアセットを削除してよろしいですか?", - "xpack.canvas.assetManager.confirmModalTitle": "アセットの削除", "xpack.canvas.assetManager.manageButtonLabel": "アセットの管理", "xpack.canvas.assetModal.emptyAssetsDescription": "アセットをインポートして開始します", "xpack.canvas.assetModal.filePickerPromptText": "画像を選択するかドラッグ &amp; ドロップしてください", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 33d60dbd17700..3a2ef39d49ece 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -4689,14 +4689,14 @@ "xpack.canvas.argFormArgSimpleForm.requiredTooltip": "此参数为必需,应指定值。", "xpack.canvas.argFormPendingArgValue.loadingMessage": "正在加载", "xpack.canvas.argFormSimpleFailure.failureTooltip": "此参数的接口无法解析该值,因此将使用回退输入", + "xpack.canvas.asset.confirmModalButtonLabel": "删除", + "xpack.canvas.asset.confirmModalDetail": "确定要删除此资产?", + "xpack.canvas.asset.confirmModalTitle": "删除资产", "xpack.canvas.asset.copyAssetTooltip": "将 ID 复制到剪贴板", "xpack.canvas.asset.createImageTooltip": "创建图像元素", "xpack.canvas.asset.deleteAssetTooltip": "删除", "xpack.canvas.asset.downloadAssetTooltip": "下载", "xpack.canvas.asset.thumbnailAltText": "资产缩略图", - "xpack.canvas.assetManager.confirmModalButtonLabel": "删除", - "xpack.canvas.assetManager.confirmModalDetail": "确定要删除此资产?", - "xpack.canvas.assetManager.confirmModalTitle": "删除资产", "xpack.canvas.assetManager.manageButtonLabel": "管理资产", "xpack.canvas.assetModal.emptyAssetsDescription": "导入您的资产以开始", "xpack.canvas.assetModal.filePickerPromptText": "选择或拖放图像", From ba643bd2984fddba32b9dfbab762de1ae13683e8 Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Tue, 21 Jul 2020 18:31:54 -0500 Subject: [PATCH 71/77] [Security Solution][Detections] Validate file type of value lists (#72746) * UI validates file type of uploaded value list * file picker itself is restricted to text/csv and text/plain * if they drag/drop an invalid file, we disable the upload button and display an error message * refactors form state to be a File instead of a FileList * Refactor validation and error message in terms of file type Instead of maintaining lists of both valid extensions and valid mime types, we simply use the latter. --- .../form.test.tsx | 27 +++++++++++++-- .../value_lists_management_modal/form.tsx | 33 ++++++++++++++----- .../translations.ts | 6 ++++ 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.test.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.test.tsx index e2e793b34eaf9..591e1c81cd2ad 100644 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.test.tsx @@ -16,7 +16,7 @@ const mockUseImportList = useImportList as jest.Mock; const mockFile = ({ name: 'foo.csv', - path: '/home/foo.csv', + type: 'text/csv', } as unknown) as File; const mockSelectFile:

    (container: ReactWrapper

    , file: File) => Promise = async ( @@ -26,7 +26,7 @@ const mockSelectFile:

    (container: ReactWrapper

    , file: File) => Promise { if (fileChange) { - fileChange(([file] as unknown) as FormEvent); + fileChange(({ item: () => file } as unknown) as FormEvent); } }); }; @@ -83,6 +83,29 @@ describe('ValueListsForm', () => { expect(onError).toHaveBeenCalledWith('whoops'); }); + it('disables upload and displays an error if file has invalid extension', async () => { + const badMockFile = ({ + name: 'foo.pdf', + type: 'application/pdf', + } as unknown) as File; + + const container = mount( + + + + ); + + await mockSelectFile(container, badMockFile); + + expect( + container.find('button[data-test-subj="value-lists-form-import-action"]').prop('disabled') + ).toEqual(true); + + expect(container.find('div[data-test-subj="value-list-file-picker-row"]').text()).toContain( + 'File must be one of the following types: [text/csv, text/plain]' + ); + }); + it('calls onSuccess if import succeeds', async () => { mockUseImportList.mockImplementation(() => ({ start: jest.fn(), diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx index b8416c3242e4a..aab665289e80d 100644 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx @@ -46,6 +46,7 @@ const options: ListTypeOptions[] = [ ]; const defaultListType: Type = 'keyword'; +const validFileTypes = ['text/csv', 'text/plain']; export interface ValueListsFormProps { onError: (error: Error) => void; @@ -54,23 +55,29 @@ export interface ValueListsFormProps { export const ValueListsFormComponent: React.FC = ({ onError, onSuccess }) => { const ctrl = useRef(new AbortController()); - const [files, setFiles] = useState(null); + const [file, setFile] = useState(null); const [type, setType] = useState(defaultListType); const filePickerRef = useRef(null); const { http } = useKibana().services; const { start: importList, ...importState } = useImportList(); + const fileIsValid = !file || validFileTypes.some((fileType) => file.type === fileType); + // EuiRadioGroup's onChange only infers 'string' from our options const handleRadioChange = useCallback((t: string) => setType(t as Type), [setType]); + const handleFileChange = useCallback((files: FileList | null) => { + setFile(files?.item(0) ?? null); + }, []); + const resetForm = useCallback(() => { if (filePickerRef.current?.fileInput) { filePickerRef.current.fileInput.value = ''; filePickerRef.current.handleChange(); } - setFiles(null); + setFile(null); setType(defaultListType); - }, [setType]); + }, []); const handleCancel = useCallback(() => { ctrl.current.abort(); @@ -91,17 +98,17 @@ export const ValueListsFormComponent: React.FC = ({ onError ); const handleImport = useCallback(() => { - if (!importState.loading && files && files.length) { + if (!importState.loading && file) { ctrl.current = new AbortController(); importList({ - file: files[0], + file, listId: undefined, http, signal: ctrl.current.signal, type, }); } - }, [importState.loading, files, importList, http, type]); + }, [importState.loading, file, importList, http, type]); useEffect(() => { if (!importState.loading && importState.result) { @@ -117,14 +124,22 @@ export const ValueListsFormComponent: React.FC = ({ onError return ( - + @@ -151,7 +166,7 @@ export const ValueListsFormComponent: React.FC = ({ onError {i18n.UPLOAD_BUTTON} diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts index dca6e43a98143..91f3f3797f422 100644 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts @@ -24,6 +24,12 @@ export const FILE_PICKER_PROMPT = i18n.translate( } ); +export const FILE_PICKER_INVALID_FILE_TYPE = (fileTypes: string): string => + i18n.translate('xpack.securitySolution.lists.uploadValueListExtensionValidationMessage', { + values: { fileTypes }, + defaultMessage: 'File must be one of the following types: [{fileTypes}]', + }); + export const CLOSE_BUTTON = i18n.translate( 'xpack.securitySolution.lists.closeValueListsModalTitle', { From eddc62ad4b9aad30121624e90223e85821f47d3d Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Tue, 21 Jul 2020 17:50:25 -0600 Subject: [PATCH 72/77] [SIEM][Detection Engine][Lists] Adds version and immutability data structures (#72730) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Summary The intent is to get the data structures in similar to rules so that we can have eventually immutable and versioned lists in later releases without too much hassle of upgrading the list and list item data structures. * Adds version and immutability data structures to the exception lists and the value lists. * Adds an optional version number to the update route of each so that you can modify the number either direction or you can omit it and it works like the detection rules where it will auto-increment the number. * Does _not_ add a version and immutability to the exception list items and value list items. * Does _not_ update the version number when you add a new exception list item or value list item. **Examples:** ❯ ./post_list.sh ```json { "_version": "WzAsMV0=", "id": "ip_list", "created_at": "2020-07-21T20:31:11.679Z", "created_by": "yo", "description": "This list describes bad internet ip", "immutable": false, "name": "Simple list with an ip", "tie_breaker_id": "d6bd7552-84d1-4f95-88c4-cc504517b4e5", "type": "ip", "updated_at": "2020-07-21T20:31:11.679Z", "updated_by": "yo", "version": 1 } ``` ❯ ./post_exception_list.sh ```json { "_tags": [ "endpoint", "process", "malware", "os:linux" ], "_version": "WzMzOTgsMV0=", "created_at": "2020-07-21T20:31:35.933Z", "created_by": "yo", "description": "This is a sample endpoint type exception", "id": "2c24b100-cb91-11ea-a872-adfddf68361e", "immutable": false, "list_id": "simple_list", "name": "Sample Endpoint Exception List", "namespace_type": "single", "tags": [ "user added string for a tag", "malware" ], "tie_breaker_id": "c11c4d53-d0be-4904-870e-d33ec7ca387f", "type": "detection", "updated_at": "2020-07-21T20:31:35.952Z", "updated_by": "yo", "version": 1 } ``` ```json ❯ ./update_list.sh { "_version": "WzEsMV0=", "created_at": "2020-07-21T20:31:11.679Z", "created_by": "yo", "description": "Some other description here for you", "id": "ip_list", "immutable": false, "name": "Changed the name here to something else", "tie_breaker_id": "d6bd7552-84d1-4f95-88c4-cc504517b4e5", "type": "ip", "updated_at": "2020-07-21T20:31:47.089Z", "updated_by": "yo", "version": 2 } ``` ```json ❯ ./update_exception_list.sh { "_tags": [ "endpoint", "process", "malware", "os:linux" ], "_version": "WzMzOTksMV0=", "created_at": "2020-07-21T20:31:35.933Z", "created_by": "yo", "description": "Different description", "id": "2c24b100-cb91-11ea-a872-adfddf68361e", "immutable": false, "list_id": "simple_list", "name": "Sample Endpoint Exception List", "namespace_type": "single", "tags": [ "user added string for a tag", "malware" ], "tie_breaker_id": "c11c4d53-d0be-4904-870e-d33ec7ca387f", "type": "endpoint", "updated_at": "2020-07-21T20:31:56.628Z", "updated_by": "yo", "version": 2 } ``` ### Checklist - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios --- x-pack/plugins/lists/common/constants.mock.ts | 2 ++ .../lists/common/schemas/common/schemas.ts | 12 ++++++++++++ .../index_es_list_schema.mock.ts | 4 ++++ .../elastic_query/index_es_list_schema.ts | 4 ++++ .../search_es_list_schema.mock.ts | 4 ++++ .../elastic_response/search_es_list_schema.ts | 4 ++++ .../create_exception_list_schema.mock.ts | 10 +++++++++- .../request/create_exception_list_schema.ts | 8 +++++++- .../request/create_list_schema.mock.ts | 3 ++- .../schemas/request/create_list_schema.ts | 15 +++++++++++++-- .../schemas/request/patch_list_schema.ts | 12 ++++++++++-- .../request/update_exception_list_schema.ts | 2 ++ .../schemas/request/update_list_schema.ts | 3 ++- .../create_endpoint_list_schema.test.ts | 2 +- .../response/exception_list_schema.mock.ts | 4 ++++ .../schemas/response/exception_list_schema.ts | 4 ++++ .../schemas/response/list_schema.mock.ts | 4 ++++ .../common/schemas/response/list_schema.ts | 4 ++++ .../exceptions_list_so_schema.ts | 7 +++++++ x-pack/plugins/lists/common/shared_imports.ts | 2 ++ .../routes/create_exception_list_route.ts | 3 +++ .../lists/server/routes/create_list_route.ts | 19 ++++++++++++++++--- .../server/routes/import_list_item_route.ts | 2 ++ .../lists/server/routes/patch_list_route.ts | 4 ++-- .../routes/update_exception_list_route.ts | 2 ++ .../lists/server/routes/update_list_route.ts | 4 ++-- .../server/saved_objects/exception_list.ts | 6 ++++++ .../exception_lists/create_endpoint_list.ts | 6 +++++- .../exception_lists/create_exception_list.ts | 8 ++++++++ .../create_exception_list_item.ts | 2 ++ .../exception_lists/exception_list_client.ts | 7 +++++++ .../exception_list_client_types.ts | 6 ++++++ .../exception_lists/update_exception_list.ts | 5 +++++ .../server/services/exception_lists/utils.ts | 18 +++++++++++++++++- .../write_lines_to_bulk_list_items.mock.ts | 2 ++ .../items/write_lines_to_bulk_list_items.ts | 5 +++++ .../server/services/lists/create_list.mock.ts | 4 ++++ .../server/services/lists/create_list.ts | 8 ++++++++ .../lists/create_list_if_it_does_not_exist.ts | 8 ++++++++ .../server/services/lists/list_client.ts | 12 ++++++++++++ .../services/lists/list_client_types.ts | 9 +++++++++ .../server/services/lists/list_mappings.json | 6 ++++++ .../server/services/lists/update_list.mock.ts | 2 ++ .../server/services/lists/update_list.ts | 6 ++++++ .../schemas/types/default_version_number.ts | 2 ++ .../common/shared_exports.ts | 4 ++++ .../autocomplete/field_value_lists.test.tsx | 4 +++- 47 files changed, 255 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/lists/common/constants.mock.ts b/x-pack/plugins/lists/common/constants.mock.ts index 6ed1d19611c68..4f01d43f47ecd 100644 --- a/x-pack/plugins/lists/common/constants.mock.ts +++ b/x-pack/plugins/lists/common/constants.mock.ts @@ -61,3 +61,5 @@ export const COMMENTS = []; export const FILTER = 'name:Nicolas Bourbaki'; export const CURSOR = 'c29tZXN0cmluZ2ZvcnlvdQ=='; export const _VERSION = 'WzI5NywxXQ=='; +export const VERSION = 1; +export const IMMUTABLE = false; diff --git a/x-pack/plugins/lists/common/schemas/common/schemas.ts b/x-pack/plugins/lists/common/schemas/common/schemas.ts index 8f1666bb542d9..26511f89c32b8 100644 --- a/x-pack/plugins/lists/common/schemas/common/schemas.ts +++ b/x-pack/plugins/lists/common/schemas/common/schemas.ts @@ -311,3 +311,15 @@ export type DeserializerOrUndefined = t.TypeOf; export const _version = t.string; export const _versionOrUndefined = t.union([_version, t.undefined]); export type _VersionOrUndefined = t.TypeOf; + +export const version = t.number; +export type Version = t.TypeOf; + +export const versionOrUndefined = t.union([version, t.undefined]); +export type VersionOrUndefined = t.TypeOf; + +export const immutable = t.boolean; +export type Immutable = t.TypeOf; + +export const immutableOrUndefined = t.union([immutable, t.undefined]); +export type ImmutableOrUndefined = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.mock.ts index 85a6b1362a582..81cbaea21d6f6 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.mock.ts @@ -8,11 +8,13 @@ import { IndexEsListSchema } from '../../../common/schemas'; import { DATE_NOW, DESCRIPTION, + IMMUTABLE, META, NAME, TIE_BREAKER, TYPE, USER, + VERSION, } from '../../../common/constants.mock'; export const getIndexESListMock = (): IndexEsListSchema => ({ @@ -20,6 +22,7 @@ export const getIndexESListMock = (): IndexEsListSchema => ({ created_by: USER, description: DESCRIPTION, deserializer: undefined, + immutable: IMMUTABLE, meta: META, name: NAME, serializer: undefined, @@ -27,4 +30,5 @@ export const getIndexESListMock = (): IndexEsListSchema => ({ type: TYPE, updated_at: DATE_NOW, updated_by: USER, + version: VERSION, }); diff --git a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts index 3ee598291149f..be41e57f99421 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_query/index_es_list_schema.ts @@ -13,6 +13,7 @@ import { created_by, description, deserializerOrUndefined, + immutable, metaOrUndefined, name, serializerOrUndefined, @@ -20,6 +21,7 @@ import { type, updated_at, updated_by, + version, } from '../common/schemas'; export const indexEsListSchema = t.exact( @@ -28,6 +30,7 @@ export const indexEsListSchema = t.exact( created_by, description, deserializer: deserializerOrUndefined, + immutable, meta: metaOrUndefined, name, serializer: serializerOrUndefined, @@ -35,6 +38,7 @@ export const indexEsListSchema = t.exact( type, updated_at, updated_by, + version, }) ); diff --git a/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.mock.ts index 703d0d0f654a8..1562a2192a173 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.mock.ts @@ -10,6 +10,7 @@ import { SearchEsListSchema } from '../../../common/schemas'; import { DATE_NOW, DESCRIPTION, + IMMUTABLE, LIST_ID, LIST_INDEX, META, @@ -17,6 +18,7 @@ import { TIE_BREAKER, TYPE, USER, + VERSION, } from '../../../common/constants.mock'; import { getShardMock } from '../../get_shard.mock'; @@ -25,6 +27,7 @@ export const getSearchEsListMock = (): SearchEsListSchema => ({ created_by: USER, description: DESCRIPTION, deserializer: undefined, + immutable: IMMUTABLE, meta: META, name: NAME, serializer: undefined, @@ -32,6 +35,7 @@ export const getSearchEsListMock = (): SearchEsListSchema => ({ type: TYPE, updated_at: DATE_NOW, updated_by: USER, + version: VERSION, }); export const getSearchListMock = (): SearchResponse => ({ diff --git a/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.ts b/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.ts index 46005b81ef680..6807201cf18d9 100644 --- a/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/elastic_response/search_es_list_schema.ts @@ -13,6 +13,7 @@ import { created_by, description, deserializerOrUndefined, + immutable, metaOrUndefined, name, serializerOrUndefined, @@ -20,6 +21,7 @@ import { type, updated_at, updated_by, + version, } from '../common/schemas'; export const searchEsListSchema = t.exact( @@ -28,6 +30,7 @@ export const searchEsListSchema = t.exact( created_by, description, deserializer: deserializerOrUndefined, + immutable, meta: metaOrUndefined, name, serializer: serializerOrUndefined, @@ -35,6 +38,7 @@ export const searchEsListSchema = t.exact( type, updated_at, updated_by, + version, }) ); diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.mock.ts index 22a56f7d42b70..d9c0474610369 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.mock.ts @@ -4,7 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { DESCRIPTION, ENDPOINT_TYPE, META, NAME, NAMESPACE_TYPE } from '../../constants.mock'; +import { + DESCRIPTION, + ENDPOINT_TYPE, + META, + NAME, + NAMESPACE_TYPE, + VERSION, +} from '../../constants.mock'; import { CreateExceptionListSchema } from './create_exception_list_schema'; @@ -17,4 +24,5 @@ export const getCreateExceptionListSchemaMock = (): CreateExceptionListSchema => namespace_type: NAMESPACE_TYPE, tags: [], type: ENDPOINT_TYPE, + version: VERSION, }); diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts index 8f714760621ff..94a4e1588f5ab 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts @@ -21,7 +21,11 @@ import { tags, } from '../common/schemas'; import { RequiredKeepUndefined } from '../../types'; -import { DefaultUuid } from '../../siem_common_deps'; +import { + DefaultUuid, + DefaultVersionNumber, + DefaultVersionNumberDecoded, +} from '../../siem_common_deps'; import { NamespaceType } from '../types'; export const createExceptionListSchema = t.intersection([ @@ -39,6 +43,7 @@ export const createExceptionListSchema = t.intersection([ meta, // defaults to undefined if not set during decode namespace_type, // defaults to 'single' if not set during decode tags, // defaults to empty array if not set during decode + version: DefaultVersionNumber, // defaults to numerical 1 if not set during decode }) ), ]); @@ -54,4 +59,5 @@ export type CreateExceptionListSchemaDecoded = Omit< tags: Tags; list_id: ListId; namespace_type: NamespaceType; + version: DefaultVersionNumberDecoded; }; diff --git a/x-pack/plugins/lists/common/schemas/request/create_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/request/create_list_schema.mock.ts index 482fabb3b997f..461890b944bfa 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_list_schema.mock.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { DESCRIPTION, LIST_ID, META, NAME, TYPE } from '../../constants.mock'; +import { DESCRIPTION, LIST_ID, META, NAME, TYPE, VERSION } from '../../constants.mock'; import { CreateListSchema } from './create_list_schema'; @@ -16,4 +16,5 @@ export const getCreateListSchemaMock = (): CreateListSchema => ({ name: NAME, serializer: undefined, type: TYPE, + version: VERSION, }); diff --git a/x-pack/plugins/lists/common/schemas/request/create_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_list_schema.ts index 38d6167ea63f3..18ed0f42ccd6f 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_list_schema.ts @@ -8,6 +8,7 @@ import * as t from 'io-ts'; import { description, deserializer, id, meta, name, serializer, type } from '../common/schemas'; import { RequiredKeepUndefined } from '../../types'; +import { DefaultVersionNumber, DefaultVersionNumberDecoded } from '../../siem_common_deps'; export const createListSchema = t.intersection([ t.exact( @@ -17,8 +18,18 @@ export const createListSchema = t.intersection([ type, }) ), - t.exact(t.partial({ deserializer, id, meta, serializer })), + t.exact( + t.partial({ + deserializer, // defaults to undefined if not set during decode + id, // defaults to undefined if not set during decode + meta, // defaults to undefined if not set during decode + serializer, // defaults to undefined if not set during decode + version: DefaultVersionNumber, // defaults to a numerical 1 if not set during decode + }) + ), ]); export type CreateListSchema = t.OutputOf; -export type CreateListSchemaDecoded = RequiredKeepUndefined>; +export type CreateListSchemaDecoded = RequiredKeepUndefined< + Omit, 'version'> +> & { version: DefaultVersionNumberDecoded }; diff --git a/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts index e0cd1571afc81..c92abd2e912eb 100644 --- a/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/patch_list_schema.ts @@ -8,7 +8,7 @@ import * as t from 'io-ts'; -import { _version, description, id, meta, name } from '../common/schemas'; +import { _version, description, id, meta, name, version } from '../common/schemas'; import { RequiredKeepUndefined } from '../../types'; export const patchListSchema = t.intersection([ @@ -17,7 +17,15 @@ export const patchListSchema = t.intersection([ id, }) ), - t.exact(t.partial({ _version, description, meta, name })), + t.exact( + t.partial({ + _version, // is undefined if not set during decode + description, // is undefined if not set during decode + meta, // is undefined if not set during decode + name, // is undefined if not set during decode + version, // is undefined if not set during decode + }) + ), ]); export type PatchListSchema = t.OutputOf; diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts index 5d7294ae27af2..dd1bc65d18230 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_schema.ts @@ -21,6 +21,7 @@ import { name, namespace_type, tags, + version, } from '../common/schemas'; import { RequiredKeepUndefined } from '../../types'; import { NamespaceType } from '../types'; @@ -42,6 +43,7 @@ export const updateExceptionListSchema = t.intersection([ meta, // defaults to undefined if not set during decode namespace_type, // defaults to 'single' if not set during decode tags, // defaults to empty array if not set during decode + version, // defaults to undefined if not set during decode }) ), ]); diff --git a/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts index 19a39d362c241..a9778f23f1302 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_list_schema.ts @@ -8,7 +8,7 @@ import * as t from 'io-ts'; -import { _version, description, id, meta, name } from '../common/schemas'; +import { _version, description, id, meta, name, version } from '../common/schemas'; import { RequiredKeepUndefined } from '../../types'; export const updateListSchema = t.intersection([ @@ -23,6 +23,7 @@ export const updateListSchema = t.intersection([ t.partial({ _version, // defaults to undefined if not set during decode meta, // defaults to undefined if not set during decode + version, // defaults to undefined if not set during decode }) ), ]); diff --git a/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.test.ts b/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.test.ts index 646cc3d97f8ee..5fccaaac22e3a 100644 --- a/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/response/create_endpoint_list_schema.test.ts @@ -41,7 +41,7 @@ describe('create_endpoint_list_schema', () => { const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'invalid keys "_tags,["endpoint","process","malware","os:linux"],_version,created_at,created_by,description,id,meta,{},name,namespace_type,tags,["user added string for a tag","malware"],tie_breaker_id,type,updated_at,updated_by"', + 'invalid keys "_tags,["endpoint","process","malware","os:linux"],_version,created_at,created_by,description,id,immutable,meta,{},name,namespace_type,tags,["user added string for a tag","malware"],tie_breaker_id,type,updated_at,updated_by,version"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts index f790ad9544d53..2655b09631b23 100644 --- a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.mock.ts @@ -8,9 +8,11 @@ import { DATE_NOW, DESCRIPTION, ENDPOINT_TYPE, + IMMUTABLE, META, TIE_BREAKER, USER, + VERSION, _VERSION, } from '../../constants.mock'; import { ENDPOINT_LIST_ID } from '../..'; @@ -23,6 +25,7 @@ export const getExceptionListSchemaMock = (): ExceptionListSchema => ({ created_by: USER, description: DESCRIPTION, id: '1', + immutable: IMMUTABLE, list_id: ENDPOINT_LIST_ID, meta: META, name: 'Sample Endpoint Exception List', @@ -32,4 +35,5 @@ export const getExceptionListSchemaMock = (): ExceptionListSchema => ({ type: ENDPOINT_TYPE, updated_at: DATE_NOW, updated_by: 'user_name', + version: VERSION, }); diff --git a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts index 11c23bc2ff354..2dbabb0e2bc3b 100644 --- a/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/exception_list_schema.ts @@ -16,6 +16,7 @@ import { description, exceptionListType, id, + immutable, list_id, metaOrUndefined, name, @@ -24,6 +25,7 @@ import { tie_breaker_id, updated_at, updated_by, + version, } from '../common/schemas'; export const exceptionListSchema = t.exact( @@ -34,6 +36,7 @@ export const exceptionListSchema = t.exact( created_by, description, id, + immutable, list_id, meta: metaOrUndefined, name, @@ -43,6 +46,7 @@ export const exceptionListSchema = t.exact( type: exceptionListType, updated_at, updated_by, + version, }) ); diff --git a/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts b/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts index 339beddb00f8e..900c7ea4322a3 100644 --- a/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts +++ b/x-pack/plugins/lists/common/schemas/response/list_schema.mock.ts @@ -8,12 +8,14 @@ import { ListSchema } from '../../../common/schemas'; import { DATE_NOW, DESCRIPTION, + IMMUTABLE, LIST_ID, META, NAME, TIE_BREAKER, TYPE, USER, + VERSION, } from '../../../common/constants.mock'; export const getListResponseMock = (): ListSchema => ({ @@ -23,6 +25,7 @@ export const getListResponseMock = (): ListSchema => ({ description: DESCRIPTION, deserializer: undefined, id: LIST_ID, + immutable: IMMUTABLE, meta: META, name: NAME, serializer: undefined, @@ -30,4 +33,5 @@ export const getListResponseMock = (): ListSchema => ({ type: TYPE, updated_at: DATE_NOW, updated_by: USER, + version: VERSION, }); diff --git a/x-pack/plugins/lists/common/schemas/response/list_schema.ts b/x-pack/plugins/lists/common/schemas/response/list_schema.ts index 7e2bc202a6520..539c6221fcb0f 100644 --- a/x-pack/plugins/lists/common/schemas/response/list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/response/list_schema.ts @@ -15,6 +15,7 @@ import { description, deserializerOrUndefined, id, + immutable, metaOrUndefined, name, serializerOrUndefined, @@ -22,6 +23,7 @@ import { type, updated_at, updated_by, + version, } from '../common/schemas'; export const listSchema = t.exact( @@ -32,6 +34,7 @@ export const listSchema = t.exact( description, deserializer: deserializerOrUndefined, id, + immutable, meta: metaOrUndefined, name, serializer: serializerOrUndefined, @@ -39,6 +42,7 @@ export const listSchema = t.exact( type, updated_at, updated_by, + version, }) ); diff --git a/x-pack/plugins/lists/common/schemas/saved_objects/exceptions_list_so_schema.ts b/x-pack/plugins/lists/common/schemas/saved_objects/exceptions_list_so_schema.ts index 0b61f122463f3..2bd2a51ca8c74 100644 --- a/x-pack/plugins/lists/common/schemas/saved_objects/exceptions_list_so_schema.ts +++ b/x-pack/plugins/lists/common/schemas/saved_objects/exceptions_list_so_schema.ts @@ -16,6 +16,7 @@ import { description, exceptionListItemType, exceptionListType, + immutableOrUndefined, itemIdOrUndefined, list_id, list_type, @@ -24,8 +25,12 @@ import { tags, tie_breaker_id, updated_by, + versionOrUndefined, } from '../common/schemas'; +/** + * Superset saved object of both lists and list items since they share the same saved object type. + */ export const exceptionListSoSchema = t.exact( t.type({ _tags, @@ -34,6 +39,7 @@ export const exceptionListSoSchema = t.exact( created_by, description, entries: entriesArrayOrUndefined, + immutable: immutableOrUndefined, item_id: itemIdOrUndefined, list_id, list_type, @@ -43,6 +49,7 @@ export const exceptionListSoSchema = t.exact( tie_breaker_id, type: t.union([exceptionListType, exceptionListItemType]), updated_by, + version: versionOrUndefined, }) ); diff --git a/x-pack/plugins/lists/common/shared_imports.ts b/x-pack/plugins/lists/common/shared_imports.ts index ad7c24b3db610..e5302b5cd5d88 100644 --- a/x-pack/plugins/lists/common/shared_imports.ts +++ b/x-pack/plugins/lists/common/shared_imports.ts @@ -8,6 +8,8 @@ export { NonEmptyString, DefaultUuid, DefaultStringArray, + DefaultVersionNumber, + DefaultVersionNumberDecoded, exactCheck, getPaths, foldLeftRight, diff --git a/x-pack/plugins/lists/server/routes/create_exception_list_route.ts b/x-pack/plugins/lists/server/routes/create_exception_list_route.ts index 897d82d6a9ba0..fbe9c6ec9d83b 100644 --- a/x-pack/plugins/lists/server/routes/create_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/create_exception_list_route.ts @@ -43,6 +43,7 @@ export const createExceptionListRoute = (router: IRouter): void => { description, list_id: listId, type, + version, } = request.body; const exceptionLists = getExceptionListClient(context); const exceptionList = await exceptionLists.getExceptionList({ @@ -59,12 +60,14 @@ export const createExceptionListRoute = (router: IRouter): void => { const createdList = await exceptionLists.createExceptionList({ _tags, description, + immutable: false, listId, meta, name, namespaceType, tags, type, + version, }); const [validated, errors] = validate(createdList, exceptionListSchema); if (errors != null) { diff --git a/x-pack/plugins/lists/server/routes/create_list_route.ts b/x-pack/plugins/lists/server/routes/create_list_route.ts index ff041699054c9..297dcfc49db34 100644 --- a/x-pack/plugins/lists/server/routes/create_list_route.ts +++ b/x-pack/plugins/lists/server/routes/create_list_route.ts @@ -9,7 +9,7 @@ import { IRouter } from 'kibana/server'; import { LIST_URL } from '../../common/constants'; import { buildRouteValidation, buildSiemResponse, transformError } from '../siem_server_deps'; import { validate } from '../../common/siem_common_deps'; -import { createListSchema, listSchema } from '../../common/schemas'; +import { CreateListSchemaDecoded, createListSchema, listSchema } from '../../common/schemas'; import { getListClient } from '.'; @@ -21,13 +21,24 @@ export const createListRoute = (router: IRouter): void => { }, path: LIST_URL, validate: { - body: buildRouteValidation(createListSchema), + body: buildRouteValidation( + createListSchema + ), }, }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const { name, description, deserializer, id, serializer, type, meta } = request.body; + const { + name, + description, + deserializer, + id, + serializer, + type, + meta, + version, + } = request.body; const lists = getListClient(context); const listExists = await lists.getListIndexExists(); if (!listExists) { @@ -49,10 +60,12 @@ export const createListRoute = (router: IRouter): void => { description, deserializer, id, + immutable: false, meta, name, serializer, type, + version, }); const [validated, errors] = validate(list, listSchema); if (errors != null) { diff --git a/x-pack/plugins/lists/server/routes/import_list_item_route.ts b/x-pack/plugins/lists/server/routes/import_list_item_route.ts index 5e88ca0f2569a..1003a0c52a794 100644 --- a/x-pack/plugins/lists/server/routes/import_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/import_list_item_route.ts @@ -55,6 +55,7 @@ export const importListItemRoute = (router: IRouter, config: ConfigType): void = serializer: list.serializer, stream, type: list.type, + version: 1, }); const [validated, errors] = validate(list, listSchema); @@ -71,6 +72,7 @@ export const importListItemRoute = (router: IRouter, config: ConfigType): void = serializer, stream, type, + version: 1, }); if (importedList == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/patch_list_route.ts b/x-pack/plugins/lists/server/routes/patch_list_route.ts index 681581c6ff6bd..421f1279f2619 100644 --- a/x-pack/plugins/lists/server/routes/patch_list_route.ts +++ b/x-pack/plugins/lists/server/routes/patch_list_route.ts @@ -27,9 +27,9 @@ export const patchListRoute = (router: IRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const { name, description, id, meta, _version } = request.body; + const { name, description, id, meta, _version, version } = request.body; const lists = getListClient(context); - const list = await lists.updateList({ _version, description, id, meta, name }); + const list = await lists.updateList({ _version, description, id, meta, name, version }); if (list == null) { return siemResponse.error({ body: `list id: "${id}" found found`, diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts index 403a9f6db934f..6fcee81ed573f 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_route.ts @@ -45,6 +45,7 @@ export const updateExceptionListRoute = (router: IRouter): void => { meta, namespace_type: namespaceType, type, + version, } = request.body; const exceptionLists = getExceptionListClient(context); if (id == null && listId == null) { @@ -64,6 +65,7 @@ export const updateExceptionListRoute = (router: IRouter): void => { namespaceType, tags, type, + version, }); if (list == null) { return siemResponse.error({ diff --git a/x-pack/plugins/lists/server/routes/update_list_route.ts b/x-pack/plugins/lists/server/routes/update_list_route.ts index 78aed23db13fc..6206c0943a8f3 100644 --- a/x-pack/plugins/lists/server/routes/update_list_route.ts +++ b/x-pack/plugins/lists/server/routes/update_list_route.ts @@ -27,9 +27,9 @@ export const updateListRoute = (router: IRouter): void => { async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const { name, description, id, meta, _version } = request.body; + const { name, description, id, meta, _version, version } = request.body; const lists = getListClient(context); - const list = await lists.updateList({ _version, description, id, meta, name }); + const list = await lists.updateList({ _version, description, id, meta, name, version }); if (list == null) { return siemResponse.error({ body: `list id: "${id}" found found`, diff --git a/x-pack/plugins/lists/server/saved_objects/exception_list.ts b/x-pack/plugins/lists/server/saved_objects/exception_list.ts index fc04c5e278d64..3bde3545837cf 100644 --- a/x-pack/plugins/lists/server/saved_objects/exception_list.ts +++ b/x-pack/plugins/lists/server/saved_objects/exception_list.ts @@ -30,6 +30,9 @@ export const commonMapping: SavedObjectsType['mappings'] = { description: { type: 'keyword', }, + immutable: { + type: 'boolean', + }, list_id: { type: 'keyword', }, @@ -54,6 +57,9 @@ export const commonMapping: SavedObjectsType['mappings'] = { updated_by: { type: 'keyword', }, + version: { + type: 'keyword', + }, }, }; diff --git a/x-pack/plugins/lists/server/services/exception_lists/create_endpoint_list.ts b/x-pack/plugins/lists/server/services/exception_lists/create_endpoint_list.ts index b9a0194e20074..b596b831f2d68 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/create_endpoint_list.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/create_endpoint_list.ts @@ -12,7 +12,7 @@ import { ENDPOINT_LIST_ID, ENDPOINT_LIST_NAME, } from '../../../common/constants'; -import { ExceptionListSchema, ExceptionListSoSchema } from '../../../common/schemas'; +import { ExceptionListSchema, ExceptionListSoSchema, Version } from '../../../common/schemas'; import { getSavedObjectType, transformSavedObjectToExceptionList } from './utils'; @@ -20,12 +20,14 @@ interface CreateEndpointListOptions { savedObjectsClient: SavedObjectsClientContract; user: string; tieBreaker?: string; + version: Version; } export const createEndpointList = async ({ savedObjectsClient, user, tieBreaker, + version, }: CreateEndpointListOptions): Promise => { const savedObjectType = getSavedObjectType({ namespaceType: 'agnostic' }); const dateNow = new Date().toISOString(); @@ -39,6 +41,7 @@ export const createEndpointList = async ({ created_by: user, description: ENDPOINT_LIST_DESCRIPTION, entries: undefined, + immutable: false, item_id: undefined, list_id: ENDPOINT_LIST_ID, list_type: 'list', @@ -48,6 +51,7 @@ export const createEndpointList = async ({ tie_breaker_id: tieBreaker ?? uuid.v4(), type: 'endpoint', updated_by: user, + version, }, { // We intentionally hard coding the id so that there can only be one exception list within the space diff --git a/x-pack/plugins/lists/server/services/exception_lists/create_exception_list.ts b/x-pack/plugins/lists/server/services/exception_lists/create_exception_list.ts index 4da74c7df48bf..c8d709ca340ad 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/create_exception_list.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/create_exception_list.ts @@ -12,11 +12,13 @@ import { ExceptionListSchema, ExceptionListSoSchema, ExceptionListType, + Immutable, ListId, MetaOrUndefined, Name, NamespaceType, Tags, + Version, _Tags, } from '../../../common/schemas'; @@ -29,16 +31,19 @@ interface CreateExceptionListOptions { namespaceType: NamespaceType; name: Name; description: Description; + immutable: Immutable; meta: MetaOrUndefined; user: string; tags: Tags; tieBreaker?: string; type: ExceptionListType; + version: Version; } export const createExceptionList = async ({ _tags, listId, + immutable, savedObjectsClient, namespaceType, name, @@ -48,6 +53,7 @@ export const createExceptionList = async ({ tags, tieBreaker, type, + version, }: CreateExceptionListOptions): Promise => { const savedObjectType = getSavedObjectType({ namespaceType }); const dateNow = new Date().toISOString(); @@ -58,6 +64,7 @@ export const createExceptionList = async ({ created_by: user, description, entries: undefined, + immutable, item_id: undefined, list_id: listId, list_type: 'list', @@ -67,6 +74,7 @@ export const createExceptionList = async ({ tie_breaker_id: tieBreaker ?? uuid.v4(), type, updated_by: user, + version, }); return transformSavedObjectToExceptionList({ savedObject }); }; diff --git a/x-pack/plugins/lists/server/services/exception_lists/create_exception_list_item.ts b/x-pack/plugins/lists/server/services/exception_lists/create_exception_list_item.ts index 1acc880c851a6..a90ec61aef4af 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/create_exception_list_item.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/create_exception_list_item.ts @@ -72,6 +72,7 @@ export const createExceptionListItem = async ({ created_by: user, description, entries, + immutable: undefined, item_id: itemId, list_id: listId, list_type: 'item', @@ -81,6 +82,7 @@ export const createExceptionListItem = async ({ tie_breaker_id: tieBreaker ?? uuid.v4(), type, updated_by: user, + version: undefined, }); return transformSavedObjectToExceptionListItem({ savedObject }); }; diff --git a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts index 08b1f517036a9..11302e64b3538 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts @@ -85,6 +85,7 @@ export class ExceptionListClient { return createEndpointList({ savedObjectsClient, user, + version: 1, }); }; @@ -176,17 +177,20 @@ export class ExceptionListClient { public createExceptionList = async ({ _tags, description, + immutable, listId, meta, name, namespaceType, tags, type, + version, }: CreateExceptionListOptions): Promise => { const { savedObjectsClient, user } = this; return createExceptionList({ _tags, description, + immutable, listId, meta, name, @@ -195,6 +199,7 @@ export class ExceptionListClient { tags, type, user, + version, }); }; @@ -209,6 +214,7 @@ export class ExceptionListClient { namespaceType, tags, type, + version, }: UpdateExceptionListOptions): Promise => { const { savedObjectsClient, user } = this; return updateExceptionList({ @@ -224,6 +230,7 @@ export class ExceptionListClient { tags, type, user, + version, }); }; diff --git a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts index b972b6564bb8a..51e3a7ee8046f 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts @@ -21,6 +21,7 @@ import { ExceptionListTypeOrUndefined, FilterOrUndefined, IdOrUndefined, + Immutable, ItemId, ItemIdOrUndefined, ListId, @@ -36,6 +37,8 @@ import { Tags, TagsOrUndefined, UpdateCommentsArray, + Version, + VersionOrUndefined, _Tags, _TagsOrUndefined, _VersionOrUndefined, @@ -61,6 +64,8 @@ export interface CreateExceptionListOptions { meta: MetaOrUndefined; tags: Tags; type: ExceptionListType; + immutable: Immutable; + version: Version; } export interface UpdateExceptionListOptions { @@ -74,6 +79,7 @@ export interface UpdateExceptionListOptions { meta: MetaOrUndefined; tags: TagsOrUndefined; type: ExceptionListTypeOrUndefined; + version: VersionOrUndefined; } export interface DeleteExceptionListOptions { diff --git a/x-pack/plugins/lists/server/services/exception_lists/update_exception_list.ts b/x-pack/plugins/lists/server/services/exception_lists/update_exception_list.ts index 99c42e56f4888..c26ff1bca4484 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/update_exception_list.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/update_exception_list.ts @@ -17,6 +17,7 @@ import { NameOrUndefined, NamespaceType, TagsOrUndefined, + VersionOrUndefined, _TagsOrUndefined, _VersionOrUndefined, } from '../../../common/schemas'; @@ -38,6 +39,7 @@ interface UpdateExceptionListOptions { tags: TagsOrUndefined; tieBreaker?: string; type: ExceptionListTypeOrUndefined; + version: VersionOrUndefined; } export const updateExceptionList = async ({ @@ -53,12 +55,14 @@ export const updateExceptionList = async ({ user, tags, type, + version, }: UpdateExceptionListOptions): Promise => { const savedObjectType = getSavedObjectType({ namespaceType }); const exceptionList = await getExceptionList({ id, listId, namespaceType, savedObjectsClient }); if (exceptionList == null) { return null; } else { + const calculatedVersion = version == null ? exceptionList.version + 1 : version; const savedObject = await savedObjectsClient.update( savedObjectType, exceptionList.id, @@ -70,6 +74,7 @@ export const updateExceptionList = async ({ tags, type, updated_by: user, + version: calculatedVersion, }, { version: _version, diff --git a/x-pack/plugins/lists/server/services/exception_lists/utils.ts b/x-pack/plugins/lists/server/services/exception_lists/utils.ts index d5e1965efcc89..b168fae741822 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/utils.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/utils.ts @@ -78,6 +78,7 @@ export const transformSavedObjectToExceptionList = ({ created_at, created_by, description, + immutable, list_id, meta, name, @@ -85,6 +86,7 @@ export const transformSavedObjectToExceptionList = ({ tie_breaker_id, type, updated_by, + version, }, id, updated_at: updatedAt, @@ -99,6 +101,7 @@ export const transformSavedObjectToExceptionList = ({ created_by, description, id, + immutable: immutable ?? false, // This should never be undefined for a list (only a list item) list_id, meta, name, @@ -108,6 +111,7 @@ export const transformSavedObjectToExceptionList = ({ type: exceptionListType.is(type) ? type : 'detection', updated_at: updatedAt ?? dateNow, updated_by, + version: version ?? 1, // This should never be undefined for a list (only a list item) }; }; @@ -121,7 +125,17 @@ export const transformSavedObjectUpdateToExceptionList = ({ const dateNow = new Date().toISOString(); const { version: _version, - attributes: { _tags, description, meta, name, tags, type, updated_by: updatedBy }, + attributes: { + _tags, + description, + immutable, + meta, + name, + tags, + type, + updated_by: updatedBy, + version, + }, id, updated_at: updatedAt, } = savedObject; @@ -135,6 +149,7 @@ export const transformSavedObjectUpdateToExceptionList = ({ created_by: exceptionList.created_by, description: description ?? exceptionList.description, id, + immutable: immutable ?? exceptionList.immutable, list_id: exceptionList.list_id, meta: meta ?? exceptionList.meta, name: name ?? exceptionList.name, @@ -144,6 +159,7 @@ export const transformSavedObjectUpdateToExceptionList = ({ type: exceptionListType.is(type) ? type : exceptionList.type, updated_at: updatedAt ?? dateNow, updated_by: updatedBy ?? exceptionList.updated_by, + version: version ?? exceptionList.version, }; }; diff --git a/x-pack/plugins/lists/server/services/items/write_lines_to_bulk_list_items.mock.ts b/x-pack/plugins/lists/server/services/items/write_lines_to_bulk_list_items.mock.ts index d868351fc4b33..758fabf3d97df 100644 --- a/x-pack/plugins/lists/server/services/items/write_lines_to_bulk_list_items.mock.ts +++ b/x-pack/plugins/lists/server/services/items/write_lines_to_bulk_list_items.mock.ts @@ -12,6 +12,7 @@ import { META, TYPE, USER, + VERSION, } from '../../../common/constants.mock'; import { getConfigMockDecoded } from '../../config.mock'; @@ -29,6 +30,7 @@ export const getImportListItemsToStreamOptionsMock = (): ImportListItemsToStream stream: new TestReadable(), type: TYPE, user: USER, + version: VERSION, }); export const getWriteBufferToItemsOptionsMock = (): WriteBufferToItemsOptions => ({ diff --git a/x-pack/plugins/lists/server/services/items/write_lines_to_bulk_list_items.ts b/x-pack/plugins/lists/server/services/items/write_lines_to_bulk_list_items.ts index 2bffe338e9075..c026b247a90a1 100644 --- a/x-pack/plugins/lists/server/services/items/write_lines_to_bulk_list_items.ts +++ b/x-pack/plugins/lists/server/services/items/write_lines_to_bulk_list_items.ts @@ -16,6 +16,7 @@ import { MetaOrUndefined, SerializerOrUndefined, Type, + Version, } from '../../../common/schemas'; import { ConfigType } from '../../config'; @@ -34,6 +35,7 @@ export interface ImportListItemsToStreamOptions { type: Type; user: string; meta: MetaOrUndefined; + version: Version; } export const importListItemsToStream = ({ @@ -48,6 +50,7 @@ export const importListItemsToStream = ({ type, user, meta, + version, }: ImportListItemsToStreamOptions): Promise => { return new Promise((resolve) => { const readBuffer = new BufferLines({ bufferSize: config.importBufferSize, input: stream }); @@ -62,12 +65,14 @@ export const importListItemsToStream = ({ description: `File uploaded from file system of ${fileNameEmitted}`, deserializer, id: fileNameEmitted, + immutable: false, listIndex, meta, name: fileNameEmitted, serializer, type, user, + version, }); } readBuffer.resume(); diff --git a/x-pack/plugins/lists/server/services/lists/create_list.mock.ts b/x-pack/plugins/lists/server/services/lists/create_list.mock.ts index 84273ff4cf814..befbe095f2d19 100644 --- a/x-pack/plugins/lists/server/services/lists/create_list.mock.ts +++ b/x-pack/plugins/lists/server/services/lists/create_list.mock.ts @@ -9,6 +9,7 @@ import { CreateListOptions } from '../lists'; import { DATE_NOW, DESCRIPTION, + IMMUTABLE, LIST_ID, LIST_INDEX, META, @@ -16,6 +17,7 @@ import { TIE_BREAKER, TYPE, USER, + VERSION, } from '../../../common/constants.mock'; export const getCreateListOptionsMock = (): CreateListOptions => ({ @@ -24,6 +26,7 @@ export const getCreateListOptionsMock = (): CreateListOptions => ({ description: DESCRIPTION, deserializer: undefined, id: LIST_ID, + immutable: IMMUTABLE, listIndex: LIST_INDEX, meta: META, name: NAME, @@ -31,4 +34,5 @@ export const getCreateListOptionsMock = (): CreateListOptions => ({ tieBreaker: TIE_BREAKER, type: TYPE, user: USER, + version: VERSION, }); diff --git a/x-pack/plugins/lists/server/services/lists/create_list.ts b/x-pack/plugins/lists/server/services/lists/create_list.ts index f97399e6dc131..85214ffb27842 100644 --- a/x-pack/plugins/lists/server/services/lists/create_list.ts +++ b/x-pack/plugins/lists/server/services/lists/create_list.ts @@ -13,12 +13,14 @@ import { Description, DeserializerOrUndefined, IdOrUndefined, + Immutable, IndexEsListSchema, ListSchema, MetaOrUndefined, Name, SerializerOrUndefined, Type, + Version, } from '../../../common/schemas'; export interface CreateListOptions { @@ -34,6 +36,8 @@ export interface CreateListOptions { meta: MetaOrUndefined; dateNow?: string; tieBreaker?: string; + immutable: Immutable; + version: Version; } export const createList = async ({ @@ -49,6 +53,8 @@ export const createList = async ({ meta, dateNow, tieBreaker, + immutable, + version, }: CreateListOptions): Promise => { const createdAt = dateNow ?? new Date().toISOString(); const body: IndexEsListSchema = { @@ -56,6 +62,7 @@ export const createList = async ({ created_by: user, description, deserializer, + immutable, meta, name, serializer, @@ -63,6 +70,7 @@ export const createList = async ({ type, updated_at: createdAt, updated_by: user, + version, }; const response = await callCluster('index', { body, diff --git a/x-pack/plugins/lists/server/services/lists/create_list_if_it_does_not_exist.ts b/x-pack/plugins/lists/server/services/lists/create_list_if_it_does_not_exist.ts index 84f5ac0308191..03a59940641c6 100644 --- a/x-pack/plugins/lists/server/services/lists/create_list_if_it_does_not_exist.ts +++ b/x-pack/plugins/lists/server/services/lists/create_list_if_it_does_not_exist.ts @@ -10,11 +10,13 @@ import { Description, DeserializerOrUndefined, Id, + Immutable, ListSchema, MetaOrUndefined, Name, SerializerOrUndefined, Type, + Version, } from '../../../common/schemas'; import { getList } from './get_list'; @@ -27,12 +29,14 @@ export interface CreateListIfItDoesNotExistOptions { deserializer: DeserializerOrUndefined; serializer: SerializerOrUndefined; description: Description; + immutable: Immutable; callCluster: LegacyAPICaller; listIndex: string; user: string; meta: MetaOrUndefined; dateNow?: string; tieBreaker?: string; + version: Version; } export const createListIfItDoesNotExist = async ({ @@ -48,6 +52,8 @@ export const createListIfItDoesNotExist = async ({ serializer, dateNow, tieBreaker, + version, + immutable, }: CreateListIfItDoesNotExistOptions): Promise => { const list = await getList({ callCluster, id, listIndex }); if (list == null) { @@ -57,6 +63,7 @@ export const createListIfItDoesNotExist = async ({ description, deserializer, id, + immutable, listIndex, meta, name, @@ -64,6 +71,7 @@ export const createListIfItDoesNotExist = async ({ tieBreaker, type, user, + version, }); } else { return list; diff --git a/x-pack/plugins/lists/server/services/lists/list_client.ts b/x-pack/plugins/lists/server/services/lists/list_client.ts index 9bece64fa943f..590bfef6625f5 100644 --- a/x-pack/plugins/lists/server/services/lists/list_client.ts +++ b/x-pack/plugins/lists/server/services/lists/list_client.ts @@ -110,11 +110,13 @@ export class ListClient { public createList = async ({ id, deserializer, + immutable, serializer, name, description, type, meta, + version, }: CreateListOptions): Promise => { const { callCluster, user } = this; const listIndex = this.getListIndex(); @@ -123,12 +125,14 @@ export class ListClient { description, deserializer, id, + immutable, listIndex, meta, name, serializer, type, user, + version, }); }; @@ -138,8 +142,10 @@ export class ListClient { serializer, name, description, + immutable, type, meta, + version, }: CreateListIfItDoesNotExistOptions): Promise => { const { callCluster, user } = this; const listIndex = this.getListIndex(); @@ -148,12 +154,14 @@ export class ListClient { description, deserializer, id, + immutable, listIndex, meta, name, serializer, type, user, + version, }); }; @@ -334,6 +342,7 @@ export class ListClient { listId, stream, meta, + version, }: ImportListItemsToStreamOptions): Promise => { const { callCluster, user, config } = this; const listItemIndex = this.getListItemIndex(); @@ -350,6 +359,7 @@ export class ListClient { stream, type, user, + version, }); }; @@ -419,6 +429,7 @@ export class ListClient { name, description, meta, + version, }: UpdateListOptions): Promise => { const { callCluster, user } = this; const listIndex = this.getListIndex(); @@ -431,6 +442,7 @@ export class ListClient { meta, name, user, + version, }); }; diff --git a/x-pack/plugins/lists/server/services/lists/list_client_types.ts b/x-pack/plugins/lists/server/services/lists/list_client_types.ts index 7fa1727be118b..ea983b38c7e5d 100644 --- a/x-pack/plugins/lists/server/services/lists/list_client_types.ts +++ b/x-pack/plugins/lists/server/services/lists/list_client_types.ts @@ -15,6 +15,7 @@ import { Filter, Id, IdOrUndefined, + Immutable, ListId, ListIdOrUndefined, MetaOrUndefined, @@ -26,6 +27,8 @@ import { SortFieldOrUndefined, SortOrderOrUndefined, Type, + Version, + VersionOrUndefined, _VersionOrUndefined, } from '../../../common/schemas'; import { ConfigType } from '../../config'; @@ -52,11 +55,13 @@ export interface DeleteListItemOptions { export interface CreateListOptions { id: IdOrUndefined; deserializer: DeserializerOrUndefined; + immutable: Immutable; serializer: SerializerOrUndefined; name: Name; description: Description; type: Type; meta: MetaOrUndefined; + version: Version; } export interface CreateListIfItDoesNotExistOptions { @@ -67,6 +72,8 @@ export interface CreateListIfItDoesNotExistOptions { description: Description; type: Type; meta: MetaOrUndefined; + version: Version; + immutable: Immutable; } export interface DeleteListItemByValueOptions { @@ -94,6 +101,7 @@ export interface ImportListItemsToStreamOptions { type: Type; stream: Readable; meta: MetaOrUndefined; + version: Version; } export interface CreateListItemOptions { @@ -119,6 +127,7 @@ export interface UpdateListOptions { name: NameOrUndefined; description: DescriptionOrUndefined; meta: MetaOrUndefined; + version: VersionOrUndefined; } export interface GetListItemOptions { diff --git a/x-pack/plugins/lists/server/services/lists/list_mappings.json b/x-pack/plugins/lists/server/services/lists/list_mappings.json index da9cfec18719a..d00b00b6469a3 100644 --- a/x-pack/plugins/lists/server/services/lists/list_mappings.json +++ b/x-pack/plugins/lists/server/services/lists/list_mappings.json @@ -34,6 +34,12 @@ }, "updated_by": { "type": "keyword" + }, + "version": { + "type": "keyword" + }, + "immutable": { + "type": "boolean" } } } diff --git a/x-pack/plugins/lists/server/services/lists/update_list.mock.ts b/x-pack/plugins/lists/server/services/lists/update_list.mock.ts index fc3d63277c5b5..dd33c85aca98f 100644 --- a/x-pack/plugins/lists/server/services/lists/update_list.mock.ts +++ b/x-pack/plugins/lists/server/services/lists/update_list.mock.ts @@ -13,6 +13,7 @@ import { META, NAME, USER, + VERSION, } from '../../../common/constants.mock'; export const getUpdateListOptionsMock = (): UpdateListOptions => ({ @@ -25,4 +26,5 @@ export const getUpdateListOptionsMock = (): UpdateListOptions => ({ meta: META, name: NAME, user: USER, + version: VERSION, }); diff --git a/x-pack/plugins/lists/server/services/lists/update_list.ts b/x-pack/plugins/lists/server/services/lists/update_list.ts index fba57ca744f9d..67d44be2ae1a7 100644 --- a/x-pack/plugins/lists/server/services/lists/update_list.ts +++ b/x-pack/plugins/lists/server/services/lists/update_list.ts @@ -16,6 +16,7 @@ import { MetaOrUndefined, NameOrUndefined, UpdateEsListSchema, + VersionOrUndefined, _VersionOrUndefined, } from '../../../common/schemas'; @@ -31,6 +32,7 @@ export interface UpdateListOptions { description: DescriptionOrUndefined; meta: MetaOrUndefined; dateNow?: string; + version: VersionOrUndefined; } export const updateList = async ({ @@ -43,12 +45,14 @@ export const updateList = async ({ user, meta, dateNow, + version, }: UpdateListOptions): Promise => { const updatedAt = dateNow ?? new Date().toISOString(); const list = await getList({ callCluster, id, listIndex }); if (list == null) { return null; } else { + const calculatedVersion = version == null ? list.version + 1 : version; const doc: UpdateEsListSchema = { description, meta, @@ -70,6 +74,7 @@ export const updateList = async ({ description: description ?? list.description, deserializer: list.deserializer, id: response._id, + immutable: list.immutable, meta, name: name ?? list.name, serializer: list.serializer, @@ -77,6 +82,7 @@ export const updateList = async ({ type: list.type, updated_at: updatedAt, updated_by: user, + version: calculatedVersion, }; } }; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts index bbba7c5b8f3bb..a2f5ca3da1b70 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts @@ -19,3 +19,5 @@ export const DefaultVersionNumber = new t.Type; diff --git a/x-pack/plugins/security_solution/common/shared_exports.ts b/x-pack/plugins/security_solution/common/shared_exports.ts index 1b5b17ef35cae..bd1086a3f21e9 100644 --- a/x-pack/plugins/security_solution/common/shared_exports.ts +++ b/x-pack/plugins/security_solution/common/shared_exports.ts @@ -7,6 +7,10 @@ export { NonEmptyString } from './detection_engine/schemas/types/non_empty_string'; export { DefaultUuid } from './detection_engine/schemas/types/default_uuid'; export { DefaultStringArray } from './detection_engine/schemas/types/default_string_array'; +export { + DefaultVersionNumber, + DefaultVersionNumberDecoded, +} from './detection_engine/schemas/types/default_version_number'; export { exactCheck } from './exact_check'; export { getPaths, foldLeftRight } from './test_utils'; export { validate, validateEither } from './validate'; diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx index 1ff5d770521f3..90e195b6e95a0 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.test.tsx @@ -15,7 +15,7 @@ import { getField } from '../../../../../../../src/plugins/data/common/index_pat import { ListSchema } from '../../../lists_plugin_deps'; import { getFoundListSchemaMock } from '../../../../../lists/common/schemas/response/found_list_schema.mock'; import { getListResponseMock } from '../../../../../lists/common/schemas/response/list_schema.mock'; -import { DATE_NOW } from '../../../../../lists/common/constants.mock'; +import { DATE_NOW, VERSION, IMMUTABLE } from '../../../../../lists/common/constants.mock'; import { AutocompleteFieldListsComponent } from './field_value_lists'; @@ -221,6 +221,8 @@ describe('AutocompleteFieldListsComponent', () => { type: 'ip', updated_at: DATE_NOW, updated_by: 'some user', + version: VERSION, + immutable: IMMUTABLE, }); }); }); From 073bd66a8612f3f453aedbe0b8e0f29afb9766bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= Date: Wed, 22 Jul 2020 02:18:28 +0200 Subject: [PATCH 73/77] [Detections] Add validation for Threshold value field (#72611) --- .../rules/step_define_rule/schema.tsx | 14 ++++++++ .../bulk_create_threshold_signals.test.ts | 35 +++++++++++++++++++ .../signals/bulk_create_threshold_signals.ts | 2 +- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx index 67d795ccf90f0..333b28bf27bbf 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx @@ -202,6 +202,20 @@ export const schema: FormSchema = { defaultMessage: 'Threshold', } ), + validations: [ + { + validator: fieldValidators.numberGreaterThanField({ + than: 1, + message: i18n.translate( + 'xpack.securitySolution.detectionEngine.validations.thresholdValueFieldData.numberGreaterThanOrEqualOneErrorMessage', + { + defaultMessage: 'Value must be greater than or equal one.', + } + ), + allowEquality: true, + }), + }, + ], }, }, }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.test.ts index 744e2b0c06efe..d97dc4ba2cbd2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.test.ts @@ -193,4 +193,39 @@ describe('getThresholdSignalQueryFields', () => { 'event.dataset': 'traefik.access', }); }); + + it('should return proper object for exists filters', () => { + const filters = { + bool: { + should: [ + { + bool: { + should: [ + { + exists: { + field: 'process.name', + }, + }, + ], + minimum_should_match: 1, + }, + }, + { + bool: { + should: [ + { + exists: { + field: 'event.type', + }, + }, + ], + minimum_should_match: 1, + }, + }, + ], + minimum_should_match: 1, + }, + }; + expect(getThresholdSignalQueryFields(filters)).toEqual({}); + }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.ts index ef9fbe485b92f..e2f3d16bd6d03 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_threshold_signals.ts @@ -83,7 +83,7 @@ export const getThresholdSignalQueryFields = (filter: unknown) => { return { ...acc, ...item.match_phrase }; } - if (item.bool.should && (item.bool.should[0].match || item.bool.should[0].match_phrase)) { + if (item.bool?.should && (item.bool.should[0].match || item.bool.should[0].match_phrase)) { return { ...acc, ...(item.bool.should[0].match || item.bool.should[0].match_phrase) }; } From 9c7d65cfc2ad88282a52654265c7d64e0442929f Mon Sep 17 00:00:00 2001 From: Yara Tercero Date: Tue, 21 Jul 2020 21:00:46 -0400 Subject: [PATCH 74/77] [Security Solution][Exceptions] - Require non empty entries and non empty string values in exception list items (#72748) ## Summary This PR updates the exception list entries schemas. - **Prior:** `entries` could be `undefined` or empty array on `ExceptionListItemSchema` - **Now:** `entries` is a required field that cannot be empty - there's really no use for an item without `entries` - **Prior:** `field` and `value` could be empty string in `EntryMatch` - **Now:** `field` and `value` can no longer be empty strings - **Prior:** `field` could be empty string and `value` could be empty array in `EntryMatchAny` - **Now:** `field` and `value` can no longer be empty string and array respectively - **Prior:** `field` and `list.id` could be empty string in `EntryList` - **Now:** `field` and `list.id` can no longer be empty strings - **Prior:** `field` could be empty string in `EntryExists` - **Now:** `field` can no longer be empty string - **Prior:** `field` could be empty string in `EntryNested` - **Now:** `field` can no longer be empty string - **Prior:** `entries` could be empty array in `EntryNested` - **Now:** `entries` can no longer be empty array --- .../create_endpoint_list_item_schema.test.ts | 8 +- .../create_endpoint_list_item_schema.ts | 4 +- .../create_exception_list_item_schema.test.ts | 8 +- .../create_exception_list_item_schema.ts | 4 +- .../update_endpoint_list_item_schema.test.ts | 8 +- .../update_endpoint_list_item_schema.ts | 4 +- .../update_exception_list_item_schema.test.ts | 8 +- .../update_exception_list_item_schema.ts | 4 +- .../types/default_entries_array.test.ts | 99 ------ .../schemas/types/default_entries_array.ts | 22 -- .../common/schemas/types/entries.mock.ts | 70 +--- .../common/schemas/types/entries.test.ts | 334 ++++-------------- .../lists/common/schemas/types/entries.ts | 57 +-- .../common/schemas/types/entry_exists.mock.ts | 15 + .../common/schemas/types/entry_exists.test.ts | 79 +++++ .../common/schemas/types/entry_exists.ts | 21 ++ .../common/schemas/types/entry_list.mock.ts | 16 + .../common/schemas/types/entry_list.test.ts | 95 +++++ .../lists/common/schemas/types/entry_list.ts | 22 ++ .../common/schemas/types/entry_match.mock.ts | 16 + .../common/schemas/types/entry_match.test.ts | 107 ++++++ .../lists/common/schemas/types/entry_match.ts | 22 ++ .../schemas/types/entry_match_any.mock.ts | 16 + .../schemas/types/entry_match_any.test.ts | 105 ++++++ .../common/schemas/types/entry_match_any.ts | 24 ++ .../common/schemas/types/entry_nested.mock.ts | 17 + .../common/schemas/types/entry_nested.test.ts | 124 +++++++ .../common/schemas/types/entry_nested.ts | 22 ++ .../lists/common/schemas/types/index.ts | 9 +- .../types/non_empty_entries_array.test.ts | 123 +++++++ .../schemas/types/non_empty_entries_array.ts | 31 ++ .../non_empty_nested_entries_array.test.ts | 131 +++++++ .../types/non_empty_nested_entries_array.ts | 40 +++ ...non_empty_or_nullable_string_array.test.ts | 69 ++++ .../non_empty_or_nullable_string_array.ts | 34 ++ .../new/exception_list_item.json | 2 +- .../exception_list_client_types.ts | 5 +- .../update_exception_list_item.ts | 4 +- .../build_exceptions_query.test.ts | 95 ++++- .../build_exceptions_query.ts | 2 +- .../common/components/autocomplete/field.tsx | 7 +- .../autocomplete/field_value_lists.tsx | 5 + .../autocomplete/field_value_match.tsx | 8 +- .../autocomplete/field_value_match_any.tsx | 8 +- .../components/autocomplete/helpers.test.ts | 8 +- .../common/components/autocomplete/helpers.ts | 2 +- .../builder/builder_exception_item.test.tsx | 6 +- .../exceptions/builder/entry_item.tsx | 4 + .../components/exceptions/helpers.test.tsx | 107 +++++- .../common/components/exceptions/helpers.tsx | 16 +- .../endpoint/lib/artifacts/lists.test.ts | 2 +- .../server/endpoint/lib/artifacts/lists.ts | 2 +- 52 files changed, 1481 insertions(+), 570 deletions(-) delete mode 100644 x-pack/plugins/lists/common/schemas/types/default_entries_array.test.ts delete mode 100644 x-pack/plugins/lists/common/schemas/types/default_entries_array.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_exists.mock.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_exists.test.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_exists.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_list.mock.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_list.test.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_list.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_match.mock.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_match.test.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_match.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_match_any.mock.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_match_any.test.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_match_any.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_nested.mock.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_nested.test.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/entry_nested.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.test.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/non_empty_or_nullable_string_array.test.ts create mode 100644 x-pack/plugins/lists/common/schemas/types/non_empty_or_nullable_string_array.ts diff --git a/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.test.ts index 916e8db483454..5de9fbb0d5b50 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.test.ts @@ -142,7 +142,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should validate an undefined for "entries" but return an array', () => { + test('it should NOT validate an undefined for "entries"', () => { const inputPayload = getCreateEndpointListItemSchemaMock(); const outputPayload = getCreateEndpointListItemSchemaMock(); delete inputPayload.entries; @@ -151,8 +151,10 @@ describe('create_endpoint_list_item_schema', () => { const checked = exactCheck(inputPayload, decoded); const message = pipe(checked, foldLeftRight); delete (message.schema as CreateEndpointListItemSchema).item_id; - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(outputPayload); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "entries"', + ]); + expect(message.schema).toEqual({}); }); test('it should validate an undefined for "tags" but return an array and generate a correct body not counting the auto generated uuid', () => { diff --git a/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts index 3f0e1a12894d4..ab30e8e35548d 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.ts @@ -20,7 +20,7 @@ import { tags, } from '../common/schemas'; import { RequiredKeepUndefined } from '../../types'; -import { CreateCommentsArray, DefaultCreateCommentsArray, DefaultEntryArray } from '../types'; +import { CreateCommentsArray, DefaultCreateCommentsArray, nonEmptyEntriesArray } from '../types'; import { EntriesArray } from '../types/entries'; import { DefaultUuid } from '../../siem_common_deps'; @@ -28,6 +28,7 @@ export const createEndpointListItemSchema = t.intersection([ t.exact( t.type({ description, + entries: nonEmptyEntriesArray, name, type: exceptionListItemType, }) @@ -36,7 +37,6 @@ export const createEndpointListItemSchema = t.intersection([ t.partial({ _tags, // defaults to empty array if not set during decode comments: DefaultCreateCommentsArray, // defaults to empty array if not set during decode - entries: DefaultEntryArray, // defaults to empty array if not set during decode item_id: DefaultUuid, // defaults to GUID (uuid v4) if not set during decode meta, // defaults to undefined if not set during decode tags, // defaults to empty array if not set during decode diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.test.ts index 34551b74d8c9f..08f3966af08d9 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.test.ts @@ -130,7 +130,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should validate an undefined for "entries" but return an array', () => { + test('it should NOT validate an undefined for "entries"', () => { const inputPayload = getCreateExceptionListItemSchemaMock(); const outputPayload = getCreateExceptionListItemSchemaMock(); delete inputPayload.entries; @@ -139,8 +139,10 @@ describe('create_exception_list_item_schema', () => { const checked = exactCheck(inputPayload, decoded); const message = pipe(checked, foldLeftRight); delete (message.schema as CreateExceptionListItemSchema).item_id; - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(outputPayload); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "entries"', + ]); + expect(message.schema).toEqual({}); }); test('it should validate an undefined for "namespace_type" but return enum "single" and generate a correct body not counting the auto generated uuid', () => { diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts index c2ccf18ed8720..c3f41cac90c64 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts @@ -25,8 +25,8 @@ import { RequiredKeepUndefined } from '../../types'; import { CreateCommentsArray, DefaultCreateCommentsArray, - DefaultEntryArray, NamespaceType, + nonEmptyEntriesArray, } from '../types'; import { EntriesArray } from '../types/entries'; import { DefaultUuid } from '../../siem_common_deps'; @@ -35,6 +35,7 @@ export const createExceptionListItemSchema = t.intersection([ t.exact( t.type({ description, + entries: nonEmptyEntriesArray, list_id, name, type: exceptionListItemType, @@ -44,7 +45,6 @@ export const createExceptionListItemSchema = t.intersection([ t.partial({ _tags, // defaults to empty array if not set during decode comments: DefaultCreateCommentsArray, // defaults to empty array if not set during decode - entries: DefaultEntryArray, // defaults to empty array if not set during decode item_id: DefaultUuid, // defaults to GUID (uuid v4) if not set during decode meta, // defaults to undefined if not set during decode namespace_type, // defaults to 'single' if not set during decode diff --git a/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.test.ts index 838cb81d84c1d..db5bc45ad028b 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.test.ts @@ -97,7 +97,7 @@ describe('update_endpoint_list_item_schema', () => { expect(message.schema).toEqual(outputPayload); }); - test('it should accept an undefined for "entries" but return an array', () => { + test('it should NOT accept an undefined for "entries"', () => { const inputPayload = getUpdateEndpointListItemSchemaMock(); const outputPayload = getUpdateEndpointListItemSchemaMock(); delete inputPayload.entries; @@ -105,8 +105,10 @@ describe('update_endpoint_list_item_schema', () => { const decoded = updateEndpointListItemSchema.decode(inputPayload); const checked = exactCheck(inputPayload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(outputPayload); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "entries"', + ]); + expect(message.schema).toEqual({}); }); test('it should accept an undefined for "tags" but return an array', () => { diff --git a/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts index 4430aa98b8e3d..5bf0cb3b7984e 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_endpoint_list_item_schema.ts @@ -22,16 +22,17 @@ import { } from '../common/schemas'; import { RequiredKeepUndefined } from '../../types'; import { - DefaultEntryArray, DefaultUpdateCommentsArray, EntriesArray, UpdateCommentsArray, + nonEmptyEntriesArray, } from '../types'; export const updateEndpointListItemSchema = t.intersection([ t.exact( t.type({ description, + entries: nonEmptyEntriesArray, name, type: exceptionListItemType, }) @@ -41,7 +42,6 @@ export const updateEndpointListItemSchema = t.intersection([ _tags, // defaults to empty array if not set during decode _version, // defaults to undefined if not set during decode comments: DefaultUpdateCommentsArray, // defaults to empty array if not set during decode - entries: DefaultEntryArray, // defaults to empty array if not set during decode id, // defaults to undefined if not set during decode item_id: t.union([t.string, t.undefined]), meta, // defaults to undefined if not set during decode diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.test.ts index 2592e44888ff6..ce589fb097a60 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.test.ts @@ -97,7 +97,7 @@ describe('update_exception_list_item_schema', () => { expect(message.schema).toEqual(outputPayload); }); - test('it should accept an undefined for "entries" but return an array', () => { + test('it should NOT accept an undefined for "entries"', () => { const inputPayload = getUpdateExceptionListItemSchemaMock(); const outputPayload = getUpdateExceptionListItemSchemaMock(); delete inputPayload.entries; @@ -105,8 +105,10 @@ describe('update_exception_list_item_schema', () => { const decoded = updateExceptionListItemSchema.decode(inputPayload); const checked = exactCheck(inputPayload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(outputPayload); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "entries"', + ]); + expect(message.schema).toEqual({}); }); test('it should accept an undefined for "namespace_type" but return enum "single"', () => { diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts index 9e0a1759fc9f4..7fbd5cd65f04d 100644 --- a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_schema.ts @@ -23,17 +23,18 @@ import { } from '../common/schemas'; import { RequiredKeepUndefined } from '../../types'; import { - DefaultEntryArray, DefaultUpdateCommentsArray, EntriesArray, NamespaceType, UpdateCommentsArray, + nonEmptyEntriesArray, } from '../types'; export const updateExceptionListItemSchema = t.intersection([ t.exact( t.type({ description, + entries: nonEmptyEntriesArray, name, type: exceptionListItemType, }) @@ -43,7 +44,6 @@ export const updateExceptionListItemSchema = t.intersection([ _tags, // defaults to empty array if not set during decode _version, // defaults to undefined if not set during decode comments: DefaultUpdateCommentsArray, // defaults to empty array if not set during decode - entries: DefaultEntryArray, // defaults to empty array if not set during decode id, // defaults to undefined if not set during decode item_id: t.union([t.string, t.undefined]), meta, // defaults to undefined if not set during decode diff --git a/x-pack/plugins/lists/common/schemas/types/default_entries_array.test.ts b/x-pack/plugins/lists/common/schemas/types/default_entries_array.test.ts deleted file mode 100644 index 21115690c0a5f..0000000000000 --- a/x-pack/plugins/lists/common/schemas/types/default_entries_array.test.ts +++ /dev/null @@ -1,99 +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 { pipe } from 'fp-ts/lib/pipeable'; -import { left } from 'fp-ts/lib/Either'; - -import { foldLeftRight, getPaths } from '../../siem_common_deps'; - -import { DefaultEntryArray } from './default_entries_array'; -import { EntriesArray } from './entries'; -import { getEntriesArrayMock, getEntryMatchMock, getEntryNestedMock } from './entries.mock'; - -// NOTE: This may seem weird, but when validating schemas that use a union -// it checks against every item in that union. Since entries consist of 5 -// different entry types, it returns 5 of these. To make more readable, -// extracted here. -const returnedSchemaError = - '"Array<({| field: string, operator: "excluded" | "included", type: "match", value: string |} | {| field: string, operator: "excluded" | "included", type: "match_any", value: DefaultStringArray |} | {| field: string, list: {| id: string, type: "binary" | "boolean" | "byte" | "date" | "date_nanos" | "date_range" | "double" | "double_range" | "float" | "float_range" | "geo_point" | "geo_shape" | "half_float" | "integer" | "integer_range" | "ip" | "ip_range" | "keyword" | "long" | "long_range" | "shape" | "short" | "text" |}, operator: "excluded" | "included", type: "list" |} | {| field: string, operator: "excluded" | "included", type: "exists" |} | {| entries: Array<{| field: string, operator: "excluded" | "included", type: "match", value: string |}>, field: string, type: "nested" |})>"'; - -describe('default_entries_array', () => { - test('it should validate an empty array', () => { - const payload: EntriesArray = []; - const decoded = DefaultEntryArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should validate an array of regular and nested entries', () => { - const payload: EntriesArray = getEntriesArrayMock(); - const decoded = DefaultEntryArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should validate an array of nested entries', () => { - const payload: EntriesArray = [{ ...getEntryNestedMock() }]; - const decoded = DefaultEntryArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should validate an array of non nested entries', () => { - const payload: EntriesArray = [{ ...getEntryMatchMock() }]; - const decoded = DefaultEntryArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should NOT validate an array of numbers', () => { - const payload = [1]; - const decoded = DefaultEntryArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - // TODO: Known weird error formatting that is on our list to address - expect(getPaths(left(message.errors))).toEqual([ - `Invalid value "1" supplied to ${returnedSchemaError}`, - `Invalid value "1" supplied to ${returnedSchemaError}`, - `Invalid value "1" supplied to ${returnedSchemaError}`, - `Invalid value "1" supplied to ${returnedSchemaError}`, - `Invalid value "1" supplied to ${returnedSchemaError}`, - ]); - expect(message.schema).toEqual({}); - }); - - test('it should NOT validate an array of strings', () => { - const payload = ['some string']; - const decoded = DefaultEntryArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([ - `Invalid value "some string" supplied to ${returnedSchemaError}`, - `Invalid value "some string" supplied to ${returnedSchemaError}`, - `Invalid value "some string" supplied to ${returnedSchemaError}`, - `Invalid value "some string" supplied to ${returnedSchemaError}`, - `Invalid value "some string" supplied to ${returnedSchemaError}`, - ]); - expect(message.schema).toEqual({}); - }); - - test('it should return a default array entry', () => { - const payload = null; - const decoded = DefaultEntryArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual([]); - }); -}); diff --git a/x-pack/plugins/lists/common/schemas/types/default_entries_array.ts b/x-pack/plugins/lists/common/schemas/types/default_entries_array.ts deleted file mode 100644 index a85fdf8537f39..0000000000000 --- a/x-pack/plugins/lists/common/schemas/types/default_entries_array.ts +++ /dev/null @@ -1,22 +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 * as t from 'io-ts'; -import { Either } from 'fp-ts/lib/Either'; - -import { EntriesArray, entriesArray } from './entries'; - -/** - * Types the DefaultEntriesArray as: - * - If null or undefined, then a default array of type entry will be set - */ -export const DefaultEntryArray = new t.Type( - 'DefaultEntryArray', - entriesArray.is, - (input): Either => - input == null ? t.success([]) : entriesArray.decode(input), - t.identity -); diff --git a/x-pack/plugins/lists/common/schemas/types/entries.mock.ts b/x-pack/plugins/lists/common/schemas/types/entries.mock.ts index 8af18c970c6ae..3ed3f4e7ff88f 100644 --- a/x-pack/plugins/lists/common/schemas/types/entries.mock.ts +++ b/x-pack/plugins/lists/common/schemas/types/entries.mock.ts @@ -4,65 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - ENTRY_VALUE, - EXISTS, - FIELD, - LIST, - LIST_ID, - MATCH, - MATCH_ANY, - NESTED, - OPERATOR, - TYPE, -} from '../../constants.mock'; - -import { - EntriesArray, - EntryExists, - EntryList, - EntryMatch, - EntryMatchAny, - EntryNested, -} from './entries'; - -export const getEntryMatchMock = (): EntryMatch => ({ - field: FIELD, - operator: OPERATOR, - type: MATCH, - value: ENTRY_VALUE, -}); - -export const getEntryMatchAnyMock = (): EntryMatchAny => ({ - field: FIELD, - operator: OPERATOR, - type: MATCH_ANY, - value: [ENTRY_VALUE], -}); - -export const getEntryListMock = (): EntryList => ({ - field: FIELD, - list: { id: LIST_ID, type: TYPE }, - operator: OPERATOR, - type: LIST, -}); - -export const getEntryExistsMock = (): EntryExists => ({ - field: FIELD, - operator: OPERATOR, - type: EXISTS, -}); - -export const getEntryNestedMock = (): EntryNested => ({ - entries: [getEntryMatchMock(), getEntryMatchMock()], - field: FIELD, - type: NESTED, -}); +import { EntriesArray } from './entries'; +import { getEntryMatchMock } from './entry_match.mock'; +import { getEntryMatchAnyMock } from './entry_match_any.mock'; +import { getEntryListMock } from './entry_list.mock'; +import { getEntryExistsMock } from './entry_exists.mock'; +import { getEntryNestedMock } from './entry_nested.mock'; export const getEntriesArrayMock = (): EntriesArray => [ - getEntryMatchMock(), - getEntryMatchAnyMock(), - getEntryListMock(), - getEntryExistsMock(), - getEntryNestedMock(), + { ...getEntryMatchMock() }, + { ...getEntryMatchAnyMock() }, + { ...getEntryListMock() }, + { ...getEntryExistsMock() }, + { ...getEntryNestedMock() }, ]; diff --git a/x-pack/plugins/lists/common/schemas/types/entries.test.ts b/x-pack/plugins/lists/common/schemas/types/entries.test.ts index 01f82f12f2b2c..cad94220a232c 100644 --- a/x-pack/plugins/lists/common/schemas/types/entries.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/entries.test.ts @@ -9,359 +9,147 @@ import { left } from 'fp-ts/lib/Either'; import { foldLeftRight, getPaths } from '../../siem_common_deps'; -import { - getEntryExistsMock, - getEntryListMock, - getEntryMatchAnyMock, - getEntryMatchMock, - getEntryNestedMock, -} from './entries.mock'; -import { - EntryExists, - EntryList, - EntryMatch, - EntryMatchAny, - EntryNested, - entriesExists, - entriesList, - entriesMatch, - entriesMatchAny, - entriesNested, -} from './entries'; +import { getEntryMatchMock } from './entry_match.mock'; +import { getEntryMatchAnyMock } from './entry_match_any.mock'; +import { getEntryListMock } from './entry_list.mock'; +import { getEntryExistsMock } from './entry_exists.mock'; +import { getEntryNestedMock } from './entry_nested.mock'; +import { getEntriesArrayMock } from './entries.mock'; +import { entriesArray, entriesArrayOrUndefined, entry } from './entries'; describe('Entries', () => { - describe('entriesMatch', () => { - test('it should validate an entry', () => { - const payload = getEntryMatchMock(); - const decoded = entriesMatch.decode(payload); + describe('entry', () => { + test('it should validate a match entry', () => { + const payload = { ...getEntryMatchMock() }; + const decoded = entry.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should validate when operator is "included"', () => { - const payload = getEntryMatchMock(); - const decoded = entriesMatch.decode(payload); + test('it should validate a match_any entry', () => { + const payload = { ...getEntryMatchAnyMock() }; + const decoded = entry.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should validate when "operator" is "excluded"', () => { - const payload = getEntryMatchMock(); - payload.operator = 'excluded'; - const decoded = entriesMatch.decode(payload); + test('it should validate a exists entry', () => { + const payload = { ...getEntryExistsMock() }; + const decoded = entry.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should not validate when "value" is not string', () => { - const payload: Omit & { value: string[] } = { - ...getEntryMatchMock(), - value: ['some value'], - }; - const decoded = entriesMatch.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "["some value"]" supplied to "value"', - ]); - expect(message.schema).toEqual({}); - }); - - test('it should not validate when "type" is not "match"', () => { - const payload: Omit & { type: string } = { - ...getEntryMatchMock(), - type: 'match_any', - }; - const decoded = entriesMatch.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "match_any" supplied to "type"', - ]); - expect(message.schema).toEqual({}); - }); - - test('it should strip out extra keys', () => { - const payload: EntryMatch & { - extraKey?: string; - } = getEntryMatchMock(); - payload.extraKey = 'some value'; - const decoded = entriesMatch.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(getEntryMatchMock()); - }); - }); - - describe('entriesMatchAny', () => { - test('it should validate an entry', () => { - const payload = getEntryMatchAnyMock(); - const decoded = entriesMatchAny.decode(payload); + test('it should validate a list entry', () => { + const payload = { ...getEntryListMock() }; + const decoded = entry.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should validate when operator is "included"', () => { - const payload = getEntryMatchAnyMock(); - const decoded = entriesMatchAny.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should validate when operator is "excluded"', () => { - const payload = getEntryMatchAnyMock(); - payload.operator = 'excluded'; - const decoded = entriesMatchAny.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should not validate when value is not string array', () => { - const payload: Omit & { value: string } = { - ...getEntryMatchAnyMock(), - value: 'some string', - }; - const decoded = entriesMatchAny.decode(payload); + test('it should NOT validate a nested entry', () => { + const payload = { ...getEntryNestedMock() }; + const decoded = entry.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "some string" supplied to "value"', + 'Invalid value "undefined" supplied to "operator"', + 'Invalid value "nested" supplied to "type"', + 'Invalid value "undefined" supplied to "value"', + 'Invalid value "undefined" supplied to "operator"', + 'Invalid value "nested" supplied to "type"', + 'Invalid value "undefined" supplied to "value"', + 'Invalid value "undefined" supplied to "list"', + 'Invalid value "undefined" supplied to "operator"', + 'Invalid value "nested" supplied to "type"', + 'Invalid value "undefined" supplied to "operator"', + 'Invalid value "nested" supplied to "type"', ]); expect(message.schema).toEqual({}); }); - - test('it should not validate when "type" is not "match_any"', () => { - const payload: Omit & { type: string } = { - ...getEntryMatchAnyMock(), - type: 'match', - }; - const decoded = entriesMatchAny.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual(['Invalid value "match" supplied to "type"']); - expect(message.schema).toEqual({}); - }); - - test('it should strip out extra keys', () => { - const payload: EntryMatchAny & { - extraKey?: string; - } = getEntryMatchAnyMock(); - payload.extraKey = 'some extra key'; - const decoded = entriesMatchAny.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(getEntryMatchAnyMock()); - }); }); - describe('entriesExists', () => { - test('it should validate an entry', () => { - const payload = getEntryExistsMock(); - const decoded = entriesExists.decode(payload); + describe('entriesArray', () => { + test('it should validate an array with match entry', () => { + const payload = [{ ...getEntryMatchMock() }]; + const decoded = entriesArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should validate when "operator" is "included"', () => { - const payload = getEntryExistsMock(); - const decoded = entriesExists.decode(payload); + test('it should validate an array with match_any entry', () => { + const payload = [{ ...getEntryMatchAnyMock() }]; + const decoded = entriesArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should validate when "operator" is "excluded"', () => { - const payload = getEntryExistsMock(); - payload.operator = 'excluded'; - const decoded = entriesExists.decode(payload); + test('it should validate an array with exists entry', () => { + const payload = [{ ...getEntryExistsMock() }]; + const decoded = entriesArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should strip out extra keys', () => { - const payload: EntryExists & { - extraKey?: string; - } = getEntryExistsMock(); - payload.extraKey = 'some extra key'; - const decoded = entriesExists.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(getEntryExistsMock()); - }); - - test('it should not validate when "type" is not "exists"', () => { - const payload: Omit & { type: string } = { - ...getEntryExistsMock(), - type: 'match', - }; - const decoded = entriesExists.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual(['Invalid value "match" supplied to "type"']); - expect(message.schema).toEqual({}); - }); - }); - - describe('entriesList', () => { - test('it should validate an entry', () => { - const payload = getEntryListMock(); - const decoded = entriesList.decode(payload); + test('it should validate an array with list entry', () => { + const payload = [{ ...getEntryListMock() }]; + const decoded = entriesArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should validate when operator is "included"', () => { - const payload = getEntryListMock(); - const decoded = entriesList.decode(payload); + test('it should validate an array with nested entry', () => { + const payload = [{ ...getEntryNestedMock() }]; + const decoded = entriesArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should validate when "operator" is "excluded"', () => { - const payload = getEntryListMock(); - payload.operator = 'excluded'; - const decoded = entriesList.decode(payload); + test('it should validate an array with all types of entries', () => { + const payload = [...getEntriesArrayMock()]; + const decoded = entriesArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - - test('it should not validate when "list" is not expected value', () => { - const payload: Omit & { list: string } = { - ...getEntryListMock(), - list: 'someListId', - }; - const decoded = entriesList.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "someListId" supplied to "list"', - ]); - expect(message.schema).toEqual({}); - }); - - test('it should not validate when "type" is not "lists"', () => { - const payload: Omit & { type: 'match_any' } = { - ...getEntryListMock(), - type: 'match_any', - }; - const decoded = entriesList.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "match_any" supplied to "type"', - ]); - expect(message.schema).toEqual({}); - }); - - test('it should strip out extra keys', () => { - const payload: EntryList & { - extraKey?: string; - } = getEntryListMock(); - payload.extraKey = 'some extra key'; - const decoded = entriesList.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(getEntryListMock()); - }); }); - describe('entriesNested', () => { - test('it should validate a nested entry', () => { - const payload = getEntryNestedMock(); - const decoded = entriesNested.decode(payload); + describe('entriesArrayOrUndefined', () => { + test('it should validate undefined', () => { + const payload = undefined; + const decoded = entriesArrayOrUndefined.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should NOT validate when "type" is not "nested"', () => { - const payload: Omit & { type: 'match' } = { - ...getEntryNestedMock(), - type: 'match', - }; - const decoded = entriesNested.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual(['Invalid value "match" supplied to "type"']); - expect(message.schema).toEqual({}); - }); - - test('it should NOT validate when "field" is not a string', () => { - const payload: Omit & { - field: number; - } = { ...getEntryNestedMock(), field: 1 }; - const decoded = entriesNested.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual(['Invalid value "1" supplied to "field"']); - expect(message.schema).toEqual({}); - }); - - test('it should NOT validate when "entries" is not a an array', () => { - const payload: Omit & { - entries: string; - } = { ...getEntryNestedMock(), entries: 'im a string' }; - const decoded = entriesNested.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "im a string" supplied to "entries"', - ]); - expect(message.schema).toEqual({}); - }); - - test('it should NOT validate when "entries" contains an entry item that is not type "match"', () => { - const payload: Omit & { - entries: EntryMatchAny[]; - } = { ...getEntryNestedMock(), entries: [getEntryMatchAnyMock()] }; - const decoded = entriesNested.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "match_any" supplied to "entries,type"', - 'Invalid value "["some host name"]" supplied to "entries,value"', - ]); - expect(message.schema).toEqual({}); - }); - - test('it should strip out extra keys', () => { - const payload: EntryNested & { - extraKey?: string; - } = getEntryNestedMock(); - payload.extraKey = 'some extra key'; - const decoded = entriesNested.decode(payload); + test('it should validate an array with nested entry', () => { + const payload = [{ ...getEntryNestedMock() }]; + const decoded = entriesArrayOrUndefined.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(getEntryNestedMock()); + expect(message.schema).toEqual(payload); }); }); }); diff --git a/x-pack/plugins/lists/common/schemas/types/entries.ts b/x-pack/plugins/lists/common/schemas/types/entries.ts index c379f77b862c8..4f20b9278d3ff 100644 --- a/x-pack/plugins/lists/common/schemas/types/entries.ts +++ b/x-pack/plugins/lists/common/schemas/types/entries.ts @@ -8,62 +8,19 @@ import * as t from 'io-ts'; -import { operator, type } from '../common/schemas'; -import { DefaultStringArray } from '../../siem_common_deps'; - -export const entriesMatch = t.exact( - t.type({ - field: t.string, - operator, - type: t.keyof({ match: null }), - value: t.string, - }) -); -export type EntryMatch = t.TypeOf; - -export const entriesMatchAny = t.exact( - t.type({ - field: t.string, - operator, - type: t.keyof({ match_any: null }), - value: DefaultStringArray, - }) -); -export type EntryMatchAny = t.TypeOf; - -export const entriesList = t.exact( - t.type({ - field: t.string, - list: t.exact(t.type({ id: t.string, type })), - operator, - type: t.keyof({ list: null }), - }) -); -export type EntryList = t.TypeOf; - -export const entriesExists = t.exact( - t.type({ - field: t.string, - operator, - type: t.keyof({ exists: null }), - }) -); -export type EntryExists = t.TypeOf; - -export const entriesNested = t.exact( - t.type({ - entries: t.array(entriesMatch), - field: t.string, - type: t.keyof({ nested: null }), - }) -); -export type EntryNested = t.TypeOf; +import { entriesMatchAny } from './entry_match_any'; +import { entriesMatch } from './entry_match'; +import { entriesExists } from './entry_exists'; +import { entriesList } from './entry_list'; +import { entriesNested } from './entry_nested'; export const entry = t.union([entriesMatch, entriesMatchAny, entriesList, entriesExists]); export type Entry = t.TypeOf; + export const entriesArray = t.array( t.union([entriesMatch, entriesMatchAny, entriesList, entriesExists, entriesNested]) ); export type EntriesArray = t.TypeOf; + export const entriesArrayOrUndefined = t.union([entriesArray, t.undefined]); export type EntriesArrayOrUndefined = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/entry_exists.mock.ts b/x-pack/plugins/lists/common/schemas/types/entry_exists.mock.ts new file mode 100644 index 0000000000000..aa93eee6374a4 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_exists.mock.ts @@ -0,0 +1,15 @@ +/* + * 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 { EXISTS, FIELD, OPERATOR } from '../../constants.mock'; + +import { EntryExists } from './entry_exists'; + +export const getEntryExistsMock = (): EntryExists => ({ + field: FIELD, + operator: OPERATOR, + type: EXISTS, +}); diff --git a/x-pack/plugins/lists/common/schemas/types/entry_exists.test.ts b/x-pack/plugins/lists/common/schemas/types/entry_exists.test.ts new file mode 100644 index 0000000000000..9d5b669333db8 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_exists.test.ts @@ -0,0 +1,79 @@ +/* + * 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 { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; + +import { foldLeftRight, getPaths } from '../../siem_common_deps'; + +import { getEntryExistsMock } from './entry_exists.mock'; +import { EntryExists, entriesExists } from './entry_exists'; + +describe('entriesExists', () => { + test('it should validate an entry', () => { + const payload = { ...getEntryExistsMock() }; + const decoded = entriesExists.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate when "operator" is "included"', () => { + const payload = { ...getEntryExistsMock() }; + const decoded = entriesExists.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate when "operator" is "excluded"', () => { + const payload = { ...getEntryExistsMock() }; + payload.operator = 'excluded'; + const decoded = entriesExists.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate when "field" is empty string', () => { + const payload: Omit & { field: string } = { + ...getEntryExistsMock(), + field: '', + }; + const decoded = entriesExists.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "field"']); + expect(message.schema).toEqual({}); + }); + + test('it should strip out extra keys', () => { + const payload: EntryExists & { + extraKey?: string; + } = { ...getEntryExistsMock() }; + payload.extraKey = 'some extra key'; + const decoded = entriesExists.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({ ...getEntryExistsMock() }); + }); + + test('it should not validate when "type" is not "exists"', () => { + const payload: Omit & { type: string } = { + ...getEntryExistsMock(), + type: 'match', + }; + const decoded = entriesExists.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "match" supplied to "type"']); + expect(message.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/entry_exists.ts b/x-pack/plugins/lists/common/schemas/types/entry_exists.ts new file mode 100644 index 0000000000000..05c82d2532218 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_exists.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/* eslint-disable @typescript-eslint/camelcase */ + +import * as t from 'io-ts'; + +import { NonEmptyString } from '../../siem_common_deps'; +import { operator } from '../common/schemas'; + +export const entriesExists = t.exact( + t.type({ + field: NonEmptyString, + operator, + type: t.keyof({ exists: null }), + }) +); +export type EntryExists = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/entry_list.mock.ts b/x-pack/plugins/lists/common/schemas/types/entry_list.mock.ts new file mode 100644 index 0000000000000..d5166b7984c93 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_list.mock.ts @@ -0,0 +1,16 @@ +/* + * 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 { FIELD, LIST, LIST_ID, OPERATOR, TYPE } from '../../constants.mock'; + +import { EntryList } from './entry_list'; + +export const getEntryListMock = (): EntryList => ({ + field: FIELD, + list: { id: LIST_ID, type: TYPE }, + operator: OPERATOR, + type: LIST, +}); diff --git a/x-pack/plugins/lists/common/schemas/types/entry_list.test.ts b/x-pack/plugins/lists/common/schemas/types/entry_list.test.ts new file mode 100644 index 0000000000000..14857edad5e3b --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_list.test.ts @@ -0,0 +1,95 @@ +/* + * 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 { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; + +import { foldLeftRight, getPaths } from '../../siem_common_deps'; + +import { getEntryListMock } from './entry_list.mock'; +import { EntryList, entriesList } from './entry_list'; + +describe('entriesList', () => { + test('it should validate an entry', () => { + const payload = { ...getEntryListMock() }; + const decoded = entriesList.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate when operator is "included"', () => { + const payload = { ...getEntryListMock() }; + const decoded = entriesList.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate when "operator" is "excluded"', () => { + const payload = { ...getEntryListMock() }; + payload.operator = 'excluded'; + const decoded = entriesList.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate when "list" is not expected value', () => { + const payload: Omit & { list: string } = { + ...getEntryListMock(), + list: 'someListId', + }; + const decoded = entriesList.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "someListId" supplied to "list"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should not validate when "list.id" is empty string', () => { + const payload: Omit & { list: { id: string; type: 'ip' } } = { + ...getEntryListMock(), + list: { id: '', type: 'ip' }, + }; + const decoded = entriesList.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "list,id"']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate when "type" is not "lists"', () => { + const payload: Omit & { type: 'match_any' } = { + ...getEntryListMock(), + type: 'match_any', + }; + const decoded = entriesList.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "match_any" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should strip out extra keys', () => { + const payload: EntryList & { + extraKey?: string; + } = { ...getEntryListMock() }; + payload.extraKey = 'some extra key'; + const decoded = entriesList.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({ ...getEntryListMock() }); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/entry_list.ts b/x-pack/plugins/lists/common/schemas/types/entry_list.ts new file mode 100644 index 0000000000000..ae9de967db027 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_list.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +/* eslint-disable @typescript-eslint/camelcase */ + +import * as t from 'io-ts'; + +import { NonEmptyString } from '../../siem_common_deps'; +import { operator, type } from '../common/schemas'; + +export const entriesList = t.exact( + t.type({ + field: NonEmptyString, + list: t.exact(t.type({ id: NonEmptyString, type })), + operator, + type: t.keyof({ list: null }), + }) +); +export type EntryList = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/entry_match.mock.ts b/x-pack/plugins/lists/common/schemas/types/entry_match.mock.ts new file mode 100644 index 0000000000000..5f3a09f17eb3b --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_match.mock.ts @@ -0,0 +1,16 @@ +/* + * 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 { ENTRY_VALUE, FIELD, MATCH, OPERATOR } from '../../constants.mock'; + +import { EntryMatch } from './entry_match'; + +export const getEntryMatchMock = (): EntryMatch => ({ + field: FIELD, + operator: OPERATOR, + type: MATCH, + value: ENTRY_VALUE, +}); diff --git a/x-pack/plugins/lists/common/schemas/types/entry_match.test.ts b/x-pack/plugins/lists/common/schemas/types/entry_match.test.ts new file mode 100644 index 0000000000000..2c64592518eb7 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_match.test.ts @@ -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 { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; + +import { foldLeftRight, getPaths } from '../../siem_common_deps'; + +import { getEntryMatchMock } from './entry_match.mock'; +import { EntryMatch, entriesMatch } from './entry_match'; + +describe('entriesMatch', () => { + test('it should validate an entry', () => { + const payload = { ...getEntryMatchMock() }; + const decoded = entriesMatch.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate when operator is "included"', () => { + const payload = { ...getEntryMatchMock() }; + const decoded = entriesMatch.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate when "operator" is "excluded"', () => { + const payload = { ...getEntryMatchMock() }; + payload.operator = 'excluded'; + const decoded = entriesMatch.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate when "field" is empty string', () => { + const payload: Omit & { field: string } = { + ...getEntryMatchMock(), + field: '', + }; + const decoded = entriesMatch.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "field"']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate when "value" is not string', () => { + const payload: Omit & { value: string[] } = { + ...getEntryMatchMock(), + value: ['some value'], + }; + const decoded = entriesMatch.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "["some value"]" supplied to "value"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should not validate when "value" is empty string', () => { + const payload: Omit & { value: string } = { + ...getEntryMatchMock(), + value: '', + }; + const decoded = entriesMatch.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "value"']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate when "type" is not "match"', () => { + const payload: Omit & { type: string } = { + ...getEntryMatchMock(), + type: 'match_any', + }; + const decoded = entriesMatch.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "match_any" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should strip out extra keys', () => { + const payload: EntryMatch & { + extraKey?: string; + } = { ...getEntryMatchMock() }; + payload.extraKey = 'some value'; + const decoded = entriesMatch.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({ ...getEntryMatchMock() }); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/entry_match.ts b/x-pack/plugins/lists/common/schemas/types/entry_match.ts new file mode 100644 index 0000000000000..a21f83f317e35 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_match.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +/* eslint-disable @typescript-eslint/camelcase */ + +import * as t from 'io-ts'; + +import { NonEmptyString } from '../../siem_common_deps'; +import { operator } from '../common/schemas'; + +export const entriesMatch = t.exact( + t.type({ + field: NonEmptyString, + operator, + type: t.keyof({ match: null }), + value: NonEmptyString, + }) +); +export type EntryMatch = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/entry_match_any.mock.ts b/x-pack/plugins/lists/common/schemas/types/entry_match_any.mock.ts new file mode 100644 index 0000000000000..ac4ef69207c8c --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_match_any.mock.ts @@ -0,0 +1,16 @@ +/* + * 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 { ENTRY_VALUE, FIELD, MATCH_ANY, OPERATOR } from '../../constants.mock'; + +import { EntryMatchAny } from './entry_match_any'; + +export const getEntryMatchAnyMock = (): EntryMatchAny => ({ + field: FIELD, + operator: OPERATOR, + type: MATCH_ANY, + value: [ENTRY_VALUE], +}); diff --git a/x-pack/plugins/lists/common/schemas/types/entry_match_any.test.ts b/x-pack/plugins/lists/common/schemas/types/entry_match_any.test.ts new file mode 100644 index 0000000000000..4dab2f45711f0 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_match_any.test.ts @@ -0,0 +1,105 @@ +/* + * 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 { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; + +import { foldLeftRight, getPaths } from '../../siem_common_deps'; + +import { getEntryMatchAnyMock } from './entry_match_any.mock'; +import { EntryMatchAny, entriesMatchAny } from './entry_match_any'; + +describe('entriesMatchAny', () => { + test('it should validate an entry', () => { + const payload = { ...getEntryMatchAnyMock() }; + const decoded = entriesMatchAny.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate when operator is "included"', () => { + const payload = { ...getEntryMatchAnyMock() }; + const decoded = entriesMatchAny.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate when operator is "excluded"', () => { + const payload = { ...getEntryMatchAnyMock() }; + payload.operator = 'excluded'; + const decoded = entriesMatchAny.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate when field is empty string', () => { + const payload: Omit & { field: string } = { + ...getEntryMatchAnyMock(), + field: '', + }; + const decoded = entriesMatchAny.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "field"']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate when value is empty array', () => { + const payload: Omit & { value: string[] } = { + ...getEntryMatchAnyMock(), + value: [], + }; + const decoded = entriesMatchAny.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "[]" supplied to "value"']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate when value is not string array', () => { + const payload: Omit & { value: string } = { + ...getEntryMatchAnyMock(), + value: 'some string', + }; + const decoded = entriesMatchAny.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "some string" supplied to "value"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should not validate when "type" is not "match_any"', () => { + const payload: Omit & { type: string } = { + ...getEntryMatchAnyMock(), + type: 'match', + }; + const decoded = entriesMatchAny.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "match" supplied to "type"']); + expect(message.schema).toEqual({}); + }); + + test('it should strip out extra keys', () => { + const payload: EntryMatchAny & { + extraKey?: string; + } = { ...getEntryMatchAnyMock() }; + payload.extraKey = 'some extra key'; + const decoded = entriesMatchAny.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({ ...getEntryMatchAnyMock() }); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/entry_match_any.ts b/x-pack/plugins/lists/common/schemas/types/entry_match_any.ts new file mode 100644 index 0000000000000..e93ad4aa131d1 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_match_any.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/* eslint-disable @typescript-eslint/camelcase */ + +import * as t from 'io-ts'; + +import { NonEmptyString } from '../../siem_common_deps'; +import { operator } from '../common/schemas'; + +import { nonEmptyOrNullableStringArray } from './non_empty_or_nullable_string_array'; + +export const entriesMatchAny = t.exact( + t.type({ + field: NonEmptyString, + operator, + type: t.keyof({ match_any: null }), + value: nonEmptyOrNullableStringArray, + }) +); +export type EntryMatchAny = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/entry_nested.mock.ts b/x-pack/plugins/lists/common/schemas/types/entry_nested.mock.ts new file mode 100644 index 0000000000000..f645bc9e40d78 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_nested.mock.ts @@ -0,0 +1,17 @@ +/* + * 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 { FIELD, NESTED } from '../../constants.mock'; + +import { EntryNested } from './entry_nested'; +import { getEntryMatchMock } from './entry_match.mock'; +import { getEntryMatchAnyMock } from './entry_match_any.mock'; + +export const getEntryNestedMock = (): EntryNested => ({ + entries: [{ ...getEntryMatchMock() }, { ...getEntryMatchAnyMock() }], + field: FIELD, + type: NESTED, +}); diff --git a/x-pack/plugins/lists/common/schemas/types/entry_nested.test.ts b/x-pack/plugins/lists/common/schemas/types/entry_nested.test.ts new file mode 100644 index 0000000000000..d9b58855413b1 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_nested.test.ts @@ -0,0 +1,124 @@ +/* + * 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 { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; + +import { foldLeftRight, getPaths } from '../../siem_common_deps'; + +import { getEntryNestedMock } from './entry_nested.mock'; +import { EntryNested, entriesNested } from './entry_nested'; +import { getEntryMatchAnyMock } from './entry_match_any.mock'; +import { getEntryExistsMock } from './entry_exists.mock'; + +describe('entriesNested', () => { + test('it should validate a nested entry', () => { + const payload = { ...getEntryNestedMock() }; + const decoded = entriesNested.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should NOT validate when "type" is not "nested"', () => { + const payload: Omit & { type: 'match' } = { + ...getEntryNestedMock(), + type: 'match', + }; + const decoded = entriesNested.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "match" supplied to "type"']); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate when "field" is empty string', () => { + const payload: Omit & { + field: string; + } = { ...getEntryNestedMock(), field: '' }; + const decoded = entriesNested.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "field"']); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate when "field" is not a string', () => { + const payload: Omit & { + field: number; + } = { ...getEntryNestedMock(), field: 1 }; + const decoded = entriesNested.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "1" supplied to "field"']); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate when "entries" is not a an array', () => { + const payload: Omit & { + entries: string; + } = { ...getEntryNestedMock(), entries: 'im a string' }; + const decoded = entriesNested.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "im a string" supplied to "entries"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should validate when "entries" contains an entry item that is type "match"', () => { + const payload = { ...getEntryNestedMock(), entries: [{ ...getEntryMatchAnyMock() }] }; + const decoded = entriesNested.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({ + entries: [ + { + field: 'host.name', + operator: 'included', + type: 'match_any', + value: ['some host name'], + }, + ], + field: 'host.name', + type: 'nested', + }); + }); + + test('it should validate when "entries" contains an entry item that is type "exists"', () => { + const payload = { ...getEntryNestedMock(), entries: [{ ...getEntryExistsMock() }] }; + const decoded = entriesNested.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({ + entries: [ + { + field: 'host.name', + operator: 'included', + type: 'exists', + }, + ], + field: 'host.name', + type: 'nested', + }); + }); + + test('it should strip out extra keys', () => { + const payload: EntryNested & { + extraKey?: string; + } = { ...getEntryNestedMock() }; + payload.extraKey = 'some extra key'; + const decoded = entriesNested.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({ ...getEntryNestedMock() }); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/entry_nested.ts b/x-pack/plugins/lists/common/schemas/types/entry_nested.ts new file mode 100644 index 0000000000000..9989f501d4338 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/entry_nested.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +/* eslint-disable @typescript-eslint/camelcase */ + +import * as t from 'io-ts'; + +import { NonEmptyString } from '../../siem_common_deps'; + +import { nonEmptyNestedEntriesArray } from './non_empty_nested_entries_array'; + +export const entriesNested = t.exact( + t.type({ + entries: nonEmptyNestedEntriesArray, + field: NonEmptyString, + type: t.keyof({ nested: null }), + }) +); +export type EntryNested = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/index.ts b/x-pack/plugins/lists/common/schemas/types/index.ts index 16433e00f2b16..463f7cfe51ce3 100644 --- a/x-pack/plugins/lists/common/schemas/types/index.ts +++ b/x-pack/plugins/lists/common/schemas/types/index.ts @@ -10,5 +10,12 @@ export * from './default_comments_array'; export * from './default_create_comments_array'; export * from './default_update_comments_array'; export * from './default_namespace'; -export * from './default_entries_array'; export * from './entries'; +export * from './entry_match'; +export * from './entry_match_any'; +export * from './entry_list'; +export * from './entry_exists'; +export * from './entry_nested'; +export * from './non_empty_entries_array'; +export * from './non_empty_or_nullable_string_array'; +export * from './non_empty_nested_entries_array'; diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts new file mode 100644 index 0000000000000..ab7002982cf28 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts @@ -0,0 +1,123 @@ +/* + * 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 { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; + +import { foldLeftRight, getPaths } from '../../siem_common_deps'; + +import { getEntryMatchMock } from './entry_match.mock'; +import { getEntryMatchAnyMock } from './entry_match_any.mock'; +import { getEntryListMock } from './entry_list.mock'; +import { getEntryExistsMock } from './entry_exists.mock'; +import { getEntryNestedMock } from './entry_nested.mock'; +import { getEntriesArrayMock } from './entries.mock'; +import { nonEmptyEntriesArray } from './non_empty_entries_array'; +import { EntriesArray } from './entries'; + +describe('non_empty_entries_array', () => { + test('it should NOT validate an empty array', () => { + const payload: EntriesArray = []; + const decoded = nonEmptyEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "[]" supplied to "NonEmptyEntriesArray"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate "undefined"', () => { + const payload = undefined; + const decoded = nonEmptyEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "NonEmptyEntriesArray"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate "null"', () => { + const payload = null; + const decoded = nonEmptyEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "null" supplied to "NonEmptyEntriesArray"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should validate an array of "match" entries', () => { + const payload: EntriesArray = [{ ...getEntryMatchMock() }, { ...getEntryMatchMock() }]; + const decoded = nonEmptyEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate an array of "match_any" entries', () => { + const payload: EntriesArray = [{ ...getEntryMatchAnyMock() }, { ...getEntryMatchAnyMock() }]; + const decoded = nonEmptyEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate an array of "exists" entries', () => { + const payload: EntriesArray = [{ ...getEntryExistsMock() }, { ...getEntryExistsMock() }]; + const decoded = nonEmptyEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate an array of "list" entries', () => { + const payload: EntriesArray = [{ ...getEntryListMock() }, { ...getEntryListMock() }]; + const decoded = nonEmptyEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate an array of "nested" entries', () => { + const payload: EntriesArray = [{ ...getEntryNestedMock() }, { ...getEntryNestedMock() }]; + const decoded = nonEmptyEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate an array of entries', () => { + const payload: EntriesArray = [...getEntriesArrayMock()]; + const decoded = nonEmptyEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should NOT validate an array of non entries', () => { + const payload = [1]; + const decoded = nonEmptyEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "1" supplied to "NonEmptyEntriesArray"', + 'Invalid value "1" supplied to "NonEmptyEntriesArray"', + 'Invalid value "1" supplied to "NonEmptyEntriesArray"', + 'Invalid value "1" supplied to "NonEmptyEntriesArray"', + 'Invalid value "1" supplied to "NonEmptyEntriesArray"', + ]); + expect(message.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.ts new file mode 100644 index 0000000000000..1370fe022c258 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.ts @@ -0,0 +1,31 @@ +/* + * 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 * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +import { EntriesArray, entriesArray } from './entries'; + +/** + * Types the nonEmptyEntriesArray as: + * - An array of entries of length 1 or greater + * + */ +export const nonEmptyEntriesArray = new t.Type( + 'NonEmptyEntriesArray', + entriesArray.is, + (input, context): Either => { + if (Array.isArray(input) && input.length === 0) { + return t.failure(input, context); + } else { + return entriesArray.validate(input, context); + } + }, + t.identity +); + +export type NonEmptyEntriesArray = t.OutputOf; +export type NonEmptyEntriesArrayDecoded = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.test.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.test.ts new file mode 100644 index 0000000000000..1154f2b6098da --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.test.ts @@ -0,0 +1,131 @@ +/* + * 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 { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; + +import { foldLeftRight, getPaths } from '../../siem_common_deps'; + +import { getEntryMatchMock } from './entry_match.mock'; +import { getEntryMatchAnyMock } from './entry_match_any.mock'; +import { getEntryExistsMock } from './entry_exists.mock'; +import { getEntryNestedMock } from './entry_nested.mock'; +import { nonEmptyNestedEntriesArray } from './non_empty_nested_entries_array'; +import { EntriesArray } from './entries'; + +describe('non_empty_nested_entries_array', () => { + test('it should NOT validate an empty array', () => { + const payload: EntriesArray = []; + const decoded = nonEmptyNestedEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "[]" supplied to "NonEmptyNestedEntriesArray"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate "undefined"', () => { + const payload = undefined; + const decoded = nonEmptyNestedEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "NonEmptyNestedEntriesArray"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate "null"', () => { + const payload = null; + const decoded = nonEmptyNestedEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "null" supplied to "NonEmptyNestedEntriesArray"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should validate an array of "match" entries', () => { + const payload: EntriesArray = [{ ...getEntryMatchMock() }, { ...getEntryMatchMock() }]; + const decoded = nonEmptyNestedEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate an array of "match_any" entries', () => { + const payload: EntriesArray = [{ ...getEntryMatchAnyMock() }, { ...getEntryMatchAnyMock() }]; + const decoded = nonEmptyNestedEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate an array of "exists" entries', () => { + const payload: EntriesArray = [{ ...getEntryExistsMock() }, { ...getEntryExistsMock() }]; + const decoded = nonEmptyNestedEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should NOT validate an array of "nested" entries', () => { + const payload: EntriesArray = [{ ...getEntryNestedMock() }, { ...getEntryNestedMock() }]; + const decoded = nonEmptyNestedEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "operator"', + 'Invalid value "nested" supplied to "type"', + 'Invalid value "undefined" supplied to "value"', + 'Invalid value "undefined" supplied to "operator"', + 'Invalid value "nested" supplied to "type"', + 'Invalid value "undefined" supplied to "value"', + 'Invalid value "undefined" supplied to "operator"', + 'Invalid value "nested" supplied to "type"', + 'Invalid value "undefined" supplied to "operator"', + 'Invalid value "nested" supplied to "type"', + 'Invalid value "undefined" supplied to "value"', + 'Invalid value "undefined" supplied to "operator"', + 'Invalid value "nested" supplied to "type"', + 'Invalid value "undefined" supplied to "value"', + 'Invalid value "undefined" supplied to "operator"', + 'Invalid value "nested" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should validate an array of entries', () => { + const payload: EntriesArray = [ + { ...getEntryExistsMock() }, + { ...getEntryMatchAnyMock() }, + { ...getEntryMatchMock() }, + ]; + const decoded = nonEmptyNestedEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should NOT validate an array of non entries', () => { + const payload = [1]; + const decoded = nonEmptyNestedEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "1" supplied to "NonEmptyNestedEntriesArray"', + 'Invalid value "1" supplied to "NonEmptyNestedEntriesArray"', + 'Invalid value "1" supplied to "NonEmptyNestedEntriesArray"', + ]); + expect(message.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.ts new file mode 100644 index 0000000000000..88a0f09b3cef0 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_nested_entries_array.ts @@ -0,0 +1,40 @@ +/* + * 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 * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +import { entriesMatchAny } from './entry_match_any'; +import { entriesMatch } from './entry_match'; +import { entriesExists } from './entry_exists'; + +export const nestedEntriesArray = t.array(t.union([entriesMatch, entriesMatchAny, entriesExists])); +export type NestedEntriesArray = t.TypeOf; + +/** + * Types the nonEmptyNestedEntriesArray as: + * - An array of entries of length 1 or greater + * + */ +export const nonEmptyNestedEntriesArray = new t.Type< + NestedEntriesArray, + NestedEntriesArray, + unknown +>( + 'NonEmptyNestedEntriesArray', + nestedEntriesArray.is, + (input, context): Either => { + if (Array.isArray(input) && input.length === 0) { + return t.failure(input, context); + } else { + return nestedEntriesArray.validate(input, context); + } + }, + t.identity +); + +export type NonEmptyNestedEntriesArray = t.OutputOf; +export type NonEmptyNestedEntriesArrayDecoded = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_or_nullable_string_array.test.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_or_nullable_string_array.test.ts new file mode 100644 index 0000000000000..e3cc9104853e5 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_or_nullable_string_array.test.ts @@ -0,0 +1,69 @@ +/* + * 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 { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; + +import { foldLeftRight, getPaths } from '../../siem_common_deps'; + +import { nonEmptyOrNullableStringArray } from './non_empty_or_nullable_string_array'; + +describe('nonEmptyOrNullableStringArray', () => { + test('it should NOT validate an empty array', () => { + const payload: string[] = []; + const decoded = nonEmptyOrNullableStringArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "[]" supplied to "NonEmptyOrNullableStringArray"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate "undefined"', () => { + const payload = undefined; + const decoded = nonEmptyOrNullableStringArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "NonEmptyOrNullableStringArray"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate "null"', () => { + const payload = null; + const decoded = nonEmptyOrNullableStringArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "null" supplied to "NonEmptyOrNullableStringArray"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate an array of with an empty string', () => { + const payload: string[] = ['im good', '']; + const decoded = nonEmptyOrNullableStringArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "["im good",""]" supplied to "NonEmptyOrNullableStringArray"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate an array of non strings', () => { + const payload = [1]; + const decoded = nonEmptyOrNullableStringArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "[1]" supplied to "NonEmptyOrNullableStringArray"', + ]); + expect(message.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_or_nullable_string_array.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_or_nullable_string_array.ts new file mode 100644 index 0000000000000..f8ae1701e1322 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_or_nullable_string_array.ts @@ -0,0 +1,34 @@ +/* + * 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 * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +/** + * Types the nonEmptyOrNullableStringArray as: + * - An array of non empty strings of length 1 or greater + * - This differs from NonEmptyStringArray in that both input and output are type array + * + */ +export const nonEmptyOrNullableStringArray = new t.Type( + 'NonEmptyOrNullableStringArray', + t.array(t.string).is, + (input, context): Either => { + const emptyValueFound = Array.isArray(input) && input.some((value) => value === ''); + const nonStringValueFound = + Array.isArray(input) && input.some((value) => typeof value !== 'string'); + + if (Array.isArray(input) && (emptyValueFound || nonStringValueFound || input.length === 0)) { + return t.failure(input, context); + } else { + return t.array(t.string).validate(input, context); + } + }, + t.identity +); + +export type NonEmptyOrNullableStringArray = t.OutputOf; +export type NonEmptyOrNullableStringArrayDecoded = t.TypeOf; diff --git a/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item.json b/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item.json index eede855aab199..5fbfcc10bcc3c 100644 --- a/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item.json +++ b/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item.json @@ -8,7 +8,7 @@ "name": "Sample Endpoint Exception List", "entries": [ { - "field": "actingProcess.file.signer", + "field": "host.ip", "operator": "excluded", "type": "exists" }, diff --git a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts index 51e3a7ee8046f..555b9c5e95a77 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts @@ -14,7 +14,6 @@ import { Description, DescriptionOrUndefined, EntriesArray, - EntriesArrayOrUndefined, ExceptionListItemType, ExceptionListItemTypeOrUndefined, ExceptionListType, @@ -140,7 +139,7 @@ export interface UpdateExceptionListItemOptions { _tags: _TagsOrUndefined; _version: _VersionOrUndefined; comments: UpdateCommentsArray; - entries: EntriesArrayOrUndefined; + entries: EntriesArray; id: IdOrUndefined; itemId: ItemIdOrUndefined; namespaceType: NamespaceType; @@ -155,7 +154,7 @@ export interface UpdateEndpointListItemOptions { _tags: _TagsOrUndefined; _version: _VersionOrUndefined; comments: UpdateCommentsArray; - entries: EntriesArrayOrUndefined; + entries: EntriesArray; id: IdOrUndefined; itemId: ItemIdOrUndefined; name: NameOrUndefined; diff --git a/x-pack/plugins/lists/server/services/exception_lists/update_exception_list_item.ts b/x-pack/plugins/lists/server/services/exception_lists/update_exception_list_item.ts index f26dd7e18dd5c..ccb74e8796705 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/update_exception_list_item.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/update_exception_list_item.ts @@ -8,7 +8,7 @@ import { SavedObjectsClientContract } from 'kibana/server'; import { DescriptionOrUndefined, - EntriesArrayOrUndefined, + EntriesArray, ExceptionListItemSchema, ExceptionListItemTypeOrUndefined, ExceptionListSoSchema, @@ -37,7 +37,7 @@ interface UpdateExceptionListItemOptions { _version: _VersionOrUndefined; name: NameOrUndefined; description: DescriptionOrUndefined; - entries: EntriesArrayOrUndefined; + entries: EntriesArray; savedObjectsClient: SavedObjectsClientContract; namespaceType: NamespaceType; itemId: ItemIdOrUndefined; diff --git a/x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.test.ts b/x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.test.ts index caf2dfb761ed0..1c7a2a5de6594 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.test.ts @@ -25,6 +25,9 @@ import { Operator, } from '../../../lists/common/schemas'; import { getExceptionListItemSchemaMock } from '../../../lists/common/schemas/response/exception_list_item_schema.mock'; +import { getEntryMatchMock } from '../../../lists/common/schemas/types/entry_match.mock'; +import { getEntryMatchAnyMock } from '../../../lists/common/schemas/types/entry_match_any.mock'; +import { getEntryExistsMock } from '../../../lists/common/schemas/types/entry_exists.mock'; describe('build_exceptions_query', () => { let exclude: boolean; @@ -295,20 +298,95 @@ describe('build_exceptions_query', () => { const item: EntryNested = { field: 'parent', type: 'nested', - entries: [makeMatchEntry({ field: 'nestedField', operator: 'included' })], + entries: [ + { + ...getEntryMatchMock(), + field: 'nestedField', + operator: 'included', + value: 'value-1', + }, + ], }; const result = buildNested({ item, language: 'kuery' }); expect(result).toEqual('parent:{ nestedField:"value-1" }'); }); + test('it returns formatted query when entry item is "exists"', () => { + const item: EntryNested = { + field: 'parent', + type: 'nested', + entries: [{ ...getEntryExistsMock(), field: 'nestedField', operator: 'included' }], + }; + const result = buildNested({ item, language: 'kuery' }); + + expect(result).toEqual('parent:{ nestedField:* }'); + }); + + test('it returns formatted query when entry item is "exists" and operator is "excluded"', () => { + const item: EntryNested = { + field: 'parent', + type: 'nested', + entries: [{ ...getEntryExistsMock(), field: 'nestedField', operator: 'excluded' }], + }; + const result = buildNested({ item, language: 'kuery' }); + + expect(result).toEqual('parent:{ not nestedField:* }'); + }); + + test('it returns formatted query when entry item is "match_any"', () => { + const item: EntryNested = { + field: 'parent', + type: 'nested', + entries: [ + { + ...getEntryMatchAnyMock(), + field: 'nestedField', + operator: 'included', + value: ['value1', 'value2'], + }, + ], + }; + const result = buildNested({ item, language: 'kuery' }); + + expect(result).toEqual('parent:{ nestedField:("value1" or "value2") }'); + }); + + test('it returns formatted query when entry item is "match_any" and operator is "excluded"', () => { + const item: EntryNested = { + field: 'parent', + type: 'nested', + entries: [ + { + ...getEntryMatchAnyMock(), + field: 'nestedField', + operator: 'excluded', + value: ['value1', 'value2'], + }, + ], + }; + const result = buildNested({ item, language: 'kuery' }); + + expect(result).toEqual('parent:{ not nestedField:("value1" or "value2") }'); + }); + test('it returns formatted query when multiple items in nested entry', () => { const item: EntryNested = { field: 'parent', type: 'nested', entries: [ - makeMatchEntry({ field: 'nestedField', operator: 'included' }), - makeMatchEntry({ field: 'nestedFieldB', operator: 'included', value: 'value-2' }), + { + ...getEntryMatchMock(), + field: 'nestedField', + operator: 'included', + value: 'value-1', + }, + { + ...getEntryMatchMock(), + field: 'nestedFieldB', + operator: 'included', + value: 'value-2', + }, ], }; const result = buildNested({ item, language: 'kuery' }); @@ -514,7 +592,7 @@ describe('build_exceptions_query', () => { entries, }); const expectedQuery = - 'b:("value-1" OR "value-2") AND parent:{ nestedField:"value-3" } AND NOT _exists_e'; + 'b:("value-1" OR "value-2") AND parent:{ NOT nestedField:"value-3" } AND NOT _exists_e'; expect(query).toEqual(expectedQuery); }); @@ -576,7 +654,7 @@ describe('build_exceptions_query', () => { language: 'kuery', entries, }); - const expectedQuery = 'b:* and parent:{ c:"value-1" and d:"value-2" } and e:*'; + const expectedQuery = 'b:* and parent:{ not c:"value-1" and d:"value-2" } and e:*'; expect(query).toEqual(expectedQuery); }); @@ -642,7 +720,8 @@ describe('build_exceptions_query', () => { language: 'kuery', entries, }); - const expectedQuery = 'b:"value" and parent:{ c:"valueC" and d:"valueD" } and e:"valueE"'; + const expectedQuery = + 'b:"value" and parent:{ not c:"valueC" and not d:"valueD" } and e:"valueE"'; expect(query).toEqual(expectedQuery); }); @@ -684,7 +763,7 @@ describe('build_exceptions_query', () => { language: 'kuery', entries, }); - const expectedQuery = 'not b:("value-1" or "value-2") and parent:{ c:"valueC" }'; + const expectedQuery = 'not b:("value-1" or "value-2") and parent:{ not c:"valueC" }'; expect(query).toEqual(expectedQuery); }); @@ -800,7 +879,7 @@ describe('build_exceptions_query', () => { exclude, }); const expectedQuery = - '(some.parentField:{ nested.field:"some value" } and some.not.nested.field:"some value") or (b:("value-1" or "value-2") and parent:{ c:"valueC" and d:"valueD" } and e:("value-1" or "value-2"))'; + '(some.parentField:{ nested.field:"some value" } and some.not.nested.field:"some value") or (b:("value-1" or "value-2") and parent:{ not c:"valueC" and not d:"valueD" } and e:("value-1" or "value-2"))'; expect(query).toEqual([{ query: expectedQuery, language: 'kuery' }]); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.ts b/x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.ts index fc4fbae02b8fb..ff492dcda3b66 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.ts @@ -126,7 +126,7 @@ export const buildNested = ({ }): string => { const { field, entries } = item; const and = getLanguageBooleanOperator({ language, value: 'and' }); - const values = entries.map((entry) => `${entry.field}:"${entry.value}"`); + const values = entries.map((entry) => evaluateValues({ item: entry, language })); return `${field}:{ ${values.join(` ${and} `)} }`; }; diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field.tsx index ed844b5130c77..fab2b1e4a7463 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field.tsx @@ -3,7 +3,7 @@ * 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, { useMemo, useCallback } from 'react'; +import React, { useState, useMemo, useCallback } from 'react'; import { EuiComboBoxOptionOption, EuiComboBox } from '@elastic/eui'; import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/common'; @@ -19,6 +19,7 @@ interface OperatorProps { isClearable: boolean; fieldTypeFilter?: string[]; fieldInputWidth?: number; + isRequired?: boolean; onChange: (a: IFieldType[]) => void; } @@ -29,10 +30,12 @@ export const FieldComponent: React.FC = ({ isLoading = false, isDisabled = false, isClearable = false, + isRequired = false, fieldTypeFilter = [], fieldInputWidth = 190, onChange, }): JSX.Element => { + const [touched, setIsTouched] = useState(false); const getLabel = useCallback((field): string => field.name, []); const optionsMemo = useMemo((): IFieldType[] => { if (indexPattern != null) { @@ -74,6 +77,8 @@ export const FieldComponent: React.FC = ({ isLoading={isLoading} isDisabled={isDisabled} isClearable={isClearable} + isInvalid={isRequired ? touched && selectedField == null : false} + onFocus={() => setIsTouched(true)} singleSelection={{ asPlainText: true }} data-test-subj="fieldAutocompleteComboBox" style={{ width: `${fieldInputWidth}px` }} diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.tsx index a9d85452651b5..cd90d6eb85623 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_lists.tsx @@ -18,6 +18,7 @@ interface AutocompleteFieldListsProps { isLoading: boolean; isDisabled: boolean; isClearable: boolean; + isRequired?: boolean; onChange: (arg: ListSchema) => void; } @@ -28,8 +29,10 @@ export const AutocompleteFieldListsComponent: React.FC { + const [touched, setIsTouched] = useState(false); const { http } = useKibana().services; const [lists, setLists] = useState([]); const { loading, result, start } = useFindLists(); @@ -97,6 +100,8 @@ export const AutocompleteFieldListsComponent: React.FC setIsTouched(true)} singleSelection={{ asPlainText: true }} sortMatchesBy="startsWith" data-test-subj="valuesAutocompleteComboBox listsComboxBox" diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx index a082811920f88..992005b3be8bc 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match.tsx @@ -3,7 +3,7 @@ * 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, { useCallback, useMemo } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { EuiComboBoxOptionOption, EuiComboBox } from '@elastic/eui'; import { uniq } from 'lodash'; @@ -22,6 +22,7 @@ interface AutocompleteFieldMatchProps { isLoading: boolean; isDisabled: boolean; isClearable: boolean; + isRequired?: boolean; fieldInputWidth?: number; onChange: (arg: string) => void; } @@ -34,9 +35,11 @@ export const AutocompleteFieldMatchComponent: React.FC { + const [touched, setIsTouched] = useState(false); const [isLoadingSuggestions, suggestions, updateSuggestions] = useFieldValueAutocomplete({ selectedField, operatorType: OperatorTypeEnum.MATCH, @@ -96,7 +99,8 @@ export const AutocompleteFieldMatchComponent: React.FC setIsTouched(true)} sortMatchesBy="startsWith" data-test-subj="valuesAutocompleteComboBox matchComboxBox" style={fieldInputWidth ? { width: `${fieldInputWidth}px` } : {}} diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.tsx index 461d49dddfdef..27807a752c141 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.tsx +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/field_value_match_any.tsx @@ -3,7 +3,7 @@ * 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, { useCallback, useMemo } from 'react'; +import React, { useState, useCallback, useMemo } from 'react'; import { EuiComboBoxOptionOption, EuiComboBox } from '@elastic/eui'; import { uniq } from 'lodash'; @@ -22,6 +22,7 @@ interface AutocompleteFieldMatchAnyProps { isLoading: boolean; isDisabled: boolean; isClearable: boolean; + isRequired?: boolean; onChange: (arg: string[]) => void; } @@ -33,8 +34,10 @@ export const AutocompleteFieldMatchAnyComponent: React.FC { + const [touched, setIsTouched] = useState(false); const [isLoadingSuggestions, suggestions, updateSuggestions] = useFieldValueAutocomplete({ selectedField, operatorType: OperatorTypeEnum.MATCH_ANY, @@ -92,7 +95,8 @@ export const AutocompleteFieldMatchAnyComponent: React.FC setIsTouched(true)} delimiter=", " data-test-subj="valuesAutocompleteComboBox matchAnyComboxBox" fullWidth diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts index cb07d99913107..b25bb245c6792 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.test.ts @@ -54,16 +54,16 @@ describe('helpers', () => { }); describe('#validateParams', () => { - test('returns true if value is undefined', () => { + test('returns false if value is undefined', () => { const isValid = validateParams(undefined, getField('@timestamp')); - expect(isValid).toBeTruthy(); + expect(isValid).toBeFalsy(); }); - test('returns true if value is empty string', () => { + test('returns false if value is empty string', () => { const isValid = validateParams('', getField('@timestamp')); - expect(isValid).toBeTruthy(); + expect(isValid).toBeFalsy(); }); test('returns true if type is "date" and value is valid', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts index 16659593784db..a65f1fa35d3c2 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/helpers.ts @@ -36,7 +36,7 @@ export const validateParams = ( ): boolean => { // Box would show error state if empty otherwise if (params == null || params === '') { - return true; + return false; } const types = field != null && field.esTypes != null ? field.esTypes : []; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.test.tsx index 9ca7a371ce81b..0f3b6ec2e94e4 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.test.tsx @@ -12,10 +12,8 @@ import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; import { ExceptionListItemComponent } from './builder_exception_item'; import { fields } from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; import { getExceptionListItemSchemaMock } from '../../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; -import { - getEntryMatchMock, - getEntryMatchAnyMock, -} from '../../../../../../lists/common/schemas/types/entries.mock'; +import { getEntryMatchMock } from '../../../../../../lists/common/schemas/types/entry_match.mock'; +import { getEntryMatchAnyMock } from '../../../../../../lists/common/schemas/types/entry_match_any.mock'; describe('ExceptionListItemComponent', () => { describe('and badge logic', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.tsx index 0f5000c8c0abe..7bf279168a9a0 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/entry_item.tsx @@ -117,6 +117,7 @@ export const EntryItemComponent: React.FC = ({ isDisabled={isLoading} onChange={handleFieldChange} data-test-subj="exceptionBuilderEntryField" + isRequired /> ); @@ -170,6 +171,7 @@ export const EntryItemComponent: React.FC = ({ isClearable={false} indexPattern={indexPattern} onChange={handleFieldMatchValueChange} + isRequired data-test-subj="exceptionBuilderEntryFieldMatch" /> ); @@ -185,6 +187,7 @@ export const EntryItemComponent: React.FC = ({ isClearable={false} indexPattern={indexPattern} onChange={handleFieldMatchAnyValueChange} + isRequired data-test-subj="exceptionBuilderEntryFieldMatchAny" /> ); @@ -199,6 +202,7 @@ export const EntryItemComponent: React.FC = ({ isDisabled={isLoading} isClearable={false} onChange={handleFieldListValueChange} + isRequired data-test-subj="exceptionBuilderEntryFieldList" /> ); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx index 7171d3c6b815e..dace2eb5f0672 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx @@ -38,18 +38,20 @@ import { existsOperator, doesNotExistOperator, } from '../autocomplete/operators'; -import { OperatorTypeEnum, OperatorEnum } from '../../../lists_plugin_deps'; +import { OperatorTypeEnum, OperatorEnum, EntryNested } from '../../../lists_plugin_deps'; import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; -import { - getEntryExistsMock, - getEntryListMock, - getEntryMatchMock, - getEntryMatchAnyMock, - getEntriesArrayMock, -} from '../../../../../lists/common/schemas/types/entries.mock'; +import { getEntryMatchMock } from '../../../../../lists/common/schemas/types/entry_match.mock'; +import { getEntryMatchAnyMock } from '../../../../../lists/common/schemas/types/entry_match_any.mock'; +import { getEntryExistsMock } from '../../../../../lists/common/schemas/types/entry_exists.mock'; +import { getEntryListMock } from '../../../../../lists/common/schemas/types/entry_list.mock'; import { getCommentsArrayMock } from '../../../../../lists/common/schemas/types/comments.mock'; +import { getEntriesArrayMock } from '../../../../../lists/common/schemas/types/entries.mock'; import { ENTRIES } from '../../../../../lists/common/constants.mock'; -import { ExceptionListItemSchema, EntriesArray } from '../../../../../lists/common/schemas'; +import { + CreateExceptionListItemSchema, + ExceptionListItemSchema, + EntriesArray, +} from '../../../../../lists/common/schemas'; import { IIndexPattern } from 'src/plugins/data/common'; describe('Exception helpers', () => { @@ -251,8 +253,8 @@ describe('Exception helpers', () => { { fieldName: 'host.name.host.name', isNested: true, - operator: 'is', - value: 'some host name', + operator: 'is one of', + value: ['some host name'], }, ]; expect(result).toEqual(expected); @@ -482,7 +484,7 @@ describe('Exception helpers', () => { }); describe('#filterExceptionItems', () => { - test('it removes empty entry items', () => { + test('it removes entry items with "value" of "undefined"', () => { const { entries, ...rest } = getExceptionListItemSchemaMock(); const mockEmptyException: EmptyEntry = { field: 'host.name', @@ -500,6 +502,85 @@ describe('Exception helpers', () => { expect(exceptions).toEqual([getExceptionListItemSchemaMock()]); }); + test('it removes "match" entry items with "value" of empty string', () => { + const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; + const mockEmptyException: EmptyEntry = { + field: 'host.name', + type: OperatorTypeEnum.MATCH, + operator: OperatorEnum.INCLUDED, + value: '', + }; + const output: Array< + ExceptionListItemSchema | CreateExceptionListItemSchema + > = filterExceptionItems([ + { + ...rest, + entries: [...entries, mockEmptyException], + }, + ]); + + expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); + }); + + test('it removes "match" entry items with "field" of empty string', () => { + const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; + const mockEmptyException: EmptyEntry = { + field: '', + type: OperatorTypeEnum.MATCH, + operator: OperatorEnum.INCLUDED, + value: 'some value', + }; + const output: Array< + ExceptionListItemSchema | CreateExceptionListItemSchema + > = filterExceptionItems([ + { + ...rest, + entries: [...entries, mockEmptyException], + }, + ]); + + expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); + }); + + test('it removes "match_any" entry items with "field" of empty string', () => { + const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; + const mockEmptyException: EmptyEntry = { + field: '', + type: OperatorTypeEnum.MATCH_ANY, + operator: OperatorEnum.INCLUDED, + value: ['some value'], + }; + const output: Array< + ExceptionListItemSchema | CreateExceptionListItemSchema + > = filterExceptionItems([ + { + ...rest, + entries: [...entries, mockEmptyException], + }, + ]); + + expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); + }); + + test('it removes "nested" entry items with "field" of empty string', () => { + const { entries, ...rest } = { ...getExceptionListItemSchemaMock() }; + const mockEmptyException: EntryNested = { + field: '', + type: OperatorTypeEnum.NESTED, + entries: [{ ...getEntryMatchMock() }], + }; + const output: Array< + ExceptionListItemSchema | CreateExceptionListItemSchema + > = filterExceptionItems([ + { + ...rest, + entries: [...entries, mockEmptyException], + }, + ]); + + expect(output).toEqual([{ ...getExceptionListItemSchemaMock() }]); + }); + test('it removes `temporaryId` from items', () => { const { meta, ...rest } = getNewExceptionItem({ listType: 'detection', @@ -509,7 +590,7 @@ describe('Exception helpers', () => { }); const exceptions = filterExceptionItems([{ ...rest, meta }]); - expect(exceptions).toEqual([{ ...rest, meta: undefined }]); + expect(exceptions).toEqual([{ ...rest, entries: [], meta: undefined }]); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx index 3d028431de8ff..4d8fc5f68870b 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx @@ -39,6 +39,7 @@ import { EntryNested, } from '../../../lists_plugin_deps'; import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/common'; +import { validate } from '../../../../common/validate'; import { TimelineNonEcsData } from '../../../graphql/types'; import { WithCopyToClipboard } from '../../lib/clipboard/with_copy_to_clipboard'; @@ -348,11 +349,22 @@ export const filterExceptionItems = ( ): Array => { return exceptions.reduce>( (acc, exception) => { - const entries = exception.entries.filter((t) => entry.is(t) || entriesNested.is(t)); + const entries = exception.entries.filter((t) => { + const [validatedEntry] = validate(t, entry); + const [validatedNestedEntry] = validate(t, entriesNested); + + if (validatedEntry != null || validatedNestedEntry != null) { + return true; + } + + return false; + }); + const item = { ...exception, entries }; + if (exceptionListItemSchema.is(item)) { return [...acc, item]; - } else if (createExceptionListItemSchema.is(item) && item.meta != null) { + } else if (createExceptionListItemSchema.is(item)) { const { meta, ...rest } = item; const itemSansMetaId: CreateExceptionListItemSchema = { ...rest, meta: undefined }; return [...acc, itemSansMetaId]; diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.test.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.test.ts index d3d073efa73c1..bb8b4fb3d5ce7 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.test.ts @@ -8,7 +8,7 @@ import { ExceptionListClient } from '../../../../../lists/server'; import { listMock } from '../../../../../lists/server/mocks'; import { getFoundExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/found_exception_list_item_schema.mock'; import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; -import { EntriesArray, EntryList } from '../../../../../lists/common/schemas/types/entries'; +import { EntriesArray, EntryList } from '../../../../../lists/common/schemas/types'; import { buildArtifact, getFullEndpointExceptionList } from './lists'; import { TranslatedEntry, TranslatedExceptionListItem } from '../../schemas/artifacts'; diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.ts index 68fa2a0511a48..5998a88527f2f 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.ts @@ -9,7 +9,7 @@ import { deflate } from 'zlib'; import { ExceptionListItemSchema } from '../../../../../lists/common/schemas'; import { validate } from '../../../../common/validate'; -import { Entry, EntryNested } from '../../../../../lists/common/schemas/types/entries'; +import { Entry, EntryNested } from '../../../../../lists/common/schemas/types'; import { FoundExceptionListItemSchema } from '../../../../../lists/common/schemas/response/found_exception_list_item_schema'; import { ExceptionListClient } from '../../../../../lists/server'; import { ENDPOINT_LIST_ID } from '../../../../common/shared_imports'; From 1a1d7049e8ea14b60eb30cc85b7f19cc98a7777b Mon Sep 17 00:00:00 2001 From: Garrett Spong Date: Tue, 21 Jul 2020 19:21:40 -0600 Subject: [PATCH 75/77] [Security Solution] Fixes exception modal not loading content (#72770) ## Summary When using the `useFetchIndexPatterns` hook multiple times within a component (e.g. add_exception_modal & edit_exception_modal), the `apolloClient` will perform `queryDeduplication` and prevent the first query from executing. A deep compare is not performed on `indices`, so another field must be passed to circumvent this. For all the lovely details, see https://github.com/apollographql/react-apollo/issues/2202 Note: As of yesterday, [support has been added](https://github.com/apollographql/apollo-client/pull/6526) for configuring `queryDeduplicating` via `context`. This is available in `apollo-client` `2.6`, so when upgrading (currently on `2.3.8`) we can swap out this workaround to leverage this functionality. Note II: This [link](https://www.apollographql.com/docs/link/links/dedup/#context) may also be an option after upgrading to a supported version. --- .../exceptions/add_exception_modal/index.tsx | 7 +++++-- .../exceptions/edit_exception_modal/index.tsx | 7 +++++-- .../detection_engine/rules/fetch_index_patterns.tsx | 10 +++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx index e630645ef8c4e..6e77cd7082d56 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx @@ -114,9 +114,12 @@ export const AddExceptionModal = memo(function AddExceptionModal({ const { loading: isSignalIndexLoading, signalIndexName } = useSignalIndex(); const [ { isLoading: isSignalIndexPatternLoading, indexPatterns: signalIndexPatterns }, - ] = useFetchIndexPatterns(signalIndexName !== null ? [signalIndexName] : []); + ] = useFetchIndexPatterns(signalIndexName !== null ? [signalIndexName] : [], 'signals'); - const [{ isLoading: isIndexPatternLoading, indexPatterns }] = useFetchIndexPatterns(ruleIndices); + const [{ isLoading: isIndexPatternLoading, indexPatterns }] = useFetchIndexPatterns( + ruleIndices, + 'rules' + ); const onError = useCallback( (error: Error) => { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx index d07a8b5f0d2f6..2d12cfbec160a 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx @@ -97,9 +97,12 @@ export const EditExceptionModal = memo(function EditExceptionModal({ const { loading: isSignalIndexLoading, signalIndexName } = useSignalIndex(); const [ { isLoading: isSignalIndexPatternLoading, indexPatterns: signalIndexPatterns }, - ] = useFetchIndexPatterns(signalIndexName !== null ? [signalIndexName] : []); + ] = useFetchIndexPatterns(signalIndexName !== null ? [signalIndexName] : [], 'signals'); - const [{ isLoading: isIndexPatternLoading, indexPatterns }] = useFetchIndexPatterns(ruleIndices); + const [{ isLoading: isIndexPatternLoading, indexPatterns }] = useFetchIndexPatterns( + ruleIndices, + 'rules' + ); const onError = useCallback( (error) => { diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx index 6257a9980e00c..c0997a5e62908 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx @@ -38,7 +38,14 @@ const DEFAULT_BROWSER_FIELDS = {}; const DEFAULT_INDEX_PATTERNS = { fields: [], title: '' }; const DEFAULT_DOC_VALUE_FIELDS: DocValueFields[] = []; -export const useFetchIndexPatterns = (defaultIndices: string[] = []): Return => { +// Fun fact: When using this hook multiple times within a component (e.g. add_exception_modal & edit_exception_modal), +// the apolloClient will perform queryDeduplication and prevent the first query from executing. A deep compare is not +// performed on `indices`, so another field must be passed to circumvent this. +// For details, see https://github.com/apollographql/react-apollo/issues/2202 +export const useFetchIndexPatterns = ( + defaultIndices: string[] = [], + queryDeduplication?: string +): Return => { const apolloClient = useApolloClient(); const [indices, setIndices] = useState(defaultIndices); @@ -74,6 +81,7 @@ export const useFetchIndexPatterns = (defaultIndices: string[] = []): Return => variables: { sourceId: 'default', defaultIndex: indices, + ...(queryDeduplication != null ? { queryDeduplication } : {}), }, context: { fetchOptions: { From 6f405289ecd7fea77d08633ccfe85ddfffe96621 Mon Sep 17 00:00:00 2001 From: Andrew Cholakian Date: Tue, 21 Jul 2020 20:36:43 -0500 Subject: [PATCH 76/77] [Uptime] Rename Whitelist to Allowlist in parse_filter_map (#71584) Fixes https://github.com/elastic/kibana/issues/71583 Co-authored-by: Elastic Machine --- .../components/overview/filter_group/parse_filter_map.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/uptime/public/components/overview/filter_group/parse_filter_map.ts b/x-pack/plugins/uptime/public/components/overview/filter_group/parse_filter_map.ts index 08766521799ea..47c86543c1287 100644 --- a/x-pack/plugins/uptime/public/components/overview/filter_group/parse_filter_map.ts +++ b/x-pack/plugins/uptime/public/components/overview/filter_group/parse_filter_map.ts @@ -14,7 +14,7 @@ interface FilterField { * If your code needs to support custom fields, introduce a second parameter to * `parseFiltersMap` to take a list of FilterField objects. */ -const filterWhitelist: FilterField[] = [ +const filterAllowList: FilterField[] = [ { name: 'ports', fieldName: 'url.port' }, { name: 'locations', fieldName: 'observer.geo.name' }, { name: 'tags', fieldName: 'tags' }, @@ -28,7 +28,7 @@ export const parseFiltersMap = (filterMapString: string) => { const filterSlices: { [key: string]: any } = {}; try { const map = new Map(JSON.parse(filterMapString)); - filterWhitelist.forEach(({ name, fieldName }) => { + filterAllowList.forEach(({ name, fieldName }) => { filterSlices[name] = map.get(fieldName) ?? []; }); return filterSlices; From ad65b2ce34354b59f38b44da1c7d0dd01e0aedc9 Mon Sep 17 00:00:00 2001 From: Andrew Goldstein Date: Wed, 22 Jul 2020 00:12:13 -0600 Subject: [PATCH 77/77] [Security Solution] Hide KQL bar (all pages) and alerts filters (Detections) when Resolver is full screen (#72788) ## Summary Fixes an issue where the KQL bar (on all pages) and alerts filters (on the `Detections` page) should be hidden when Resolver is in full screen mode. **To reproduce:** 1) Navigate to the `Detections` page 2) Enter `agent.type : endpoint` in the KQL bar to only show endpoint alerts 3) Click the `Full screen` button in the detections table **Expected result** * The KQL bar, inspect button, alerts filters (`Open | In progress | Closed`), and `Showing n alerts`, `Select all n alerts`, and `Additional filters` actions are visible in full screen mode 4) Click the `Analyze event` button to show Resolver **Expected result** * The KQL bar, inspect button, alerts filters (`Open | In progress | Closed`), `Showing n alerts`, `Select all n alerts`, and `Additional filters` actions are **NOT** visible in full screen mode **when Resolver is open** **Actual result** * The KQL bar, inspect button, alerts filters (`Open | In progress | Closed`), `Showing n alerts`, `Select all n alerts`, and `Additional filters` actions are (incorrectly) visible in full screen mode, per the screenshot below: ![filters-in-full-screen-mode](https://user-images.githubusercontent.com/4459398/88079205-9f565b80-cb3a-11ea-996a-fb71bf43c473.png) 5) Click the `< Back to events` button **Expected result** * The KQL bar, inspect button, alerts filters (`Open | In progress | Closed`), `Showing n alerts`, `Select all n alerts`, and `Additional filters` actions become visible again 6) Press the `Esc` (Escape) key to exit Full screen mode **Expected result** * The KQL bar, inspect button, alerts filters (`Open | In progress | Closed`), `Showing n alerts`, `Select all n alerts`, and `Additional filters` actions are (still) visible ## Screenshot (fixed) The following screenshot of the fix was taken from the `Detections` page after following the reproduction steps above: ![filters-in-full-screen-mode-fixed](https://user-images.githubusercontent.com/4459398/88125154-e882cb80-cb8b-11ea-9b45-718fd9ef0844.png) --- .../cypress/integration/events_viewer.spec.ts | 2 +- .../events_viewer/events_viewer.test.tsx | 247 ++++++++++++++++++ .../events_viewer/events_viewer.tsx | 26 +- .../filters_global/filters_global.tsx | 19 +- .../components/header_section/index.test.tsx | 24 ++ .../alerts_filter_group/index.tsx | 2 +- .../detection_engine.test.tsx | 1 + .../detection_engine/detection_engine.tsx | 13 +- .../rules/details/index.test.tsx | 1 + .../detection_engine/rules/details/index.tsx | 13 +- .../public/hosts/pages/details/index.tsx | 193 ++++++++------ .../public/hosts/pages/hosts.tsx | 29 +- .../public/network/pages/network.tsx | 24 +- .../components/timeline/helpers.test.tsx | 42 ++- .../timelines/components/timeline/helpers.tsx | 11 + 15 files changed, 537 insertions(+), 110 deletions(-) diff --git a/x-pack/plugins/security_solution/cypress/integration/events_viewer.spec.ts b/x-pack/plugins/security_solution/cypress/integration/events_viewer.spec.ts index 84ca1e20e9576..cd4573817cc27 100644 --- a/x-pack/plugins/security_solution/cypress/integration/events_viewer.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/events_viewer.spec.ts @@ -153,7 +153,7 @@ describe('Events Viewer', () => { }); }); - context('Events columns', () => { + context.skip('Events columns', () => { before(() => { loginAndWaitForPage(HOSTS_URL); openEvents(); diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx index 049953e21febd..833688ae57993 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx @@ -15,11 +15,17 @@ import { wait as waitFor } from '@testing-library/react'; import { mockEventViewerResponse } from './mock'; import { StatefulEventsViewer } from '.'; +import { EventsViewer } from './events_viewer'; import { defaultHeaders } from './default_headers'; import { useFetchIndexPatterns } from '../../../detections/containers/detection_engine/rules/fetch_index_patterns'; import { mockBrowserFields, mockDocValueFields } from '../../containers/source/mock'; import { eventsDefaultModel } from './default_model'; import { useMountAppended } from '../../utils/use_mount_appended'; +import { inputsModel } from '../../store/inputs'; +import { TimelineId } from '../../../../common/types/timeline'; +import { KqlMode } from '../../../timelines/store/timeline/model'; +import { SortDirection } from '../../../timelines/components/timeline/body/sort'; +import { AlertsTableFilterGroup } from '../../../detections/components/alerts_table/alerts_filter_group'; jest.mock('../../components/url_state/normalize_time_range.ts'); @@ -40,6 +46,39 @@ const defaultMocks = { isLoading: false, }; +const utilityBar = (refetch: inputsModel.Refetch, totalCount: number) => ( +

    +); + +const eventsViewerDefaultProps = { + browserFields: {}, + columns: [], + dataProviders: [], + deletedEventIds: [], + docValueFields: [], + end: to, + filters: [], + id: TimelineId.detectionsPage, + indexPattern: mockIndexPattern, + isLive: false, + isLoadingIndexPattern: false, + itemsPerPage: 10, + itemsPerPageOptions: [], + kqlMode: 'filter' as KqlMode, + onChangeItemsPerPage: jest.fn(), + query: { + query: '', + language: 'kql', + }, + start: from, + sort: { + columnId: 'foo', + sortDirection: 'none' as SortDirection, + }, + toggleColumn: jest.fn(), + utilityBar, +}; + describe('EventsViewer', () => { const mount = useMountAppended(); @@ -213,4 +252,212 @@ describe('EventsViewer', () => { }); }); }); + + describe('headerFilterGroup', () => { + test('it renders the provided headerFilterGroup', async () => { + const wrapper = mount( + + + } + /> + + + ); + + await waitFor(() => { + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="alerts-table-filter-group"]`).exists()).toBe(true); + }); + }); + + test('it has a visible HeaderFilterGroupWrapper when Resolver is NOT showing, because graphEventId is undefined', async () => { + const wrapper = mount( + + + } + /> + + + ); + + await waitFor(() => { + wrapper.update(); + + expect( + wrapper.find(`[data-test-subj="header-filter-group-wrapper"]`).first() + ).not.toHaveStyleRule('visibility', 'hidden'); + }); + }); + + test('it has a visible HeaderFilterGroupWrapper when Resolver is NOT showing, because graphEventId is an empty string', async () => { + const wrapper = mount( + + + } + /> + + + ); + + await waitFor(() => { + wrapper.update(); + + expect( + wrapper.find(`[data-test-subj="header-filter-group-wrapper"]`).first() + ).not.toHaveStyleRule('visibility', 'hidden'); + }); + }); + + test('it does NOT have a visible HeaderFilterGroupWrapper when Resolver is showing, because graphEventId is a valid id', async () => { + const wrapper = mount( + + + } + /> + + + ); + + await waitFor(() => { + wrapper.update(); + + expect( + wrapper.find(`[data-test-subj="header-filter-group-wrapper"]`).first() + ).toHaveStyleRule('visibility', 'hidden'); + }); + }); + + test('it (still) renders an invisible headerFilterGroup (to maintain state while hidden) when Resolver is showing, because graphEventId is a valid id', async () => { + const wrapper = mount( + + + } + /> + + + ); + + await waitFor(() => { + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="alerts-table-filter-group"]`).exists()).toBe(true); + }); + }); + }); + + describe('utilityBar', () => { + test('it renders the provided utilityBar when Resolver is NOT showing, because graphEventId is undefined', async () => { + const wrapper = mount( + + + + + + ); + + await waitFor(() => { + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="mock-utility-bar"]`).exists()).toBe(true); + }); + }); + + test('it renders the provided utilityBar when Resolver is NOT showing, because graphEventId is an empty string', async () => { + const wrapper = mount( + + + + + + ); + + await waitFor(() => { + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="mock-utility-bar"]`).exists()).toBe(true); + }); + }); + + test('it does NOT render the provided utilityBar when Resolver is showing, because graphEventId is a valid id', async () => { + const wrapper = mount( + + + + + + ); + + await waitFor(() => { + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="mock-utility-bar"]`).exists()).toBe(false); + }); + }); + }); + + describe('header inspect button', () => { + test('it renders the inspect button when Resolver is NOT showing, because graphEventId is undefined', async () => { + const wrapper = mount( + + + + + + ); + + await waitFor(() => { + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="inspect-icon-button"]`).exists()).toBe(true); + }); + }); + + test('it renders the inspect button when Resolver is NOT showing, because graphEventId is an empty string', async () => { + const wrapper = mount( + + + + + + ); + + await waitFor(() => { + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="inspect-icon-button"]`).exists()).toBe(true); + }); + }); + + test('it does NOT render the inspect button when Resolver is showing, because graphEventId is a valid id', async () => { + const wrapper = mount( + + + + + + ); + + await waitFor(() => { + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="inspect-icon-button"]`).exists()).toBe(false); + }); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx index 3f474da102ca4..bc036b38524ba 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx @@ -22,7 +22,7 @@ import { StatefulBody } from '../../../timelines/components/timeline/body/statef import { DataProvider } from '../../../timelines/components/timeline/data_providers/data_provider'; import { OnChangeItemsPerPage } from '../../../timelines/components/timeline/events'; import { Footer, footerHeight } from '../../../timelines/components/timeline/footer'; -import { combineQueries } from '../../../timelines/components/timeline/helpers'; +import { combineQueries, resolverIsShowing } from '../../../timelines/components/timeline/helpers'; import { TimelineRefetch } from '../../../timelines/components/timeline/refetch_timeline'; import { EventDetailsWidthProvider } from './event_details_width_context'; import * as i18n from './translations'; @@ -73,6 +73,16 @@ const EventsContainerLoading = styled.div` overflow: auto; `; +/** + * Hides stateful headerFilterGroup implementations, but prevents the component + * from being unmounted, to preserve the state of the component + */ +const HeaderFilterGroupWrapper = styled.header<{ show: boolean }>` + ${({ show }) => css` + ${show ? '' : 'visibility: hidden;'}; + `} +`; + interface Props { browserFields: BrowserFields; columns: ColumnHeaderOptions[]; @@ -234,14 +244,21 @@ const EventsViewerComponent: React.FC = ({ return ( <> - {headerFilterGroup} + {headerFilterGroup && ( + + {headerFilterGroup} + + )} - {utilityBar && ( + {utilityBar && !resolverIsShowing(graphEventId) && ( {utilityBar?.(refetch, totalCountMinusDeleted)} )} @@ -307,6 +324,7 @@ export const EventsViewer = React.memo( prevProps.deletedEventIds === nextProps.deletedEventIds && prevProps.end === nextProps.end && deepEqual(prevProps.filters, nextProps.filters) && + prevProps.headerFilterGroup === nextProps.headerFilterGroup && prevProps.height === nextProps.height && prevProps.id === nextProps.id && deepEqual(prevProps.indexPattern, nextProps.indexPattern) && diff --git a/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx index 65901ec589daf..b52438486406e 100644 --- a/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx @@ -39,16 +39,27 @@ const Wrapper = styled.aside<{ isSticky?: boolean }>` `; Wrapper.displayName = 'Wrapper'; +const FiltersGlobalContainer = styled.header<{ show: boolean }>` + ${({ show }) => css` + ${show ? '' : 'display: none;'}; + `} +`; + +FiltersGlobalContainer.displayName = 'FiltersGlobalContainer'; + export interface FiltersGlobalProps { children: React.ReactNode; + show?: boolean; } -export const FiltersGlobal = React.memo(({ children }) => ( +export const FiltersGlobal = React.memo(({ children, show = true }) => ( {({ style, isSticky }) => ( - - {children} - + + + {children} + + )} )); diff --git a/x-pack/plugins/security_solution/public/common/components/header_section/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_section/index.test.tsx index b33ce22651d65..32f6216be63f2 100644 --- a/x-pack/plugins/security_solution/public/common/components/header_section/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_section/index.test.tsx @@ -131,4 +131,28 @@ describe('HeaderSection', () => { .exists() ).toBe(true); }); + + test('it renders an inspect button when an `id` is provided', () => { + const wrapper = mount( + + +

    {'Test children'}

    +
    +
    + ); + + expect(wrapper.find('[data-test-subj="inspect-icon-button"]').first().exists()).toBe(true); + }); + + test('it does NOT an inspect button when an `id` is NOT provided', () => { + const wrapper = mount( + + +

    {'Test children'}

    +
    +
    + ); + + expect(wrapper.find('[data-test-subj="inspect-icon-button"]').first().exists()).toBe(false); + }); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx index ba64868b70817..a227d2d3c3a8e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_filter_group/index.tsx @@ -36,7 +36,7 @@ const AlertsTableFilterGroupComponent: React.FC = ({ onFilterGroupChanged }, [setFilterGroup, onFilterGroupChanged]); return ( - + { = ({ filters, + graphEventId, query, setAbsoluteRangeDatePicker, }) => { @@ -151,7 +156,7 @@ export const DetectionEnginePageComponent: React.FC = ({ {indicesExist ? ( - + @@ -232,13 +237,19 @@ export const DetectionEnginePageComponent: React.FC = ({ const makeMapStateToProps = () => { const getGlobalInputs = inputsSelectors.globalSelector(); + const getTimeline = timelineSelectors.getTimelineByIdSelector(); return (state: State) => { const globalInputs: InputsRange = getGlobalInputs(state); const { query, filters } = globalInputs; + const timeline: TimelineModel = + getTimeline(state, TimelineId.detectionsPage) ?? timelineDefaults; + const { graphEventId } = timeline; + return { query, filters, + graphEventId, }; }; }; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx index a251c617e542a..5e6587dab1736 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx @@ -82,6 +82,7 @@ describe('RuleDetailsPageComponent', () => { { export const RuleDetailsPageComponent: FC = ({ filters, + graphEventId, query, setAbsoluteRangeDatePicker, }) => { @@ -351,7 +356,7 @@ export const RuleDetailsPageComponent: FC = ({ {indicesExist ? ( - + @@ -541,13 +546,19 @@ RuleDetailsPageComponent.displayName = 'RuleDetailsPageComponent'; const makeMapStateToProps = () => { const getGlobalInputs = inputsSelectors.globalSelector(); + const getTimeline = timelineSelectors.getTimelineByIdSelector(); return (state: State) => { const globalInputs: InputsRange = getGlobalInputs(state); const { query, filters } = globalInputs; + const timeline: TimelineModel = + getTimeline(state, TimelineId.detectionsRulesDetailsPage) ?? timelineDefaults; + const { graphEventId } = timeline; + return { query, filters, + graphEventId, }; }; }; diff --git a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx index 447d003625c8f..781aa711ff0d9 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; +import { EuiHorizontalRule, EuiSpacer, EuiWindowEvent } from '@elastic/eui'; +import { noop } from 'lodash/fp'; import React, { useEffect, useCallback, useMemo } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { StickyContainer } from 'react-sticky'; @@ -44,6 +45,13 @@ import { navTabsHostDetails } from './nav_tabs'; import { HostDetailsProps } from './types'; import { type } from './utils'; import { getHostDetailsPageFilters } from './helpers'; +import { showGlobalFilters } from '../../../timelines/components/timeline/helpers'; +import { useFullScreen } from '../../../common/containers/use_full_screen'; +import { Display } from '../display'; +import { timelineSelectors } from '../../../timelines/store/timeline'; +import { TimelineModel } from '../../../timelines/store/timeline/model'; +import { TimelineId } from '../../../../common/types/timeline'; +import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; const HostOverviewManage = manageQuery(HostOverview); const KpiHostDetailsManage = manageQuery(KpiHostsComponent); @@ -51,6 +59,7 @@ const KpiHostDetailsManage = manageQuery(KpiHostsComponent); const HostDetailsComponent = React.memo( ({ filters, + graphEventId, query, setAbsoluteRangeDatePicker, setHostDetailsTablesActivePageToZero, @@ -58,6 +67,7 @@ const HostDetailsComponent = React.memo( hostDetailsPagePath, }) => { const { to, from, deleteQuery, setQuery, isInitializing } = useGlobalTime(); + const { globalFullScreen } = useFullScreen(); useEffect(() => { setHostDetailsTablesActivePageToZero(); }, [setHostDetailsTablesActivePageToZero, detailName]); @@ -93,90 +103,93 @@ const HostDetailsComponent = React.memo( <> {indicesExist ? ( - + + - - - } - title={detailName} - /> - - - {({ hostOverview, loading, id, inspect, refetch }) => ( - - {({ isLoadingAnomaliesData, anomaliesData }) => ( - { - const fromTo = scoreIntervalToDateTime(score, interval); - setAbsoluteRangeDatePicker({ - id: 'global', - from: fromTo.from, - to: fromTo.to, - }); - }} - /> - )} - - )} - - - - - - {({ kpiHostDetails, id, inspect, loading, refetch }) => ( - - )} - - - - - - - + + + + } + title={detailName} + /> + + + {({ hostOverview, loading, id, inspect, refetch }) => ( + + {({ isLoadingAnomaliesData, anomaliesData }) => ( + { + const fromTo = scoreIntervalToDateTime(score, interval); + setAbsoluteRangeDatePicker({ + id: 'global', + from: fromTo.from, + to: fromTo.to, + }); + }} + /> + )} + + )} + + + + + + {({ kpiHostDetails, id, inspect, loading, refetch }) => ( + + )} + + + + + + + + { const getGlobalQuerySelector = inputsSelectors.globalQuerySelector(); const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); - return (state: State) => ({ - query: getGlobalQuerySelector(state), - filters: getGlobalFiltersQuerySelector(state), - }); + const getTimeline = timelineSelectors.getTimelineByIdSelector(); + return (state: State) => { + const timeline: TimelineModel = + getTimeline(state, TimelineId.hostsPageEvents) ?? timelineDefaults; + const { graphEventId } = timeline; + + return { + query: getGlobalQuerySelector(state), + filters: getGlobalFiltersQuerySelector(state), + graphEventId, + }; + }; }; const mapDispatchToProps = { diff --git a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx index a3885eac5377c..1219effa5ff6d 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx @@ -26,6 +26,7 @@ import { KpiHostsQuery } from '../containers/kpi_hosts'; import { useFullScreen } from '../../common/containers/use_full_screen'; import { useGlobalTime } from '../../common/containers/use_global_time'; import { useWithSource } from '../../common/containers/source'; +import { TimelineId } from '../../../common/types/timeline'; import { LastEventIndexKey } from '../../graphql/types'; import { useKibana } from '../../common/lib/kibana'; import { convertToBuildEsQuery } from '../../common/lib/keury'; @@ -44,11 +45,15 @@ import { HostsComponentProps } from './types'; import { filterHostData } from './navigation'; import { hostsModel } from '../store'; import { HostsTableType } from '../store/model'; +import { showGlobalFilters } from '../../timelines/components/timeline/helpers'; +import { timelineSelectors } from '../../timelines/store/timeline'; +import { timelineDefaults } from '../../timelines/store/timeline/defaults'; +import { TimelineModel } from '../../timelines/store/timeline/model'; const KpiHostsComponentManage = manageQuery(KpiHostsComponent); export const HostsComponent = React.memo( - ({ filters, query, setAbsoluteRangeDatePicker, hostsPagePath }) => { + ({ filters, graphEventId, query, setAbsoluteRangeDatePicker, hostsPagePath }) => { const { to, from, deleteQuery, setQuery, isInitializing } = useGlobalTime(); const { globalFullScreen } = useFullScreen(); const capabilities = useMlCapabilities(); @@ -93,7 +98,7 @@ export const HostsComponent = React.memo( {indicesExist ? ( - + @@ -167,10 +172,22 @@ HostsComponent.displayName = 'HostsComponent'; const makeMapStateToProps = () => { const getGlobalQuerySelector = inputsSelectors.globalQuerySelector(); const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); - const mapStateToProps = (state: State) => ({ - query: getGlobalQuerySelector(state), - filters: getGlobalFiltersQuerySelector(state), - }); + const getTimeline = timelineSelectors.getTimelineByIdSelector(); + const mapStateToProps = (state: State) => { + const hostsPageEventsTimeline: TimelineModel = + getTimeline(state, TimelineId.hostsPageEvents) ?? timelineDefaults; + const { graphEventId: hostsPageEventsGraphEventId } = hostsPageEventsTimeline; + + const hostsPageExternalAlertsTimeline: TimelineModel = + getTimeline(state, TimelineId.hostsPageExternalAlerts) ?? timelineDefaults; + const { graphEventId: hostsPageExternalAlertsGraphEventId } = hostsPageExternalAlertsTimeline; + + return { + query: getGlobalQuerySelector(state), + filters: getGlobalFiltersQuerySelector(state), + graphEventId: hostsPageEventsGraphEventId ?? hostsPageExternalAlertsGraphEventId, + }; + }; return mapStateToProps; }; diff --git a/x-pack/plugins/security_solution/public/network/pages/network.tsx b/x-pack/plugins/security_solution/public/network/pages/network.tsx index 0def110c45a14..ca8da4eb711e5 100644 --- a/x-pack/plugins/security_solution/public/network/pages/network.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/network.tsx @@ -41,6 +41,11 @@ import { OverviewEmpty } from '../../overview/components/overview_empty'; import * as i18n from './translations'; import { NetworkComponentProps } from './types'; import { NetworkRouteType } from './navigation/types'; +import { showGlobalFilters } from '../../timelines/components/timeline/helpers'; +import { timelineSelectors } from '../../timelines/store/timeline'; +import { TimelineId } from '../../../common/types/timeline'; +import { timelineDefaults } from '../../timelines/store/timeline/defaults'; +import { TimelineModel } from '../../timelines/store/timeline/model'; const KpiNetworkComponentManage = manageQuery(KpiNetworkComponent); const sourceId = 'default'; @@ -48,6 +53,7 @@ const sourceId = 'default'; const NetworkComponent = React.memo( ({ filters, + graphEventId, query, setAbsoluteRangeDatePicker, networkPagePath, @@ -100,7 +106,7 @@ const NetworkComponent = React.memo( {indicesExist ? ( - + @@ -189,10 +195,18 @@ NetworkComponent.displayName = 'NetworkComponent'; const makeMapStateToProps = () => { const getGlobalQuerySelector = inputsSelectors.globalQuerySelector(); const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); - const mapStateToProps = (state: State) => ({ - query: getGlobalQuerySelector(state), - filters: getGlobalFiltersQuerySelector(state), - }); + const getTimeline = timelineSelectors.getTimelineByIdSelector(); + const mapStateToProps = (state: State) => { + const timeline: TimelineModel = + getTimeline(state, TimelineId.networkPageExternalAlerts) ?? timelineDefaults; + const { graphEventId } = timeline; + + return { + query: getGlobalQuerySelector(state), + filters: getGlobalFiltersQuerySelector(state), + graphEventId, + }; + }; return mapStateToProps; }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.test.tsx index c371d1862be72..21b96dfe4118d 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.test.tsx @@ -9,7 +9,7 @@ import { mockIndexPattern } from '../../../common/mock'; import { DataProviderType } from './data_providers/data_provider'; import { mockDataProviders } from './data_providers/mock/mock_data_providers'; -import { buildGlobalQuery, combineQueries } from './helpers'; +import { buildGlobalQuery, combineQueries, resolverIsShowing, showGlobalFilters } from './helpers'; import { mockBrowserFields } from '../../../common/containers/source/mock'; import { EsQueryConfig, Filter, esFilters } from '../../../../../../../src/plugins/data/public'; @@ -500,4 +500,44 @@ describe('Combined Queries', () => { '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 1"}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 3"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"name":"Provider 4"}}],"minimum_should_match":1}}]}}]}},{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 2"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"name":"Provider 5"}}],"minimum_should_match":1}}]}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"host.name":"host-1"}}],"minimum_should_match":1}}]}}],"should":[],"must_not":[]}}' ); }); + + describe('resolverIsShowing', () => { + test('it returns true when graphEventId is NOT an empty string', () => { + expect(resolverIsShowing('a valid id')).toBe(true); + }); + + test('it returns false when graphEventId is undefined', () => { + expect(resolverIsShowing(undefined)).toBe(false); + }); + + test('it returns false when graphEventId is an empty string', () => { + expect(resolverIsShowing('')).toBe(false); + }); + }); + + describe('showGlobalFilters', () => { + test('it returns false when `globalFullScreen` is true and `graphEventId` is NOT an empty string, because Resolver IS showing', () => { + expect(showGlobalFilters({ globalFullScreen: true, graphEventId: 'a valid id' })).toBe(false); + }); + + test('it returns true when `globalFullScreen` is true and `graphEventId` is undefined, because Resolver is NOT showing', () => { + expect(showGlobalFilters({ globalFullScreen: true, graphEventId: undefined })).toBe(true); + }); + + test('it returns true when `globalFullScreen` is true and `graphEventId` is an empty string, because Resolver is NOT showing', () => { + expect(showGlobalFilters({ globalFullScreen: true, graphEventId: '' })).toBe(true); + }); + + test('it returns true when `globalFullScreen` is false and `graphEventId` is NOT an empty string, because Resolver IS showing', () => { + expect(showGlobalFilters({ globalFullScreen: false, graphEventId: 'a valid id' })).toBe(true); + }); + + test('it returns true when `globalFullScreen` is false and `graphEventId` is undefined, because Resolver is NOT showing', () => { + expect(showGlobalFilters({ globalFullScreen: false, graphEventId: undefined })).toBe(true); + }); + + test('it returns true when `globalFullScreen` is false and `graphEventId` is an empty string, because Resolver is NOT showing', () => { + expect(showGlobalFilters({ globalFullScreen: false, graphEventId: '' })).toBe(true); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx index b21ea3e4f86e9..84387720b5b11 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx @@ -158,3 +158,14 @@ export const combineQueries = ({ export const STATEFUL_EVENT_CSS_CLASS_NAME = 'event-column-view'; export const DEFAULT_ICON_BUTTON_WIDTH = 24; + +export const resolverIsShowing = (graphEventId: string | undefined): boolean => + graphEventId != null && graphEventId !== ''; + +export const showGlobalFilters = ({ + globalFullScreen, + graphEventId, +}: { + globalFullScreen: boolean; + graphEventId: string | undefined; +}): boolean => (globalFullScreen && resolverIsShowing(graphEventId) ? false : true);