Skip to content

Commit 33a91c3

Browse files
Block simulate API calls if datasource version is missing (#657) (#659)
* Block simulate on ingest if version not foundg * more cleanup after rebase * Add checks in all modals * Set defaults for calls of getEffectiveVesion * rename fn --------- (cherry picked from commit 1d0fea7) Signed-off-by: Tyler Ohlsen <ohltyler@amazon.com> Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 34ff91e commit 33a91c3

File tree

10 files changed

+103
-47
lines changed

10 files changed

+103
-47
lines changed

public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_expression_modal.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ import {
5353
injectParameters,
5454
prepareDocsForSimulate,
5555
unwrapTransformedDocs,
56+
useDataSourceVersion,
57+
useMissingDataSourceVersion,
5658
} from '../../../../../../utils';
5759
import { TextField } from '../../../input_fields';
5860
import {
@@ -94,6 +96,11 @@ const MAX_INPUT_DOCS = 10;
9496
export function ConfigureExpressionModal(props: ConfigureExpressionModalProps) {
9597
const dispatch = useAppDispatch();
9698
const dataSourceId = getDataSourceId();
99+
const dataSourceVersion = useDataSourceVersion(dataSourceId);
100+
const missingDataSourceVersion = useMissingDataSourceVersion(
101+
dataSourceId,
102+
dataSourceVersion
103+
);
97104
const { values, setFieldValue, setFieldTouched } = useFormikContext<
98105
WorkflowFormValues
99106
>();
@@ -407,6 +414,8 @@ export function ConfigureExpressionModal(props: ConfigureExpressionModalProps) {
407414
style={{ width: '100px' }}
408415
isLoading={isFetching}
409416
disabled={
417+
(props.context === PROCESSOR_CONTEXT.INGEST &&
418+
missingDataSourceVersion) ||
410419
onIngestAndNoDocs ||
411420
onSearchAndNoQuery ||
412421
!props.isDataFetchingAvailable ||

public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_multi_expression_modal.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ import {
5151
injectParameters,
5252
prepareDocsForSimulate,
5353
unwrapTransformedDocs,
54+
useDataSourceVersion,
55+
useMissingDataSourceVersion,
5456
} from '../../../../../../utils';
5557
import { TextField } from '../../../input_fields';
5658
import {
@@ -91,6 +93,11 @@ export function ConfigureMultiExpressionModal(
9193
) {
9294
const dispatch = useAppDispatch();
9395
const dataSourceId = getDataSourceId();
96+
const dataSourceVersion = useDataSourceVersion(dataSourceId);
97+
const missingDataSourceVersion = useMissingDataSourceVersion(
98+
dataSourceId,
99+
dataSourceVersion
100+
);
94101
const { values, setFieldValue, setFieldTouched } = useFormikContext<
95102
WorkflowFormValues
96103
>();
@@ -433,6 +440,8 @@ export function ConfigureMultiExpressionModal(
433440
style={{ width: '100px' }}
434441
isLoading={isFetching}
435442
disabled={
443+
(props.context === PROCESSOR_CONTEXT.INGEST &&
444+
missingDataSourceVersion) ||
436445
onIngestAndNoDocs ||
437446
onSearchAndNoQuery ||
438447
!props.isDataFetchingAvailable ||

public/pages/workflow_detail/workflow_inputs/processor_inputs/ml_processor_inputs/modals/configure_template_modal.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ import {
5757
injectParameters,
5858
prepareDocsForSimulate,
5959
unwrapTransformedDocs,
60+
useDataSourceVersion,
61+
useMissingDataSourceVersion,
6062
} from '../../../../../../utils';
6163
import { TextField } from '../../../input_fields';
6264
import {
@@ -102,6 +104,11 @@ const PROMPT_EDITOR_ID = 'promptEditor';
102104
export function ConfigureTemplateModal(props: ConfigureTemplateModalProps) {
103105
const dispatch = useAppDispatch();
104106
const dataSourceId = getDataSourceId();
107+
const dataSourceVersion = useDataSourceVersion(dataSourceId);
108+
const missingDataSourceVersion = useMissingDataSourceVersion(
109+
dataSourceId,
110+
dataSourceVersion
111+
);
105112
const { values, setFieldValue, setFieldTouched } = useFormikContext<
106113
WorkflowFormValues
107114
>();
@@ -638,6 +645,8 @@ export function ConfigureTemplateModal(props: ConfigureTemplateModalProps) {
638645
style={{ width: '100px' }}
639646
isLoading={isFetching}
640647
disabled={
648+
(props.context === PROCESSOR_CONTEXT.INGEST &&
649+
missingDataSourceVersion) ||
641650
onIngestAndNoDocs ||
642651
onSearchAndNoQuery ||
643652
!props.isDataFetchingAvailable ||

public/pages/workflow_detail/workflow_inputs/processors_list.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {
3232
import {
3333
formikToUiConfig,
3434
getDataSourceFromURL,
35-
getEffectiveVersion,
35+
getDataSourceVersion,
3636
} from '../../../utils';
3737
import {
3838
CollapseProcessor,
@@ -120,9 +120,9 @@ export function ProcessorsList(props: ProcessorsListProps) {
120120
}
121121

122122
if (dataSourceId !== undefined) {
123-
getEffectiveVersion(dataSourceId)
123+
getDataSourceVersion(dataSourceId)
124124
.then((ver) => {
125-
setVersion(ver);
125+
setVersion(ver || MIN_SUPPORTED_VERSION);
126126
})
127127
.catch(console.error);
128128
}

public/pages/workflow_detail/workflow_inputs/search_inputs/search_inputs.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ import { EnrichSearchRequest } from './enrich_search_request';
1111
import { EnrichSearchResponse } from './enrich_search_response';
1212
import {
1313
CachedFormikState,
14+
MIN_SUPPORTED_VERSION,
1415
OMIT_SYSTEM_INDEX_PATTERN,
1516
WorkflowConfig,
1617
} from '../../../../../common';
1718
import { catIndices, useAppDispatch } from '../../../../store';
18-
import { getDataSourceId, getEffectiveVersion } from '../../../../utils';
19+
import { getDataSourceId, getDataSourceVersion } from '../../../../utils';
1920

2021
interface SearchInputsProps {
2122
uiConfig: WorkflowConfig;
@@ -42,10 +43,11 @@ export function SearchInputs(props: SearchInputsProps) {
4243
const checkVersion = async () => {
4344
try {
4445
if (dataSourceId !== undefined) {
45-
const version = await getEffectiveVersion(dataSourceId);
46+
const version =
47+
(await getDataSourceVersion(dataSourceId)) || MIN_SUPPORTED_VERSION;
4648
setShowTransformQuery(semver.gte(version, '2.19.0'));
4749
} else {
48-
setShowTransformQuery(true);
50+
setShowTransformQuery(true);
4951
}
5052
} catch (error) {
5153
console.error('Error checking version:', error);

public/pages/workflow_detail/workflow_inputs/workflow_inputs.tsx

+9-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import {
6060
sleep,
6161
useDataSourceVersion,
6262
getIsPreV219,
63+
useMissingDataSourceVersion,
6364
} from '../../../utils';
6465
import { BooleanField } from './input_fields';
6566
import '../workspace/workspace-styles.scss';
@@ -104,6 +105,10 @@ export function WorkflowInputs(props: WorkflowInputsProps) {
104105
const dataSourceId = getDataSourceId();
105106
const dataSourceVersion = useDataSourceVersion(dataSourceId);
106107
const isPreV219 = getIsPreV219(dataSourceVersion);
108+
const missingDataSourceVersion = useMissingDataSourceVersion(
109+
dataSourceId,
110+
dataSourceVersion
111+
);
107112

108113
// transient running states
109114
const [isUpdatingSearchPipeline, setIsUpdatingSearchPipeline] = useState<
@@ -610,7 +615,10 @@ export function WorkflowInputs(props: WorkflowInputsProps) {
610615
if (
611616
!isEmpty(values?.ingest?.enrich) &&
612617
values?.ingest?.pipelineName !== undefined &&
613-
values?.ingest?.pipelineName !== ''
618+
values?.ingest?.pipelineName !== '' &&
619+
// if the data source version is missing/undefined, we cannot
620+
// guarantee that the simulate API will be available
621+
!missingDataSourceVersion
614622
) {
615623
const curDocs = prepareDocsForSimulate(
616624
values?.ingest?.docs,

public/pages/workflows/import_workflow/import_workflow_modal.tsx

+9-13
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ import {
4444
WORKFLOW_NAME_RESTRICTIONS,
4545
} from '../../../../common';
4646
import { WORKFLOWS_TAB } from '../workflows';
47-
import { getDataSourceId, getEffectiveVersion, formatDisplayVersion } from '../../../utils/utils';
47+
import {
48+
getDataSourceId,
49+
formatDisplayVersion,
50+
useDataSourceVersion,
51+
} from '../../../utils/utils';
4852

4953
interface ImportWorkflowModalProps {
5054
isImportModalOpen: boolean;
@@ -62,17 +66,7 @@ interface ImportWorkflowModalProps {
6266
export function ImportWorkflowModal(props: ImportWorkflowModalProps) {
6367
const dispatch = useAppDispatch();
6468
const dataSourceId = getDataSourceId();
65-
const [dataSourceVersion, setDataSourceVersion] = useState<
66-
string | undefined
67-
>(undefined);
68-
useEffect(() => {
69-
async function getVersion() {
70-
if (dataSourceId !== undefined) {
71-
setDataSourceVersion(await getEffectiveVersion(dataSourceId));
72-
}
73-
}
74-
getVersion();
75-
}, [dataSourceId]);
69+
const dataSourceVersion = useDataSourceVersion(dataSourceId);
7670
const { workflows } = useSelector((state: AppState) => state.workflows);
7771

7872
// workflow name state
@@ -171,7 +165,9 @@ export function ImportWorkflowModal(props: ImportWorkflowModalProps) {
171165
<>
172166
<EuiFlexItem>
173167
<EuiCallOut
174-
title={`The uploaded file is not compatible with the current data source version ${formatDisplayVersion(dataSourceVersion)}. Upload a compatible file or switch to another data source.`}
168+
title={`The uploaded file is not compatible with the current data source version ${formatDisplayVersion(
169+
dataSourceVersion
170+
)}. Upload a compatible file or switch to another data source.`}
175171
iconType={'alert'}
176172
color="danger"
177173
/>

public/pages/workflows/new_workflow/new_workflow.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { enrichPresetWorkflowWithUiMetadata } from './utils';
3030
import {
3131
getDataSourceId,
3232
isDataSourceReady,
33-
getEffectiveVersion,
33+
getDataSourceVersion,
3434
} from '../../../utils';
3535
import { getDataSourceEnabled } from '../../../services';
3636
import semver from 'semver';
@@ -64,7 +64,8 @@ const filterPresetsByVersion = async (
6464
WORKFLOW_TYPE.CUSTOM,
6565
];
6666

67-
const version = await getEffectiveVersion(dataSourceId);
67+
const version =
68+
(await getDataSourceVersion(dataSourceId)) || MIN_SUPPORTED_VERSION;
6869

6970
if (semver.lt(version, MIN_SUPPORTED_VERSION)) {
7071
return [];
@@ -159,7 +160,8 @@ export function NewWorkflow(props: NewWorkflowProps) {
159160
return;
160161
}
161162

162-
const version = await getEffectiveVersion(dataSourceId);
163+
const version =
164+
(await getDataSourceVersion(dataSourceId)) || MIN_SUPPORTED_VERSION;
163165

164166
const enrichedWorkflows = presetWorkflows.map((presetWorkflow) =>
165167
enrichPresetWorkflowWithUiMetadata(presetWorkflow, version)

public/pages/workflows/new_workflow/quick_configure_modal.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ export function QuickConfigureModal(props: QuickConfigureModalProps) {
260260
<EuiFlexGroup direction="column" gutterSize="s">
261261
<EuiFlexItem>
262262
<TextField
263-
label="Name - required"
263+
label="Name"
264264
fullWidth={true}
265265
fieldPath={`name`}
266266
showError={true}
@@ -308,7 +308,7 @@ export function QuickConfigureModal(props: QuickConfigureModalProps) {
308308
modelCategory={MODEL_CATEGORY.LLM}
309309
fieldPath="llm"
310310
showMissingInterfaceCallout={false}
311-
label="Large language model - required"
311+
label="Large language model"
312312
helpText="The large language model to generate user-friendly responses."
313313
fullWidth={true}
314314
showError={true}
@@ -340,7 +340,7 @@ export function QuickConfigureModal(props: QuickConfigureModalProps) {
340340
modelCategory={MODEL_CATEGORY.EMBEDDING}
341341
fieldPath="embeddingModel"
342342
showMissingInterfaceCallout={false}
343-
label="Embedding model - required"
343+
label="Embedding model"
344344
helpText="The model to generate embeddings."
345345
fullWidth={true}
346346
showError={true}

public/utils/utils.tsx

+42-21
Original file line numberDiff line numberDiff line change
@@ -160,27 +160,39 @@ export function isValidWorkflow(workflowObj: any): boolean {
160160

161161
// Determines if a file used for import workflow is compatible with the current data source version.
162162
export async function isCompatibleWorkflow(
163-
workflowObj: any,
163+
workflowObj: any,
164164
dataSourceId?: string | undefined
165165
): Promise<boolean> {
166166
const compatibility = workflowObj?.version?.compatibility;
167167

168168
// Default to true when compatibility cannot be assessed (empty/invalid compatibility array or MDS disabled.)
169-
if (!Array.isArray(compatibility) || compatibility.length === 0 || dataSourceId === undefined) {
169+
if (
170+
!Array.isArray(compatibility) ||
171+
compatibility.length === 0 ||
172+
dataSourceId === undefined
173+
) {
170174
return true;
171175
}
172176

173-
const dataSourceVersion = await getEffectiveVersion(dataSourceId);
174-
const [effectiveMajorVersion, effectiveMinorVersion] = dataSourceVersion.split('.').map(Number);
175-
177+
const dataSourceVersion =
178+
(await getDataSourceVersion(dataSourceId)) || MIN_SUPPORTED_VERSION;
179+
const [
180+
effectiveMajorVersion,
181+
effectiveMinorVersion,
182+
] = dataSourceVersion.split('.').map(Number);
183+
176184
// Checks if any version in compatibility array matches the current dataSourceVersion (major.minor)
177-
return compatibility.some(compatibleVersion => {
178-
const [compatibleMajor, compatibleMinor] = compatibleVersion.split('.').map(Number);
179-
return effectiveMajorVersion === compatibleMajor && effectiveMinorVersion === compatibleMinor;
185+
return compatibility.some((compatibleVersion) => {
186+
const [compatibleMajor, compatibleMinor] = compatibleVersion
187+
.split('.')
188+
.map(Number);
189+
return (
190+
effectiveMajorVersion === compatibleMajor &&
191+
effectiveMinorVersion === compatibleMinor
192+
);
180193
});
181194
}
182195

183-
184196
export function isValidUiWorkflow(workflowObj: any): boolean {
185197
return (
186198
isValidWorkflow(workflowObj) &&
@@ -561,7 +573,7 @@ export function useDataSourceVersion(
561573
useEffect(() => {
562574
async function getVersion() {
563575
if (dataSourceId !== undefined) {
564-
setDataSourceVersion(await getEffectiveVersion(dataSourceId));
576+
setDataSourceVersion(await getDataSourceVersion(dataSourceId));
565577
}
566578
}
567579
getVersion();
@@ -933,13 +945,13 @@ export function getFieldValue(jsonObj: {}, fieldName: string): any | undefined {
933945
return undefined;
934946
}
935947

936-
// Get the version from the selected data source
937-
export const getEffectiveVersion = async (
948+
// Get the version from the selected data source, if found
949+
export const getDataSourceVersion = async (
938950
dataSourceId: string | undefined
939-
): Promise<string> => {
951+
): Promise<string | undefined> => {
940952
try {
941953
if (dataSourceId === undefined) {
942-
throw new Error('Data source is required');
954+
throw new Error();
943955
}
944956

945957
if (dataSourceId === '') {
@@ -951,16 +963,26 @@ export const getEffectiveVersion = async (
951963
'data-source',
952964
dataSourceId
953965
);
954-
const version =
955-
dataSource?.attributes?.dataSourceVersion || MIN_SUPPORTED_VERSION;
956-
return version;
966+
return dataSource?.attributes?.dataSourceVersion;
957967
} catch (error) {
958-
console.error('Error getting version:', error);
959-
return MIN_SUPPORTED_VERSION;
968+
console.error('Error getting version: ', error);
969+
return undefined;
960970
}
961971
};
962972

963-
973+
export function useMissingDataSourceVersion(
974+
dataSourceId: string | undefined,
975+
dataSourceVersion: string | undefined
976+
): boolean {
977+
const [missingVersion, setMissingVersion] = useState<boolean>(false);
978+
useEffect(() => {
979+
setMissingVersion(
980+
dataSourceId !== undefined && dataSourceVersion === undefined
981+
);
982+
}, [dataSourceId, dataSourceVersion]);
983+
return missingVersion;
984+
}
985+
964986
/**
965987
* Formats version string to show only major.minor numbers
966988
* Example: "3.0.0-alpha1" -> "3.0"
@@ -970,4 +992,3 @@ export function formatDisplayVersion(version: string): string {
970992
const [major, minor] = version.split('.');
971993
return `${major}.${minor}`;
972994
}
973-

0 commit comments

Comments
 (0)