diff --git a/public/components/FeatureAnywhereContextMenu/CreateAnomalyDetector/AddAnomalyDetector.tsx b/public/components/FeatureAnywhereContextMenu/CreateAnomalyDetector/AddAnomalyDetector.tsx index 486324c0..1b4fd4ba 100644 --- a/public/components/FeatureAnywhereContextMenu/CreateAnomalyDetector/AddAnomalyDetector.tsx +++ b/public/components/FeatureAnywhereContextMenu/CreateAnomalyDetector/AddAnomalyDetector.tsx @@ -96,6 +96,7 @@ import { getUISettings, getUiActions, getQueryService, + getSavedObjectsClient, } from '../../../../public/services'; import { prettifyErrorMessage } from '../../../../server/utils/helpers'; import { @@ -112,6 +113,12 @@ import { FLYOUT_MODES } from '../AnywhereParentFlyout/constants'; import { DetectorListItem } from '../../../../public/models/interfaces'; import { VisualizeEmbeddable } from '../../../../../../src/plugins/visualizations/public'; +interface References { + id: string; + name: string; + type: string; +} + function AddAnomalyDetector({ embeddable, closeFlyout, @@ -126,24 +133,42 @@ function AddAnomalyDetector({ VisualizeEmbeddable | ErrorEmbeddable >(); + const indexPatternId = embeddable.vis.data.aggs.indexPattern.id; + const [dataSourceId, setDataSourceId] = useState(undefined); + + async function getDataSourceId() { + try { + const indexPattern = await getSavedObjectsClient().get('index-pattern', indexPatternId); + const refs = indexPattern.references as References[]; + const foundDataSourceId = refs.find(ref => ref.type === 'data-source')?.id; + setDataSourceId(foundDataSourceId); + } catch (error) { + console.error("Error fetching index pattern:", error); + } + } + + // useEffect to dispatch actions once dataSourceId fetch is complete useEffect(() => { - const getInitialIndices = async () => { - await dispatch(getIndices(queryText)); - }; - getInitialIndices(); - dispatch(getMappings(embeddable.vis.data.aggs.indexPattern.title)); + async function fetchData() { + await getDataSourceId(); - const createEmbeddable = async () => { + const getIndicesDispatchCall = dispatch(getIndices(queryText, dataSourceId)); + const getMappingDispatchCall = dispatch(getMappings(embeddable.vis.data.aggs.indexPattern.title, dataSourceId)); + await Promise.all([getIndicesDispatchCall, getMappingDispatchCall]); + } + + async function createEmbeddable() { const visEmbeddable = await fetchVisEmbeddable( embeddable.vis.id, getEmbeddable(), getQueryService() ); setGeneratedEmbeddable(visEmbeddable); - }; - + } + fetchData(); createEmbeddable(); - }, []); + }, [dataSourceId]); + const [isShowVis, setIsShowVis] = useState(false); const [accordionsOpen, setAccordionsOpen] = useState({ modelFeatures: true }); const [detectorNameFromVis, setDetectorNameFromVis] = useState( @@ -310,6 +335,7 @@ function AddAnomalyDetector({ name: OVERLAY_ANOMALIES, args: { detectorId: detectorId, + dataSourceId: dataSourceId }, } as VisLayerExpressionFn; @@ -338,7 +364,7 @@ function AddAnomalyDetector({ formikProps.setSubmitting(true); try { const detectorToCreate = formikToDetector(formikProps.values); - await dispatch(createDetector(detectorToCreate)) + await dispatch(createDetector(detectorToCreate, dataSourceId)) .then(async (response) => { dispatch(startDetector(response.response.id)) .then((startDetectorResponse) => {}) @@ -410,7 +436,7 @@ function AddAnomalyDetector({ }); }) .catch((err: any) => { - dispatch(getDetectorCount()).then((response: any) => { + dispatch(getDetectorCount(dataSourceId)).then((response: any) => { const totalDetectors = get(response, 'response.count', 0); if (totalDetectors === MAX_DETECTORS) { notifications.toasts.addDanger( @@ -517,7 +543,7 @@ function AddAnomalyDetector({ if (error) { return error; } - const resp = await dispatch(matchDetector(detectorName)); + const resp = await dispatch(matchDetector(detectorName, dataSourceId)); const match = get(resp, 'response.match', false); if (!match) { return undefined; @@ -625,6 +651,7 @@ function AddAnomalyDetector({ embeddableVisId={embeddable.vis.id} selectedDetector={selectedDetector} setSelectedDetector={setSelectedDetector} + dataSourceId={dataSourceId} > )} {mode === FLYOUT_MODES.create && ( diff --git a/public/components/FeatureAnywhereContextMenu/CreateAnomalyDetector/AssociateExisting/containers/AssociateExisting.tsx b/public/components/FeatureAnywhereContextMenu/CreateAnomalyDetector/AssociateExisting/containers/AssociateExisting.tsx index cad7a718..cb3f29fd 100644 --- a/public/components/FeatureAnywhereContextMenu/CreateAnomalyDetector/AssociateExisting/containers/AssociateExisting.tsx +++ b/public/components/FeatureAnywhereContextMenu/CreateAnomalyDetector/AssociateExisting/containers/AssociateExisting.tsx @@ -47,11 +47,13 @@ import { PLUGIN_NAME, } from '../../../../../../public/utils/constants'; import { renderTime } from '../../../../../../public/pages/DetectorsList/utils/tableUtils'; +import { getAllDetectorsQueryParamsWithDataSourceId } from '../../../../../pages/utils/helpers'; interface AssociateExistingProps { embeddableVisId: string; selectedDetector: DetectorListItem | undefined; setSelectedDetector(detector: DetectorListItem | undefined): void; + dataSourceId: string | undefined; } export function AssociateExisting( @@ -147,7 +149,7 @@ export function AssociateExisting( }, []); const getDetectors = async () => { - dispatch(getDetectorList(GET_ALL_DETECTORS_QUERY_PARAMS)); + dispatch(getDetectorList(getAllDetectorsQueryParamsWithDataSourceId(associateExistingProps.dataSourceId))); }; const selectedOptions = useMemo(() => { diff --git a/public/expressions/helpers.ts b/public/expressions/helpers.ts index 298e14ba..c11ace78 100644 --- a/public/expressions/helpers.ts +++ b/public/expressions/helpers.ts @@ -33,7 +33,8 @@ export const getAnomalies = async ( detectorId: string, startTime: number, endTime: number, - resultIndex: string + resultIndex: string, + dataSourceId: string = '', ): Promise => { const anomalySummaryQuery = getAnomalySummaryQuery( startTime, @@ -45,14 +46,14 @@ export const getAnomalies = async ( let anomalySummaryResponse; if (resultIndex === '') { anomalySummaryResponse = await getClient().post( - `..${AD_NODE_API.DETECTOR}/results/_search`, + `..${AD_NODE_API.DETECTOR}/results/_search/${dataSourceId}`, { body: JSON.stringify(anomalySummaryQuery), } ); } else { anomalySummaryResponse = await getClient().post( - `..${AD_NODE_API.DETECTOR}/results/_search/${resultIndex}/true`, + `..${AD_NODE_API.DETECTOR}/results/_search/${resultIndex}/true/${dataSourceId}`, { body: JSON.stringify(anomalySummaryQuery), } @@ -62,11 +63,11 @@ export const getAnomalies = async ( return parsePureAnomalies(anomalySummaryResponse); }; -export const getDetectorResponse = async (detectorId: string) => { - const resp = await getClient().get(`..${AD_NODE_API.DETECTOR}/${detectorId}`); +export const getDetectorResponse = async (detectorId: string, dataSourceId: string = '') => { + const url = dataSourceId ? `..${AD_NODE_API.DETECTOR}/${detectorId}/${dataSourceId}` : `..${AD_NODE_API.DETECTOR}/${detectorId}`; + const resp = await getClient().get(url); return resp; }; - // This takes anomalies and returns them as vis layer of type PointInTimeEvents export const convertAnomaliesToPointInTimeEventsVisLayer = ( anomalies: AnomalyData[], diff --git a/public/expressions/overlay_anomalies.ts b/public/expressions/overlay_anomalies.ts index 0df420b2..ea701c2c 100644 --- a/public/expressions/overlay_anomalies.ts +++ b/public/expressions/overlay_anomalies.ts @@ -42,6 +42,7 @@ type Name = typeof OVERLAY_ANOMALIES; interface Arguments { detectorId: string; + dataSourceId: string; } export type OverlayAnomaliesExpressionFunctionDefinition = @@ -78,11 +79,17 @@ export const overlayAnomaliesFunction = default: '""', help: '', }, + dataSourceId: { + types: ['string'], + default: '""', + help: '', + }, }, async fn(input, args, context): Promise { // Parsing all of the args & input const detectorId = get(args, 'detectorId', ''); + const dataSourceId = get(args, 'dataSourceId', ''); const timeRange = get( context, 'searchContext.timeRange', @@ -103,7 +110,7 @@ export const overlayAnomaliesFunction = urlPath: `${PLUGIN_NAME}#/detectors/${detectorId}/results`, //details page for detector in AD plugin }; try { - const detectorResponse = await getDetectorResponse(detectorId); + const detectorResponse = await getDetectorResponse(detectorId, dataSourceId); if (get(detectorResponse, 'error', '').includes(CANT_FIND_KEY_WORD)) { throw new Error('Anomaly Detector - ' + DETECTOR_HAS_BEEN_DELETED); } else if (