Skip to content

Commit

Permalink
[Discover] Extend Elasticsearch query rule with search source based d…
Browse files Browse the repository at this point in the history
…ata fetching (#124534)

* [Discover] introduce .index-threshold rule

* [Discover] change filters in alert expression

* [Discover] fix cursor issue

* [Discover] add loading

* [Discover] separate validation params

* [Discover] add view alert route

* [Discover] enable "view in app" for alert created from discover

* [Discover] fix filter popover

* [Discover] fix linting, unit tests

* [Discover] fix remaining tests

* [Discover] add unit tests, add link back to stack management for es query

* Update src/plugins/discover/public/application/view_alert/view_alert_route.tsx

* [Discover] add tool tip for data view without time field

* [Discover] add info alert about possible document difference that triggered alert and displayed documents

* [Discover] update unit test

* [Discover] fix unit tests

* Update x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx

Co-authored-by: gchaps <[email protected]>

* Update x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type/alert_type.ts

Co-authored-by: gchaps <[email protected]>

* Update x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type/alert_type.ts

Co-authored-by: gchaps <[email protected]>

* Update x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type/alert_type.ts

Co-authored-by: gchaps <[email protected]>

* Update src/plugins/discover/public/application/main/components/top_nav/open_alerts_popover.tsx

Co-authored-by: gchaps <[email protected]>

* Update x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx

Co-authored-by: gchaps <[email protected]>

* [Discover] fix unit tests

* [Discover] fix security solution alerts

* [Discover] fix eslint errors

* [Discover] fix unit tests

* Update x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type/alert_type.ts

Co-authored-by: gchaps <[email protected]>

* Update x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type/alert_type.ts

Co-authored-by: gchaps <[email protected]>

* [Discover] apply suggestions

* [Discover] fix tests

* Update x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type/alert_type.ts

* [Discover] remove close button in filters

* Improve code structure

* Fix missing name in fetchEsQuery

* Fix messages

* Fix messages, again

* Refactor

* Refactor, add tests + a bit more of documentation

* Move size field, change text

* Implement readonly callout

* change icon in callout

* add padding to popover

* Hide query and filter UI if there are no values to display

* [Discover] add unit test, improve comparator types

* [Discover] fix linting and unit test

* [Discover] add es query alert integration tests

* [Discover] fix linting

* [Discover] uncomment one expect

* [Discover] fix latesTimestamp for searchSource type, unify test logic

* Update x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx

Co-authored-by: gchaps <[email protected]>

* [Discover] apply suggestions

* [Discover] make searchType optional, adjust tests

* [Discover] remove updated translations

* [Discover] apply suggestions

* [Discover] fix unit test

* [Discover] close popover on alert rule creation

* [Discover] apply suggestions

* [Discover] add first functional test

* [Discover] implement tests

* Move functionals x-pack since ssl is needed

* Fix potential flakiness in functional test

* [Discover] remove timeout waiter

* Fix functional test

- adding permissions to fix the functional

* [Discover] add logger

* [Discover] add more log points

* [Discover] wait for indices creation finished

* Try to fix the functional flakiness
- by creating data views in a serial way
- lets see if that work

Co-authored-by: gchaps <[email protected]>
Co-authored-by: Matthias Wilhelm <[email protected]>
Co-authored-by: andreadelrio <[email protected]>
  • Loading branch information
4 people authored Apr 1, 2022
1 parent f9d83f9 commit 0427952
Show file tree
Hide file tree
Showing 84 changed files with 3,560 additions and 1,287 deletions.
7 changes: 6 additions & 1 deletion src/plugins/data/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ export * from './deprecated';

export { getEsQueryConfig, FilterStateStore } from '../common';
export { FilterLabel, FilterItem } from './ui';
export { getDisplayValueFromFilter, generateFilters, extractTimeRange } from './query';
export {
getDisplayValueFromFilter,
generateFilters,
extractTimeRange,
getIndexPatternFromFilter,
} from './query';

/**
* Exporters (CSV)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,8 @@
.globalFilterItem__popoverAnchor {
display: block;
}

.globalFilterItem__readonlyPanel {
min-width: auto;
padding: $euiSizeM;
}
2 changes: 1 addition & 1 deletion src/plugins/data/public/ui/filter_bar/filter_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { IDataPluginServices, IIndexPattern } from '../..';

import { UI_SETTINGS } from '../../../common';

interface Props {
export interface Props {
filters: Filter[];
onFiltersUpdated?: (filters: Filter[]) => void;
className: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@ export interface FilterLabelProps {
filter: Filter;
valueLabel?: string;
filterLabelStatus?: FilterLabelStatus;
hideAlias?: boolean;
}

// Needed for React.lazy
// eslint-disable-next-line import/no-default-export
export default function FilterLabel({ filter, valueLabel, filterLabelStatus }: FilterLabelProps) {
export default function FilterLabel({
filter,
valueLabel,
filterLabelStatus,
hideAlias,
}: FilterLabelProps) {
const prefixText = filter.meta.negate
? ` ${i18n.translate('data.filter.filterBar.negatedFilterPrefix', {
defaultMessage: 'NOT ',
Expand All @@ -38,7 +44,7 @@ export default function FilterLabel({ filter, valueLabel, filterLabelStatus }: F
return <span className="globalFilterLabel__value">{text}</span>;
};

if (filter.meta.alias !== null) {
if (!hideAlias && filter.meta.alias !== null) {
return (
<Fragment>
{prefix}
Expand Down
67 changes: 41 additions & 26 deletions src/plugins/data/public/ui/filter_bar/filter_item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import { EuiContextMenu, EuiPopover } from '@elastic/eui';
import { EuiContextMenu, EuiPopover, EuiPopoverProps } from '@elastic/eui';
import { InjectedIntl } from '@kbn/i18n-react';
import {
Filter,
Expand All @@ -16,7 +16,7 @@ import {
toggleFilterDisabled,
} from '@kbn/es-query';
import classNames from 'classnames';
import React, { MouseEvent, useState, useEffect } from 'react';
import React, { MouseEvent, useState, useEffect, HTMLAttributes } from 'react';
import { IUiSettingsClient } from 'src/core/public';
import { FilterEditor } from './filter_editor';
import { FilterView } from './filter_view';
Expand All @@ -37,8 +37,11 @@ export interface FilterItemProps {
uiSettings: IUiSettingsClient;
hiddenPanelOptions?: PanelOptions[];
timeRangeForSuggestionsOverride?: boolean;
readonly?: boolean;
}

type FilterPopoverProps = HTMLAttributes<HTMLDivElement> & EuiPopoverProps;

interface LabelOptions {
title: string;
status: FilterLabelStatus;
Expand Down Expand Up @@ -349,32 +352,44 @@ export function FilterItem(props: FilterItemProps) {
return null;
}

const badge = (
<FilterView
filter={filter}
valueLabel={valueLabelConfig.title}
filterLabelStatus={valueLabelConfig.status}
errorMessage={valueLabelConfig.message}
className={getClasses(filter.meta.negate ?? false, valueLabelConfig)}
iconOnClick={() => props.onRemove()}
onClick={handleBadgeClick}
data-test-subj={getDataTestSubj(valueLabelConfig)}
/>
);
const filterViewProps = {
filter,
valueLabel: valueLabelConfig.title,
filterLabelStatus: valueLabelConfig.status,
errorMessage: valueLabelConfig.message,
className: getClasses(!!filter.meta.negate, valueLabelConfig),
iconOnClick: props.onRemove,
onClick: handleBadgeClick,
'data-test-subj': getDataTestSubj(valueLabelConfig),
readonly: props.readonly,
};

const popoverProps: FilterPopoverProps = {
id: `popoverFor_filter${id}`,
className: `globalFilterItem__popover`,
anchorClassName: `globalFilterItem__popoverAnchor`,
isOpen: isPopoverOpen,
closePopover: () => {
setIsPopoverOpen(false);
},
button: <FilterView {...filterViewProps} />,
panelPaddingSize: 'none',
};

if (props.readonly) {
return (
<EuiPopover
panelClassName="globalFilterItem__readonlyPanel"
anchorPosition="upCenter"
{...popoverProps}
>
<FilterView {...filterViewProps} hideAlias />
</EuiPopover>
);
}

return (
<EuiPopover
id={`popoverFor_filter${id}`}
className={`globalFilterItem__popover`}
anchorClassName={`globalFilterItem__popoverAnchor`}
isOpen={isPopoverOpen}
closePopover={() => {
setIsPopoverOpen(false);
}}
button={badge}
anchorPosition="downLeft"
panelPaddingSize="none"
>
<EuiPopover anchorPosition="downLeft" {...popoverProps}>
<EuiContextMenu initialPanelId={0} panels={getPanels()} />
</EuiPopover>
);
Expand Down
60 changes: 38 additions & 22 deletions src/plugins/data/public/ui/filter_bar/filter_view/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import { EuiBadge, useInnerText } from '@elastic/eui';
import { EuiBadge, EuiBadgeProps, useInnerText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { FC } from 'react';
import { Filter, isFilterPinned } from '@kbn/es-query';
Expand All @@ -18,6 +18,8 @@ interface Props {
valueLabel: string;
filterLabelStatus: FilterLabelStatus;
errorMessage?: string;
readonly?: boolean;
hideAlias?: boolean;
[propName: string]: any;
}

Expand All @@ -28,6 +30,8 @@ export const FilterView: FC<Props> = ({
valueLabel,
errorMessage,
filterLabelStatus,
readonly,
hideAlias,
...rest
}: Props) => {
const [ref, innerText] = useInnerText();
Expand All @@ -50,33 +54,45 @@ export const FilterView: FC<Props> = ({
})} ${title}`;
}

const badgeProps: EuiBadgeProps = readonly
? {
title,
color: 'hollow',
onClick,
onClickAriaLabel: i18n.translate('data.filter.filterBar.filterItemReadOnlyBadgeAriaLabel', {
defaultMessage: 'Filter entry',
}),
iconOnClick,
}
: {
title,
color: 'hollow',
iconType: 'cross',
iconSide: 'right',
closeButtonProps: {
// Removing tab focus on close button because the same option can be obtained through the context menu
// Also, we may want to add a `DEL` keyboard press functionality
tabIndex: -1,
},
iconOnClick,
iconOnClickAriaLabel: i18n.translate('data.filter.filterBar.filterItemBadgeIconAriaLabel', {
defaultMessage: 'Delete {filter}',
values: { filter: innerText },
}),
onClick,
onClickAriaLabel: i18n.translate('data.filter.filterBar.filterItemBadgeAriaLabel', {
defaultMessage: 'Filter actions',
}),
};

return (
<EuiBadge
title={title}
color="hollow"
iconType="cross"
iconSide="right"
closeButtonProps={{
// Removing tab focus on close button because the same option can be obtained through the context menu
// Also, we may want to add a `DEL` keyboard press functionality
tabIndex: -1,
}}
iconOnClick={iconOnClick}
iconOnClickAriaLabel={i18n.translate('data.filter.filterBar.filterItemBadgeIconAriaLabel', {
defaultMessage: 'Delete {filter}',
values: { filter: innerText },
})}
onClick={onClick}
onClickAriaLabel={i18n.translate('data.filter.filterBar.filterItemBadgeAriaLabel', {
defaultMessage: 'Filter actions',
})}
{...rest}
>
<EuiBadge {...badgeProps} {...rest}>
<span ref={ref}>
<FilterLabel
filter={filter}
valueLabel={valueLabel}
filterLabelStatus={filterLabelStatus}
hideAlias={hideAlias}
/>
</span>
</EuiBadge>
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/discover/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"dataViewFieldEditor",
"dataViewEditor"
],
"optionalPlugins": ["home", "share", "usageCollection", "spaces"],
"optionalPlugins": ["home", "share", "usageCollection", "spaces", "triggersActionsUi"],
"requiredBundles": ["kibanaUtils", "home", "kibanaReact", "dataViews"],
"extraPublicDirs": ["common"],
"owner": {
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/discover/public/application/discover_router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { SingleDocRoute } from './doc';
import { DiscoverMainRoute } from './main';
import { NotFoundRoute } from './not_found';
import { DiscoverServices } from '../build_services';
import { ViewAlertRoute } from './view_alert';

export const discoverRouter = (services: DiscoverServices, history: History) => (
<KibanaContextProvider services={services}>
Expand All @@ -36,6 +37,9 @@ export const discoverRouter = (services: DiscoverServices, history: History) =>
<Route path="/doc/:indexPatternId/:index">
<SingleDocRoute />
</Route>
<Route path="/viewAlert/:id">
<ViewAlertRoute />
</Route>
<Route path="/view/:id">
<DiscoverMainRoute />
</Route>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { onSaveSearch } from './on_save_search';
import { GetStateReturn } from '../../services/discover_state';
import { openOptionsPopover } from './open_options_popover';
import type { TopNavMenuData } from '../../../../../../navigation/public';
import { openAlertsPopover } from './open_alerts_popover';

/**
* Helper function to build the top nav links
Expand Down Expand Up @@ -59,6 +60,25 @@ export const getTopNavLinks = ({
testId: 'discoverOptionsButton',
};

const alerts = {
id: 'alerts',
label: i18n.translate('discover.localMenu.localMenu.alertsTitle', {
defaultMessage: 'Alerts',
}),
description: i18n.translate('discover.localMenu.alertsDescription', {
defaultMessage: 'Alerts',
}),
run: (anchorElement: HTMLElement) => {
openAlertsPopover({
I18nContext: services.core.i18n.Context,
anchorElement,
searchSource: savedSearch.searchSource,
services,
});
},
testId: 'discoverAlertsButton',
};

const newSearch = {
id: 'new',
label: i18n.translate('discover.localMenu.localMenu.newSearchTitle', {
Expand Down Expand Up @@ -162,6 +182,7 @@ export const getTopNavLinks = ({
...(services.capabilities.advancedSettings.save ? [options] : []),
newSearch,
openSearch,
...(services.triggersActionsUi ? [alerts] : []),
shareSearch,
inspectSearch,
...(services.capabilities.discover.save ? [saveSearch] : []),
Expand Down
Loading

0 comments on commit 0427952

Please sign in to comment.