From 3e37d64260d79cb8ca508695ffbf929a65efe3dd Mon Sep 17 00:00:00 2001 From: mbondyra Date: Wed, 28 Jan 2026 11:23:25 +0100 Subject: [PATCH 1/3] [CPS] Support CPS in ESQL Vega and display override badge on Dashboard when overwritten --- .../vega/public/data_model/search_api.ts | 3 +- .../extract_project_routing_overrides.test.ts | 75 +++++++++++++++++++ .../lib/extract_project_routing_overrides.ts | 61 +++++++++++++++ .../vis_types/vega/public/vega_type.ts | 11 +++ .../visualizations/public/embeddable/types.ts | 2 + .../embeddable/visualize_embeddable.tsx | 21 ++++++ .../public/vis_types/base_vis_type.ts | 2 + .../visualizations/public/vis_types/types.ts | 8 ++ .../components/visualize_byvalue_editor.tsx | 6 +- 9 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 src/platform/plugins/private/vis_types/vega/public/lib/extract_project_routing_overrides.test.ts create mode 100644 src/platform/plugins/private/vis_types/vega/public/lib/extract_project_routing_overrides.ts diff --git a/src/platform/plugins/private/vis_types/vega/public/data_model/search_api.ts b/src/platform/plugins/private/vis_types/vega/public/data_model/search_api.ts index 8b6110519f390..df5878b30dd9f 100644 --- a/src/platform/plugins/private/vis_types/vega/public/data_model/search_api.ts +++ b/src/platform/plugins/private/vis_types/vega/public/data_model/search_api.ts @@ -57,7 +57,7 @@ export class SearchAPI { public readonly inspectorAdapters?: VegaInspectorAdapters, private readonly searchSessionId?: string, private readonly executionContext?: KibanaExecutionContext, - private readonly projectRouting?: ProjectRouting + public readonly projectRouting?: ProjectRouting ) {} search(searchRequests: SearchRequest[]) { @@ -160,6 +160,7 @@ export class SearchAPI { abortSignal: this.abortSignal, sessionId: this.searchSessionId, executionContext: this.executionContext, + projectRouting: this.projectRouting, } ) .pipe( diff --git a/src/platform/plugins/private/vis_types/vega/public/lib/extract_project_routing_overrides.test.ts b/src/platform/plugins/private/vis_types/vega/public/lib/extract_project_routing_overrides.test.ts new file mode 100644 index 0000000000000..a3e19d0a68e4f --- /dev/null +++ b/src/platform/plugins/private/vis_types/vega/public/lib/extract_project_routing_overrides.test.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { extractProjectRoutingOverrides } from './extract_project_routing_overrides'; + +describe('extractProjectRoutingOverrides', () => { + it('should extract project routing from ES|QL query with SET instruction', () => { + const spec = { + data: { + name: 'metric', + url: { + '%type%': 'esql', + query: 'SET project_routing = "_alias:_origin"; FROM logs-* | STATS count=COUNT()', + }, + }, + }; + + const result = extractProjectRoutingOverrides(spec); + + expect(result).toEqual([{ name: 'metric', value: '_alias:_origin' }]); + }); + it('should extract project routing from ES|QL query with multiple sources', () => { + const spec = { + data: [ + { + name: 'metric', + url: { + '%type%': 'esql', + query: + 'SET project_routing = "_alias:_origin"; FROM kibana_sample_data_logs | STATS total=COUNT()', + }, + }, + { + name: 'metric2', + url: { + '%type%': 'esql', + query: + 'SET project_routing = "_alias:*"; FROM kibana_sample_data_logs | STATS total=COUNT()', + }, + }, + ], + }; + + const result = extractProjectRoutingOverrides(spec); + + expect(result).toEqual([ + { name: 'metric', value: '_alias:_origin' }, + { name: 'metric2', value: '_alias:*' }, + ]); + }); + + it('should return undefined when no ES|QL queries with project routing', () => { + const spec = { + data: [ + { + name: 'regular', + url: { + '%type%': 'elasticsearch', + index: 'logs-*', + }, + }, + ], + }; + + const result = extractProjectRoutingOverrides(spec); + + expect(result).toBeUndefined(); + }); +}); diff --git a/src/platform/plugins/private/vis_types/vega/public/lib/extract_project_routing_overrides.ts b/src/platform/plugins/private/vis_types/vega/public/lib/extract_project_routing_overrides.ts new file mode 100644 index 0000000000000..cc7f7c2936f8c --- /dev/null +++ b/src/platform/plugins/private/vis_types/vega/public/lib/extract_project_routing_overrides.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { getProjectRoutingFromEsqlQuery } from '@kbn/esql-utils'; +import type { ProjectRoutingOverrides } from '@kbn/presentation-publishing'; + +interface DataUrl { + '%type%'?: string; + query?: string; +} + +interface DataObject { + name?: string; + url?: string | DataUrl; +} + +interface VegaSpec { + data?: DataObject | DataObject[]; + [key: string]: unknown; +} + +/** + * Extracts project routing overrides from a Vega specification. + * Searches for ES|QL queries in the data.url objects and extracts project routing information. + */ +export function extractProjectRoutingOverrides(spec: VegaSpec): ProjectRoutingOverrides { + const overrides: Array<{ name?: string; value: string }> = []; + + const processDataObject = (dataObj: DataObject) => { + if (dataObj.url && typeof dataObj.url === 'object') { + const dataUrl = dataObj.url as DataUrl; + // Check if this is an ES|QL data source + if (dataUrl['%type%'] === 'esql' && typeof dataUrl.query === 'string') { + const projectRoutingValue = getProjectRoutingFromEsqlQuery(dataUrl.query); + if (projectRoutingValue) { + overrides.push({ + name: dataObj.name, + value: projectRoutingValue, + }); + } + } + } + }; + + // Process data field + if (spec.data) { + if (Array.isArray(spec.data)) { + spec.data.forEach(processDataObject); + } else if (typeof spec.data === 'object') { + processDataObject(spec.data); + } + } + + return overrides.length > 0 ? overrides : undefined; +} diff --git a/src/platform/plugins/private/vis_types/vega/public/vega_type.ts b/src/platform/plugins/private/vis_types/vega/public/vega_type.ts index 1fde88b37e107..429d1444f0e66 100644 --- a/src/platform/plugins/private/vis_types/vega/public/vega_type.ts +++ b/src/platform/plugins/private/vis_types/vega/public/vega_type.ts @@ -16,6 +16,7 @@ import { VIS_EVENT_TO_TRIGGER, VisGroups } from '@kbn/visualizations-plugin/publ import { getDefaultSpec } from './default_spec'; import { extractIndexPatternsFromSpec } from './lib/extract_index_pattern'; +import { extractProjectRoutingOverrides } from './lib/extract_project_routing_overrides'; import { createInspectorAdapters } from './vega_inspector'; import { toExpressionAst } from './to_ast'; import { getInfoMessage } from './components/vega_info_message'; @@ -60,6 +61,16 @@ export const vegaVisType: VisTypeDefinition = { } return []; }, + getProjectRoutingOverrides: async (visParams) => { + try { + const spec = parse(visParams.spec, { legacyRoot: false, keepWsc: true }); + + return extractProjectRoutingOverrides(spec); + } catch (e) { + // spec is invalid + } + return undefined; + }, inspectorAdapters: createInspectorAdapters, /** * This is necessary for showing actions bar in top of vega editor diff --git a/src/platform/plugins/shared/visualizations/public/embeddable/types.ts b/src/platform/plugins/shared/visualizations/public/embeddable/types.ts index 8df0de4edac92..7992b73627a58 100644 --- a/src/platform/plugins/shared/visualizations/public/embeddable/types.ts +++ b/src/platform/plugins/shared/visualizations/public/embeddable/types.ts @@ -18,6 +18,7 @@ import type { HasSupportedTriggers, PublishesDataLoading, PublishesDataViews, + PublishesProjectRoutingOverrides, PublishesRendered, PublishesTimeRange, PublishesTitle, @@ -59,6 +60,7 @@ export type VisualizeApi = Partial & PublishesDataViews & PublishesDataLoading & PublishesRendered & + PublishesProjectRoutingOverrides & Required & HasVisualizeConfig & HasInspectorAdapters & diff --git a/src/platform/plugins/shared/visualizations/public/embeddable/visualize_embeddable.tsx b/src/platform/plugins/shared/visualizations/public/embeddable/visualize_embeddable.tsx index 82507c47ae71f..d1fe58168b985 100644 --- a/src/platform/plugins/shared/visualizations/public/embeddable/visualize_embeddable.tsx +++ b/src/platform/plugins/shared/visualizations/public/embeddable/visualize_embeddable.tsx @@ -34,6 +34,7 @@ import { titleComparators, useBatchedPublishingSubjects, useStateFromPublishingSubject, + type ProjectRoutingOverrides, } from '@kbn/presentation-publishing'; import { apiPublishesSearchSession } from '@kbn/presentation-publishing/interfaces/fetch/publishes_search_session'; import { get, isEqual } from 'lodash'; @@ -88,6 +89,16 @@ export const getVisualizeEmbeddableFactory: (deps: { const initialVisInstance = await createVisInstance(runtimeState.serializedVis); const vis$ = new BehaviorSubject(initialVisInstance); + let initialProjectRoutingOverrides: ProjectRoutingOverrides; + if (initialVisInstance.type.getProjectRoutingOverrides) { + initialProjectRoutingOverrides = await initialVisInstance.type.getProjectRoutingOverrides( + initialVisInstance.params + ); + } + const projectRoutingOverrides$ = new BehaviorSubject( + initialProjectRoutingOverrides + ); + // Track UI state const onUiStateChange = () => serializedVis$.next(vis$.getValue().serialize()); @@ -100,6 +111,15 @@ export const getVisualizeEmbeddableFactory: (deps: { const vis = await createVisInstance(serializedVis); vis.uiState.on('change', onUiStateChange); vis$.next(vis); + + // Update project routing overrides when vis changes + if (vis.type.getProjectRoutingOverrides) { + const newOverrides = await vis.type.getProjectRoutingOverrides(vis.params); + if (!isEqual(projectRoutingOverrides$.getValue(), newOverrides)) { + projectRoutingOverrides$.next(newOverrides); + } + } + const { params, abortController } = await getExpressionParams(); return { params, abortController }; }) @@ -235,6 +255,7 @@ export const getVisualizeEmbeddableFactory: (deps: { defaultTitle$, dataLoading$, dataViews$: new BehaviorSubject(initialDataViews), + projectRoutingOverrides$, rendered$: hasRendered$, supportedTriggers: () => [ACTION_CONVERT_TO_LENS, APPLY_FILTER_TRIGGER, SELECT_RANGE_TRIGGER], serializeState: () => { diff --git a/src/platform/plugins/shared/visualizations/public/vis_types/base_vis_type.ts b/src/platform/plugins/shared/visualizations/public/vis_types/base_vis_type.ts index e7519729eaa03..f01c361d09b48 100644 --- a/src/platform/plugins/shared/visualizations/public/vis_types/base_vis_type.ts +++ b/src/platform/plugins/shared/visualizations/public/vis_types/base_vis_type.ts @@ -47,6 +47,7 @@ export class BaseVisType { public readonly hierarchicalData; public readonly setup; public readonly getUsedIndexPattern; + public readonly getProjectRoutingOverrides; public readonly inspectorAdapters; public readonly fetchDatatable: boolean; public readonly toExpressionAst; @@ -83,6 +84,7 @@ export class BaseVisType { this.hasPartialRows = opts.hasPartialRows ?? false; this.hierarchicalData = opts.hierarchicalData ?? false; this.getUsedIndexPattern = opts.getUsedIndexPattern; + this.getProjectRoutingOverrides = opts.getProjectRoutingOverrides; this.inspectorAdapters = opts.inspectorAdapters; this.fetchDatatable = opts.fetchDatatable ?? false; this.toExpressionAst = opts.toExpressionAst; diff --git a/src/platform/plugins/shared/visualizations/public/vis_types/types.ts b/src/platform/plugins/shared/visualizations/public/vis_types/types.ts index 6b592833d8d86..a72859d88cdac 100644 --- a/src/platform/plugins/shared/visualizations/public/vis_types/types.ts +++ b/src/platform/plugins/shared/visualizations/public/vis_types/types.ts @@ -127,6 +127,14 @@ export interface VisTypeDefinition { */ readonly getUsedIndexPattern?: (visParams: VisParams) => DataView[] | Promise; + /** + * Vega may provide project routing overrides. + * This method should return an array of project routing values extracted from the vega spec. + */ + readonly getProjectRoutingOverrides?: ( + visParams: VisParams + ) => Promise | undefined>; + readonly isAccessible?: boolean; /** * It is the visualization icon, displayed on the wizard. diff --git a/src/platform/plugins/shared/visualizations/public/visualize_app/components/visualize_byvalue_editor.tsx b/src/platform/plugins/shared/visualizations/public/visualize_app/components/visualize_byvalue_editor.tsx index 7cb0ed0848073..551abcceb9ab6 100644 --- a/src/platform/plugins/shared/visualizations/public/visualize_app/components/visualize_byvalue_editor.tsx +++ b/src/platform/plugins/shared/visualizations/public/visualize_app/components/visualize_byvalue_editor.tsx @@ -24,6 +24,7 @@ import { import type { VisualizeServices } from '../types'; import { VisualizeEditorCommon } from './visualize_editor_common'; import type { VisualizeAppProps } from '../app'; +import { useProjectRouting } from '../utils/use/use_project_routing'; export const VisualizeByValueEditor = ({ onAppLeave }: VisualizeAppProps) => { const [originatingApp, setOriginatingApp] = useState(); @@ -76,13 +77,16 @@ export const VisualizeByValueEditor = ({ onAppLeave }: VisualizeAppProps) => { eventEmitter, byValueVisInstance ); + // Initialize CPS project routing manager for Vega + const projectRoutingManager = useProjectRouting(services); const { isEmbeddableRendered, currentAppState } = useEditorUpdates( services, eventEmitter, setHasUnsavedChanges, appState, byValueVisInstance, - visEditorController + visEditorController, + projectRoutingManager ); useLinkedSearchUpdates(services, eventEmitter, appState, byValueVisInstance); useDataViewUpdates(services, eventEmitter, appState, byValueVisInstance); From 61f46bdc15af1fcb489727448b10ff301495c8b2 Mon Sep 17 00:00:00 2001 From: mbondyra Date: Wed, 28 Jan 2026 11:23:43 +0100 Subject: [PATCH 2/3] non-mergeable workaround to test --- .../server/search/strategies/common/async_utils.ts | 4 +--- .../strategies/es_search/es_search_strategy.ts | 7 ++++++- .../strategies/ese_search/ese_search_strategy.ts | 12 ++++++++++++ .../search/strategies/ese_search/request_utils.ts | 2 +- .../esql_async_search/esql_async_search_strategy.ts | 1 + .../strategies/esql_search/esql_search_strategy.ts | 1 + 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/platform/plugins/shared/data/server/search/strategies/common/async_utils.ts b/src/platform/plugins/shared/data/server/search/strategies/common/async_utils.ts index 5d1d8be8cc8fa..359a566f4555b 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/common/async_utils.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/common/async_utils.ts @@ -29,7 +29,7 @@ export function getCommonDefaultAsyncSubmitParams( ): Pick< AsyncSearchSubmitRequest, 'keep_alive' | 'wait_for_completion_timeout' | 'keep_on_completion' -> & { project_routing?: string } { +> { const useSearchSessions = config.sessions.enabled && !!options.sessionId && !overrides?.disableSearchSessions; const keepAlive = @@ -44,8 +44,6 @@ export function getCommonDefaultAsyncSubmitParams( keep_on_completion: useSearchSessions, // The initial keepalive is as defined in defaultExpiration if search sessions are used or 1m otherwise. keep_alive: keepAlive, - // Pass project routing for CPS if available - ...(options.projectRouting !== undefined && { project_routing: options.projectRouting }), }; } diff --git a/src/platform/plugins/shared/data/server/search/strategies/es_search/es_search_strategy.ts b/src/platform/plugins/shared/data/server/search/strategies/es_search/es_search_strategy.ts index f68ec28ab2de1..ae7a1e0301d59 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/es_search/es_search_strategy.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/es_search/es_search_strategy.ts @@ -70,9 +70,14 @@ export const esSearchStrategyProvider = ( ...defaults, ...getShardTimeout(config), ...(terminateAfter ? { terminate_after: terminateAfter } : {}), - ...(options.projectRouting !== undefined && { project_routing: options.projectRouting }), ...requestParams, }; + + // If project_routing is present, explicitly pass it to override + if (options.projectRouting !== undefined) { + params.project_routing = options.projectRouting; + } + const { body, meta } = await esClient.asCurrentUser.search(params, { signal: abortSignal, ...transport, diff --git a/src/platform/plugins/shared/data/server/search/strategies/ese_search/ese_search_strategy.ts b/src/platform/plugins/shared/data/server/search/strategies/ese_search/ese_search_strategy.ts index edba475faf8a6..f48cdfff74894 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/ese_search/ese_search_strategy.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/ese_search/ese_search_strategy.ts @@ -100,10 +100,22 @@ export const enhancedEsSearchStrategyProvider = ( { esClient, uiSettingsClient }: SearchStrategyDependencies ) { const client = useInternalUser ? esClient.asInternalUser : esClient.asCurrentUser; + const params = { ...(await getDefaultAsyncSubmitParams(uiSettingsClient, searchConfig, options, isServerless)), ...request.params, }; + + // If project_routing is present, explicitly pass it in the body to override + if ( + options.projectRouting !== undefined && + typeof params.body === 'object' && + params.body !== null + ) { + // @ts-expect-error project_routing missing in body type + params.body.project_routing = options.projectRouting; + } + const { body, headers, meta } = await client.asyncSearch.submit(params, { ...options.transport, signal: options.abortSignal, diff --git a/src/platform/plugins/shared/data/server/search/strategies/ese_search/request_utils.ts b/src/platform/plugins/shared/data/server/search/strategies/ese_search/request_utils.ts index 931bcc0152be6..957343be6974a 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/ese_search/request_utils.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/ese_search/request_utils.ts @@ -49,7 +49,7 @@ export async function getDefaultAsyncSubmitParams( | 'ignore_unavailable' | 'track_total_hits' | 'keep_on_completion' - > & { project_routing?: string } + > > { return { // TODO: adjust for partial results diff --git a/src/platform/plugins/shared/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts b/src/platform/plugins/shared/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts index 1c8221521d377..241443c750302 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts @@ -113,6 +113,7 @@ export const esqlAsyncSearchStrategyProvider = ( const params = { ...(await getCommonDefaultAsyncSubmitParams(searchConfig, options)), ...requestParams, + project_routing: options.projectRouting, }; return esClient.asCurrentUser.transport.request( diff --git a/src/platform/plugins/shared/data/server/search/strategies/esql_search/esql_search_strategy.ts b/src/platform/plugins/shared/data/server/search/strategies/esql_search/esql_search_strategy.ts index 53c44152e9cdf..c2d3e145d70a8 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/esql_search/esql_search_strategy.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/esql_search/esql_search_strategy.ts @@ -45,6 +45,7 @@ export const esqlSearchStrategyProvider = ( querystring: dropNullColumns ? 'drop_null_columns' : '', body: { ...requestParams, + project_routing: options.projectRouting, }, }, { From 2bb9f1158a8ab8fee7cb9fd099e59c64cc54b689 Mon Sep 17 00:00:00 2001 From: mbondyra Date: Wed, 28 Jan 2026 11:24:02 +0100 Subject: [PATCH 3/3] Revert "non-mergeable workaround to test" This reverts commit 61f46bdc15af1fcb489727448b10ff301495c8b2. --- .../server/search/strategies/common/async_utils.ts | 4 +++- .../strategies/es_search/es_search_strategy.ts | 7 +------ .../strategies/ese_search/ese_search_strategy.ts | 12 ------------ .../search/strategies/ese_search/request_utils.ts | 2 +- .../esql_async_search/esql_async_search_strategy.ts | 1 - .../strategies/esql_search/esql_search_strategy.ts | 1 - 6 files changed, 5 insertions(+), 22 deletions(-) diff --git a/src/platform/plugins/shared/data/server/search/strategies/common/async_utils.ts b/src/platform/plugins/shared/data/server/search/strategies/common/async_utils.ts index 359a566f4555b..5d1d8be8cc8fa 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/common/async_utils.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/common/async_utils.ts @@ -29,7 +29,7 @@ export function getCommonDefaultAsyncSubmitParams( ): Pick< AsyncSearchSubmitRequest, 'keep_alive' | 'wait_for_completion_timeout' | 'keep_on_completion' -> { +> & { project_routing?: string } { const useSearchSessions = config.sessions.enabled && !!options.sessionId && !overrides?.disableSearchSessions; const keepAlive = @@ -44,6 +44,8 @@ export function getCommonDefaultAsyncSubmitParams( keep_on_completion: useSearchSessions, // The initial keepalive is as defined in defaultExpiration if search sessions are used or 1m otherwise. keep_alive: keepAlive, + // Pass project routing for CPS if available + ...(options.projectRouting !== undefined && { project_routing: options.projectRouting }), }; } diff --git a/src/platform/plugins/shared/data/server/search/strategies/es_search/es_search_strategy.ts b/src/platform/plugins/shared/data/server/search/strategies/es_search/es_search_strategy.ts index ae7a1e0301d59..f68ec28ab2de1 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/es_search/es_search_strategy.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/es_search/es_search_strategy.ts @@ -70,14 +70,9 @@ export const esSearchStrategyProvider = ( ...defaults, ...getShardTimeout(config), ...(terminateAfter ? { terminate_after: terminateAfter } : {}), + ...(options.projectRouting !== undefined && { project_routing: options.projectRouting }), ...requestParams, }; - - // If project_routing is present, explicitly pass it to override - if (options.projectRouting !== undefined) { - params.project_routing = options.projectRouting; - } - const { body, meta } = await esClient.asCurrentUser.search(params, { signal: abortSignal, ...transport, diff --git a/src/platform/plugins/shared/data/server/search/strategies/ese_search/ese_search_strategy.ts b/src/platform/plugins/shared/data/server/search/strategies/ese_search/ese_search_strategy.ts index f48cdfff74894..edba475faf8a6 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/ese_search/ese_search_strategy.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/ese_search/ese_search_strategy.ts @@ -100,22 +100,10 @@ export const enhancedEsSearchStrategyProvider = ( { esClient, uiSettingsClient }: SearchStrategyDependencies ) { const client = useInternalUser ? esClient.asInternalUser : esClient.asCurrentUser; - const params = { ...(await getDefaultAsyncSubmitParams(uiSettingsClient, searchConfig, options, isServerless)), ...request.params, }; - - // If project_routing is present, explicitly pass it in the body to override - if ( - options.projectRouting !== undefined && - typeof params.body === 'object' && - params.body !== null - ) { - // @ts-expect-error project_routing missing in body type - params.body.project_routing = options.projectRouting; - } - const { body, headers, meta } = await client.asyncSearch.submit(params, { ...options.transport, signal: options.abortSignal, diff --git a/src/platform/plugins/shared/data/server/search/strategies/ese_search/request_utils.ts b/src/platform/plugins/shared/data/server/search/strategies/ese_search/request_utils.ts index 957343be6974a..931bcc0152be6 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/ese_search/request_utils.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/ese_search/request_utils.ts @@ -49,7 +49,7 @@ export async function getDefaultAsyncSubmitParams( | 'ignore_unavailable' | 'track_total_hits' | 'keep_on_completion' - > + > & { project_routing?: string } > { return { // TODO: adjust for partial results diff --git a/src/platform/plugins/shared/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts b/src/platform/plugins/shared/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts index 241443c750302..1c8221521d377 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts @@ -113,7 +113,6 @@ export const esqlAsyncSearchStrategyProvider = ( const params = { ...(await getCommonDefaultAsyncSubmitParams(searchConfig, options)), ...requestParams, - project_routing: options.projectRouting, }; return esClient.asCurrentUser.transport.request( diff --git a/src/platform/plugins/shared/data/server/search/strategies/esql_search/esql_search_strategy.ts b/src/platform/plugins/shared/data/server/search/strategies/esql_search/esql_search_strategy.ts index c2d3e145d70a8..53c44152e9cdf 100644 --- a/src/platform/plugins/shared/data/server/search/strategies/esql_search/esql_search_strategy.ts +++ b/src/platform/plugins/shared/data/server/search/strategies/esql_search/esql_search_strategy.ts @@ -45,7 +45,6 @@ export const esqlSearchStrategyProvider = ( querystring: dropNullColumns ? 'drop_null_columns' : '', body: { ...requestParams, - project_routing: options.projectRouting, }, }, {