diff --git a/common/constants/index.ts b/common/constants/index.ts index 724aae24..e8a1b68f 100644 --- a/common/constants/index.ts +++ b/common/constants/index.ts @@ -72,7 +72,7 @@ export const SKIPPING_INDEX_ACCELERATION_METHODS = [ export const ACCELERATION_ADD_FIELDS_TEXT = '(add fields here)'; export const ACCELERATION_INDEX_NAME_REGEX = /^[a-z][a-z_]*$/; -export const ACCELERATION_S3_URL_REGEX = /^(s3|s3a):\/\/[a-zA-Z0-9.\-]+\/.*/; +export const ACCELERATION_S3_URL_REGEX = /^(s3|s3a):\/\/[a-zA-Z0-9.\-]+/; export const ACCELERATION_DEFUALT_SKIPPING_INDEX_NAME = 'skipping'; export const ACCELERATION_INDEX_NAME_INFO = `All OpenSearch acceleration indices have a naming format of pattern: \`prefix__suffix\`. They share a common prefix structure, which is \`flint____\`. Additionally, they may have a suffix that varies based on the index type. @@ -89,6 +89,7 @@ export const ACCELERATION_INDEX_NAME_INFO = `All OpenSearch acceleration indices - All user given index names must be in lowercase letters. Index name cannot begin with underscores. Spaces, commas, and characters -, :, ", *, +, /, \, |, ?, #, >, or < are not allowed. `; +export const OPENSEARCH_SQL_INIT_QUERY = `SHOW tables LIKE '%';`; export const TIMESTAMP_DATATYPE = 'timestamp'; export const FETCH_OPENSEARCH_INDICES_PATH = '/api/sql_console/sqlquery'; export const POLL_INTERVAL_MS = 2000; diff --git a/common/utils/async_query_helpers.ts b/common/utils/async_query_helpers.ts index 1dad6116..b2153237 100644 --- a/common/utils/async_query_helpers.ts +++ b/common/utils/async_query_helpers.ts @@ -13,8 +13,9 @@ import { } from '../constants'; export const setAsyncSessionId = (value: string | null) => { - if (value === null) sessionStorage.removeItem(ASYNC_QUERY_SESSION_ID); - else sessionStorage.setItem(ASYNC_QUERY_SESSION_ID, value); + if (value !== null) { + sessionStorage.setItem(ASYNC_QUERY_SESSION_ID, value); + } }; export const getAsyncSessionId = () => { diff --git a/public/components/Main/main.tsx b/public/components/Main/main.tsx index fe1ebacc..bf7c101c 100644 --- a/public/components/Main/main.tsx +++ b/public/components/Main/main.tsx @@ -25,6 +25,7 @@ import { ChromeBreadcrumb, CoreStart } from '../../../../../src/core/public'; import { ASYNC_QUERY_ENDPOINT, ASYNC_QUERY_JOB_ENDPOINT, + OPENSEARCH_SQL_INIT_QUERY, POLL_INTERVAL_MS, } from '../../../common/constants'; import { AsyncQueryLoadingStatus } from '../../../common/types'; @@ -239,7 +240,7 @@ export class Main extends React.Component { this.onChange = this.onChange.bind(this); this.state = { language: 'SQL', - sqlQueriesString: "SHOW tables LIKE '%';", + sqlQueriesString: OPENSEARCH_SQL_INIT_QUERY, pplQueriesString: '', queries: [], queryTranslations: [], @@ -816,8 +817,11 @@ export class Main extends React.Component { } handleDataSelect = (selectedItems: EuiComboBoxOptionOption[]) => { - if (selectedItems[0].label !== 'OpenSearch' && this.state.language === 'SQL') { - this.updateSQLQueries(''); + this.updateSQLQueries(''); + this.updatePPLQueries(''); + this.onClear(); + if (selectedItems[0].label === 'OpenSearch' && this.state.language === 'SQL') { + this.updateSQLQueries(OPENSEARCH_SQL_INIT_QUERY); } this.setState({ selectedDatasource: selectedItems, diff --git a/public/components/acceleration/create/__tests__/__snapshots__/create_acceleration.test.tsx.snap b/public/components/acceleration/create/__tests__/__snapshots__/create_acceleration.test.tsx.snap index b01c43b2..74c1d775 100644 --- a/public/components/acceleration/create/__tests__/__snapshots__/create_acceleration.test.tsx.snap +++ b/public/components/acceleration/create/__tests__/__snapshots__/create_acceleration.test.tsx.snap @@ -574,7 +574,7 @@ Array [ min="1" placeholder="Number of primary shards" type="number" - value="1" + value="5" /> @@ -582,7 +582,7 @@ Array [ class="euiFormHelpText euiFormRow__text" id="some_html_id-help-0" > - Specify the number of primary shards for the index. Default is 1. The number of primary shards cannot be changed after the index is created. + Specify the number of primary shards for the index. The number of primary shards cannot be changed after the index is created. @@ -627,7 +627,7 @@ Array [ class="euiFormHelpText euiFormRow__text" id="some_html_id-help-0" > - Specify the number of replicas each primary shard should have. Default is 1. + Specify the number of replicas each primary shard should have. @@ -1819,7 +1819,7 @@ Array [ onFocus={[Function]} placeholder="Number of primary shards" type="number" - value={1} + value={5} /> @@ -1827,7 +1827,7 @@ Array [ className="euiFormHelpText euiFormRow__text" id="some_html_id-help-0" > - Specify the number of primary shards for the index. Default is 1. The number of primary shards cannot be changed after the index is created. + Specify the number of primary shards for the index. The number of primary shards cannot be changed after the index is created. , @@ -1875,7 +1875,7 @@ Array [ className="euiFormHelpText euiFormRow__text" id="some_html_id-help-0" > - Specify the number of replicas each primary shard should have. Default is 1. + Specify the number of replicas each primary shard should have. , diff --git a/public/components/acceleration/create/__tests__/utils.test.tsx b/public/components/acceleration/create/__tests__/utils.test.tsx index 97425c4a..547a5317 100644 --- a/public/components/acceleration/create/__tests__/utils.test.tsx +++ b/public/components/acceleration/create/__tests__/utils.test.tsx @@ -186,6 +186,11 @@ describe('validateCheckpointLocation', () => { expect(validCheckpoint).toEqual([]); }); + it('should return an empty array when the checkpoint location is a valid S3A URL with just bucket in checkpoint', () => { + const validCheckpoint = validateCheckpointLocation('auto', 's3a://valid-s3-bucket'); + expect(validCheckpoint).toEqual([]); + }); + it('should return an empty array when using manual refresh with no checkpoint location', () => { const validMaterializedCheckpoint = validateCheckpointLocation('manual', ''); expect(validMaterializedCheckpoint).toEqual([]); diff --git a/public/components/acceleration/create/create_acceleration.tsx b/public/components/acceleration/create/create_acceleration.tsx index ebb9dd93..eb5433a4 100644 --- a/public/components/acceleration/create/create_acceleration.tsx +++ b/public/components/acceleration/create/create_acceleration.tsx @@ -61,7 +61,7 @@ export const CreateAcceleration = ({ }, }, accelerationIndexName: ACCELERATION_DEFUALT_SKIPPING_INDEX_NAME, - primaryShardsCount: 1, + primaryShardsCount: 5, replicaShardsCount: 1, refreshType: 'auto', checkpointLocation: undefined, diff --git a/public/components/acceleration/selectors/__tests__/__snapshots__/define_index_options.test.tsx.snap b/public/components/acceleration/selectors/__tests__/__snapshots__/define_index_options.test.tsx.snap index acc218be..7eef9e2f 100644 --- a/public/components/acceleration/selectors/__tests__/__snapshots__/define_index_options.test.tsx.snap +++ b/public/components/acceleration/selectors/__tests__/__snapshots__/define_index_options.test.tsx.snap @@ -277,7 +277,7 @@ Array [ className="euiFormLabel euiFormControlLayout__prepend" htmlFor="some_html_id" > - flint_{Datasource Name}_{Database Name}_{Table Name}_ + flint_{Datasource Name}_{Database Name}_ @@ -204,7 +204,7 @@ Array [ className="euiFormHelpText euiFormRow__text" id="some_html_id-help-0" > - Specify the number of primary shards for the index. Default is 1. The number of primary shards cannot be changed after the index is created. + Specify the number of primary shards for the index. The number of primary shards cannot be changed after the index is created. , @@ -252,7 +252,7 @@ Array [ className="euiFormHelpText euiFormRow__text" id="some_html_id-help-0" > - Specify the number of replicas each primary shard should have. Default is 1. + Specify the number of replicas each primary shard should have. , @@ -604,7 +604,7 @@ Array [ onFocus={[Function]} placeholder="Number of primary shards" type="number" - value={1} + value={5} /> @@ -612,7 +612,7 @@ Array [ className="euiFormHelpText euiFormRow__text" id="some_html_id-help-0" > - Specify the number of primary shards for the index. Default is 1. The number of primary shards cannot be changed after the index is created. + Specify the number of primary shards for the index. The number of primary shards cannot be changed after the index is created. , @@ -660,7 +660,7 @@ Array [ className="euiFormHelpText euiFormRow__text" id="some_html_id-help-0" > - Specify the number of replicas each primary shard should have. Default is 1. + Specify the number of replicas each primary shard should have. , @@ -1012,7 +1012,7 @@ Array [ onFocus={[Function]} placeholder="Number of primary shards" type="number" - value={1} + value={5} /> @@ -1020,7 +1020,7 @@ Array [ className="euiFormHelpText euiFormRow__text" id="some_html_id-help-0" > - Specify the number of primary shards for the index. Default is 1. The number of primary shards cannot be changed after the index is created. + Specify the number of primary shards for the index. The number of primary shards cannot be changed after the index is created. , @@ -1068,7 +1068,7 @@ Array [ className="euiFormHelpText euiFormRow__text" id="some_html_id-help-0" > - Specify the number of replicas each primary shard should have. Default is 1. + Specify the number of replicas each primary shard should have. , diff --git a/public/components/acceleration/selectors/define_index_options.tsx b/public/components/acceleration/selectors/define_index_options.tsx index 6d57e675..9f8c89b8 100644 --- a/public/components/acceleration/selectors/define_index_options.tsx +++ b/public/components/acceleration/selectors/define_index_options.tsx @@ -72,7 +72,10 @@ export const DefineIndexOptions = ({ accelerationFormData.database !== '' ? accelerationFormData.database : '{Database Name}'; const dataTable = accelerationFormData.dataTable !== '' ? accelerationFormData.dataTable : '{Table Name}'; - const prependValue = `flint_${dataSource}_${database}_${dataTable}_`; + const prependValue = + accelerationFormData.accelerationIndexType === 'materialized' + ? `flint_${dataSource}_${database}_` + : `flint_${dataSource}_${database}_${dataTable}_`; return [ prependValue, , diff --git a/public/components/acceleration/selectors/index_setting_options.tsx b/public/components/acceleration/selectors/index_setting_options.tsx index 56d2a635..45796a34 100644 --- a/public/components/acceleration/selectors/index_setting_options.tsx +++ b/public/components/acceleration/selectors/index_setting_options.tsx @@ -56,7 +56,7 @@ export const IndexSettingOptions = ({ }, ]; - const [primaryShards, setPrimaryShards] = useState(1); + const [primaryShards, setPrimaryShards] = useState(5); const [replicaCount, setReplicaCount] = useState(1); const [refreshTypeSelected, setRefreshTypeSelected] = useState(autoRefreshId); const [refreshWindow, setRefreshWindow] = useState(1); @@ -156,7 +156,7 @@ export const IndexSettingOptions = ({ /> @@ -181,7 +181,7 @@ export const IndexSettingOptions = ({ diff --git a/public/components/acceleration/selectors/index_type_selector.tsx b/public/components/acceleration/selectors/index_type_selector.tsx index dc155e9f..00e1e92d 100644 --- a/public/components/acceleration/selectors/index_type_selector.tsx +++ b/public/components/acceleration/selectors/index_type_selector.tsx @@ -18,6 +18,7 @@ import { ACCELERATION_INDEX_TYPES, ACC_INDEX_TYPE_DOCUMENTATION_URL, } from '../../../../common/constants'; +import { useToast } from '../../../../common/toast'; import { AccelerationIndexType, CreateAccelerationForm, @@ -36,6 +37,7 @@ export const IndexTypeSelector = ({ accelerationFormData, setAccelerationFormData, }: IndexTypeSelectorProps) => { + const { setToast } = useToast(); const [selectedIndexType, setSelectedIndexType] = useState[]>([ ACCELERATION_INDEX_TYPES[0], ]); @@ -50,7 +52,11 @@ export const IndexTypeSelector = ({ query: `DESC ${accelerationFormData.dataSource}.${accelerationFormData.database}.${accelerationFormData.dataTable}`, datasource: accelerationFormData.dataSource, }; + const errorMessage = 'ERROR: failed to load table columns'; getJobId(query, http, (id: string) => { + if (id === undefined) { + setToast(errorMessage, 'danger'); + } pollQueryStatus(id, http, (data: { status: string; results: any[] }) => { if (data.status === 'SUCCESS') { const dataTableFields: DataTableFieldsType[] = data.results @@ -68,6 +74,7 @@ export const IndexTypeSelector = ({ } if (data.status === 'FAILED') { setLoading(false); + setToast(errorMessage, 'danger'); } }); }); diff --git a/public/components/acceleration/selectors/source_selector.tsx b/public/components/acceleration/selectors/source_selector.tsx index d296c237..0c488127 100644 --- a/public/components/acceleration/selectors/source_selector.tsx +++ b/public/components/acceleration/selectors/source_selector.tsx @@ -7,6 +7,7 @@ import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow, EuiSpacer, EuiText } import producer from 'immer'; import React, { useEffect, useState } from 'react'; import { CoreStart } from '../../../../../../src/core/public'; +import { useToast } from '../../../../common/toast'; import { CreateAccelerationForm } from '../../../../common/types'; import { getJobId, pollQueryStatus } from '../../../../common/utils/async_query_helpers'; import { hasError, validateDataSource } from '../create/utils'; @@ -24,6 +25,7 @@ export const AccelerationDataSourceSelector = ({ setAccelerationFormData, selectedDatasource, }: AccelerationDataSourceSelectorProps) => { + const { setToast } = useToast(); const [dataConnections, setDataConnections] = useState[]>([]); const [selectedDataConnection, setSelectedDataConnection] = useState< EuiComboBoxOptionOption[] @@ -52,6 +54,7 @@ export const AccelerationDataSourceSelector = ({ }) .catch((err) => { console.error(err); + setToast(`ERROR: failed to load datasources`, 'danger'); }); setLoadingComboBoxes({ ...loadingComboBoxes, dataSource: false }); }; @@ -63,7 +66,11 @@ export const AccelerationDataSourceSelector = ({ query: `SHOW SCHEMAS IN ${accelerationFormData.dataSource}`, datasource: accelerationFormData.dataSource, }; + const errorMessage = `ERROR: failed to load databases`; getJobId(query, http, (id: string) => { + if (id === undefined) { + setToast(errorMessage, 'danger'); + } pollQueryStatus(id, http, (data: { status: string; results: any[] }) => { if (data.status === 'SUCCESS') { let databaseOptions: EuiComboBoxOptionOption[] = []; @@ -74,6 +81,7 @@ export const AccelerationDataSourceSelector = ({ } if (data.status === 'FAILED') { setLoadingComboBoxes({ ...loadingComboBoxes, database: false }); + setToast(errorMessage, 'danger'); } }); }); @@ -86,7 +94,11 @@ export const AccelerationDataSourceSelector = ({ query: `SHOW TABLES IN ${accelerationFormData.dataSource}.${accelerationFormData.database}`, datasource: accelerationFormData.dataSource, }; + const errorMessage = `ERROR: failed to load tables`; getJobId(query, http, (id: string) => { + if (id === undefined) { + setToast(errorMessage, 'danger'); + } pollQueryStatus(id, http, (data: { status: string; results: any[] }) => { if (data.status === 'SUCCESS') { let dataTableOptions: EuiComboBoxOptionOption[] = []; @@ -97,6 +109,7 @@ export const AccelerationDataSourceSelector = ({ } if (data.status === 'FAILED') { setLoadingComboBoxes({ ...loadingComboBoxes, dataTable: false }); + setToast(errorMessage, 'danger'); } }); }); diff --git a/public/components/acceleration/visual_editors/materialized_view/add_column_popover.tsx b/public/components/acceleration/visual_editors/materialized_view/add_column_popover.tsx index 6d91c5b7..f396e0a8 100644 --- a/public/components/acceleration/visual_editors/materialized_view/add_column_popover.tsx +++ b/public/components/acceleration/visual_editors/materialized_view/add_column_popover.tsx @@ -26,7 +26,6 @@ import { CreateAccelerationForm, MaterializedViewColumn, } from '../../../../../common/types'; -import { validateMaterializedViewData } from '../../create/utils'; interface AddColumnPopOverProps { isColumnPopOverOpen: boolean; @@ -82,10 +81,6 @@ export const AddColumnPopOver = ({ setAccelerationFormData( producer((accData) => { accData.materializedViewQueryData.columnsValues = newColumnExpresionValue; - accData.formErrors.materializedViewError = validateMaterializedViewData( - accData.accelerationIndexType, - accData.materializedViewQueryData - ); }) ); diff --git a/public/components/acceleration/visual_editors/materialized_view/column_expression.tsx b/public/components/acceleration/visual_editors/materialized_view/column_expression.tsx index 5f9a0909..9569b2d8 100644 --- a/public/components/acceleration/visual_editors/materialized_view/column_expression.tsx +++ b/public/components/acceleration/visual_editors/materialized_view/column_expression.tsx @@ -22,7 +22,6 @@ import { CreateAccelerationForm, MaterializedViewColumn, } from '../../../../../common/types'; -import { validateMaterializedViewData } from '../../create/utils'; interface ColumnExpressionProps { index: number; @@ -57,10 +56,6 @@ export const ColumnExpression = ({ setAccelerationFormData( producer((accData) => { accData.materializedViewQueryData.columnsValues = newColumnExpresionValue; - accData.formErrors.materializedViewError = validateMaterializedViewData( - accData.accelerationIndexType, - accData.materializedViewQueryData - ); }) ); setColumnExpressionValues(newColumnExpresionValue); diff --git a/public/components/acceleration/visual_editors/materialized_view/group_by_tumble_expression.tsx b/public/components/acceleration/visual_editors/materialized_view/group_by_tumble_expression.tsx index 0207c164..9ee0a12f 100644 --- a/public/components/acceleration/visual_editors/materialized_view/group_by_tumble_expression.tsx +++ b/public/components/acceleration/visual_editors/materialized_view/group_by_tumble_expression.tsx @@ -18,7 +18,7 @@ import producer from 'immer'; import React, { useState } from 'react'; import { ACCELERATION_TIME_INTERVAL, TIMESTAMP_DATATYPE } from '../../../../../common/constants'; import { CreateAccelerationForm, GroupByTumbleType } from '../../../../../common/types'; -import { hasError, pluralizeTime, validateMaterializedViewData } from '../../create/utils'; +import { hasError, pluralizeTime } from '../../create/utils'; interface GroupByTumbleExpressionProps { accelerationFormData: CreateAccelerationForm; @@ -41,10 +41,6 @@ export const GroupByTumbleExpression = ({ setAccelerationFormData( producer((accData) => { accData.materializedViewQueryData.groupByTumbleValue = newGroupByValue; - accData.formErrors.materializedViewError = validateMaterializedViewData( - accData.accelerationIndexType, - accData.materializedViewQueryData - ); }) ); }; @@ -90,9 +86,10 @@ export const GroupByTumbleExpression = ({ anchorPosition="downLeft" > - + { accData.materializedViewQueryData.columnsValues = newColumnExpresionValue; - accData.formErrors.materializedViewError = validateMaterializedViewData( - accData.accelerationIndexType, - accData.materializedViewQueryData - ); }) ); setColumnExpressionValues(newColumnExpresionValue);