From 8b5f3248b7df5f0236cd1693bb61b22f8c7cc56e Mon Sep 17 00:00:00 2001 From: Paul Sebastian Date: Tue, 24 Oct 2023 13:44:07 -0700 Subject: [PATCH 1/7] config panel dark mode fix (#1169) Signed-off-by: Paul Sebastian --- .../explorer/visualizations/config_panel/config_panel.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/components/event_analytics/explorer/visualizations/config_panel/config_panel.scss b/public/components/event_analytics/explorer/visualizations/config_panel/config_panel.scss index 8e0032e9f5..23028f83a2 100644 --- a/public/components/event_analytics/explorer/visualizations/config_panel/config_panel.scss +++ b/public/components/event_analytics/explorer/visualizations/config_panel/config_panel.scss @@ -204,4 +204,9 @@ $vis-editor-sidebar-min-width: 350px; .panel_section, .cp__rightHeader { border-bottom: 1px solid $border-color-on-dark; } + + .panelItem_box { + color: #8D98A3; + background-color: #293847; + } } \ No newline at end of file From acb0c7805f1ee6b4effb45c8e688b639d38953e1 Mon Sep 17 00:00:00 2001 From: "opensearch-trigger-bot[bot]" <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:01:06 -0700 Subject: [PATCH 2/7] Fix events home table and toast life time (#1170) (#1174) * Fix 2.11 UX issues * Change toast time life * update snapshots --------- (cherry picked from commit a9b36fc7eadddc484c856a6bb66803bbc9cea40b) Signed-off-by: Kavitha Conjeevaram Mohan Signed-off-by: github-actions[bot] Co-authored-by: github-actions[bot] --- .../components/event_analytics/explorer/explorer.tsx | 4 ++-- .../__snapshots__/saved_query_table.test.tsx.snap | 8 ++++---- .../event_analytics/home/saved_objects_table.tsx | 2 +- public/components/event_analytics/index.tsx | 12 ++++++++++-- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/public/components/event_analytics/explorer/explorer.tsx b/public/components/event_analytics/explorer/explorer.tsx index 12b9b306f3..d311cdcc1b 100644 --- a/public/components/event_analytics/explorer/explorer.tsx +++ b/public/components/event_analytics/explorer/explorer.tsx @@ -794,7 +794,7 @@ export const Explorer = ({ setLiveTailName(name); setLiveTailTabId((curSelectedTabId.current as unknown) as string); setIsLiveTailOn(true); - setToast('Live tail On', 'success'); + setToast('Live tail On', 'success', '', 'right', 2000); setIsLiveTailPopoverOpen(false); setLiveTimestamp( dateMath.parse(endingTime, { roundUp: true })?.utc().format(DATE_PICKER_FORMAT) || '' @@ -819,7 +819,7 @@ export const Explorer = ({ setIsLiveTailOn(false); setLiveHits(0); setIsLiveTailPopoverOpen(false); - if (isLiveTailOnRef.current) setToast('Live tail Off', 'danger'); + if (isLiveTailOnRef.current) setToast('Live tail Off', 'danger', '', 'right', 2000); }; useEffect(() => { diff --git a/public/components/event_analytics/home/__tests__/__snapshots__/saved_query_table.test.tsx.snap b/public/components/event_analytics/home/__tests__/__snapshots__/saved_query_table.test.tsx.snap index c8cb713279..5cd192bb4c 100644 --- a/public/components/event_analytics/home/__tests__/__snapshots__/saved_query_table.test.tsx.snap +++ b/public/components/event_analytics/home/__tests__/__snapshots__/saved_query_table.test.tsx.snap @@ -144,7 +144,7 @@ exports[`Saved query table component Renders saved query table 1`] = ` "filters": Array [ Object { "field": "type", - "multiSelect": false, + "multiSelect": "or", "name": "Type", "options": Array [ Object { @@ -186,7 +186,7 @@ exports[`Saved query table component Renders saved query table 1`] = ` Array [ Object { "field": "type", - "multiSelect": false, + "multiSelect": "or", "name": "Type", "options": Array [ Object { @@ -334,7 +334,7 @@ exports[`Saved query table component Renders saved query table 1`] = ` Array [ Object { "field": "type", - "multiSelect": false, + "multiSelect": "or", "name": "Type", "options": Array [ Object { @@ -386,7 +386,7 @@ exports[`Saved query table component Renders saved query table 1`] = ` config={ Object { "field": "type", - "multiSelect": false, + "multiSelect": "or", "name": "Type", "options": Array [ Object { diff --git a/public/components/event_analytics/home/saved_objects_table.tsx b/public/components/event_analytics/home/saved_objects_table.tsx index fbf761d907..79c76c4ecc 100644 --- a/public/components/event_analytics/home/saved_objects_table.tsx +++ b/public/components/event_analytics/home/saved_objects_table.tsx @@ -116,7 +116,7 @@ export function SavedQueryTable({ type: 'field_value_selection', field: 'type', name: 'Type', - multiSelect: false, + multiSelect: 'or', options: FILTER_OPTIONS.map((i) => ({ value: i, name: i, diff --git a/public/components/event_analytics/index.tsx b/public/components/event_analytics/index.tsx index 8158765990..585bfead98 100644 --- a/public/components/event_analytics/index.tsx +++ b/public/components/event_analytics/index.tsx @@ -31,15 +31,23 @@ export const EventAnalytics = ({ ...props }: EventAnalyticsProps) => { const [toasts, setToasts] = useState([]); + const [toastLifeTime, setToastLifeTime] = useState(6000); const eventAnalyticsBreadcrumb = { text: 'Logs', href: '#/', }; - const setToast = (title: string, color = 'success', text?: ReactChild, side?: string) => { + const setToast = ( + title: string, + color = 'success', + text?: ReactChild, + side?: string, + toastLifeTimeMs?: number + ) => { if (!text) text = ''; setToasts([...toasts, { id: new Date().toISOString(), title, text, color } as Toast]); + if (toastLifeTimeMs) setToastLifeTime(toastLifeTimeMs); }; return ( @@ -49,7 +57,7 @@ export const EventAnalytics = ({ dismissToast={(removedToast) => { setToasts(toasts.filter((toast) => toast.id !== removedToast.id)); }} - toastLifeTimeMs={6000} + toastLifeTimeMs={toastLifeTime} /> From a6c03339966ee986bb5330232095da9ef0142e58 Mon Sep 17 00:00:00 2001 From: Eric Wei Date: Tue, 24 Oct 2023 14:09:22 -0700 Subject: [PATCH 3/7] [Explorer] Modify text in empty prompt (#1172) * remove unused files Signed-off-by: Eric Wei * missing snapshots Signed-off-by: Eric Wei * remove unused files Signed-off-by: Eric Wei * adjust text on empty prompt Signed-off-by: Eric * add snapshots Signed-off-by: Eric --------- Signed-off-by: Eric Wei Signed-off-by: Eric --- .../__tests__/__snapshots__/no_results.test.tsx.snap | 12 ++++-------- .../event_analytics/explorer/no_results.tsx | 6 ++---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/public/components/event_analytics/__tests__/__snapshots__/no_results.test.tsx.snap b/public/components/event_analytics/__tests__/__snapshots__/no_results.test.tsx.snap index 97a94028cb..3e23d7126c 100644 --- a/public/components/event_analytics/__tests__/__snapshots__/no_results.test.tsx.snap +++ b/public/components/event_analytics/__tests__/__snapshots__/no_results.test.tsx.snap @@ -106,27 +106,23 @@ exports[`No result component Renders No result component 1`] = ` data-test-subj="obsNoResultsTimefilter" > - Expand your time range or modify your query + Select a data source, expand your time range, or modify the query

- Your query may not match anything in the current time range, - or there may not be any data at all in the currently selected time range. - Try change time range, query filters or choose different time fields. + After selection, check the time range, query filters, fields, and query

diff --git a/public/components/event_analytics/explorer/no_results.tsx b/public/components/event_analytics/explorer/no_results.tsx index 14ee3a5733..d6c96af865 100644 --- a/public/components/event_analytics/explorer/no_results.tsx +++ b/public/components/event_analytics/explorer/no_results.tsx @@ -30,15 +30,13 @@ export const NoResults = () => {

From 365a2fdf990e756d7772bf79fcefb1672566dcfd Mon Sep 17 00:00:00 2001 From: Eric Wei Date: Tue, 24 Oct 2023 20:42:50 -0700 Subject: [PATCH 4/7] [Explorer] Supports session for s3 direct query (#1178) * remove unused files Signed-off-by: Eric Wei * missing snapshots Signed-off-by: Eric Wei * remove unused files Signed-off-by: Eric Wei * supports session id for direct query Signed-off-by: Eric * update snapshots Signed-off-by: Eric * remove logging Signed-off-by: Eric --------- Signed-off-by: Eric Wei Signed-off-by: Eric --- common/constants/data_sources.ts | 5 +++ common/constants/shared.ts | 4 ++ common/types/explorer.ts | 7 +++ common/utils/query_session_utils.ts | 16 +++++++ common/utils/shared.ts | 8 ++++ .../components/common/search/sql_search.tsx | 29 +++++++----- .../datasources/datasources_selection.tsx | 44 ++++++++++++++++++- public/services/requests/sql.ts | 11 +---- .../routes/datasources/datasources_router.ts | 1 + 9 files changed, 104 insertions(+), 21 deletions(-) create mode 100644 common/utils/query_session_utils.ts create mode 100644 common/utils/shared.ts diff --git a/common/constants/data_sources.ts b/common/constants/data_sources.ts index aa596ad108..ad5c0cfdf4 100644 --- a/common/constants/data_sources.ts +++ b/common/constants/data_sources.ts @@ -14,3 +14,8 @@ export const enum QUERY_LANGUAGE { SQL = 'SQL', DQL = 'DQL', } +export enum DATA_SOURCE_TYPES { + DEFAULT_CLUSTER_TYPE = DEFAULT_DATA_SOURCE_TYPE, + SPARK = 'spark', + S3Glue = 's3glue', +} diff --git a/common/constants/shared.ts b/common/constants/shared.ts index 198ce05a33..2116454852 100644 --- a/common/constants/shared.ts +++ b/common/constants/shared.ts @@ -246,3 +246,7 @@ export const VISUALIZATION_ERROR = { }; export const S3_DATASOURCE_TYPE = 'S3_DATASOURCE'; + +export const ASYNC_QUERY_SESSION_ID = 'async-query-session-id'; + +export const DIRECT_DUMMY_QUERY = 'select 1'; diff --git a/common/types/explorer.ts b/common/types/explorer.ts index a36dd81a8d..9daf690743 100644 --- a/common/types/explorer.ts +++ b/common/types/explorer.ts @@ -427,3 +427,10 @@ export enum DirectQueryLoadingStatus { SCHEDULED = 'SCHEDULED', CANCELED = 'CANCELED', } + +export interface DirectQueryRequest { + query: string; + lang: string; + datasource: string; + sessionId?: string; +} diff --git a/common/utils/query_session_utils.ts b/common/utils/query_session_utils.ts new file mode 100644 index 0000000000..ad0e0a1afb --- /dev/null +++ b/common/utils/query_session_utils.ts @@ -0,0 +1,16 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ASYNC_QUERY_SESSION_ID } from '../constants/shared'; + +export const setAsyncSessionId = (value: string | null) => { + if (value !== null) { + sessionStorage.setItem(ASYNC_QUERY_SESSION_ID, value); + } +}; + +export const getAsyncSessionId = () => { + return sessionStorage.getItem(ASYNC_QUERY_SESSION_ID); +}; diff --git a/common/utils/shared.ts b/common/utils/shared.ts new file mode 100644 index 0000000000..a6f226a6dd --- /dev/null +++ b/common/utils/shared.ts @@ -0,0 +1,8 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export function get(obj: Record, path: string, defaultValue?: T): T { + return path.split('.').reduce((acc: any, part: string) => acc && acc[part], obj) || defaultValue; +} diff --git a/public/components/common/search/sql_search.tsx b/public/components/common/search/sql_search.tsx index 5a0b18ae73..0ba84061d4 100644 --- a/public/components/common/search/sql_search.tsx +++ b/public/components/common/search/sql_search.tsx @@ -18,11 +18,11 @@ import { EuiPopoverFooter, EuiToolTip, } from '@elastic/eui'; -import { isEqual, lowerCase } from 'lodash'; +import { isEqual } from 'lodash'; import React, { useEffect, useState } from 'react'; import { batch, useDispatch, useSelector } from 'react-redux'; import { APP_ANALYTICS_TAB_ID_REGEX, RAW_QUERY } from '../../../../common/constants/explorer'; -import { DirectQueryLoadingStatus } from '../../../../common/types/explorer'; +import { DirectQueryLoadingStatus, DirectQueryRequest } from '../../../../common/types/explorer'; import { PPL_NEWLINE_REGEX, PPL_SPAN_REGEX } from '../../../../common/constants/shared'; import { uiSettingsService } from '../../../../common/utils'; import { useFetchEvents } from '../../../components/event_analytics/hooks'; @@ -38,6 +38,8 @@ import { PPLReferenceFlyout } from '../helpers'; import { Autocomplete } from './autocomplete'; import { changeQuery } from '../../../components/event_analytics/redux/slices/query_slice'; import { QUERY_LANGUAGE } from '../../../../common/constants/data_sources'; +import { getAsyncSessionId, setAsyncSessionId } from '../../../../common/utils/query_session_utils'; +import { get as getObjValue } from '../../../../common/utils/shared'; export interface IQueryBarProps { query: string; tempQuery: string; @@ -101,7 +103,7 @@ export const DirectSearch = (props: any) => { stopPolling, } = usePolling((params) => { return sqlService.fetchWithJobId(params); - }, 5000); + }, 2000); const requestParams = { tabId }; const { dispatchOnGettingHis } = useFetchEvents({ @@ -190,13 +192,21 @@ export const DirectSearch = (props: any) => { ); }); dispatch(updateSearchMetaData({ tabId, data: { isPolling: true, lang } })); + const sessionId = getAsyncSessionId(); + const requestPayload = { + lang: lang.toLowerCase(), + query: tempQuery || query, + datasource: explorerSearchMetadata.datasources[0].label, + } as DirectQueryRequest; + + if (sessionId) { + requestPayload.sessionId = sessionId; + } + sqlService - .fetch({ - lang: lowerCase(lang), - query: tempQuery || query, - datasource: explorerSearchMetadata.datasources[0].name, - }) + .fetch(requestPayload) .then((result) => { + setAsyncSessionId(getObjValue(result, 'sessionId', null)); if (result.queryId) { startPolling({ queryId: result.queryId, @@ -208,8 +218,7 @@ export const DirectSearch = (props: any) => { .catch((e) => { setIsQueryRunning(false); console.error(e); - }) - .finally(() => {}); + }); }; useEffect(() => { diff --git a/public/components/event_analytics/explorer/datasources/datasources_selection.tsx b/public/components/event_analytics/explorer/datasources/datasources_selection.tsx index bbea0a6282..3c6e34df1f 100644 --- a/public/components/event_analytics/explorer/datasources/datasources_selection.tsx +++ b/public/components/event_analytics/explorer/datasources/datasources_selection.tsx @@ -23,7 +23,7 @@ import { reset as resetQueryResults } from '../../redux/slices/query_result_slic import { reset as resetVisualization } from '../../redux/slices/visualization_slice'; import { reset as resetVisConfig } from '../../redux/slices/viualization_config_slice'; import { reset as resetQuery } from '../../redux/slices/query_slice'; -import { SelectedDataSource } from '../../../../../common/types/explorer'; +import { DirectQueryRequest, SelectedDataSource } from '../../../../../common/types/explorer'; import { ObservabilityDefaultDataSource } from '../../../../framework/datasources/obs_opensearch_datasource'; import { DATA_SOURCE_TYPE_URL_PARAM_KEY, @@ -32,7 +32,16 @@ import { DEFAULT_DATA_SOURCE_TYPE, DEFAULT_DATA_SOURCE_TYPE_NAME, DEFAULT_DATA_SOURCE_OBSERVABILITY_DISPLAY_NAME, + DATA_SOURCE_TYPES, + QUERY_LANGUAGE, } from '../../../../../common/constants/data_sources'; +import { SQLService } from '../../../../services/requests/sql'; +import { get as getObjValue } from '../../../../../common/utils/shared'; +import { + setAsyncSessionId, + getAsyncSessionId, +} from '../../../../../common/utils/query_session_utils'; +import { DIRECT_DUMMY_QUERY } from '../../../../../common/constants/shared'; const getDataSourceState = (selectedSourceState: SelectedDataSource[]) => { if (selectedSourceState.length === 0) return []; @@ -70,7 +79,8 @@ const removeDataSourceFromURLParams = (currURL: string) => { }; export const DataSourceSelection = ({ tabId }: { tabId: string }) => { - const { dataSources } = coreRefs; + const { dataSources, http } = coreRefs; + const sqlService = new SQLService(http!); const dispatch = useDispatch(); const routerContext = useContext(LogExplorerRouterContext); const explorerSearchMetadata = useSelector(selectSearchMetaData)[tabId]; @@ -109,6 +119,23 @@ export const DataSourceSelection = ({ tabId }: { tabId: string }) => { setSelectedSources(selectedSource); }; + const runDummyQuery = (dataSource: string) => { + const requestPayload = { + lang: QUERY_LANGUAGE.SQL.toLowerCase(), + query: DIRECT_DUMMY_QUERY, + datasource: dataSource, + } as DirectQueryRequest; + + sqlService + .fetch(requestPayload) + .then((result) => { + setAsyncSessionId(getObjValue(result, 'sessionId', null)); + }) + .catch((e) => { + console.error(e); + }); + }; + useEffect(() => { setSelectedSources(getDataSourceState(explorerSearchMetadata.datasources)); }, [explorerSearchMetadata.datasources]); @@ -166,6 +193,19 @@ export const DataSourceSelection = ({ tabId }: { tabId: string }) => { } }, []); + useEffect(() => { + // Execute a dummy query to initialize the cluster and obtain a sessionId for subsequent queries. + const dsType = explorerSearchMetadata.datasources?.[0]?.type; + const dsName = explorerSearchMetadata.datasources?.[0]?.label; + if ( + !getAsyncSessionId() && + [DATA_SOURCE_TYPES.SPARK, DATA_SOURCE_TYPES.S3Glue].includes(dsType) && + dsName + ) { + runDummyQuery(dsName); + } + }, [explorerSearchMetadata.datasources]); + /** * Process the data source options to display different than discover's group names. * Temporary solution for version 2.11. diff --git a/public/services/requests/sql.ts b/public/services/requests/sql.ts index e87d4d7267..2073804ad8 100644 --- a/public/services/requests/sql.ts +++ b/public/services/requests/sql.ts @@ -4,7 +4,7 @@ */ import { CoreStart } from '../../../../../src/core/public'; -import { PPL_BASE, PPL_SEARCH } from '../../../common/constants/shared'; +import { DirectQueryRequest } from '../../../common/types/explorer'; export class SQLService { private http; @@ -12,14 +12,7 @@ export class SQLService { this.http = http; } - fetch = async ( - params: { - query: string; - lang: string; - datasource: string; - }, - errorHandler?: (error: any) => void - ) => { + fetch = async (params: DirectQueryRequest, errorHandler?: (error: any) => void) => { return this.http .post('/api/observability/query/jobs', { body: JSON.stringify(params), diff --git a/server/routes/datasources/datasources_router.ts b/server/routes/datasources/datasources_router.ts index eb8d6a635c..45279ccf76 100644 --- a/server/routes/datasources/datasources_router.ts +++ b/server/routes/datasources/datasources_router.ts @@ -16,6 +16,7 @@ export function registerDatasourcesRoute(router: IRouter) { query: schema.string(), lang: schema.string(), datasource: schema.string(), + sessionId: schema.maybe(schema.string()), }), }, }, From 2d229b1882e7ab183560a3d9038ee937d84ab5ae Mon Sep 17 00:00:00 2001 From: Shenoy Pratik Date: Tue, 24 Oct 2023 22:09:17 -0700 Subject: [PATCH 5/7] Support cancellation of async queries (#1177) * update routes and services Signed-off-by: Shenoy Pratik * update public components Signed-off-by: Shenoy Pratik * fix imports Signed-off-by: Shenoy Pratik --------- Signed-off-by: Shenoy Pratik --- .../components/common/search/sql_search.tsx | 11 ++--- .../explorer/direct_query_running.tsx | 42 ++++++++++++------- .../redux/slices/search_meta_data_slice.ts | 6 ++- public/services/requests/sql.ts | 9 ++++ .../opensearch_observability_plugin.ts | 16 +++++++ .../routes/datasources/datasources_router.ts | 29 +++++++++++++ 6 files changed, 91 insertions(+), 22 deletions(-) diff --git a/public/components/common/search/sql_search.tsx b/public/components/common/search/sql_search.tsx index 0ba84061d4..d7bbb2f873 100644 --- a/public/components/common/search/sql_search.tsx +++ b/public/components/common/search/sql_search.tsx @@ -21,11 +21,15 @@ import { import { isEqual } from 'lodash'; import React, { useEffect, useState } from 'react'; import { batch, useDispatch, useSelector } from 'react-redux'; +import { QUERY_LANGUAGE } from '../../../../common/constants/data_sources'; import { APP_ANALYTICS_TAB_ID_REGEX, RAW_QUERY } from '../../../../common/constants/explorer'; -import { DirectQueryLoadingStatus, DirectQueryRequest } from '../../../../common/types/explorer'; import { PPL_NEWLINE_REGEX, PPL_SPAN_REGEX } from '../../../../common/constants/shared'; +import { DirectQueryLoadingStatus, DirectQueryRequest } from '../../../../common/types/explorer'; import { uiSettingsService } from '../../../../common/utils'; +import { getAsyncSessionId, setAsyncSessionId } from '../../../../common/utils/query_session_utils'; +import { get as getObjValue } from '../../../../common/utils/shared'; import { useFetchEvents } from '../../../components/event_analytics/hooks'; +import { changeQuery } from '../../../components/event_analytics/redux/slices/query_slice'; import { usePolling } from '../../../components/hooks/use_polling'; import { coreRefs } from '../../../framework/core_refs'; import { SQLService } from '../../../services/requests/sql'; @@ -36,10 +40,6 @@ import { } from '../../event_analytics/redux/slices/search_meta_data_slice'; import { PPLReferenceFlyout } from '../helpers'; import { Autocomplete } from './autocomplete'; -import { changeQuery } from '../../../components/event_analytics/redux/slices/query_slice'; -import { QUERY_LANGUAGE } from '../../../../common/constants/data_sources'; -import { getAsyncSessionId, setAsyncSessionId } from '../../../../common/utils/query_session_utils'; -import { get as getObjValue } from '../../../../common/utils/shared'; export interface IQueryBarProps { query: string; tempQuery: string; @@ -208,6 +208,7 @@ export const DirectSearch = (props: any) => { .then((result) => { setAsyncSessionId(getObjValue(result, 'sessionId', null)); if (result.queryId) { + dispatch(updateSearchMetaData({ tabId, data: { queryId: result.queryId } })); startPolling({ queryId: result.queryId, }); diff --git a/public/components/event_analytics/explorer/direct_query_running.tsx b/public/components/event_analytics/explorer/direct_query_running.tsx index dcd884dd12..1d62327bee 100644 --- a/public/components/event_analytics/explorer/direct_query_running.tsx +++ b/public/components/event_analytics/explorer/direct_query_running.tsx @@ -3,18 +3,42 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { EuiButton, EuiEmptyPrompt, EuiProgress, EuiSpacer, EuiText } from '@elastic/eui'; import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { EuiProgress, EuiEmptyPrompt, EuiButton, EuiText, EuiSpacer } from '@elastic/eui'; +import { DirectQueryLoadingStatus } from '../../../../common/types/explorer'; +import { coreRefs } from '../../../framework/core_refs'; +import { SQLService } from '../../../services/requests/sql'; import { selectSearchMetaData, update as updateSearchMetaData, } from '../redux/slices/search_meta_data_slice'; -import { DirectQueryLoadingStatus } from '../../../../common/types/explorer'; export const DirectQueryRunning = ({ tabId }: { tabId: string }) => { const explorerSearchMeta = useSelector(selectSearchMetaData)[tabId] || {}; const dispatch = useDispatch(); + const sqlService = new SQLService(coreRefs.http); + + const cancelQuery = () => { + if (explorerSearchMeta.queryId !== '') { + sqlService + .deleteWithJobId({ queryId: explorerSearchMeta.queryId }) + .catch((e) => { + console.error(e); + }) + .finally(() => { + dispatch( + updateSearchMetaData({ + tabId, + data: { + isPolling: false, + }, + }) + ); + }); + } + }; + return ( } @@ -25,19 +49,7 @@ export const DirectQueryRunning = ({ tabId }: { tabId: string }) => { Status: {explorerSearchMeta.status ?? DirectQueryLoadingStatus.SCHEDULED} - { - dispatch( - updateSearchMetaData({ - tabId, - data: { - isPolling: false, - }, - }) - ); - }} - > + Cancel diff --git a/public/components/event_analytics/redux/slices/search_meta_data_slice.ts b/public/components/event_analytics/redux/slices/search_meta_data_slice.ts index 524e13bd8c..449515440d 100644 --- a/public/components/event_analytics/redux/slices/search_meta_data_slice.ts +++ b/public/components/event_analytics/redux/slices/search_meta_data_slice.ts @@ -3,14 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { createSlice, createSelector, PayloadAction } from '@reduxjs/toolkit'; -import { initialTabId } from '../../../../framework/redux/store/shared_state'; +import { PayloadAction, createSelector, createSlice } from '@reduxjs/toolkit'; import { REDUX_EXPL_SLICE_SEARCH_META_DATA } from '../../../../../common/constants/explorer'; import { DirectQueryLoadingStatus, SelectedDataSource } from '../../../../../common/types/explorer'; +import { initialTabId } from '../../../../framework/redux/store/shared_state'; const searchMetaInitialState = { lang: 'PPL', datasources: [], + queryId: '', isPolling: false, }; @@ -24,6 +25,7 @@ interface SearchMetaData { lang: string; datasources: SelectedDataSource[]; isPolling: boolean; + queryId: string; status: DirectQueryLoadingStatus; } diff --git a/public/services/requests/sql.ts b/public/services/requests/sql.ts index 2073804ad8..b28323f033 100644 --- a/public/services/requests/sql.ts +++ b/public/services/requests/sql.ts @@ -6,6 +6,7 @@ import { CoreStart } from '../../../../../src/core/public'; import { DirectQueryRequest } from '../../../common/types/explorer'; + export class SQLService { private http; constructor(http: CoreStart['http']) { @@ -31,4 +32,12 @@ export class SQLService { throw error; }); }; + + deleteWithJobId = async (params: { queryId: string }, errorHandler?: (error: any) => void) => { + return this.http.delete(`/api/observability/query/jobs/${params.queryId}`).catch((error) => { + console.error('delete error: ', error.body); + if (errorHandler) errorHandler(error); + throw error; + }); + }; } diff --git a/server/adaptors/opensearch_observability_plugin.ts b/server/adaptors/opensearch_observability_plugin.ts index 0694d850c3..170c8e588d 100644 --- a/server/adaptors/opensearch_observability_plugin.ts +++ b/server/adaptors/opensearch_observability_plugin.ts @@ -117,6 +117,7 @@ export function OpenSearchObservabilityPlugin(Client: any, config: any, componen method: 'DELETE', }); + // Get async job status observability.getJobStatus = clientAction({ url: { fmt: `${JOBS_ENDPOINT_BASE}/<%=queryId%>`, @@ -130,6 +131,21 @@ export function OpenSearchObservabilityPlugin(Client: any, config: any, componen method: 'GET', }); + // Delete async job + observability.deleteJob = clientAction({ + url: { + fmt: `${JOBS_ENDPOINT_BASE}/<%=queryId%>`, + req: { + queryId: { + type: 'string', + required: true, + }, + }, + }, + method: 'DELETE', + }); + + // Run async job observability.runDirectQuery = clientAction({ url: { fmt: `${JOBS_ENDPOINT_BASE}`, diff --git a/server/routes/datasources/datasources_router.ts b/server/routes/datasources/datasources_router.ts index 45279ccf76..c740c46235 100644 --- a/server/routes/datasources/datasources_router.ts +++ b/server/routes/datasources/datasources_router.ts @@ -71,4 +71,33 @@ export function registerDatasourcesRoute(router: IRouter) { } } ); + + router.delete( + { + path: `${OBSERVABILITY_BASE}${JOBS_BASE}/{queryId}`, + validate: { + params: schema.object({ + queryId: schema.string(), + }), + }, + }, + async (context, request, response): Promise => { + try { + const res = await context.observability_plugin.observabilityClient + .asScoped(request) + .callAsCurrentUser('observability.deleteJob', { + queryId: request.params.queryId, + }); + return response.ok({ + body: res, + }); + } catch (error: any) { + console.error('Error in deleting job:', error); + return response.custom({ + statusCode: error.statusCode || 500, + body: error.message, + }); + } + } + ); } From 0b238a0314d97e2c46ba535be0c2d022b61618b5 Mon Sep 17 00:00:00 2001 From: Eric Wei Date: Wed, 25 Oct 2023 16:37:30 -0700 Subject: [PATCH 6/7] Bug fixes for observability count distribution and application analytics (#1187) * remove unused files Signed-off-by: Eric Wei * missing snapshots Signed-off-by: Eric Wei * remove unused files Signed-off-by: Eric Wei * fix for count distribution disappear on page refresh Signed-off-by: Eric * fix query composing issue in app analytics Signed-off-by: Eric * add one fix for count distribution and update snapshots Signed-off-by: Eric --------- Signed-off-by: Eric Wei Signed-off-by: Eric --- public/components/common/query_utils/index.ts | 5 ++++- .../event_analytics/explorer/explorer.tsx | 17 +++++++++++++++-- .../count_distribution/count_distribution.tsx | 1 - .../redux/slices/count_distribution_slice.ts | 1 + 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/public/components/common/query_utils/index.ts b/public/components/common/query_utils/index.ts index bed3432dbb..9f4024bb31 100644 --- a/public/components/common/query_utils/index.ts +++ b/public/components/common/query_utils/index.ts @@ -245,7 +245,10 @@ export const buildPatternsQuery = ( return finalQuery; }; -export const buildQuery = (baseQuery: string, currQuery: string) => baseQuery + '| ' + currQuery; +export const buildQuery = (baseQuery: string, currQuery: string) => { + if (!currQuery) return baseQuery; + return `${baseQuery} | ${currQuery}`; +}; export const buildRawQuery = (query: IQuery, appBaseQuery: string) => { if (appBaseQuery && !query.rawQuery.includes(appBaseQuery)) diff --git a/public/components/event_analytics/explorer/explorer.tsx b/public/components/event_analytics/explorer/explorer.tsx index d311cdcc1b..1f4806b3c0 100644 --- a/public/components/event_analytics/explorer/explorer.tsx +++ b/public/components/event_analytics/explorer/explorer.tsx @@ -258,6 +258,12 @@ export const Explorer = ({ ...TIME_INTERVAL_OPTIONS, ]); selectedIntervalRef.current = { text: 'Auto', value: 'auto_' + minInterval }; + dispatch( + updateCountDistribution({ + tabId, + data: { selectedInterval: selectedIntervalRef.current.value.replace(/^auto_/, '') }, + }) + ); }; useEffect(() => { @@ -495,13 +501,18 @@ export const Explorer = ({ selectedIntervalRef.current = timeIntervalOptions[intervalOptionsIndex]; getPatterns(intrv, getErrorHandler('Error fetching patterns')); }} - stateInterval={selectedIntervalRef.current?.value} + stateInterval={ + countDistribution.selectedInterval || selectedIntervalRef.current?.value + } startTime={appLogEvents ? startTime : dateRange[0]} endTime={appLogEvents ? endTime : dateRange[1]} /> + @@ -783,6 +794,8 @@ export const Explorer = ({ subType, selectedCustomPanelOptions, explorerSearchMeta, + selectedIntervalRef.current, + countDistribution, ]); const liveTailLoop = async ( diff --git a/public/components/event_analytics/explorer/visualizations/count_distribution/count_distribution.tsx b/public/components/event_analytics/explorer/visualizations/count_distribution/count_distribution.tsx index 6fa6778819..8e5f10f315 100644 --- a/public/components/event_analytics/explorer/visualizations/count_distribution/count_distribution.tsx +++ b/public/components/event_analytics/explorer/visualizations/count_distribution/count_distribution.tsx @@ -4,7 +4,6 @@ */ import React from 'react'; -import { EuiPanel } from '@elastic/eui'; import { BarOrientation, LONG_CHART_COLOR } from '../../../../../../common/constants/shared'; import { Plt } from '../../../../visualizations/plotly/plot'; import { fillTimeDataWithEmpty } from '../../../utils/utils'; diff --git a/public/components/event_analytics/redux/slices/count_distribution_slice.ts b/public/components/event_analytics/redux/slices/count_distribution_slice.ts index 59aa1e03f2..b960c5064b 100644 --- a/public/components/event_analytics/redux/slices/count_distribution_slice.ts +++ b/public/components/event_analytics/redux/slices/count_distribution_slice.ts @@ -17,6 +17,7 @@ export const countDistributionSlice = createSlice({ reducers: { render: (state, { payload }) => { state[payload.tabId] = { + ...state[payload.tabId], ...payload.data, }; }, From 22b6fc6742a09e1feacf7ec6e1314a6bea42eaed Mon Sep 17 00:00:00 2001 From: Simeon Widdis Date: Fri, 27 Oct 2023 13:23:16 -0700 Subject: [PATCH 7/7] Add integrations queries for Flint (#1150) --- .../setup_integration.test.tsx.snap | 35 ++++- .../components/create_integration_helpers.ts | 13 +- .../components/setup_integration.tsx | 139 +++++++++++++----- .../aws_cloudtrail/aws_cloudtrail-1.0.0.json | 2 +- .../aws_elb/assets/create_mv-1.0.0.sql | 38 +++++ .../aws_elb/assets/create_table-1.0.0.sql | 36 +++++ .../aws_elb/assets/refresh_mv-1.0.0.sql | 1 + .../repository/aws_elb/aws_elb-1.0.0.json | 19 ++- .../aws_vpc_flow/aws_vpc_flow-1.0.0.json | 2 +- .../repository/nginx/nginx-1.0.0.json | 2 +- 10 files changed, 237 insertions(+), 50 deletions(-) create mode 100644 server/adaptors/integrations/__data__/repository/aws_elb/assets/create_mv-1.0.0.sql create mode 100644 server/adaptors/integrations/__data__/repository/aws_elb/assets/create_table-1.0.0.sql create mode 100644 server/adaptors/integrations/__data__/repository/aws_elb/assets/refresh_mv-1.0.0.sql diff --git a/public/components/integrations/components/__tests__/__snapshots__/setup_integration.test.tsx.snap b/public/components/integrations/components/__tests__/__snapshots__/setup_integration.test.tsx.snap index e8f7bee82d..3688bcb349 100644 --- a/public/components/integrations/components/__tests__/__snapshots__/setup_integration.test.tsx.snap +++ b/public/components/integrations/components/__tests__/__snapshots__/setup_integration.test.tsx.snap @@ -31,6 +31,7 @@ exports[`Integration Setup Page Renders integration setup page as expected 1`] = Object { "connectionDataSource": "", "connectionLocation": "", + "connectionTableName": "sample", "connectionType": "index", "displayName": "sample Integration", } @@ -87,9 +88,15 @@ exports[`Integration Setup Page Renders integration setup page as expected 1`] = @@ -101,12 +108,15 @@ exports[`Integration Setup Page Renders integration setup page as expected 1`] = className="euiFormRow__labelWrapper" >