diff --git a/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_preview.test.ts b/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_preview.test.ts index fc680213c1995d..3efece9d6286f6 100644 --- a/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_preview.test.ts +++ b/src/plugins/data_view_field_editor/__jest__/client_integration/field_editor_flyout_preview.test.ts @@ -292,8 +292,7 @@ describe('Field editor Preview panel', () => { subTitle: 'First doc - subTitle', title: 'First doc - title', }, - documentId: '001', - index: 'testIndexPattern', + index: 'testIndex', script: { source: 'echo("hello")', }, diff --git a/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx b/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx index 9f2ca0ef53e1b6..6e21cc00e5dd56 100644 --- a/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx +++ b/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx @@ -333,11 +333,10 @@ export const FieldPreviewProvider: FunctionComponent = ({ children }) => { const currentApiCall = ++previewCount.current; const response = await getFieldPreview({ - index: dataView.title, + index: currentDocIndex, document: document!, context: `${type!}_field` as PainlessExecuteContext, script: script!, - documentId: currentDocId, }); if (currentApiCall !== previewCount.current) { @@ -391,7 +390,7 @@ export const FieldPreviewProvider: FunctionComponent = ({ children }) => { allParamsDefined, scriptEditorValidation, hasSomeParamsChanged, - dataView.title, + currentDocIndex, ]); const goToNextDoc = useCallback(() => { diff --git a/src/plugins/data_view_field_editor/public/lib/api.ts b/src/plugins/data_view_field_editor/public/lib/api.ts index 67233db393cb80..723bc7483d33fd 100644 --- a/src/plugins/data_view_field_editor/public/lib/api.ts +++ b/src/plugins/data_view_field_editor/public/lib/api.ts @@ -16,13 +16,11 @@ export const initApi = (httpClient: HttpSetup) => { context, script, document, - documentId, }: { index: string; context: PainlessExecuteContext; script: { source: string } | null; document: Record; - documentId: string; }) => { return sendRequest(httpClient, { path: `${API_BASE_PATH}/field_preview`, @@ -32,7 +30,6 @@ export const initApi = (httpClient: HttpSetup) => { context, script, document, - documentId, }, }); }; diff --git a/src/plugins/data_view_field_editor/server/routes/field_preview.ts b/src/plugins/data_view_field_editor/server/routes/field_preview.ts index 5595eeeaeddfbf..6423694f76ec97 100644 --- a/src/plugins/data_view_field_editor/server/routes/field_preview.ts +++ b/src/plugins/data_view_field_editor/server/routes/field_preview.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { schema } from '@kbn/config-schema'; +import { HttpResponsePayload } from '@kbn/core/server'; import { API_BASE_PATH } from '../../common/constants'; import { RouteDependencies } from '../types'; @@ -26,7 +26,6 @@ const bodySchema = schema.object({ schema.literal('long_field'), ]), document: schema.object({}, { unknowns: 'allow' }), - documentId: schema.string(), }); export const registerFieldPreviewRoute = ({ router }: RouteDependencies): void => { @@ -40,48 +39,28 @@ export const registerFieldPreviewRoute = ({ router }: RouteDependencies): void = async (ctx, req, res) => { const { client } = (await ctx.core).elasticsearch; - const type = req.body.context.split('_field')[0] as estypes.MappingRuntimeFieldType; const body = { - runtime_mappings: { - my_runtime_field: { - type, - script: req.body.script, - }, - }, - size: 1, - query: { - term: { - _id: req.body.documentId, - }, + script: req.body.script, + context: req.body.context, + context_setup: { + document: req.body.document, + index: req.body.index, }, - fields: ['my_runtime_field'], }; try { - // Ideally we want to use the Painless _execute API to get the runtime field preview. - // There is a current ES limitation that requires a user to have too many privileges - // to execute the script. (issue: https://github.com/elastic/elasticsearch/issues/48856) - // Until we find a way to execute a script without advanced privileges we are going to - // use the Search API to get the field value (and possible errors). - // Note: here is the PR were we changed from using Painless _execute to _search and should be - // reverted when the ES issue is fixed: https://github.com/elastic/kibana/pull/115070 - const response = await client.asCurrentUser.search({ - index: req.body.index, - body, - }); - - const fieldValue = response.hits.hits[0]?.fields?.my_runtime_field ?? ''; + // client types need to be update to support this request format + // @ts-expect-error + const { result } = await client.asCurrentUser.scriptsPainlessExecute(body); + const fieldValue = result as HttpResponsePayload; return res.ok({ body: { values: fieldValue } }); - } catch (error: any) { + } catch (error) { // Assume invalid painless script was submitted // Return 200 with error object const handleCustomError = () => { return res.ok({ - body: { - values: [], - error: error.body.error.failed_shards[0]?.reason ?? {}, - }, + body: { values: [], ...error.body }, }); }; diff --git a/test/api_integration/apis/data_view_field_editor/field_preview.ts b/test/api_integration/apis/data_view_field_editor/field_preview.ts index 0c2446af541e93..d1943983683f1d 100644 --- a/test/api_integration/apis/data_view_field_editor/field_preview.ts +++ b/test/api_integration/apis/data_view_field_editor/field_preview.ts @@ -13,7 +13,6 @@ import { FtrProviderContext } from '../../ftr_provider_context'; import { API_BASE_PATH } from './constants'; const INDEX_NAME = 'api-integration-test-field-preview'; -const DOC_ID = '1'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); @@ -39,15 +38,6 @@ export default function ({ getService }: FtrProviderContext) { }); }; - const addDoc = async () => { - await es.index({ - index: INDEX_NAME, - id: DOC_ID, - body: document, - refresh: 'wait_for', - }); - }; - const deleteIndex = async () => { await es.indices.delete({ index: INDEX_NAME, @@ -55,10 +45,7 @@ export default function ({ getService }: FtrProviderContext) { }; describe('Field preview', function () { - before(async () => { - await createIndex(); - await addDoc(); - }); + before(async () => await createIndex()); after(async () => await deleteIndex()); describe('should return the script value', () => { @@ -91,7 +78,6 @@ export default function ({ getService }: FtrProviderContext) { const payload = { script: test.script, document, - documentId: DOC_ID, context: test.context, index: INDEX_NAME, }; @@ -153,7 +139,6 @@ export default function ({ getService }: FtrProviderContext) { script: { source: 'emit(123)' }, // We send a long but the type is "keyword" context: 'keyword_field', index: INDEX_NAME, - documentId: DOC_ID, }) .set('kbn-xsrf', 'xxx');