From ed19554ac4e61f4f1a6ba158713eb19155ec4a1e Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 14 Oct 2023 21:44:33 -0500
Subject: [PATCH 001/168] add stale while revalidate
---
.../rest_api_routes/internal/fields_for.ts | 32 ++++++++++++++-----
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
index 7d39b41d5caee..1f6965d060b73 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
@@ -113,8 +113,12 @@ const validate: FullValidationConfig = {
},
};
-const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, IBody> =
- (isRollupsEnabled) => async (context, request, response) => {
+const handler: (
+ isRollupsEnabled: () => boolean
+) => (cacheHeader: boolean) => RequestHandler<{}, IQuery, IBody> =
+ (isRollupsEnabled) =>
+ (cacheHeader = false) =>
+ async (context, request, response) => {
const { asCurrentUser } = (await context.core).elasticsearch.client;
const indexPatterns = new IndexPatternsFetcher(asCurrentUser, undefined, isRollupsEnabled());
const {
@@ -159,11 +163,19 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
indices,
};
+ const headers: Record = {
+ 'content-type': 'application/json',
+ // Etag?
+ // Expires
+ };
+
+ if (cacheHeader) {
+ headers['cache-control'] = 'private, max-age=31536000, stale-while-revalidate=86400';
+ }
+
return response.ok({
body,
- headers: {
- 'content-type': 'application/json',
- },
+ headers,
});
} catch (error) {
if (
@@ -196,12 +208,16 @@ export const registerFieldForWildcard = async (
const configuredHandler = handler(isRollupsEnabled);
// handler
- router.versioned.put({ path, access }).addVersion({ version, validate }, configuredHandler);
- router.versioned.post({ path, access }).addVersion({ version, validate }, configuredHandler);
+ router.versioned
+ .put({ path, access, options: {} })
+ .addVersion({ version, validate }, configuredHandler(false));
+ router.versioned
+ .post({ path, access })
+ .addVersion({ version, validate }, configuredHandler(false));
router.versioned
.get({ path, access })
.addVersion(
{ version, validate: { request: { query: querySchema }, response: validate.response } },
- configuredHandler
+ configuredHandler(true)
);
};
From da2dddc39e6b3c41095674817ade620a583b986c Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 14 Oct 2023 22:16:33 -0500
Subject: [PATCH 002/168] add cache busting
---
src/plugins/data_views/common/types.ts | 1 +
.../public/data_views/data_views_api_client.ts | 14 +++++++++++---
.../server/rest_api_routes/internal/fields_for.ts | 1 +
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/plugins/data_views/common/types.ts b/src/plugins/data_views/common/types.ts
index 522bec8873534..16190b233717d 100644
--- a/src/plugins/data_views/common/types.ts
+++ b/src/plugins/data_views/common/types.ts
@@ -314,6 +314,7 @@ export interface GetFieldsOptions {
includeUnmapped?: boolean;
fields?: string[];
allowHidden?: boolean;
+ forceRefresh?: boolean;
}
/**
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index bb53c68eafaa7..a31ea076e0e88 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -29,10 +29,16 @@ export class DataViewsApiClient implements IDataViewsApiClient {
this.http = http;
}
- private _request(url: string, query?: {}, body?: string): Promise {
+ private _request(
+ url: string,
+ query?: {},
+ body?: string,
+ forceRefresh?: boolean
+ ): Promise {
+ const headers = forceRefresh ? { cache: 'reload' } : undefined;
const request = body
? this.http.post(url, { query, body, version })
- : this.http.fetch(url, { query, version });
+ : this.http.fetch(url, { query, version, headers });
return request.catch((resp) => {
if (resp.body.statusCode === 404 && resp.body.attributes?.code === 'no_matching_indices') {
throw new DataViewMissingIndices(resp.body.message);
@@ -60,6 +66,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
indexFilter,
includeUnmapped,
fields,
+ forceRefresh,
} = options;
return this._request(
FIELDS_FOR_WILDCARD_PATH,
@@ -72,7 +79,8 @@ export class DataViewsApiClient implements IDataViewsApiClient {
include_unmapped: includeUnmapped,
fields,
},
- indexFilter ? JSON.stringify({ index_filter: indexFilter }) : undefined
+ indexFilter ? JSON.stringify({ index_filter: indexFilter }) : undefined,
+ forceRefresh
).then((response) => {
return response || { fields: [], indices: [] };
});
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
index 1f6965d060b73..d076894fb972f 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
@@ -170,6 +170,7 @@ const handler: (
};
if (cacheHeader) {
+ // revalidates if 5 minutes passed, otherwise caches for a year
headers['cache-control'] = 'private, max-age=31536000, stale-while-revalidate=86400';
}
From fdcbfb6a591225c3e1ed138c0bec35b7a06f2094 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 16 Oct 2023 22:17:50 -0500
Subject: [PATCH 003/168] garbage test code mostly to be removed later
---
src/plugins/data_views/common/types.ts | 3 ---
.../data_views/public/data_views/data_views_api_client.ts | 8 +++++++-
.../server/rest_api_routes/internal/fields_for.ts | 5 ++++-
3 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/src/plugins/data_views/common/types.ts b/src/plugins/data_views/common/types.ts
index 8a9ba90a158bb..b29ec67c71d60 100644
--- a/src/plugins/data_views/common/types.ts
+++ b/src/plugins/data_views/common/types.ts
@@ -309,11 +309,8 @@ export interface GetFieldsOptions {
indexFilter?: QueryDslQueryContainer;
includeUnmapped?: boolean;
fields?: string[];
-<<<<<<< HEAD
allowHidden?: boolean;
forceRefresh?: boolean;
-=======
->>>>>>> main
}
/**
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index a31ea076e0e88..9baaf93c91e22 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -35,7 +35,13 @@ export class DataViewsApiClient implements IDataViewsApiClient {
body?: string,
forceRefresh?: boolean
): Promise {
- const headers = forceRefresh ? { cache: 'reload' } : undefined;
+ console.log('HERE', new Date().getMinutes());
+ if (new Date().getMinutes() % 2 === 0) {
+ forceRefresh = true;
+ }
+ // const headers = forceRefresh ? { cache: 'reload' } : undefined;
+ const headers = forceRefresh ? { 'Cache-Control': 'no-cache' } : undefined;
+
const request = body
? this.http.post(url, { query, body, version })
: this.http.fetch(url, { query, version, headers });
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
index 52e7214762986..25048e52b85c1 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
@@ -161,13 +161,16 @@ const handler: (
const headers: Record = {
'content-type': 'application/json',
+ Etag: '123456',
+ 'If-None-Match': '123456',
// Etag?
// Expires
};
if (cacheHeader) {
// revalidates if 5 minutes passed, otherwise caches for a year
- headers['cache-control'] = 'private, max-age=31536000, stale-while-revalidate=86400';
+ // headers['cache-control'] = 'private, max-age=31536000, stale-while-revalidate=86400';
+ headers['cache-control'] = 'max-age=31536000, stale-while-revalidate=86400';
}
return response.ok({
From 7f0609591a0baef95189a8de8cb632e26cf4431a Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Sun, 29 Oct 2023 23:45:45 -0500
Subject: [PATCH 004/168] Update
src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
Co-authored-by: Davis McPhee
---
.../data_views/server/rest_api_routes/internal/fields_for.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
index d076894fb972f..d5d93163356f2 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
@@ -171,7 +171,7 @@ const handler: (
if (cacheHeader) {
// revalidates if 5 minutes passed, otherwise caches for a year
- headers['cache-control'] = 'private, max-age=31536000, stale-while-revalidate=86400';
+ headers['cache-control'] = 'private, max-age=300, stale-while-revalidate=2592000';
}
return response.ok({
From 671461f5ae65fd35bec09186fb6b223bf788179b Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Tue, 31 Oct 2023 21:41:59 -0500
Subject: [PATCH 005/168] Update
src/plugins/data_views/public/data_views/data_views_api_client.ts
Co-authored-by: Davis McPhee
---
.../data_views/public/data_views/data_views_api_client.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index a31ea076e0e88..ec496721b7b94 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -35,7 +35,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
body?: string,
forceRefresh?: boolean
): Promise {
- const headers = forceRefresh ? { cache: 'reload' } : undefined;
+ const cacheOptions = forceRefresh ? { cache: 'reload' } : {};
const request = body
? this.http.post(url, { query, body, version })
: this.http.fetch(url, { query, version, headers });
From 2c61688283e1c151a6a113e42c3914ffd465baf9 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Tue, 31 Oct 2023 21:42:07 -0500
Subject: [PATCH 006/168] Update
src/plugins/data_views/public/data_views/data_views_api_client.ts
Co-authored-by: Davis McPhee
---
.../data_views/public/data_views/data_views_api_client.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index ec496721b7b94..cb069d9dff6bf 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -38,7 +38,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
const cacheOptions = forceRefresh ? { cache: 'reload' } : {};
const request = body
? this.http.post(url, { query, body, version })
- : this.http.fetch(url, { query, version, headers });
+ : this.http.fetch(url, { query, version, ...cacheOptions });
return request.catch((resp) => {
if (resp.body.statusCode === 404 && resp.body.attributes?.code === 'no_matching_indices') {
throw new DataViewMissingIndices(resp.body.message);
From 691df4fadad29befcd021db88b4690da921bafc2 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 1 Nov 2023 20:05:58 -0500
Subject: [PATCH 007/168] caching fields requests mostly working
---
src/plugins/data_views/common/constants.ts | 6 +
.../data_views/data_views_api_client.ts | 14 +-
.../field_capabilities/field_capabilities.ts | 2 +-
.../server/rest_api_routes/internal/fields.ts | 205 ++++++++++++++++++
src/plugins/data_views/server/routes.ts | 2 +
5 files changed, 224 insertions(+), 5 deletions(-)
create mode 100644 src/plugins/data_views/server/rest_api_routes/internal/fields.ts
diff --git a/src/plugins/data_views/common/constants.ts b/src/plugins/data_views/common/constants.ts
index dc396f2772aa8..43dc67362bf26 100644
--- a/src/plugins/data_views/common/constants.ts
+++ b/src/plugins/data_views/common/constants.ts
@@ -58,6 +58,12 @@ export const PLUGIN_NAME = 'DataViews';
*/
export const FIELDS_FOR_WILDCARD_PATH = '/internal/data_views/_fields_for_wildcard';
+/**
+ * Fields path. Like fields for wildcard but GET only
+ * @public
+ */
+export const FIELDS_PATH = '/internal/data_views/fields';
+
/**
* Existing indices path
* @public
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index 104443c16b5ff..9f58daf501490 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -10,7 +10,7 @@ import { HttpSetup } from '@kbn/core/public';
import { DataViewMissingIndices } from '../../common/lib';
import { GetFieldsOptions, IDataViewsApiClient } from '../../common';
import { FieldsForWildcardResponse } from '../../common/types';
-import { FIELDS_FOR_WILDCARD_PATH } from '../../common/constants';
+import { FIELDS_FOR_WILDCARD_PATH, FIELDS_PATH } from '../../common/constants';
const API_BASE_URL: string = `/api/index_patterns/`;
const version = '1';
@@ -35,15 +35,19 @@ export class DataViewsApiClient implements IDataViewsApiClient {
body?: string,
forceRefresh?: boolean
): Promise {
+ /*
console.log('HERE', new Date().getMinutes());
if (new Date().getMinutes() % 2 === 0) {
forceRefresh = true;
}
- const cacheOptions = forceRefresh ? { cache: 'reload' as RequestCache } : {};
+ */
+ // const headers = forceRefresh ? { 'Cache-Control': '' } : undefined;
+ // const cacheOptions = forceRefresh ? { cache: 'reload' as RequestCache } : {};
const request = body
? this.http.post(url, { query, body, version })
- : this.http.fetch(url, { query, version, ...cacheOptions });
+ : this.http.fetch(url, { query, version });
+ // : this.http.fetch(url, { query, version, ...cacheOptions });
return request.catch((resp) => {
if (resp.body.statusCode === 404 && resp.body.attributes?.code === 'no_matching_indices') {
throw new DataViewMissingIndices(resp.body.message);
@@ -73,8 +77,10 @@ export class DataViewsApiClient implements IDataViewsApiClient {
fields,
forceRefresh,
} = options;
+ const path = indexFilter ? FIELDS_FOR_WILDCARD_PATH : FIELDS_PATH;
+
return this._request(
- FIELDS_FOR_WILDCARD_PATH,
+ path,
{
pattern,
meta_fields: metaFields,
diff --git a/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_capabilities.ts b/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_capabilities.ts
index 73e550ebd68ce..f3b2f2db2b108 100644
--- a/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_capabilities.ts
+++ b/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_capabilities.ts
@@ -56,7 +56,7 @@ export async function getFieldCapabilities(params: FieldCapabilitiesParams) {
const allFieldsUnsorted = Object.keys(fieldsFromFieldCapsByName)
// not all meta fields are provided, so remove and manually add
.filter((name) => !fieldsFromFieldCapsByName[name].metadata_field)
- .concat(fieldCapsArr.length ? metaFields : [])
+ .concat(fieldCapsArr.length ? metaFields : []) // empty field lists should stay empty
.reduce<{ names: string[]; map: Map }>(
(agg, value) => {
// This is intentionally using a Map to be highly optimized with very large indexes AND be safe for user provided data
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
new file mode 100644
index 0000000000000..210ceb48890a0
--- /dev/null
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -0,0 +1,205 @@
+/*
+ * 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 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 or the Server
+ * Side Public License, v 1.
+ */
+
+import { estypes } from '@elastic/elasticsearch';
+import { schema } from '@kbn/config-schema';
+import { IRouter, RequestHandler, StartServicesAccessor } from '@kbn/core/server';
+import { FullValidationConfig } from '@kbn/core-http-server';
+import { IndexPatternsFetcher } from '../../fetcher';
+import type {
+ DataViewsServerPluginStart,
+ DataViewsServerPluginStartDependencies,
+} from '../../types';
+import type { FieldDescriptorRestResponse } from '../route_types';
+import { FIELDS_PATH as path } from '../../../common/constants';
+
+/**
+ * Accepts one of the following:
+ * 1. An array of field names
+ * 2. A JSON-stringified array of field names
+ * 3. A single field name (not comma-separated)
+ * @returns an array of field names
+ * @param fields
+ */
+export const parseFields = (fields: string | string[]): string[] => {
+ if (Array.isArray(fields)) return fields;
+ try {
+ return JSON.parse(fields);
+ } catch (e) {
+ if (!fields.includes(',')) return [fields];
+ throw new Error(
+ 'metaFields should be an array of field names, a JSON-stringified array of field names, or a single field name'
+ );
+ }
+};
+
+const access = 'internal';
+
+type IBody = { index_filter?: estypes.QueryDslQueryContainer } | undefined;
+interface IQuery {
+ pattern: string;
+ meta_fields: string | string[];
+ type?: string;
+ rollup_index?: string;
+ allow_no_index?: boolean;
+ include_unmapped?: boolean;
+ fields?: string[];
+}
+
+const querySchema = schema.object({
+ pattern: schema.string(),
+ meta_fields: schema.oneOf([schema.string(), schema.arrayOf(schema.string())], {
+ defaultValue: [],
+ }),
+ type: schema.maybe(schema.string()),
+ rollup_index: schema.maybe(schema.string()),
+ allow_no_index: schema.maybe(schema.boolean()),
+ include_unmapped: schema.maybe(schema.boolean()),
+ fields: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])),
+});
+
+const fieldSubTypeSchema = schema.object({
+ multi: schema.maybe(schema.object({ parent: schema.string() })),
+ nested: schema.maybe(schema.object({ path: schema.string() })),
+});
+
+const FieldDescriptorSchema = schema.object({
+ aggregatable: schema.boolean(),
+ name: schema.string(),
+ readFromDocValues: schema.boolean(),
+ searchable: schema.boolean(),
+ type: schema.string(),
+ esTypes: schema.maybe(schema.arrayOf(schema.string())),
+ subType: fieldSubTypeSchema,
+ metadata_field: schema.maybe(schema.boolean()),
+ fixedInterval: schema.maybe(schema.arrayOf(schema.string())),
+ timeZone: schema.maybe(schema.arrayOf(schema.string())),
+ timeSeriesMetric: schema.maybe(
+ schema.oneOf([
+ schema.literal('histogram'),
+ schema.literal('summary'),
+ schema.literal('counter'),
+ schema.literal('gauge'),
+ schema.literal('position'),
+ ])
+ ),
+ timeSeriesDimension: schema.maybe(schema.boolean()),
+ conflictDescriptions: schema.maybe(
+ schema.recordOf(schema.string(), schema.arrayOf(schema.string()))
+ ),
+});
+
+const validate: FullValidationConfig = {
+ request: {
+ query: querySchema,
+ },
+ response: {
+ 200: {
+ body: schema.object({
+ fields: schema.arrayOf(FieldDescriptorSchema),
+ indices: schema.arrayOf(schema.string()),
+ }),
+ },
+ },
+};
+
+const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, IBody> =
+ (isRollupsEnabled) => async (context, request, response) => {
+ const { asCurrentUser } = (await context.core).elasticsearch.client;
+ const indexPatterns = new IndexPatternsFetcher(asCurrentUser, undefined, isRollupsEnabled());
+ const {
+ pattern,
+ meta_fields: metaFields,
+ type,
+ rollup_index: rollupIndex,
+ allow_no_index: allowNoIndex,
+ include_unmapped: includeUnmapped,
+ } = request.query;
+
+ let parsedFields: string[] = [];
+ let parsedMetaFields: string[] = [];
+ try {
+ parsedMetaFields = parseFields(metaFields);
+ parsedFields = parseFields(request.query.fields ?? []);
+ } catch (error) {
+ return response.badRequest();
+ }
+
+ try {
+ const { fields, indices } = await indexPatterns.getFieldsForWildcard({
+ pattern,
+ // todo should these be added elsewhere?
+ metaFields: parsedMetaFields,
+ type,
+ rollupIndex,
+ fieldCapsOptions: {
+ allow_no_indices: allowNoIndex || false,
+ includeUnmapped,
+ },
+ ...(parsedFields.length > 0 ? { fields: parsedFields } : {}),
+ });
+
+ const body: { fields: FieldDescriptorRestResponse[]; indices: string[] } = {
+ fields,
+ indices,
+ };
+
+ // todo are these needed?
+ const headers: Record = {
+ 'content-type': 'application/json',
+ Etag: '123456',
+ 'If-None-Match': '123456',
+ // Etag?
+ // Expires
+ };
+
+ headers['cache-control'] = 'private, max-age=300, stale-while-revalidate=2592000';
+
+ return response.ok({
+ body,
+ headers,
+ });
+ } catch (error) {
+ if (
+ typeof error === 'object' &&
+ !!error?.isBoom &&
+ !!error?.output?.payload &&
+ typeof error?.output?.payload === 'object'
+ ) {
+ const payload = error?.output?.payload;
+ return response.notFound({
+ body: {
+ message: payload.message,
+ attributes: payload,
+ },
+ });
+ } else {
+ return response.notFound();
+ }
+ }
+ };
+
+export const registerFields = async (
+ router: IRouter,
+ getStartServices: StartServicesAccessor<
+ DataViewsServerPluginStartDependencies,
+ DataViewsServerPluginStart
+ >,
+ isRollupsEnabled: () => boolean
+) => {
+ // handler
+ /*
+ router.versioned
+ .get({ path, access })
+ .addVersion(
+ { version, validate: { request: { query: querySchema }, response: validate.response } },
+ handler(isRollupsEnabled)
+ );
+ */
+ router.get({ path, validate: { query: querySchema } }, handler(isRollupsEnabled));
+};
diff --git a/src/plugins/data_views/server/routes.ts b/src/plugins/data_views/server/routes.ts
index c77dd9a8236cf..51f991449029a 100644
--- a/src/plugins/data_views/server/routes.ts
+++ b/src/plugins/data_views/server/routes.ts
@@ -14,6 +14,7 @@ import type { DataViewsServerPluginStart, DataViewsServerPluginStartDependencies
import { registerExistingIndicesPath } from './rest_api_routes/internal/existing_indices';
import { registerFieldForWildcard } from './rest_api_routes/internal/fields_for';
import { registerHasDataViewsRoute } from './rest_api_routes/internal/has_data_views';
+import { registerFields } from './rest_api_routes/internal/fields';
export function registerRoutes(
http: HttpServiceSetup,
@@ -30,5 +31,6 @@ export function registerRoutes(
registerExistingIndicesPath(router);
registerFieldForWildcard(router, getStartServices, isRollupsEnabled);
+ registerFields(router, getStartServices, isRollupsEnabled);
registerHasDataViewsRoute(router);
}
From 609a96221e911dbacc14572fda294bc6585e67c6 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 1 Nov 2023 22:08:02 -0500
Subject: [PATCH 008/168] implement advanced setting for cache length AND etag
headers
---
.../src/response.ts | 7 ++++
packages/core/http/core-http-server/index.ts | 1 +
.../http/core-http-server/src/router/index.ts | 1 +
.../core-http-server/src/router/response.ts | 4 +-
.../src/router/response_factory.ts | 13 ++++++
src/plugins/data_views/server/plugin.ts | 2 +
.../server/rest_api_routes/internal/fields.ts | 42 +++++++++++++++----
src/plugins/data_views/server/ui_settings.ts | 24 +++++++++++
8 files changed, 82 insertions(+), 12 deletions(-)
create mode 100644 src/plugins/data_views/server/ui_settings.ts
diff --git a/packages/core/http/core-http-router-server-internal/src/response.ts b/packages/core/http/core-http-router-server-internal/src/response.ts
index 1fc8d310233c7..0251f3b3ef203 100644
--- a/packages/core/http/core-http-router-server-internal/src/response.ts
+++ b/packages/core/http/core-http-router-server-internal/src/response.ts
@@ -17,6 +17,7 @@ import type {
ErrorHttpResponseOptions,
KibanaErrorResponseFactory,
KibanaRedirectionResponseFactory,
+ KibanaNotModifiedResponseFactory,
KibanaSuccessResponseFactory,
KibanaResponseFactory,
LifecycleResponseFactory,
@@ -51,6 +52,11 @@ const redirectionResponseFactory: KibanaRedirectionResponseFactory = {
redirected: (options: RedirectResponseOptions) => new KibanaResponse(302, options.body, options),
};
+const notModifiedResponseFactory: KibanaNotModifiedResponseFactory = {
+ notModified: (options: HttpResponseOptions = {}) =>
+ new KibanaResponse(304, options.body, options),
+};
+
const errorResponseFactory: KibanaErrorResponseFactory = {
badRequest: (options: ErrorHttpResponseOptions = {}) =>
new KibanaResponse(400, options.body || 'Bad Request', options),
@@ -120,6 +126,7 @@ export const fileResponseFactory = {
export const kibanaResponseFactory: KibanaResponseFactory = {
...successResponseFactory,
...redirectionResponseFactory,
+ ...notModifiedResponseFactory,
...errorResponseFactory,
...fileResponseFactory,
custom: (
diff --git a/packages/core/http/core-http-server/index.ts b/packages/core/http/core-http-server/index.ts
index 94eefba610a44..cd2ae2fd7cec1 100644
--- a/packages/core/http/core-http-server/index.ts
+++ b/packages/core/http/core-http-server/index.ts
@@ -95,6 +95,7 @@ export type {
IKibanaSocket,
KibanaErrorResponseFactory,
KibanaRedirectionResponseFactory,
+ KibanaNotModifiedResponseFactory,
KibanaSuccessResponseFactory,
KibanaResponseFactory,
LifecycleResponseFactory,
diff --git a/packages/core/http/core-http-server/src/router/index.ts b/packages/core/http/core-http-server/src/router/index.ts
index c72d7386e867d..628bab27db54f 100644
--- a/packages/core/http/core-http-server/src/router/index.ts
+++ b/packages/core/http/core-http-server/src/router/index.ts
@@ -66,6 +66,7 @@ export type { IKibanaSocket } from './socket';
export type {
KibanaErrorResponseFactory,
KibanaRedirectionResponseFactory,
+ KibanaNotModifiedResponseFactory,
KibanaSuccessResponseFactory,
KibanaResponseFactory,
LifecycleResponseFactory,
diff --git a/packages/core/http/core-http-server/src/router/response.ts b/packages/core/http/core-http-server/src/router/response.ts
index 07ec226e8c3a9..194333d42f9c9 100644
--- a/packages/core/http/core-http-server/src/router/response.ts
+++ b/packages/core/http/core-http-server/src/router/response.ts
@@ -95,9 +95,7 @@ export interface FileHttpResponseOptions {
}
};
-const access = 'internal';
-
type IBody = { index_filter?: estypes.QueryDslQueryContainer } | undefined;
interface IQuery {
pattern: string;
@@ -63,11 +62,13 @@ const querySchema = schema.object({
fields: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])),
});
+/**
const fieldSubTypeSchema = schema.object({
multi: schema.maybe(schema.object({ parent: schema.string() })),
nested: schema.maybe(schema.object({ path: schema.string() })),
});
+/*
const FieldDescriptorSchema = schema.object({
aggregatable: schema.boolean(),
name: schema.string(),
@@ -94,6 +95,7 @@ const FieldDescriptorSchema = schema.object({
),
});
+/*
const validate: FullValidationConfig = {
request: {
query: querySchema,
@@ -107,10 +109,19 @@ const validate: FullValidationConfig = {
},
},
};
+*/
+
+function calculateHash(srcBuffer: Buffer) {
+ const hash = createHash('sha1');
+ hash.update(srcBuffer);
+ return hash.digest('hex');
+}
const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, IBody> =
(isRollupsEnabled) => async (context, request, response) => {
- const { asCurrentUser } = (await context.core).elasticsearch.client;
+ const core = await context.core;
+ const uiSettings = core.uiSettings.client;
+ const { asCurrentUser } = core.elasticsearch.client;
const indexPatterns = new IndexPatternsFetcher(asCurrentUser, undefined, isRollupsEnabled());
const {
pattern,
@@ -149,16 +160,29 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
indices,
};
+ const etag = calculateHash(Buffer.from(JSON.stringify(body)));
+
// todo are these needed?
const headers: Record = {
'content-type': 'application/json',
- Etag: '123456',
- 'If-None-Match': '123456',
- // Etag?
+ // 'If-None-Match': '123456',
+ etag,
// Expires
};
- headers['cache-control'] = 'private, max-age=300, stale-while-revalidate=2592000';
+ // todo consider running in parallel with the request
+ const cacheMaxAge = await uiSettings.get('data_views:cache_max_age');
+
+ if (cacheMaxAge) {
+ const stale = 365 * 24 * 60 * 60 - cacheMaxAge;
+ headers[
+ 'cache-control'
+ ] = `private, max-age=${cacheMaxAge}, stale-while-revalidate=${stale}`;
+ }
+
+ if (etag === request.headers.etag) {
+ return response.notModified({ headers });
+ }
return response.ok({
body,
@@ -193,7 +217,7 @@ export const registerFields = async (
isRollupsEnabled: () => boolean
) => {
// handler
- /*
+ /* This seems to fail due to lack of custom headers on cache requests
router.versioned
.get({ path, access })
.addVersion(
diff --git a/src/plugins/data_views/server/ui_settings.ts b/src/plugins/data_views/server/ui_settings.ts
new file mode 100644
index 0000000000000..7e995112fdc1c
--- /dev/null
+++ b/src/plugins/data_views/server/ui_settings.ts
@@ -0,0 +1,24 @@
+/*
+ * 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 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 or the Server
+ * Side Public License, v 1.
+ */
+
+import { i18n } from '@kbn/i18n';
+import { schema } from '@kbn/config-schema';
+
+export const cacheMaxAge = {
+ 'data_views:cache_max_age': {
+ name: i18n.translate('dataViews.advancedSettings.cacheMaxAgeTitle', {
+ defaultMessage: 'Field cache max age',
+ }),
+ value: 300,
+ description: i18n.translate('dataViews.advancedSettings.cacheMaxAgeText', {
+ defaultMessage:
+ "Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching.",
+ }),
+ schema: schema.number(),
+ },
+};
From 2aec419735bb70882fbefd9af9953231891849ce Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 1 Nov 2023 22:20:56 -0500
Subject: [PATCH 009/168] add mock
---
.../core/http/core-http-router-server-mocks/src/router.mock.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/core/http/core-http-router-server-mocks/src/router.mock.ts b/packages/core/http/core-http-router-server-mocks/src/router.mock.ts
index 4272cf130b38e..d5904699b5813 100644
--- a/packages/core/http/core-http-router-server-mocks/src/router.mock.ts
+++ b/packages/core/http/core-http-router-server-mocks/src/router.mock.ts
@@ -121,6 +121,7 @@ const createResponseFactoryMock = (): jest.Mocked => ({
ok: jest.fn(),
accepted: jest.fn(),
noContent: jest.fn(),
+ notModified: jest.fn(),
custom: jest.fn(),
redirected: jest.fn(),
badRequest: jest.fn(),
From 2abf10eb9c96bbf90144c3cd9dee75229d8cb7fa Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Thu, 2 Nov 2023 00:20:24 -0500
Subject: [PATCH 010/168] attempt to fix discover alerting functional test
---
.../public/data_views/data_views_api_client.test.ts | 2 +-
.../discover_ml_uptime/discover/search_source_alert.ts | 7 +++++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.test.ts b/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
index 90a208650a965..6320226aea96f 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
@@ -8,7 +8,7 @@
import { http } from './data_views_api_client.test.mock';
import { DataViewsApiClient } from './data_views_api_client';
-import { FIELDS_FOR_WILDCARD_PATH as expectedPath } from '../../common/constants';
+import { FIELDS_PATH as expectedPath } from '../../common/constants';
describe('IndexPatternsApiClient', () => {
let fetchSpy: jest.SpyInstance;
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 6b668f75d56d3..98eb7bd0bbf90 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -307,6 +307,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('Search source Alert', () => {
before(async () => {
+ await kibanaServer.uiSettings.replace({
+ 'data_views:fields_max_cache': '0',
+ });
await security.testUser.setRoles(['discover_alert']);
log.debug('create source indices');
@@ -330,6 +333,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await deleteConnector(connectorId);
await security.testUser.restoreDefaults();
await kibanaServer.savedObjects.cleanStandardList();
+ await kibanaServer.uiSettings.replace({
+ 'data_views:fields_max_cache': '300',
+ });
});
it('should create an alert when there is no data view', async () => {
@@ -398,6 +404,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await checkInitialRuleParamsState(SOURCE_DATA_VIEW, true);
});
+ // this test fails with caching in place
it('should navigate to alert results via link provided in notification', async () => {
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
From 4de45b5b76521dd05a8f2cd041bce44ff8824e63 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Thu, 2 Nov 2023 08:55:10 -0500
Subject: [PATCH 011/168] 304 sohuldn't accept body
---
.../core/http/core-http-router-server-internal/src/response.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/core/http/core-http-router-server-internal/src/response.ts b/packages/core/http/core-http-router-server-internal/src/response.ts
index 0251f3b3ef203..71b03761b6da8 100644
--- a/packages/core/http/core-http-router-server-internal/src/response.ts
+++ b/packages/core/http/core-http-router-server-internal/src/response.ts
@@ -49,7 +49,7 @@ const successResponseFactory: KibanaSuccessResponseFactory = {
};
const redirectionResponseFactory: KibanaRedirectionResponseFactory = {
- redirected: (options: RedirectResponseOptions) => new KibanaResponse(302, options.body, options),
+ redirected: (options: RedirectResponseOptions) => new KibanaResponse(302, undefined, options),
};
const notModifiedResponseFactory: KibanaNotModifiedResponseFactory = {
From 8d8fbb4b7728f05eb3c0ae3cb5dff16716325b08 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 3 Nov 2023 17:44:53 -0500
Subject: [PATCH 012/168] try setting cache to zero to see if fewer tests fail
---
src/plugins/data_views/server/ui_settings.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_views/server/ui_settings.ts b/src/plugins/data_views/server/ui_settings.ts
index 7e995112fdc1c..a2d0feb05bbe8 100644
--- a/src/plugins/data_views/server/ui_settings.ts
+++ b/src/plugins/data_views/server/ui_settings.ts
@@ -14,7 +14,7 @@ export const cacheMaxAge = {
name: i18n.translate('dataViews.advancedSettings.cacheMaxAgeTitle', {
defaultMessage: 'Field cache max age',
}),
- value: 300,
+ value: 0,
description: i18n.translate('dataViews.advancedSettings.cacheMaxAgeText', {
defaultMessage:
"Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching.",
From 146ba0bcbb647c3608be69d198f0536ba8bfbf11 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 4 Nov 2023 17:03:34 -0500
Subject: [PATCH 013/168] remove some comments
---
.../public/data_views/data_views_api_client.ts | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index 9f58daf501490..bda9f40417352 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -35,19 +35,11 @@ export class DataViewsApiClient implements IDataViewsApiClient {
body?: string,
forceRefresh?: boolean
): Promise {
- /*
- console.log('HERE', new Date().getMinutes());
- if (new Date().getMinutes() % 2 === 0) {
- forceRefresh = true;
- }
- */
- // const headers = forceRefresh ? { 'Cache-Control': '' } : undefined;
- // const cacheOptions = forceRefresh ? { cache: 'reload' as RequestCache } : {};
+ const cacheOptions = forceRefresh ? { cache: 'reload' as RequestCache } : {};
const request = body
? this.http.post(url, { query, body, version })
- : this.http.fetch(url, { query, version });
- // : this.http.fetch(url, { query, version, ...cacheOptions });
+ : this.http.fetch(url, { query, version, ...cacheOptions });
return request.catch((resp) => {
if (resp.body.statusCode === 404 && resp.body.attributes?.code === 'no_matching_indices') {
throw new DataViewMissingIndices(resp.body.message);
From 830b9591813b05a32e98d41f1e265191ea3ec218 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 4 Nov 2023 21:41:22 -0500
Subject: [PATCH 014/168] fix tests
---
.../http/core-http-router-server-internal/src/response.ts | 5 ++---
.../server/collectors/management/schema.ts | 7 +++++++
.../server/collectors/management/types.ts | 1 +
src/plugins/telemetry/schema/oss_plugins.json | 6 ++++++
.../cypress/e2e/automated_response_actions/form.cy.ts | 4 ++--
5 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/packages/core/http/core-http-router-server-internal/src/response.ts b/packages/core/http/core-http-router-server-internal/src/response.ts
index 71b03761b6da8..d96eaa6571bf0 100644
--- a/packages/core/http/core-http-router-server-internal/src/response.ts
+++ b/packages/core/http/core-http-router-server-internal/src/response.ts
@@ -49,12 +49,11 @@ const successResponseFactory: KibanaSuccessResponseFactory = {
};
const redirectionResponseFactory: KibanaRedirectionResponseFactory = {
- redirected: (options: RedirectResponseOptions) => new KibanaResponse(302, undefined, options),
+ redirected: (options: RedirectResponseOptions) => new KibanaResponse(302, options.body, options),
};
const notModifiedResponseFactory: KibanaNotModifiedResponseFactory = {
- notModified: (options: HttpResponseOptions = {}) =>
- new KibanaResponse(304, options.body, options),
+ notModified: (options: HttpResponseOptions = {}) => new KibanaResponse(304, undefined, options),
};
const errorResponseFactory: KibanaErrorResponseFactory = {
diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts
index 0862d6ece004a..339610725175f 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts
@@ -162,6 +162,13 @@ export const stackManagementSchema: MakeSchemaFrom = {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
},
+ 'data_views:cache_max_age': {
+ type: 'long',
+ _meta: {
+ description:
+ "Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching.",
+ },
+ },
'discover:searchOnPageLoad': {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts
index 3499471e0d5a8..f6aabe88236b2 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts
@@ -78,6 +78,7 @@ export interface UsageStats {
'doc_table:highlight': boolean;
'discover:searchOnPageLoad': boolean;
'doc_table:hideTimeColumn': boolean;
+ 'data_views:cache_max_age': number;
'discover:sampleSize': number;
'discover:sampleRowsPerPage': number;
defaultColumns: string[];
diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json
index 0854944f39404..63eb184813892 100644
--- a/src/plugins/telemetry/schema/oss_plugins.json
+++ b/src/plugins/telemetry/schema/oss_plugins.json
@@ -9428,6 +9428,12 @@
"description": "Non-default value of setting."
}
},
+ "data_views:cache_max_age": {
+ "type": "long",
+ "_meta": {
+ "description": "Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching."
+ }
+ },
"discover:searchOnPageLoad": {
"type": "boolean",
"_meta": {
diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts
index a370f2a89cb6f..11f2651755bf0 100644
--- a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts
+++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { FIELDS_FOR_WILDCARD_PATH } from '@kbn/data-views-plugin/common/constants';
+import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
import {
addEndpointResponseAction,
fillUpNewRule,
@@ -186,7 +186,7 @@ describe(
});
it('All response action controls are disabled', () => {
- cy.intercept('GET', `${FIELDS_FOR_WILDCARD_PATH}*`).as('getFieldsForWildcard');
+ cy.intercept('GET', `${FIELDS_PATH}*`).as('getFieldsForWildcard');
visitRuleActions(ruleId);
cy.wait('@getFieldsForWildcard');
cy.getByTestSubj('edit-rule-actions-tab').click();
From 9638c362afc5c7a07e31932f642be1242f6e6edc Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 4 Nov 2023 22:56:50 -0500
Subject: [PATCH 015/168] restore default cache max-age
---
src/plugins/data_views/server/ui_settings.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_views/server/ui_settings.ts b/src/plugins/data_views/server/ui_settings.ts
index a2d0feb05bbe8..7e995112fdc1c 100644
--- a/src/plugins/data_views/server/ui_settings.ts
+++ b/src/plugins/data_views/server/ui_settings.ts
@@ -14,7 +14,7 @@ export const cacheMaxAge = {
name: i18n.translate('dataViews.advancedSettings.cacheMaxAgeTitle', {
defaultMessage: 'Field cache max age',
}),
- value: 0,
+ value: 300,
description: i18n.translate('dataViews.advancedSettings.cacheMaxAgeText', {
defaultMessage:
"Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching.",
From 442c048159bea7310faebf7632177a38186d08e6 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 6 Nov 2023 22:42:55 -0600
Subject: [PATCH 016/168] fix 304 responses, implement refresh button,
hopefully fix a test
---
.../src/response_adapter.ts | 8 ++-
.../edit_index_pattern/edit_index_pattern.tsx | 12 ++++-
.../index_header/index_header.tsx | 29 ++++++++++-
.../index_pattern_table.tsx | 2 +-
.../data_views/common/data_views/data_view.ts | 6 +++
.../common/data_views/data_views.ts | 52 +++++++++++++++----
src/plugins/data_views/common/types.ts | 1 +
.../data_views/data_views_api_client.ts | 26 +++++++---
.../server/rest_api_routes/internal/fields.ts | 13 ++++-
.../apps/discover/group3/_sidebar.ts | 17 ++++++
test/functional/page_objects/settings_page.ts | 8 +++
11 files changed, 149 insertions(+), 25 deletions(-)
diff --git a/packages/core/http/core-http-router-server-internal/src/response_adapter.ts b/packages/core/http/core-http-router-server-internal/src/response_adapter.ts
index f6a00bb7e6b92..a5cc1ca1f8d96 100644
--- a/packages/core/http/core-http-router-server-internal/src/response_adapter.ts
+++ b/packages/core/http/core-http-router-server-internal/src/response_adapter.ts
@@ -33,7 +33,8 @@ function setHeaders(response: HapiResponseObject, headers: Record code >= 100 && code < 300,
- isRedirect: (code: number) => code >= 300 && code < 400,
+ isNotModified: (code: number) => code === 304,
+ isRedirect: (code: number) => code >= 300 && code < 400 && code !== 304,
isError: (code: number) => code >= 400 && code < 600,
};
@@ -76,7 +77,10 @@ export class HapiResponseAdapter {
if (statusHelpers.isError(kibanaResponse.status)) {
return this.toError(kibanaResponse);
}
- if (statusHelpers.isSuccess(kibanaResponse.status)) {
+ if (
+ statusHelpers.isSuccess(kibanaResponse.status) ||
+ statusHelpers.isNotModified(kibanaResponse.status)
+ ) {
return this.toSuccess(kibanaResponse);
}
if (statusHelpers.isRedirect(kibanaResponse.status)) {
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
index 71ff8ce38636c..ba1d8373119cb 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
@@ -93,6 +93,9 @@ export const EditIndexPattern = withRouter(
const [showEditDialog, setShowEditDialog] = useState(false);
const [relationships, setRelationships] = useState([]);
const [allowedTypes, setAllowedTypes] = useState([]);
+ const [refreshCount, setRefreshCount] = useState(0);
+ const [isRefreshing, setIsRefreshing] = React.useState(false);
+
const conflictFieldsUrl = useMemo(() => {
return setStateToKbnUrl(
APP_STATE_STORAGE_KEY,
@@ -142,7 +145,7 @@ export const EditIndexPattern = withRouter(
setConflictedFields(
indexPattern.fields.getAll().filter((field) => field.type === 'conflict')
);
- }, [indexPattern]);
+ }, [indexPattern, refreshCount]);
useEffect(() => {
setTags(
@@ -244,8 +247,15 @@ export const EditIndexPattern = withRouter(
deleteIndexPatternClick={() =>
removeHandler([indexPattern as RemoveDataViewProps], {warning}
)
}
+ refreshIndexPatternClick={async () => {
+ setIsRefreshing(true);
+ await dataViews.refreshFields(indexPattern, false, true);
+ setRefreshCount(refreshCount + 1);
+ setIsRefreshing(false);
+ }}
defaultIndex={defaultIndex}
canSave={userEditPermission}
+ isRefreshing={isRefreshing}
>
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
index 83c965f2b9332..cf1ce9faedb55 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
@@ -8,7 +8,7 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
-import { EuiButton, EuiButtonEmpty, EuiPageHeader } from '@elastic/eui';
+import { EuiButton, EuiButtonEmpty, EuiPageHeader, EuiToolTip } from '@elastic/eui';
import { DataView } from '@kbn/data-views-plugin/public';
interface IndexHeaderProps {
@@ -17,7 +17,9 @@ interface IndexHeaderProps {
setDefault?: () => void;
editIndexPatternClick?: () => void;
deleteIndexPatternClick?: () => void;
+ refreshIndexPatternClick?: () => void;
canSave: boolean;
+ isRefreshing?: boolean;
}
const setDefaultAriaLabel = i18n.translate('indexPatternManagement.editDataView.setDefaultAria', {
@@ -44,19 +46,44 @@ const removeTooltip = i18n.translate('indexPatternManagement.editDataView.remove
defaultMessage: 'Delete',
});
+const refreshAriaLabel = i18n.translate('indexPatternManagement.editDataView.refreshAria', {
+ defaultMessage: 'Refresh',
+});
+
+const refreshTooltip = i18n.translate('indexPatternManagement.editDataView.refreshTooltip', {
+ defaultMessage: 'Refresh local copy of data view field list',
+});
+
+const refreshLabel = i18n.translate('indexPatternManagement.editDataView.refreshLabel', {
+ defaultMessage: 'Refresh',
+});
+
export const IndexHeader: React.FC = ({
defaultIndex,
indexPattern,
setDefault,
editIndexPatternClick,
deleteIndexPatternClick,
+ refreshIndexPatternClick,
children,
canSave,
+ isRefreshing,
}) => {
return (
{indexPattern.getName()}}
rightSideItems={[
+ {refreshTooltip}
}>
+
+ {refreshLabel}
+
+ ,
canSave && (
{dataView.getName()}
{dataView.name ? (
diff --git a/src/plugins/data_views/common/data_views/data_view.ts b/src/plugins/data_views/common/data_views/data_view.ts
index 27681021757ff..71145fb6ac157 100644
--- a/src/plugins/data_views/common/data_views/data_view.ts
+++ b/src/plugins/data_views/common/data_views/data_view.ts
@@ -61,6 +61,8 @@ export class DataView extends AbstractDataView implements DataViewBase {
*/
public flattenHit: (hit: Record, deep?: boolean) => Record;
+ private etag: string | undefined;
+
/**
* constructor
* @param config - config data and dependencies
@@ -77,6 +79,10 @@ export class DataView extends AbstractDataView implements DataViewBase {
this.fields.replaceAll(Object.values(spec.fields || {}));
}
+ getEtag = () => this.etag;
+
+ setEtag = (etag: string) => (this.etag = etag);
+
/**
* Returns scripted fields
*/
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index 7ec161e689e76..d618f4e6b9784 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -261,7 +261,11 @@ export interface DataViewsServicePublicMethods {
* Refresh fields for data view instance
* @params dataView - Data view instance
*/
- refreshFields: (indexPattern: DataView, displayErrors?: boolean) => Promise;
+ refreshFields: (
+ indexPattern: DataView,
+ displayErrors?: boolean,
+ forceRefresh?: boolean
+ ) => Promise;
/**
* Converts data view saved object to spec
* @params savedObject - Data view saved object
@@ -533,7 +537,10 @@ export class DataViewsService {
pattern: indexPattern.title as string,
});
- private getFieldsAndIndicesForDataView = async (dataView: DataView) => {
+ private getFieldsAndIndicesForDataView = async (
+ dataView: DataView,
+ forceRefresh: boolean = false
+ ) => {
const metaFields = await this.config.get(META_FIELDS);
return this.apiClient.getFieldsForWildcard({
type: dataView.type,
@@ -541,6 +548,7 @@ export class DataViewsService {
allowNoIndex: true,
pattern: dataView.getIndexPattern(),
metaFields,
+ forceRefresh,
});
};
@@ -556,8 +564,18 @@ export class DataViewsService {
});
};
- private refreshFieldsFn = async (indexPattern: DataView) => {
- const { fields, indices } = await this.getFieldsAndIndicesForDataView(indexPattern);
+ private refreshFieldsFn = async (indexPattern: DataView, forceRefresh: boolean = false) => {
+ const { fields, indices, etag } = await this.getFieldsAndIndicesForDataView(
+ indexPattern,
+ forceRefresh
+ );
+
+ if (etag === indexPattern.getEtag()) {
+ return;
+ } else {
+ indexPattern.setEtag(etag);
+ }
+
fields.forEach((field) => (field.isMapped = true));
const scripted = this.scriptedFieldsEnabled
? indexPattern.getScriptedFields().map((field) => field.spec)
@@ -583,13 +601,17 @@ export class DataViewsService {
* @param dataView
* @param displayErrors - If set false, API consumer is responsible for displaying and handling errors.
*/
- refreshFields = async (dataView: DataView, displayErrors: boolean = true) => {
+ refreshFields = async (
+ dataView: DataView,
+ displayErrors: boolean = true,
+ forceRefresh: boolean = false
+ ) => {
if (!displayErrors) {
- return this.refreshFieldsFn(dataView);
+ return this.refreshFieldsFn(dataView, forceRefresh);
}
try {
- await this.refreshFieldsFn(dataView);
+ await this.refreshFieldsFn(dataView, forceRefresh);
} catch (err) {
if (err instanceof DataViewMissingIndices) {
// not considered an error, check dataView.matchedIndices.length to be 0
@@ -630,7 +652,11 @@ export class DataViewsService {
: [];
try {
let updatedFieldList: FieldSpec[];
- const { fields: newFields, indices } = await this.getFieldsAndIndicesForWildcard(options);
+ const {
+ fields: newFields,
+ indices,
+ etag,
+ } = await this.getFieldsAndIndicesForWildcard(options);
newFields.forEach((field) => (field.isMapped = true));
// If allowNoIndex, only update field list if field caps finds fields. To support
@@ -641,7 +667,7 @@ export class DataViewsService {
updatedFieldList = fieldsAsArr;
}
- return { fields: this.fieldArrayToMap(updatedFieldList, fieldAttrs), indices };
+ return { fields: this.fieldArrayToMap(updatedFieldList, fieldAttrs), indices, etag };
} catch (err) {
if (err instanceof DataViewMissingIndices) {
// not considered an error, check dataView.matchedIndices.length to be 0
@@ -753,7 +779,7 @@ export class DataViewsService {
displayErrors?: boolean;
}) => {
const { title, type, typeMeta, runtimeFieldMap } = spec;
- const { fields, indices } = await this.refreshFieldSpecMap(
+ const { fields, indices, etag } = await this.refreshFieldSpecMap(
spec.fields || {},
savedObjectId,
spec.title as string,
@@ -770,7 +796,7 @@ export class DataViewsService {
const runtimeFieldSpecs = this.getRuntimeFields(runtimeFieldMap, spec.fieldAttrs);
// mapped fields overwrite runtime fields
- return { fields: { ...runtimeFieldSpecs, ...fields }, indices: indices || [] };
+ return { fields: { ...runtimeFieldSpecs, ...fields }, indices: indices || [], etag };
};
private initFromSavedObject = async (
@@ -784,6 +810,7 @@ export class DataViewsService {
let fields: Record = {};
let indices: string[] = [];
+ let etag: string | undefined;
if (!displayErrors) {
const fieldsAndIndices = await this.initFromSavedObjectLoadFields({
@@ -793,6 +820,7 @@ export class DataViewsService {
});
fields = fieldsAndIndices.fields;
indices = fieldsAndIndices.indices;
+ etag = fieldsAndIndices.etag;
} else {
try {
const fieldsAndIndices = await this.initFromSavedObjectLoadFields({
@@ -802,6 +830,7 @@ export class DataViewsService {
});
fields = fieldsAndIndices.fields;
indices = fieldsAndIndices.indices;
+ etag = fieldsAndIndices.etag;
} catch (err) {
if (err instanceof DataViewMissingIndices) {
// not considered an error, check dataView.matchedIndices.length to be 0
@@ -826,6 +855,7 @@ export class DataViewsService {
: {};
const indexPattern = await this.createFromSpec(spec, true, displayErrors);
+ indexPattern.setEtag(etag!);
indexPattern.matchedIndices = indices;
indexPattern.resetOriginalSavedObjectBody();
return indexPattern;
diff --git a/src/plugins/data_views/common/types.ts b/src/plugins/data_views/common/types.ts
index c2b79c72f8eeb..7c3cc0cacb618 100644
--- a/src/plugins/data_views/common/types.ts
+++ b/src/plugins/data_views/common/types.ts
@@ -319,6 +319,7 @@ export interface GetFieldsOptions {
export interface FieldsForWildcardResponse {
fields: FieldSpec[];
indices: string[];
+ etag: string;
}
/**
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index bda9f40417352..ff184722a4a3b 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { HttpSetup } from '@kbn/core/public';
+import { HttpSetup, HttpResponse } from '@kbn/core/public';
import { DataViewMissingIndices } from '../../common/lib';
import { GetFieldsOptions, IDataViewsApiClient } from '../../common';
import { FieldsForWildcardResponse } from '../../common/types';
@@ -34,12 +34,17 @@ export class DataViewsApiClient implements IDataViewsApiClient {
query?: {},
body?: string,
forceRefresh?: boolean
- ): Promise {
- const cacheOptions = forceRefresh ? { cache: 'reload' as RequestCache } : {};
+ ): Promise | undefined> {
+ const asResponse = true;
+ // circle back to this, will likely need changes to any code that loads fields
+ // const rawResponse = true;
+ const rawResponse = false;
+ const cacheOptions = forceRefresh ? { cache: 'no-cache' as RequestCache } : {};
const request = body
- ? this.http.post(url, { query, body, version })
- : this.http.fetch(url, { query, version, ...cacheOptions });
+ ? this.http.post(url, { query, body, version, asResponse })
+ : this.http.fetch(url, { query, version, ...cacheOptions, asResponse, rawResponse });
+
return request.catch((resp) => {
if (resp.body.statusCode === 404 && resp.body.attributes?.code === 'no_matching_indices') {
throw new DataViewMissingIndices(resp.body.message);
@@ -85,7 +90,11 @@ export class DataViewsApiClient implements IDataViewsApiClient {
indexFilter ? JSON.stringify({ index_filter: indexFilter }) : undefined,
forceRefresh
).then((response) => {
- return response || { fields: [], indices: [] };
+ return {
+ indices: response?.body?.indices || [],
+ fields: response?.body?.fields || [],
+ etag: response?.response?.headers?.get('etag') || '',
+ };
});
}
@@ -96,6 +105,9 @@ export class DataViewsApiClient implements IDataViewsApiClient {
const response = await this._request<{ result: boolean }>(
this._getUrl(['has_user_index_pattern'])
);
- return response?.result ?? false;
+
+ // const body = await response?.response?.json();
+ // return body?.result ?? false;
+ return response?.body?.result ?? false;
}
}
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index c965cf1d63895..0e2dd5d0589db 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -180,8 +180,17 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
] = `private, max-age=${cacheMaxAge}, stale-while-revalidate=${stale}`;
}
- if (etag === request.headers.etag) {
- return response.notModified({ headers });
+ // move to util
+ const ifNoneMatch = request.headers['if-none-match'];
+ if (ifNoneMatch) {
+ let requestHash = (ifNoneMatch as string).slice(1, -1);
+ if (requestHash.indexOf('-') > -1) {
+ requestHash = requestHash.split('-')[0];
+ }
+
+ if (etag === requestHash) {
+ return response.notModified({ headers });
+ }
}
return response.ok({
diff --git a/test/functional/apps/discover/group3/_sidebar.ts b/test/functional/apps/discover/group3/_sidebar.ts
index b47e71f452818..46664ff900978 100644
--- a/test/functional/apps/discover/group3/_sidebar.ts
+++ b/test/functional/apps/discover/group3/_sidebar.ts
@@ -17,6 +17,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'discover',
'timePicker',
'header',
+ 'settings',
'unifiedSearch',
'unifiedFieldList',
]);
@@ -285,6 +286,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
+ //
describe('renders field groups', function () {
it('should show field list groups excluding subfields', async function () {
await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
@@ -475,6 +477,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
});
+ //
it('should work correctly for a data view for a missing index', async function () {
// but we are skipping importing the index itself
await kibanaServer.importExport.load(
@@ -492,6 +495,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
+ // console.log('######################## await timeout');
+ // await new Promise((r) => setTimeout(r, 10000 * 60));
expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be(
'0 available fields. 0 empty fields. 0 meta fields.'
);
@@ -526,6 +531,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
await browser.refresh();
+ // here
+ await PageObjects.settings.refreshDataViewFieldList('with-timefield');
+ await PageObjects.common.navigateToApp('discover');
+ await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be(
@@ -546,8 +555,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
+ // console.log('######################## await timeout');
+ // await new Promise((r) => setTimeout(r, 1000 * 300));
+ // todo - comapre to main. This looks correct in this branch
expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be(
'0 available fields. 7 empty fields. 3 meta fields.'
+ // '0 available fields. 13 empty fields. 0 empty fields. 3 meta fields.'
);
await testSubjects.existOrFail(
`${PageObjects.unifiedFieldList.getSidebarSectionSelector(
@@ -571,6 +584,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await esArchiver.unload(
'test/functional/fixtures/es_archiver/index_pattern_without_timefield'
);
+ // console.log('######################## await timeout');
+ // await new Promise((r) => setTimeout(r, 1000 * 30));
});
it('should work when filters change', async () => {
@@ -755,6 +770,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
+ // console.log('######################## await timeout');
+ // await new Promise((r) => setTimeout(r, 1000 * 30));
expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be(
'0 available fields. 7 empty fields. 3 meta fields.'
);
diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts
index 0a2fd76076914..d81c1e09777d0 100644
--- a/test/functional/page_objects/settings_page.ts
+++ b/test/functional/page_objects/settings_page.ts
@@ -483,6 +483,14 @@ export class SettingsPageObject extends FtrService {
await customDataViewIdInput.type(value);
}
+ async refreshDataViewFieldList(dataViewName: string) {
+ await this.navigateTo();
+ await this.clickKibanaIndexPatterns();
+ await this.header.waitUntilLoadingHasFinished();
+ await this.testSubjects.click(`detail-link-${dataViewName}`);
+ await this.testSubjects.click('refreshDataViewButton');
+ }
+
async createIndexPattern(
indexPatternName: string,
// null to bypass default value
From 3f533ab5edb5f1ee489c8af5f78df787ff8abc29 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 7 Nov 2023 00:18:23 -0600
Subject: [PATCH 017/168] fix tests
---
packages/kbn-optimizer/limits.yml | 2 +-
src/plugins/data_views/common/data_views/data_views.ts | 4 ++--
src/plugins/data_views/common/types.ts | 2 +-
.../apps/management/data_views/_index_pattern_results_sort.ts | 2 ++
.../server/services/log_views/log_views_client.test.ts | 3 +++
.../apps/observability_log_explorer/columns_selection.ts | 4 +++-
6 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml
index de07bccf8bbcb..ce983447cb5da 100644
--- a/packages/kbn-optimizer/limits.yml
+++ b/packages/kbn-optimizer/limits.yml
@@ -31,7 +31,7 @@ pageLoadAssetSize:
dataViewEditor: 28082
dataViewFieldEditor: 27000
dataViewManagement: 5100
- dataViews: 48300
+ dataViews: 48800
dataVisualizer: 27530
devTools: 38637
discover: 99999
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index d618f4e6b9784..e6ab814ee7bd0 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -570,10 +570,10 @@ export class DataViewsService {
forceRefresh
);
- if (etag === indexPattern.getEtag()) {
+ if (indexPattern.getEtag() && etag === indexPattern.getEtag()) {
return;
} else {
- indexPattern.setEtag(etag);
+ indexPattern.setEtag(etag!);
}
fields.forEach((field) => (field.isMapped = true));
diff --git a/src/plugins/data_views/common/types.ts b/src/plugins/data_views/common/types.ts
index 7c3cc0cacb618..dae5599e276a0 100644
--- a/src/plugins/data_views/common/types.ts
+++ b/src/plugins/data_views/common/types.ts
@@ -319,7 +319,7 @@ export interface GetFieldsOptions {
export interface FieldsForWildcardResponse {
fields: FieldSpec[];
indices: string[];
- etag: string;
+ etag?: string;
}
/**
diff --git a/test/functional/apps/management/data_views/_index_pattern_results_sort.ts b/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
index 71dc85eed1f0e..2f11ae3cfb2e3 100644
--- a/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
+++ b/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
@@ -67,6 +67,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('field list pagination', function () {
const EXPECTED_FIELD_COUNT = 85;
it('makelogs data should have expected number of fields', async function () {
+ // did this work?
+ await this.testSubjects.click('refreshDataViewButton');
await retry.try(async function () {
const TabCount = await PageObjects.settings.getFieldsTabCount();
expect(TabCount).to.be('' + EXPECTED_FIELD_COUNT);
diff --git a/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts
index 125167d6deea8..5d9ae8eed5394 100644
--- a/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts
+++ b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts
@@ -252,6 +252,7 @@ describe('LogViewsClient class', () => {
"allowNoIndex": false,
"deleteFieldFormat": [Function],
"deleteScriptedFieldInternal": [Function],
+ "etag": undefined,
"fieldAttrs": Object {},
"fieldFormatMap": Object {},
"fieldFormats": Object {
@@ -274,6 +275,7 @@ describe('LogViewsClient class', () => {
},
"fields": FldList [],
"flattenHit": [Function],
+ "getEtag": [Function],
"getFieldAttrs": [Function],
"getIndexPattern": [Function],
"getName": [Function],
@@ -298,6 +300,7 @@ describe('LogViewsClient class', () => {
},
},
"scriptedFields": Array [],
+ "setEtag": [Function],
"setFieldFormat": [Function],
"setIndexPattern": [Function],
"shortDotsEnable": false,
diff --git a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
index 7738d3b97b2bc..83b88d3615547 100644
--- a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
+++ b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
@@ -13,7 +13,7 @@ const defaultLogColumns = ['@timestamp', 'service.name', 'host.name', 'message']
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const retry = getService('retry');
- const PageObjects = getPageObjects(['discover', 'observabilityLogExplorer']);
+ const PageObjects = getPageObjects(['discover', 'observabilityLogExplorer', 'settings']);
describe('Columns selection initialization and update', () => {
before(async () => {
@@ -30,6 +30,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('when the log explorer loads', () => {
it("should initialize the table columns to logs' default selection", async () => {
+ // did this work?
+ PageObjects.settings.refreshDataViewFieldList('All logs');
await PageObjects.observabilityLogExplorer.navigateTo();
await retry.try(async () => {
From ffde29ebbb26d4d2b6c19c75ec053cc02a09c302 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 7 Nov 2023 00:41:38 -0600
Subject: [PATCH 018/168] revert fields_for_wildcard changes
---
.../rest_api_routes/internal/fields_for.ts | 33 +++++--------------
1 file changed, 8 insertions(+), 25 deletions(-)
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
index 9d9f09d79446d..32197ea5a96d4 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
@@ -111,12 +111,8 @@ const validate: FullValidationConfig = {
},
};
-const handler: (
- isRollupsEnabled: () => boolean
-) => (cacheHeader: boolean) => RequestHandler<{}, IQuery, IBody> =
- (isRollupsEnabled) =>
- (cacheHeader = false) =>
- async (context, request, response) => {
+const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, IBody> =
+ (isRollupsEnabled) => async (context, request, response) => {
const { asCurrentUser } = (await context.core).elasticsearch.client;
const indexPatterns = new IndexPatternsFetcher(asCurrentUser, undefined, isRollupsEnabled());
const {
@@ -159,22 +155,11 @@ const handler: (
indices,
};
- const headers: Record = {
- 'content-type': 'application/json',
- Etag: '123456',
- 'If-None-Match': '123456',
- // Etag?
- // Expires
- };
-
- if (cacheHeader) {
- // revalidates if 5 minutes passed, otherwise caches for a year
- headers['cache-control'] = 'private, max-age=300, stale-while-revalidate=2592000';
- }
-
return response.ok({
body,
- headers,
+ headers: {
+ 'content-type': 'application/json',
+ },
});
} catch (error) {
if (
@@ -209,14 +194,12 @@ export const registerFieldForWildcard = async (
// handler
router.versioned
.put({ path, access, options: {} })
- .addVersion({ version, validate }, configuredHandler(false));
- router.versioned
- .post({ path, access })
- .addVersion({ version, validate }, configuredHandler(false));
+ .addVersion({ version, validate }, configuredHandler);
+ router.versioned.post({ path, access }).addVersion({ version, validate }, configuredHandler);
router.versioned
.get({ path, access })
.addVersion(
{ version, validate: { request: { query: querySchema }, response: validate.response } },
- configuredHandler(true)
+ configuredHandler
);
};
From 40704e754279b297cedfb477ac7b1fd291d9240a Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 7 Nov 2023 00:42:50 -0600
Subject: [PATCH 019/168] revert fields_for_wildcard changes
---
.../data_views/server/rest_api_routes/internal/fields_for.ts | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
index 32197ea5a96d4..15d761935c0a7 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
@@ -192,9 +192,7 @@ export const registerFieldForWildcard = async (
const configuredHandler = handler(isRollupsEnabled);
// handler
- router.versioned
- .put({ path, access, options: {} })
- .addVersion({ version, validate }, configuredHandler);
+ router.versioned.put({ path, access }).addVersion({ version, validate }, configuredHandler);
router.versioned.post({ path, access }).addVersion({ version, validate }, configuredHandler);
router.versioned
.get({ path, access })
From 4b02f2d0738d7c646b3aef119f40b4a81523c091 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 7 Nov 2023 07:57:15 -0600
Subject: [PATCH 020/168] functional test fixes
---
.../apps/management/data_views/_index_pattern_results_sort.ts | 3 ++-
.../apps/discover/feature_controls/discover_security.ts | 4 ++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/test/functional/apps/management/data_views/_index_pattern_results_sort.ts b/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
index 2f11ae3cfb2e3..aef25d91634e5 100644
--- a/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
+++ b/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
@@ -12,6 +12,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const kibanaServer = getService('kibanaServer');
const retry = getService('retry');
+ const testSubjects = getService('testSubjects');
const PageObjects = getPageObjects(['settings', 'common']);
describe('index result field sort', function describeIndexTests() {
@@ -68,7 +69,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const EXPECTED_FIELD_COUNT = 85;
it('makelogs data should have expected number of fields', async function () {
// did this work?
- await this.testSubjects.click('refreshDataViewButton');
+ await testSubjects.click('refreshDataViewButton');
await retry.try(async function () {
const TabCount = await PageObjects.settings.getFieldsTabCount();
expect(TabCount).to.be('' + EXPECTED_FIELD_COUNT);
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index ee810f7ddebfb..ed6e1bc27abcb 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -31,6 +31,7 @@ export default function (ctx: FtrProviderContext) {
'spaceSelector',
'header',
'unifiedFieldList',
+ 'settings',
]);
const testSubjects = getService('testSubjects');
const appsMenu = getService('appsMenu');
@@ -447,6 +448,9 @@ export default function (ctx: FtrProviderContext) {
it('allows to access only via a permitted index alias', async () => {
await globalNav.badgeExistsOrFail('Read only');
+ await PageObjects.settings.refreshDataViewFieldList('logstash-*');
+ await PageObjects.common.navigateToApp('discover');
+
// can't access logstash index directly
await PageObjects.discover.selectIndexPattern('logstash-*');
await PageObjects.header.waitUntilLoadingHasFinished();
From 78bd5379f9794813756f2148937b11f44003979a Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 7 Nov 2023 09:20:30 -0600
Subject: [PATCH 021/168] disable cache for sanity check
---
src/plugins/data_views/server/ui_settings.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_views/server/ui_settings.ts b/src/plugins/data_views/server/ui_settings.ts
index 7e995112fdc1c..a2d0feb05bbe8 100644
--- a/src/plugins/data_views/server/ui_settings.ts
+++ b/src/plugins/data_views/server/ui_settings.ts
@@ -14,7 +14,7 @@ export const cacheMaxAge = {
name: i18n.translate('dataViews.advancedSettings.cacheMaxAgeTitle', {
defaultMessage: 'Field cache max age',
}),
- value: 300,
+ value: 0,
description: i18n.translate('dataViews.advancedSettings.cacheMaxAgeText', {
defaultMessage:
"Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching.",
From 86681bee37476a92192f12a147e49395f941eb8f Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 7 Nov 2023 11:15:52 -0600
Subject: [PATCH 022/168] cleanup
---
.../edit_index_pattern/edit_index_pattern.tsx | 4 +-
src/plugins/data_views/common/utils.test.ts | 66 ++++++++++++-------
src/plugins/data_views/common/utils.ts | 8 +++
.../data_views/data_views_api_client.ts | 1 +
.../server/rest_api_routes/internal/fields.ts | 30 ++-------
5 files changed, 59 insertions(+), 50 deletions(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
index ba1d8373119cb..17835dbdf8aef 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
@@ -93,7 +93,7 @@ export const EditIndexPattern = withRouter(
const [showEditDialog, setShowEditDialog] = useState(false);
const [relationships, setRelationships] = useState([]);
const [allowedTypes, setAllowedTypes] = useState([]);
- const [refreshCount, setRefreshCount] = useState(0);
+ const [refreshCount, setRefreshCount] = useState(0); // used for forcing rerender of field list
const [isRefreshing, setIsRefreshing] = React.useState(false);
const conflictFieldsUrl = useMemo(() => {
@@ -250,7 +250,7 @@ export const EditIndexPattern = withRouter(
refreshIndexPatternClick={async () => {
setIsRefreshing(true);
await dataViews.refreshFields(indexPattern, false, true);
- setRefreshCount(refreshCount + 1);
+ setRefreshCount(refreshCount + 1); // rerender field list
setIsRefreshing(false);
}}
defaultIndex={defaultIndex}
diff --git a/src/plugins/data_views/common/utils.test.ts b/src/plugins/data_views/common/utils.test.ts
index 3351a15da1a13..e8602def7f712 100644
--- a/src/plugins/data_views/common/utils.test.ts
+++ b/src/plugins/data_views/common/utils.test.ts
@@ -8,6 +8,7 @@
import { isFilterable } from '.';
import type { DataViewField } from './fields';
+import { unwrapEtag } from './utils';
const mockField = {
name: 'foo',
@@ -16,38 +17,55 @@ const mockField = {
type: 'string',
} as DataViewField;
-describe('isFilterable', () => {
- describe('types', () => {
- it('should return true for filterable types', () => {
- ['string', 'number', 'date', 'ip', 'boolean'].forEach((type) => {
- expect(isFilterable({ ...mockField, type } as DataViewField)).toBe(true);
+describe('common utils', () => {
+ describe('isFilterable', () => {
+ describe('types', () => {
+ it('should return true for filterable types', () => {
+ ['string', 'number', 'date', 'ip', 'boolean'].forEach((type) => {
+ expect(isFilterable({ ...mockField, type } as DataViewField)).toBe(true);
+ });
});
- });
- it('should return false for filterable types if the field is not searchable', () => {
- ['string', 'number', 'date', 'ip', 'boolean'].forEach((type) => {
- expect(isFilterable({ ...mockField, type, searchable: false } as DataViewField)).toBe(
- false
- );
+ it('should return false for filterable types if the field is not searchable', () => {
+ ['string', 'number', 'date', 'ip', 'boolean'].forEach((type) => {
+ expect(isFilterable({ ...mockField, type, searchable: false } as DataViewField)).toBe(
+ false
+ );
+ });
});
- });
- it('should return false for un-filterable types', () => {
- ['geo_point', 'geo_shape', 'attachment', 'murmur3', '_source', 'unknown', 'conflict'].forEach(
- (type) => {
+ it('should return false for un-filterable types', () => {
+ [
+ 'geo_point',
+ 'geo_shape',
+ 'attachment',
+ 'murmur3',
+ '_source',
+ 'unknown',
+ 'conflict',
+ ].forEach((type) => {
expect(isFilterable({ ...mockField, type } as DataViewField)).toBe(false);
- }
- );
+ });
+ });
});
- });
- it('should return true for scripted fields', () => {
- expect(isFilterable({ ...mockField, scripted: true, searchable: false } as DataViewField)).toBe(
- true
- );
+ it('should return true for scripted fields', () => {
+ expect(
+ isFilterable({ ...mockField, scripted: true, searchable: false } as DataViewField)
+ ).toBe(true);
+ });
+
+ it('should return true for the _id field', () => {
+ expect(isFilterable({ ...mockField, name: '_id' } as DataViewField)).toBe(true);
+ });
});
- it('should return true for the _id field', () => {
- expect(isFilterable({ ...mockField, name: '_id' } as DataViewField)).toBe(true);
+ describe('unwrapEtag', () => {
+ it('should return the etag without quotes', () => {
+ expect(unwrapEtag('"foo"')).toBe('foo');
+ });
+ it('should return the etag without quotes and without gzip', () => {
+ expect(unwrapEtag('"foo-gzip"')).toBe('foo');
+ });
});
});
diff --git a/src/plugins/data_views/common/utils.ts b/src/plugins/data_views/common/utils.ts
index e63167ff4d3ff..507f90e764c5e 100644
--- a/src/plugins/data_views/common/utils.ts
+++ b/src/plugins/data_views/common/utils.ts
@@ -27,3 +27,11 @@ export async function findByName(client: PersistenceAPI, name: string) {
return savedObjects ? savedObjects[0] : undefined;
}
}
+
+export function unwrapEtag(ifNoneMatch: string) {
+ let requestHash = (ifNoneMatch as string).slice(1, -1);
+ if (requestHash.indexOf('-') > -1) {
+ requestHash = requestHash.split('-')[0];
+ }
+ return requestHash;
+}
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index ff184722a4a3b..4305876720a6a 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -37,6 +37,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
): Promise | undefined> {
const asResponse = true;
// circle back to this, will likely need changes to any code that loads fields
+ // setting to true skips automatic json parsing
// const rawResponse = true;
const rawResponse = false;
const cacheOptions = forceRefresh ? { cache: 'no-cache' as RequestCache } : {};
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index 0e2dd5d0589db..5fbcacc2b2b14 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -11,6 +11,7 @@ import { estypes } from '@elastic/elasticsearch';
import { schema } from '@kbn/config-schema';
import { IRouter, RequestHandler, StartServicesAccessor } from '@kbn/core/server';
// import { FullValidationConfig } from '@kbn/core-http-server';
+import { unwrapEtag } from '../../../common/utils';
import { IndexPatternsFetcher } from '../../fetcher';
import type {
DataViewsServerPluginStart,
@@ -144,7 +145,6 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
try {
const { fields, indices } = await indexPatterns.getFieldsForWildcard({
pattern,
- // todo should these be added elsewhere?
metaFields: parsedMetaFields,
type,
rollupIndex,
@@ -162,15 +162,9 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
const etag = calculateHash(Buffer.from(JSON.stringify(body)));
- // todo are these needed?
- const headers: Record = {
- 'content-type': 'application/json',
- // 'If-None-Match': '123456',
- etag,
- // Expires
- };
+ const headers: Record = { 'content-type': 'application/json', etag };
- // todo consider running in parallel with the request
+ // todo examine how long this takes
const cacheMaxAge = await uiSettings.get('data_views:cache_max_age');
if (cacheMaxAge) {
@@ -180,14 +174,11 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
] = `private, max-age=${cacheMaxAge}, stale-while-revalidate=${stale}`;
}
- // move to util
const ifNoneMatch = request.headers['if-none-match'];
- if (ifNoneMatch) {
- let requestHash = (ifNoneMatch as string).slice(1, -1);
- if (requestHash.indexOf('-') > -1) {
- requestHash = requestHash.split('-')[0];
- }
+ const ifNoneMatchString = Array.isArray(ifNoneMatch) ? ifNoneMatch[0] : ifNoneMatch;
+ if (ifNoneMatchString) {
+ const requestHash = unwrapEtag(ifNoneMatchString);
if (etag === requestHash) {
return response.notModified({ headers });
}
@@ -225,14 +216,5 @@ export const registerFields = async (
>,
isRollupsEnabled: () => boolean
) => {
- // handler
- /* This seems to fail due to lack of custom headers on cache requests
- router.versioned
- .get({ path, access })
- .addVersion(
- { version, validate: { request: { query: querySchema }, response: validate.response } },
- handler(isRollupsEnabled)
- );
- */
router.get({ path, validate: { query: querySchema } }, handler(isRollupsEnabled));
};
From 4099571b9f0ae693e92c9a415ad8d560dde2c3bb Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 7 Nov 2023 12:15:27 -0600
Subject: [PATCH 023/168] fix test
---
.../apps/discover/feature_controls/discover_security.ts | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index ed6e1bc27abcb..fa01fc5b8d57f 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -448,8 +448,9 @@ export default function (ctx: FtrProviderContext) {
it('allows to access only via a permitted index alias', async () => {
await globalNav.badgeExistsOrFail('Read only');
- await PageObjects.settings.refreshDataViewFieldList('logstash-*');
- await PageObjects.common.navigateToApp('discover');
+ // this doesn't work since the user doesn't have access
+ // await PageObjects.settings.refreshDataViewFieldList('logstash-*');
+ // await PageObjects.common.navigateToApp('discover');
// can't access logstash index directly
await PageObjects.discover.selectIndexPattern('logstash-*');
From 97e7689334b60932dc8dea7bf7ef4c8e9a30a004 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 7 Nov 2023 14:58:07 -0600
Subject: [PATCH 024/168] restore default cache time length
---
src/plugins/data_views/server/ui_settings.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_views/server/ui_settings.ts b/src/plugins/data_views/server/ui_settings.ts
index a2d0feb05bbe8..7e995112fdc1c 100644
--- a/src/plugins/data_views/server/ui_settings.ts
+++ b/src/plugins/data_views/server/ui_settings.ts
@@ -14,7 +14,7 @@ export const cacheMaxAge = {
name: i18n.translate('dataViews.advancedSettings.cacheMaxAgeTitle', {
defaultMessage: 'Field cache max age',
}),
- value: 0,
+ value: 300,
description: i18n.translate('dataViews.advancedSettings.cacheMaxAgeText', {
defaultMessage:
"Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching.",
From 7b7189d120e75c866a887c218235fd298c513ef8 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 7 Nov 2023 21:26:27 -0600
Subject: [PATCH 025/168] functional test fix
---
.../apps/discover_ml_uptime/discover/search_source_alert.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 98eb7bd0bbf90..792eb9c042e2d 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -406,6 +406,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// this test fails with caching in place
it('should navigate to alert results via link provided in notification', async () => {
+ // todo verify this fixes something
+ await PageObjects.settings.refreshDataViewFieldList(SOURCE_DATA_VIEW);
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
From 521e02888d2ec55f3cea51c0540acaa0b2fa648c Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 10 Nov 2023 00:12:02 -0600
Subject: [PATCH 026/168] hopefully fix some functional tests
---
.../cypress/e2e/automated_response_actions/form.cy.ts | 6 +++---
.../test/functional/apps/maps/group4/es_pew_pew_source.js | 6 +++++-
x-pack/test/functional/apps/maps/group4/index.js | 2 ++
x-pack/test/functional/apps/maps/group4/mvt_scaling.js | 4 ++++
4 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts
index 88131f1031f1e..bf60ac20a4fe6 100644
--- a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts
+++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
+// import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
import {
addEndpointResponseAction,
fillUpNewRule,
@@ -186,9 +186,9 @@ describe(
});
it('All response action controls are disabled', () => {
- cy.intercept('GET', `${FIELDS_PATH}*`).as('getFieldsForWildcard');
+ // cy.intercept('GET', `${FIELDS_PATH}*`).as('getFieldsForWildcard');
visitRuleActions(ruleId);
- cy.wait('@getFieldsForWildcard');
+ // cy.wait('@getFieldsForWildcard');
cy.getByTestSubj('edit-rule-actions-tab').click();
cy.getByTestSubj('response-actions-wrapper').within(() => {
diff --git a/x-pack/test/functional/apps/maps/group4/es_pew_pew_source.js b/x-pack/test/functional/apps/maps/group4/es_pew_pew_source.js
index ea94ee3bc67d8..a61ccc6081ffb 100644
--- a/x-pack/test/functional/apps/maps/group4/es_pew_pew_source.js
+++ b/x-pack/test/functional/apps/maps/group4/es_pew_pew_source.js
@@ -15,7 +15,11 @@ export default function ({ getPageObjects, getService }) {
describe('point to point source', () => {
before(async () => {
- await security.testUser.setRoles(['global_maps_all', 'geoconnections_data_reader']);
+ await security.testUser.setRoles([
+ 'global_maps_all',
+ 'geoconnections_data_reader',
+ 'test_logstash_reader',
+ ]);
await PageObjects.maps.loadSavedMap('pew pew demo');
});
diff --git a/x-pack/test/functional/apps/maps/group4/index.js b/x-pack/test/functional/apps/maps/group4/index.js
index 6af1369928d98..9fa5e81bdf242 100644
--- a/x-pack/test/functional/apps/maps/group4/index.js
+++ b/x-pack/test/functional/apps/maps/group4/index.js
@@ -63,6 +63,7 @@ export default function ({ loadTestFile, getService }) {
loadTestFile(require.resolve('./mvt_joins'));
loadTestFile(require.resolve('./mapbox_styles'));
loadTestFile(require.resolve('./mvt_scaling'));
+ /*
loadTestFile(require.resolve('./mvt_geotile_grid'));
loadTestFile(require.resolve('./add_layer_panel'));
loadTestFile(require.resolve('./file_upload'));
@@ -72,5 +73,6 @@ export default function ({ loadTestFile, getService }) {
loadTestFile(require.resolve('./geofile_wizard_auto_open'));
loadTestFile(require.resolve('./lens'));
loadTestFile(require.resolve('./tile_map'));
+ */
});
}
diff --git a/x-pack/test/functional/apps/maps/group4/mvt_scaling.js b/x-pack/test/functional/apps/maps/group4/mvt_scaling.js
index cd779392ba821..a6b2c6256646a 100644
--- a/x-pack/test/functional/apps/maps/group4/mvt_scaling.js
+++ b/x-pack/test/functional/apps/maps/group4/mvt_scaling.js
@@ -136,6 +136,8 @@ export default function ({ getPageObjects, getService }) {
describe('filtering', () => {
before(async () => {
await PageObjects.maps.loadSavedMap('MVT documents');
+ console.log('awaiting');
+ await new Promise((resolve) => setTimeout(resolve, 1000 * 60 * 10));
});
async function getTileUrl() {
@@ -223,6 +225,8 @@ export default function ({ getPageObjects, getService }) {
await PageObjects.maps.openLayerPanel('logstash-*');
await testSubjects.click('mapLayerPanelApplyGlobalTimeCheckbox');
await PageObjects.maps.waitForLayersToLoad();
+ console.log('HERE HERE HERE');
+ await new Promise((resolve) => setTimeout(resolve, 1000 * 60 * 10));
});
after(async () => {
From d93f86b2b43f4bf6000d967bd534b1e6064baf46 Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Fri, 10 Nov 2023 06:17:50 +0000
Subject: [PATCH 027/168] [CI] Auto-commit changed files from 'node
scripts/lint_ts_projects --fix'
---
.../security_solution/public/management/cypress/tsconfig.json | 1 -
1 file changed, 1 deletion(-)
diff --git a/x-pack/plugins/security_solution/public/management/cypress/tsconfig.json b/x-pack/plugins/security_solution/public/management/cypress/tsconfig.json
index 8a38566931281..20cb7534941b3 100644
--- a/x-pack/plugins/security_solution/public/management/cypress/tsconfig.json
+++ b/x-pack/plugins/security_solution/public/management/cypress/tsconfig.json
@@ -30,7 +30,6 @@
"@kbn/cases-plugin",
"@kbn/test",
"@kbn/repo-info",
- "@kbn/data-views-plugin",
"@kbn/tooling-log",
]
}
From 48455115195404b2e526fa865d7fc3e6e491f209 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 10 Nov 2023 09:07:42 -0600
Subject: [PATCH 028/168] add vary header which should clear cache on user
change
---
.../core-http-browser-internal/src/fetch.ts | 1 -
.../public/data_views/data_views_api_client.ts | 16 +++++++++++++---
src/plugins/data_views/public/plugin.ts | 7 ++++++-
src/plugins/data_views/public/types.ts | 3 +++
x-pack/plugins/security/public/plugin.tsx | 18 ++++++++++++++++--
.../functional/apps/maps/group4/mvt_scaling.js | 4 ----
6 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/packages/core/http/core-http-browser-internal/src/fetch.ts b/packages/core/http/core-http-browser-internal/src/fetch.ts
index 60d71ba0dc72e..22b827dc614eb 100644
--- a/packages/core/http/core-http-browser-internal/src/fetch.ts
+++ b/packages/core/http/core-http-browser-internal/src/fetch.ts
@@ -118,7 +118,6 @@ export class Fetch {
private createRequest(options: HttpFetchOptionsWithPath): Request {
const context = this.params.executionContext.withGlobalContext(options.context);
const { version } = options;
-
// Merge and destructure options out that are not applicable to the Fetch API.
const {
query,
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index 4305876720a6a..d205b1f06bc2d 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -20,16 +20,18 @@ const version = '1';
*/
export class DataViewsApiClient implements IDataViewsApiClient {
private http: HttpSetup;
+ private getCurrentUserId: () => Promise;
/**
* constructor
* @param http http dependency
*/
- constructor(http: HttpSetup) {
+ constructor(http: HttpSetup, getCurrentUserId: () => Promise) {
this.http = http;
+ this.getCurrentUserId = getCurrentUserId;
}
- private _request(
+ private async _request(
url: string,
query?: {},
body?: string,
@@ -41,10 +43,18 @@ export class DataViewsApiClient implements IDataViewsApiClient {
// const rawResponse = true;
const rawResponse = false;
const cacheOptions = forceRefresh ? { cache: 'no-cache' as RequestCache } : {};
+ const userId = await this.getCurrentUserId();
const request = body
? this.http.post(url, { query, body, version, asResponse })
- : this.http.fetch(url, { query, version, ...cacheOptions, asResponse, rawResponse });
+ : this.http.fetch(url, {
+ query,
+ version,
+ ...cacheOptions,
+ asResponse,
+ rawResponse,
+ headers: { 'user-hash': userId, Vary: 'user-hash' },
+ });
return request.catch((resp) => {
if (resp.body.statusCode === 404 && resp.body.attributes?.code === 'no_matching_indices') {
diff --git a/src/plugins/data_views/public/plugin.ts b/src/plugins/data_views/public/plugin.ts
index d00292c3f4fe8..72603ceb8246c 100644
--- a/src/plugins/data_views/public/plugin.ts
+++ b/src/plugins/data_views/public/plugin.ts
@@ -15,6 +15,7 @@ import {
DataViewsPublicPluginStart,
DataViewsPublicSetupDependencies,
DataViewsPublicStartDependencies,
+ UserIdGetter,
} from './types';
import { DataViewsApiClient } from '.';
@@ -41,6 +42,7 @@ export class DataViewsPublicPlugin
{
private readonly hasData = new HasData();
private rollupsEnabled: boolean = false;
+ private userIdGetter: UserIdGetter = async () => undefined;
constructor(private readonly initializerContext: PluginInitializerContext) {}
@@ -62,6 +64,9 @@ export class DataViewsPublicPlugin
return {
enableRollups: () => (this.rollupsEnabled = true),
+ setUserIdGetter: (userIdGetter: UserIdGetter) => {
+ this.userIdGetter = userIdGetter;
+ },
};
}
@@ -86,7 +91,7 @@ export class DataViewsPublicPlugin
hasData: this.hasData.start(core),
uiSettings: new UiSettingsPublicToCommon(uiSettings),
savedObjectsClient: new ContentMagementWrapper(contentManagement.client),
- apiClient: new DataViewsApiClient(http),
+ apiClient: new DataViewsApiClient(http, this.userIdGetter),
fieldFormats,
http,
onNotification: (toastInputFields, key) => {
diff --git a/src/plugins/data_views/public/types.ts b/src/plugins/data_views/public/types.ts
index 7d6cbbc6cf533..d01e606b968e3 100644
--- a/src/plugins/data_views/public/types.ts
+++ b/src/plugins/data_views/public/types.ts
@@ -106,11 +106,14 @@ export interface DataViewsPublicStartDependencies {
contentManagement: ContentManagementPublicStart;
}
+export type UserIdGetter = () => Promise;
+
/**
* Data plugin public Setup contract
*/
export interface DataViewsPublicPluginSetup {
enableRollups: () => void;
+ setUserIdGetter: (userIdGetter: UserIdGetter) => void;
}
export interface DataViewsServicePublic extends DataViewsServicePublicMethods {
diff --git a/x-pack/plugins/security/public/plugin.tsx b/x-pack/plugins/security/public/plugin.tsx
index eb5b2723f9eab..630b98d8ccdf1 100644
--- a/x-pack/plugins/security/public/plugin.tsx
+++ b/x-pack/plugins/security/public/plugin.tsx
@@ -13,7 +13,10 @@ import type {
Plugin,
PluginInitializerContext,
} from '@kbn/core/public';
-import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
+import type {
+ DataViewsPublicPluginSetup,
+ DataViewsPublicPluginStart,
+} from '@kbn/data-views-plugin/public';
import type { FeaturesPluginStart } from '@kbn/features-plugin/public';
import type { HomePublicPluginSetup } from '@kbn/home-plugin/public';
import { i18n } from '@kbn/i18n';
@@ -45,6 +48,7 @@ export interface PluginSetupDependencies {
management?: ManagementSetup;
share?: SharePluginSetup;
cloud?: CloudSetup;
+ dataViews?: DataViewsPublicPluginSetup;
}
export interface PluginStartDependencies {
@@ -87,7 +91,7 @@ export class SecurityPlugin
public setup(
core: CoreSetup,
- { cloud, home, licensing, management, share }: PluginSetupDependencies
+ { cloud, home, licensing, management, share, dataViews }: PluginSetupDependencies
): SecurityPluginSetup {
const { license } = this.securityLicenseService.setup({ license$: licensing.license$ });
@@ -159,6 +163,16 @@ export class SecurityPlugin
this.anonymousAccessService.setup({ share });
}
+ const userIdGetter = async () => {
+ const [, , security] = await core.getStartServices();
+ const { profile_uid: profileUid } = await (
+ security as SecurityPluginStart
+ ).authc.getCurrentUser();
+ return profileUid;
+ };
+
+ dataViews?.setUserIdGetter(userIdGetter);
+
return {
authc: this.authc,
license,
diff --git a/x-pack/test/functional/apps/maps/group4/mvt_scaling.js b/x-pack/test/functional/apps/maps/group4/mvt_scaling.js
index a6b2c6256646a..cd779392ba821 100644
--- a/x-pack/test/functional/apps/maps/group4/mvt_scaling.js
+++ b/x-pack/test/functional/apps/maps/group4/mvt_scaling.js
@@ -136,8 +136,6 @@ export default function ({ getPageObjects, getService }) {
describe('filtering', () => {
before(async () => {
await PageObjects.maps.loadSavedMap('MVT documents');
- console.log('awaiting');
- await new Promise((resolve) => setTimeout(resolve, 1000 * 60 * 10));
});
async function getTileUrl() {
@@ -225,8 +223,6 @@ export default function ({ getPageObjects, getService }) {
await PageObjects.maps.openLayerPanel('logstash-*');
await testSubjects.click('mapLayerPanelApplyGlobalTimeCheckbox');
await PageObjects.maps.waitForLayersToLoad();
- console.log('HERE HERE HERE');
- await new Promise((resolve) => setTimeout(resolve, 1000 * 60 * 10));
});
after(async () => {
From 7f521306d6d2a2236f1d9c08cea2c84941273fb1 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 10 Nov 2023 11:18:55 -0600
Subject: [PATCH 029/168] test fixes
---
packages/core/http/core-http-browser-internal/src/fetch.ts | 1 +
.../public/data_views/data_views_api_client.test.ts | 2 +-
src/plugins/data_views/public/mocks.ts | 1 +
.../test/functional/apps/maps/group4/es_pew_pew_source.js | 6 +-----
x-pack/test/functional/apps/maps/group4/index.js | 2 --
.../apps/observability_log_explorer/columns_selection.ts | 2 +-
6 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/packages/core/http/core-http-browser-internal/src/fetch.ts b/packages/core/http/core-http-browser-internal/src/fetch.ts
index 22b827dc614eb..60d71ba0dc72e 100644
--- a/packages/core/http/core-http-browser-internal/src/fetch.ts
+++ b/packages/core/http/core-http-browser-internal/src/fetch.ts
@@ -118,6 +118,7 @@ export class Fetch {
private createRequest(options: HttpFetchOptionsWithPath): Request {
const context = this.params.executionContext.withGlobalContext(options.context);
const { version } = options;
+
// Merge and destructure options out that are not applicable to the Fetch API.
const {
query,
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.test.ts b/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
index 6320226aea96f..e6c4ed3ddbb4e 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
@@ -16,7 +16,7 @@ describe('IndexPatternsApiClient', () => {
beforeEach(() => {
fetchSpy = jest.spyOn(http, 'fetch').mockImplementation(() => Promise.resolve({}));
- indexPatternsApiClient = new DataViewsApiClient(http);
+ indexPatternsApiClient = new DataViewsApiClient(http, () => Promise.resolve(undefined));
});
test('uses the right URI to fetch fields for wildcard', async function () {
diff --git a/src/plugins/data_views/public/mocks.ts b/src/plugins/data_views/public/mocks.ts
index e9d5b487b8b00..0edea939ab8df 100644
--- a/src/plugins/data_views/public/mocks.ts
+++ b/src/plugins/data_views/public/mocks.ts
@@ -13,6 +13,7 @@ export type Start = jest.Mocked>;
const createSetupContract = (): Setup => ({
enableRollups: jest.fn(),
+ setUserIdGetter: jest.fn(),
});
const createStartContract = (): Start => {
diff --git a/x-pack/test/functional/apps/maps/group4/es_pew_pew_source.js b/x-pack/test/functional/apps/maps/group4/es_pew_pew_source.js
index a61ccc6081ffb..ea94ee3bc67d8 100644
--- a/x-pack/test/functional/apps/maps/group4/es_pew_pew_source.js
+++ b/x-pack/test/functional/apps/maps/group4/es_pew_pew_source.js
@@ -15,11 +15,7 @@ export default function ({ getPageObjects, getService }) {
describe('point to point source', () => {
before(async () => {
- await security.testUser.setRoles([
- 'global_maps_all',
- 'geoconnections_data_reader',
- 'test_logstash_reader',
- ]);
+ await security.testUser.setRoles(['global_maps_all', 'geoconnections_data_reader']);
await PageObjects.maps.loadSavedMap('pew pew demo');
});
diff --git a/x-pack/test/functional/apps/maps/group4/index.js b/x-pack/test/functional/apps/maps/group4/index.js
index 9fa5e81bdf242..6af1369928d98 100644
--- a/x-pack/test/functional/apps/maps/group4/index.js
+++ b/x-pack/test/functional/apps/maps/group4/index.js
@@ -63,7 +63,6 @@ export default function ({ loadTestFile, getService }) {
loadTestFile(require.resolve('./mvt_joins'));
loadTestFile(require.resolve('./mapbox_styles'));
loadTestFile(require.resolve('./mvt_scaling'));
- /*
loadTestFile(require.resolve('./mvt_geotile_grid'));
loadTestFile(require.resolve('./add_layer_panel'));
loadTestFile(require.resolve('./file_upload'));
@@ -73,6 +72,5 @@ export default function ({ loadTestFile, getService }) {
loadTestFile(require.resolve('./geofile_wizard_auto_open'));
loadTestFile(require.resolve('./lens'));
loadTestFile(require.resolve('./tile_map'));
- */
});
}
diff --git a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
index 83b88d3615547..ef3a8473e320d 100644
--- a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
+++ b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
@@ -31,7 +31,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('when the log explorer loads', () => {
it("should initialize the table columns to logs' default selection", async () => {
// did this work?
- PageObjects.settings.refreshDataViewFieldList('All logs');
+ // PageObjects.settings.refreshDataViewFieldList('All logs');
await PageObjects.observabilityLogExplorer.navigateTo();
await retry.try(async () => {
From abcf7d622e37e5a211409ea0721284ad54c5cfbd Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 10 Nov 2023 21:52:38 -0600
Subject: [PATCH 030/168] I think I implemented the Vary header
---
.../data_views/data_views_api_client.ts | 2 +-
src/plugins/data_views/server/index.ts | 1 +
src/plugins/data_views/server/plugin.ts | 18 ++++++++-----
.../server/rest_api_routes/internal/fields.ts | 21 +++++++++++-----
src/plugins/data_views/server/routes.ts | 25 +++++++++++++------
src/plugins/data_views/server/types.ts | 6 +++++
x-pack/plugins/security/server/plugin.ts | 18 ++++++++++++-
7 files changed, 69 insertions(+), 22 deletions(-)
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index d205b1f06bc2d..8b39ab76727f1 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -53,7 +53,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
...cacheOptions,
asResponse,
rawResponse,
- headers: { 'user-hash': userId, Vary: 'user-hash' },
+ headers: { 'user-hash': userId },
});
return request.catch((resp) => {
diff --git a/src/plugins/data_views/server/index.ts b/src/plugins/data_views/server/index.ts
index a489feabbf935..1bf5cc883ded2 100644
--- a/src/plugins/data_views/server/index.ts
+++ b/src/plugins/data_views/server/index.ts
@@ -16,6 +16,7 @@ export type {
DataViewsServerPluginStart,
DataViewsServerPluginSetupDependencies,
DataViewsServerPluginStartDependencies,
+ GetUserId,
} from './types';
import { PluginInitializerContext } from '@kbn/core/server';
diff --git a/src/plugins/data_views/server/plugin.ts b/src/plugins/data_views/server/plugin.ts
index c08e1533e6140..bdb1ac192d5a8 100644
--- a/src/plugins/data_views/server/plugin.ts
+++ b/src/plugins/data_views/server/plugin.ts
@@ -21,6 +21,7 @@ import {
DataViewsServerPluginStart,
DataViewsServerPluginSetupDependencies,
DataViewsServerPluginStartDependencies,
+ GetUserId,
} from './types';
import { DataViewsStorage } from './content_management';
import { cacheMaxAge } from './ui_settings';
@@ -36,6 +37,7 @@ export class DataViewsServerPlugin
{
private readonly logger: Logger;
private rollupsEnabled: boolean = false;
+ private getUserId: GetUserId = async () => undefined;
constructor(private readonly initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get('dataView');
@@ -50,12 +52,13 @@ export class DataViewsServerPlugin
core.uiSettings.register(cacheMaxAge);
const dataViewRestCounter = usageCollection?.createUsageCounter('dataViewsRestApi');
- registerRoutes(
- core.http,
- core.getStartServices,
- () => this.rollupsEnabled,
- dataViewRestCounter
- );
+ registerRoutes({
+ http: core.http,
+ getStartServices: core.getStartServices,
+ isRollupsEnabled: () => this.rollupsEnabled,
+ dataViewRestCounter,
+ getUserIdGetter: () => this.getUserId,
+ });
expressions.registerFunction(getIndexPatternLoad({ getStartServices: core.getStartServices }));
registerIndexPatternsUsageCollector(core.getStartServices, usageCollection);
@@ -74,6 +77,9 @@ export class DataViewsServerPlugin
return {
enableRollups: () => (this.rollupsEnabled = true),
+ setGetUserId: (getUserId: GetUserId) => {
+ this.getUserId = getUserId;
+ },
};
}
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index 5fbcacc2b2b14..e80ea74387213 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -9,7 +9,7 @@
import { createHash } from 'crypto';
import { estypes } from '@elastic/elasticsearch';
import { schema } from '@kbn/config-schema';
-import { IRouter, RequestHandler, StartServicesAccessor } from '@kbn/core/server';
+import { IRouter, RequestHandler, StartServicesAccessor, KibanaRequest } from '@kbn/core/server';
// import { FullValidationConfig } from '@kbn/core-http-server';
import { unwrapEtag } from '../../../common/utils';
import { IndexPatternsFetcher } from '../../fetcher';
@@ -118,8 +118,11 @@ function calculateHash(srcBuffer: Buffer) {
return hash.digest('hex');
}
-const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, IBody> =
- (isRollupsEnabled) => async (context, request, response) => {
+const handler: (
+ isRollupsEnabled: () => boolean,
+ getUserId: () => (kibanaRequest: KibanaRequest) => Promise
+) => RequestHandler<{}, IQuery, IBody> =
+ (isRollupsEnabled, getUserId) => async (context, request, response) => {
const core = await context.core;
const uiSettings = core.uiSettings.client;
const { asCurrentUser } = core.elasticsearch.client;
@@ -162,7 +165,12 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
const etag = calculateHash(Buffer.from(JSON.stringify(body)));
- const headers: Record = { 'content-type': 'application/json', etag };
+ const headers: Record = {
+ 'content-type': 'application/json',
+ etag,
+ vary: 'accept-encoding, user-hash',
+ 'user-hash': (await getUserId()(request)) || '',
+ };
// todo examine how long this takes
const cacheMaxAge = await uiSettings.get('data_views:cache_max_age');
@@ -214,7 +222,8 @@ export const registerFields = async (
DataViewsServerPluginStartDependencies,
DataViewsServerPluginStart
>,
- isRollupsEnabled: () => boolean
+ isRollupsEnabled: () => boolean,
+ getUserId: () => (request: KibanaRequest) => Promise
) => {
- router.get({ path, validate: { query: querySchema } }, handler(isRollupsEnabled));
+ router.get({ path, validate: { query: querySchema } }, handler(isRollupsEnabled, getUserId));
};
diff --git a/src/plugins/data_views/server/routes.ts b/src/plugins/data_views/server/routes.ts
index 51f991449029a..4acc09aafe2ab 100644
--- a/src/plugins/data_views/server/routes.ts
+++ b/src/plugins/data_views/server/routes.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { HttpServiceSetup, StartServicesAccessor } from '@kbn/core/server';
+import { HttpServiceSetup, StartServicesAccessor, KibanaRequest } from '@kbn/core/server';
import { UsageCounter } from '@kbn/usage-collection-plugin/server';
import { routes } from './rest_api_routes/public';
import type { DataViewsServerPluginStart, DataViewsServerPluginStartDependencies } from './types';
@@ -16,21 +16,30 @@ import { registerFieldForWildcard } from './rest_api_routes/internal/fields_for'
import { registerHasDataViewsRoute } from './rest_api_routes/internal/has_data_views';
import { registerFields } from './rest_api_routes/internal/fields';
-export function registerRoutes(
- http: HttpServiceSetup,
+interface RegisterRoutesArgs {
+ http: HttpServiceSetup;
getStartServices: StartServicesAccessor<
DataViewsServerPluginStartDependencies,
DataViewsServerPluginStart
- >,
- isRollupsEnabled: () => boolean,
- dataViewRestCounter?: UsageCounter
-) {
+ >;
+ isRollupsEnabled: () => boolean;
+ dataViewRestCounter?: UsageCounter;
+ getUserIdGetter: () => (request: KibanaRequest) => Promise;
+}
+
+export function registerRoutes({
+ http,
+ getStartServices,
+ dataViewRestCounter,
+ isRollupsEnabled,
+ getUserIdGetter,
+}: RegisterRoutesArgs) {
const router = http.createRouter();
routes.forEach((route) => route(router, getStartServices, dataViewRestCounter));
registerExistingIndicesPath(router);
registerFieldForWildcard(router, getStartServices, isRollupsEnabled);
- registerFields(router, getStartServices, isRollupsEnabled);
+ registerFields(router, getStartServices, isRollupsEnabled, getUserIdGetter);
registerHasDataViewsRoute(router);
}
diff --git a/src/plugins/data_views/server/types.ts b/src/plugins/data_views/server/types.ts
index 6bf438dc634bd..1349d47234950 100644
--- a/src/plugins/data_views/server/types.ts
+++ b/src/plugins/data_views/server/types.ts
@@ -16,8 +16,11 @@ import { ExpressionsServerSetup } from '@kbn/expressions-plugin/server';
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
import { FieldFormatsSetup, FieldFormatsStart } from '@kbn/field-formats-plugin/server';
import type { ContentManagementServerSetup } from '@kbn/content-management-plugin/server';
+import { SecurityPluginStart } from '@kbn/security-plugin/server';
import { DataViewsService } from '../common';
+export type GetUserId = (request: KibanaRequest) => Promise;
+
/**
* Data Views service factory
*/
@@ -59,6 +62,7 @@ export interface DataViewsServerPluginStart {
*/
export interface DataViewsServerPluginSetup {
enableRollups: () => void;
+ setGetUserId: (getUserId: GetUserId) => void;
}
/**
@@ -97,4 +101,6 @@ export interface DataViewsServerPluginStartDependencies {
* Logger
*/
logger: Logger;
+
+ security: SecurityPluginStart;
}
diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts
index 341ab79e97e5b..e87881b1a824e 100644
--- a/x-pack/plugins/security/server/plugin.ts
+++ b/x-pack/plugins/security/server/plugin.ts
@@ -18,6 +18,7 @@ import type {
Plugin,
PluginInitializerContext,
} from '@kbn/core/server';
+import type { DataViewsServerPluginSetup } from '@kbn/data-views-plugin/server';
import type {
PluginSetupContract as FeaturesPluginSetup,
PluginStartContract as FeaturesPluginStart,
@@ -118,6 +119,7 @@ export interface PluginSetupDependencies {
taskManager: TaskManagerSetupContract;
usageCollection?: UsageCollectionSetup;
spaces?: SpacesPluginSetup;
+ dataViews: DataViewsServerPluginSetup;
}
export interface PluginStartDependencies {
@@ -242,7 +244,14 @@ export class SecurityPlugin
public setup(
core: CoreSetup,
- { features, licensing, taskManager, usageCollection, spaces }: PluginSetupDependencies
+ {
+ features,
+ licensing,
+ taskManager,
+ usageCollection,
+ spaces,
+ dataViews,
+ }: PluginSetupDependencies
) {
this.kibanaIndexName = core.savedObjects.getDefaultIndex();
const config$ = this.initializerContext.config.create>().pipe(
@@ -259,6 +268,13 @@ export class SecurityPlugin
const config = this.getConfig();
const kibanaIndexName = this.getKibanaIndexName();
+ async function getUserId(request: KibanaRequest): Promise {
+ const [, , security] = await core.getStartServices();
+ return security.authc.getCurrentUser(request)?.profile_uid;
+ }
+
+ dataViews.setGetUserId(getUserId);
+
// A subset of `start` services we need during `setup`.
const startServicesPromise = core.getStartServices().then(([coreServices, depsServices]) => ({
elasticsearch: coreServices.elasticsearch,
From 5f123aed067c0be4358e70d5c1f8ddf6ac942009 Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Sat, 11 Nov 2023 03:58:21 +0000
Subject: [PATCH 031/168] [CI] Auto-commit changed files from 'node
scripts/lint_ts_projects --fix'
---
src/plugins/data_views/tsconfig.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/plugins/data_views/tsconfig.json b/src/plugins/data_views/tsconfig.json
index e5613323bc222..cf3d7aa75e551 100644
--- a/src/plugins/data_views/tsconfig.json
+++ b/src/plugins/data_views/tsconfig.json
@@ -33,6 +33,7 @@
"@kbn/object-versioning",
"@kbn/core-saved-objects-server",
"@kbn/logging",
+ "@kbn/security-plugin",
],
"exclude": [
"target/**/*",
From ebc5c678b3acb46ad3d4974a3dc8149398fc4efa Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 10 Nov 2023 22:08:23 -0600
Subject: [PATCH 032/168] remove unused type
---
src/plugins/data_views/server/types.ts | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/plugins/data_views/server/types.ts b/src/plugins/data_views/server/types.ts
index 1349d47234950..1fe900dc58113 100644
--- a/src/plugins/data_views/server/types.ts
+++ b/src/plugins/data_views/server/types.ts
@@ -16,7 +16,6 @@ import { ExpressionsServerSetup } from '@kbn/expressions-plugin/server';
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
import { FieldFormatsSetup, FieldFormatsStart } from '@kbn/field-formats-plugin/server';
import type { ContentManagementServerSetup } from '@kbn/content-management-plugin/server';
-import { SecurityPluginStart } from '@kbn/security-plugin/server';
import { DataViewsService } from '../common';
export type GetUserId = (request: KibanaRequest) => Promise;
@@ -101,6 +100,4 @@ export interface DataViewsServerPluginStartDependencies {
* Logger
*/
logger: Logger;
-
- security: SecurityPluginStart;
}
From efdc60aafc58d77e0dc308189e26a307d654de19 Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Sat, 11 Nov 2023 04:14:41 +0000
Subject: [PATCH 033/168] [CI] Auto-commit changed files from 'node
scripts/lint_ts_projects --fix'
---
src/plugins/data_views/tsconfig.json | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/plugins/data_views/tsconfig.json b/src/plugins/data_views/tsconfig.json
index cf3d7aa75e551..e5613323bc222 100644
--- a/src/plugins/data_views/tsconfig.json
+++ b/src/plugins/data_views/tsconfig.json
@@ -33,7 +33,6 @@
"@kbn/object-versioning",
"@kbn/core-saved-objects-server",
"@kbn/logging",
- "@kbn/security-plugin",
],
"exclude": [
"target/**/*",
From 0b90af39cd3a82f5a348de1d28126369873df044 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 10 Nov 2023 22:23:18 -0600
Subject: [PATCH 034/168] remove unused type
---
src/plugins/data_views/tsconfig.json | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/plugins/data_views/tsconfig.json b/src/plugins/data_views/tsconfig.json
index cf3d7aa75e551..66079b0126d6c 100644
--- a/src/plugins/data_views/tsconfig.json
+++ b/src/plugins/data_views/tsconfig.json
@@ -32,8 +32,7 @@
"@kbn/content-management-utils",
"@kbn/object-versioning",
"@kbn/core-saved-objects-server",
- "@kbn/logging",
- "@kbn/security-plugin",
+ "@kbn/logging"
],
"exclude": [
"target/**/*",
From cbfc4ded9424f2c0827f12b08a58348cfbd02045 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 10 Nov 2023 23:18:35 -0600
Subject: [PATCH 035/168] fix jest test
---
x-pack/plugins/security/server/plugin.test.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/x-pack/plugins/security/server/plugin.test.ts b/x-pack/plugins/security/server/plugin.test.ts
index e838016e94524..0426a1fd674eb 100644
--- a/x-pack/plugins/security/server/plugin.test.ts
+++ b/x-pack/plugins/security/server/plugin.test.ts
@@ -51,6 +51,9 @@ describe('Security Plugin', () => {
licensing: { license$: of({}), featureUsage: { register: jest.fn() } },
features: featuresPluginMock.createSetup(),
taskManager: taskManagerMock.createSetup(),
+ dataViews: {
+ setGetUserId: jest.fn(),
+ },
} as unknown as PluginSetupDependencies;
mockCoreStart = coreMock.createStart();
From cde6207c3de681cf28aed9fa0340ead878d83ac0 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 11 Nov 2023 21:22:41 -0600
Subject: [PATCH 036/168] add console.log debugging for functional tests
---
src/plugins/data_views/common/data_views/data_views.ts | 9 ++++++++-
.../public/data_views/data_views_api_client.ts | 2 ++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index e6ab814ee7bd0..a93c15fd80385 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -542,7 +542,7 @@ export class DataViewsService {
forceRefresh: boolean = false
) => {
const metaFields = await this.config.get(META_FIELDS);
- return this.apiClient.getFieldsForWildcard({
+ const result = await this.apiClient.getFieldsForWildcard({
type: dataView.type,
rollupIndex: dataView?.typeMeta?.params?.rollup_index,
allowNoIndex: true,
@@ -550,6 +550,13 @@ export class DataViewsService {
metaFields,
forceRefresh,
});
+
+ console.log(
+ 'getFieldsAndIndicesForDataView result',
+ dataView.getIndexPattern(),
+ JSON.stringify(result.fields, 0, 2)
+ );
+ return result;
};
private getFieldsAndIndicesForWildcard = async (options: GetFieldsOptions) => {
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index 8b39ab76727f1..e9e774fa119a1 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -56,6 +56,8 @@ export class DataViewsApiClient implements IDataViewsApiClient {
headers: { 'user-hash': userId },
});
+ console.log('User id:', userId);
+
return request.catch((resp) => {
if (resp.body.statusCode === 404 && resp.body.attributes?.code === 'no_matching_indices') {
throw new DataViewMissingIndices(resp.body.message);
From 2c0e5d5b0861c9af62cf6d1514ae9c4984bb9550 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 11 Nov 2023 21:52:19 -0600
Subject: [PATCH 037/168] add console.log debugging for functional tests
---
src/plugins/data_views/common/data_views/data_views.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index a93c15fd80385..ec550edc5e4dd 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -554,7 +554,7 @@ export class DataViewsService {
console.log(
'getFieldsAndIndicesForDataView result',
dataView.getIndexPattern(),
- JSON.stringify(result.fields, 0, 2)
+ JSON.stringify(result.fields, undefined, 2)
);
return result;
};
From e2b2ba72a6fc2428122551cde82db51228b76719 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 12 Nov 2023 00:08:31 -0600
Subject: [PATCH 038/168] add refresh button in data view picker, attempt to
fix field formatter functional test
---
.../public/dataview_picker/change_dataview.tsx | 17 +++++++++++++++++
.../management/data_views/_field_formatter.ts | 1 +
test/functional/page_objects/discover_page.ts | 7 +++++++
test/functional/page_objects/settings_page.ts | 12 +++++++-----
4 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
index e1565f1ff6b0d..1a90b47103988 100644
--- a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
+++ b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
@@ -217,6 +217,23 @@ export function ChangeDataView({
) : (
),
+ {
+ const dataView = await dataViews.get(currentDataViewId!);
+ await dataViews.refreshFields(dataView, undefined, true);
+ if (onEditDataView) {
+ onEditDataView(dataView);
+ }
+ setPopoverIsOpen(false);
+ }}
+ >
+ {i18n.translate('unifiedSearch.query.queryBar.indexPattern.refreshFieldButton', {
+ defaultMessage: 'Refresh field list',
+ })}
+ ,
);
}
diff --git a/test/functional/apps/management/data_views/_field_formatter.ts b/test/functional/apps/management/data_views/_field_formatter.ts
index 881ba6197510a..8473cf4af1736 100644
--- a/test/functional/apps/management/data_views/_field_formatter.ts
+++ b/test/functional/apps/management/data_views/_field_formatter.ts
@@ -465,6 +465,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.navigateTo();
await PageObjects.settings.clickKibanaIndexPatterns();
await PageObjects.settings.clickIndexPatternByName(indexTitle);
+ await PageObjects.settings.refreshDataViewFieldList();
});
afterEach(async () => {
diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts
index 47a79132212cc..c84afdb5d98bd 100644
--- a/test/functional/page_objects/discover_page.ts
+++ b/test/functional/page_objects/discover_page.ts
@@ -409,6 +409,13 @@ export class DiscoverPageObject extends FtrService {
});
}
+ public async refreshFieldList() {
+ await this.clickIndexPatternActions();
+ await this.testSubjects.click('data-view-refresh-fields');
+ // trying to wait for pop over to be closed
+ // await this.testSubjects.waitForHidden('changeDataViewPopover');
+ }
+
public async clickAddNewField() {
await this.retry.try(async () => {
await this.testSubjects.click('indexPattern-add-field');
diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts
index d81c1e09777d0..177cb50b3c1bb 100644
--- a/test/functional/page_objects/settings_page.ts
+++ b/test/functional/page_objects/settings_page.ts
@@ -483,11 +483,13 @@ export class SettingsPageObject extends FtrService {
await customDataViewIdInput.type(value);
}
- async refreshDataViewFieldList(dataViewName: string) {
- await this.navigateTo();
- await this.clickKibanaIndexPatterns();
- await this.header.waitUntilLoadingHasFinished();
- await this.testSubjects.click(`detail-link-${dataViewName}`);
+ async refreshDataViewFieldList(dataViewName?: string) {
+ if (dataViewName) {
+ await this.navigateTo();
+ await this.clickKibanaIndexPatterns();
+ await this.header.waitUntilLoadingHasFinished();
+ await this.testSubjects.click(`detail-link-${dataViewName}`);
+ }
await this.testSubjects.click('refreshDataViewButton');
}
From c929e5f33e1a50236c70600b2e7c5a79d5e109a9 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 12 Nov 2023 11:21:43 -0600
Subject: [PATCH 039/168] functional test fixes
---
.../apps/management/data_views/_index_pattern_filter.ts | 2 ++
.../apps/discover_ml_uptime/discover/search_source_alert.ts | 3 +--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/test/functional/apps/management/data_views/_index_pattern_filter.ts b/test/functional/apps/management/data_views/_index_pattern_filter.ts
index 5c0dc5d0284f0..3e462ee6d6673 100644
--- a/test/functional/apps/management/data_views/_index_pattern_filter.ts
+++ b/test/functional/apps/management/data_views/_index_pattern_filter.ts
@@ -167,6 +167,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.clickIndexPatternLogstash();
+ await PageObjects.settings.refreshDataViewFieldList();
+
await testSubjects.existOrFail('dataViewMappingConflict');
expect(await PageObjects.settings.getFieldTypes()).to.eql([
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 792eb9c042e2d..9982a8cf1ad3d 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -211,6 +211,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.discover.clickNewSearchButton(); // reset params
await PageObjects.discover.selectIndexPattern(OUTPUT_DATA_VIEW);
+ await PageObjects.discover.refreshFieldList();
let ruleId: string;
if (type === 'name') {
@@ -406,8 +407,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// this test fails with caching in place
it('should navigate to alert results via link provided in notification', async () => {
- // todo verify this fixes something
- await PageObjects.settings.refreshDataViewFieldList(SOURCE_DATA_VIEW);
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
From 8f59cf5b91f7619c891b8fd2206fe800831bd64e Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 12 Nov 2023 11:43:13 -0600
Subject: [PATCH 040/168] fix transform functional test
---
.../apps/observability_log_explorer/columns_selection.ts | 4 ++--
.../creation_runtime_mappings.ts | 4 +++-
.../functional/tests/discover_integration.ts | 2 ++
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
index ef3a8473e320d..15c1ce1a468eb 100644
--- a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
+++ b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
@@ -30,11 +30,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('when the log explorer loads', () => {
it("should initialize the table columns to logs' default selection", async () => {
- // did this work?
- // PageObjects.settings.refreshDataViewFieldList('All logs');
await PageObjects.observabilityLogExplorer.navigateTo();
await retry.try(async () => {
+ // did this work?
+ await PageObjects.discover.refreshFieldList();
expect(await PageObjects.discover.getColumnHeaders()).to.eql(defaultLogColumns);
});
});
diff --git a/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts b/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts
index 3f0adc5783893..f975dec539622 100644
--- a/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts
+++ b/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts
@@ -19,9 +19,10 @@ import {
PivotTransformTestData,
} from '../../helpers';
-export default function ({ getService }: FtrProviderContext) {
+export default function ({ getPageObjects, getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const transform = getService('transform');
+ const PageObjects = getPageObjects(['discover']);
const runtimeMappings = {
rt_airline_lower: {
@@ -446,6 +447,7 @@ export default function ({ getService }: FtrProviderContext) {
await transform.testExecution.logTestStep('redirects to Discover page');
await transform.wizard.redirectToDiscover();
+ await PageObjects.discover.refreshFieldList();
if (isLatestTransformTestData(testData)) {
const fromTime = 'Feb 7, 2016 @ 00:00:00.000';
diff --git a/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts b/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts
index 8258b4570ed9b..cac4c36852b56 100644
--- a/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts
+++ b/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts
@@ -104,6 +104,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
beforeEach(async () => {
await PageObjects.common.navigateToApp('discover');
await PageObjects.discover.selectIndexPattern('logstash-*');
+ // did this fix a test?
+ await PageObjects.discover.refreshFieldList();
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.header.waitUntilLoadingHasFinished();
});
From 7e7da4a480cb289c90555b43f6edc04a8f4e8036 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 12 Nov 2023 17:25:05 -0600
Subject: [PATCH 041/168] fix data view mgmt type filter on refresh
---
.../components/edit_index_pattern/edit_index_pattern.tsx | 1 +
.../public/components/edit_index_pattern/tabs/tabs.tsx | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
index 17835dbdf8aef..de42a9d7bd078 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
@@ -250,6 +250,7 @@ export const EditIndexPattern = withRouter(
refreshIndexPatternClick={async () => {
setIsRefreshing(true);
await dataViews.refreshFields(indexPattern, false, true);
+ setFields(indexPattern.getNonScriptedFields());
setRefreshCount(refreshCount + 1); // rerender field list
setIsRefreshing(false);
}}
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
index 0128d013af6f5..818127ab9e8ab 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
@@ -265,7 +265,7 @@ export const Tabs: React.FC = ({
const refreshFilters = useCallback(() => {
const tempIndexedFieldTypes: string[] = [];
const tempScriptedFieldLanguages: string[] = [];
- indexPattern.fields.getAll().forEach((field) => {
+ fields.forEach((field) => {
if (field.scripted) {
if (field.lang) {
tempScriptedFieldLanguages.push(field.lang);
@@ -284,7 +284,7 @@ export const Tabs: React.FC = ({
setIndexedFieldTypes(convertToEuiFilterOptions(tempIndexedFieldTypes));
setScriptedFieldLanguages(convertToEuiFilterOptions(tempScriptedFieldLanguages));
- }, [indexPattern]);
+ }, [fields]);
const closeFieldEditor = useCallback(() => {
if (closeEditorHandler.current) {
From fd083a1173f7bd90856965093335337a763eaa05 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 12 Nov 2023 17:44:39 -0600
Subject: [PATCH 042/168] try to fix another test
---
.../apps/observability_log_explorer/columns_selection.ts | 4 +++-
.../creation/index_pattern/creation_index_pattern.ts | 2 ++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
index 15c1ce1a468eb..f7fd36b3edb02 100644
--- a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
+++ b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
@@ -31,10 +31,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('when the log explorer loads', () => {
it("should initialize the table columns to logs' default selection", async () => {
await PageObjects.observabilityLogExplorer.navigateTo();
+ await new Promise((r) => setTimeout(r, 1000 * 60 * 10));
await retry.try(async () => {
// did this work?
- await PageObjects.discover.refreshFieldList();
+ // no, different ids
+ // await PageObjects.discover.refreshFieldList();
expect(await PageObjects.discover.getColumnHeaders()).to.eql(defaultLogColumns);
});
});
diff --git a/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts b/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts
index 69406c5830421..2b873b5bfae25 100644
--- a/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts
+++ b/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts
@@ -835,6 +835,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await transform.testExecution.logTestStep('should navigate to discover');
await transform.table.clickTransformRowAction(testData.transformId, 'Discover');
await pageObjects.discover.waitUntilSearchingHasFinished();
+ // did this work?
+ await pageObjects.discover.refreshFieldList();
if (testData.discoverAdjustSuperDatePicker) {
await transform.testExecution.logTestStep(
From 4e5d94d179e0811fdab5e44d5cfe71948fe9fbc7 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 12 Nov 2023 19:41:24 -0600
Subject: [PATCH 043/168] script field functional test fixes
---
.../public/components/edit_index_pattern/tabs/tabs.tsx | 6 ++++--
.../apps/observability_log_explorer/columns_selection.ts | 1 -
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
index 818127ab9e8ab..0642bd2509e49 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
@@ -265,7 +265,7 @@ export const Tabs: React.FC = ({
const refreshFilters = useCallback(() => {
const tempIndexedFieldTypes: string[] = [];
const tempScriptedFieldLanguages: string[] = [];
- fields.forEach((field) => {
+ indexPattern.fields.getAll().forEach((field) => {
if (field.scripted) {
if (field.lang) {
tempScriptedFieldLanguages.push(field.lang);
@@ -284,7 +284,9 @@ export const Tabs: React.FC = ({
setIndexedFieldTypes(convertToEuiFilterOptions(tempIndexedFieldTypes));
setScriptedFieldLanguages(convertToEuiFilterOptions(tempScriptedFieldLanguages));
- }, [fields]);
+ // need to reset based on changes to fields but indexPattern is the same
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [indexPattern, fields]);
const closeFieldEditor = useCallback(() => {
if (closeEditorHandler.current) {
diff --git a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
index f7fd36b3edb02..b9442c8378126 100644
--- a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
+++ b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
@@ -31,7 +31,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('when the log explorer loads', () => {
it("should initialize the table columns to logs' default selection", async () => {
await PageObjects.observabilityLogExplorer.navigateTo();
- await new Promise((r) => setTimeout(r, 1000 * 60 * 10));
await retry.try(async () => {
// did this work?
From 651a792353eceac6d36a532df34d45ed300bfc4b Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 12 Nov 2023 20:11:03 -0600
Subject: [PATCH 044/168] I hope I fixed the maps functional test
---
x-pack/test/functional/apps/maps/group4/index.js | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/x-pack/test/functional/apps/maps/group4/index.js b/x-pack/test/functional/apps/maps/group4/index.js
index 6af1369928d98..25285f9340962 100644
--- a/x-pack/test/functional/apps/maps/group4/index.js
+++ b/x-pack/test/functional/apps/maps/group4/index.js
@@ -5,12 +5,13 @@
* 2.0.
*/
-export default function ({ loadTestFile, getService }) {
+export default function ({ loadTestFile, getService, getPageObjects }) {
const kibanaServer = getService('kibanaServer');
const esArchiver = getService('esArchiver');
const browser = getService('browser');
const log = getService('log');
const supertest = getService('supertest');
+ const PageObjects = getPageObjects(['discover', 'common']);
describe('maps app', function () {
this.tags(['skipFirefox']);
@@ -49,6 +50,9 @@ export default function ({ loadTestFile, getService }) {
defaultIndex: 'c698b940-e149-11e8-a35a-370a8516603a',
});
await browser.setWindowSize(1600, 1000);
+
+ await PageObjects.common.navigateToApp('discover');
+ await PageObjects.discover.refreshFieldList(); // refreshes field list cache from previous tests
});
after(async () => {
From 86852433567828f6df0f738efa2a855ee0f78544 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 12 Nov 2023 21:51:10 -0600
Subject: [PATCH 045/168] fix some functional tests
---
src/plugins/data_views/common/data_views/data_views.ts | 1 +
src/plugins/data_views/server/ui_settings.ts | 2 +-
src/plugins/data_views/tsconfig.json | 2 +-
test/functional/page_objects/discover_page.ts | 2 --
x-pack/test/functional/apps/maps/group4/index.js | 2 ++
.../apps/observability_log_explorer/columns_selection.ts | 3 +++
6 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index ec550edc5e4dd..edfb68249e837 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -551,6 +551,7 @@ export class DataViewsService {
forceRefresh,
});
+ // todo
console.log(
'getFieldsAndIndicesForDataView result',
dataView.getIndexPattern(),
diff --git a/src/plugins/data_views/server/ui_settings.ts b/src/plugins/data_views/server/ui_settings.ts
index 7e995112fdc1c..b276d440a06f4 100644
--- a/src/plugins/data_views/server/ui_settings.ts
+++ b/src/plugins/data_views/server/ui_settings.ts
@@ -17,7 +17,7 @@ export const cacheMaxAge = {
value: 300,
description: i18n.translate('dataViews.advancedSettings.cacheMaxAgeText', {
defaultMessage:
- "Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching.",
+ "Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching. A hard reload of Kibana may be necessary for your browser to pick up the new setting.",
}),
schema: schema.number(),
},
diff --git a/src/plugins/data_views/tsconfig.json b/src/plugins/data_views/tsconfig.json
index 66079b0126d6c..e5613323bc222 100644
--- a/src/plugins/data_views/tsconfig.json
+++ b/src/plugins/data_views/tsconfig.json
@@ -32,7 +32,7 @@
"@kbn/content-management-utils",
"@kbn/object-versioning",
"@kbn/core-saved-objects-server",
- "@kbn/logging"
+ "@kbn/logging",
],
"exclude": [
"target/**/*",
diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts
index c84afdb5d98bd..3604ad349dd39 100644
--- a/test/functional/page_objects/discover_page.ts
+++ b/test/functional/page_objects/discover_page.ts
@@ -412,8 +412,6 @@ export class DiscoverPageObject extends FtrService {
public async refreshFieldList() {
await this.clickIndexPatternActions();
await this.testSubjects.click('data-view-refresh-fields');
- // trying to wait for pop over to be closed
- // await this.testSubjects.waitForHidden('changeDataViewPopover');
}
public async clickAddNewField() {
diff --git a/x-pack/test/functional/apps/maps/group4/index.js b/x-pack/test/functional/apps/maps/group4/index.js
index 25285f9340962..4186670bb9b73 100644
--- a/x-pack/test/functional/apps/maps/group4/index.js
+++ b/x-pack/test/functional/apps/maps/group4/index.js
@@ -11,6 +11,7 @@ export default function ({ loadTestFile, getService, getPageObjects }) {
const browser = getService('browser');
const log = getService('log');
const supertest = getService('supertest');
+ const security = getService('security');
const PageObjects = getPageObjects(['discover', 'common']);
describe('maps app', function () {
@@ -51,6 +52,7 @@ export default function ({ loadTestFile, getService, getPageObjects }) {
});
await browser.setWindowSize(1600, 1000);
+ await security.testUser.setRoles(['kibana_admin']); // necessary to refresh field list
await PageObjects.common.navigateToApp('discover');
await PageObjects.discover.refreshFieldList(); // refreshes field list cache from previous tests
});
diff --git a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
index b9442c8378126..81198bab7ae63 100644
--- a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
+++ b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
@@ -13,6 +13,7 @@ const defaultLogColumns = ['@timestamp', 'service.name', 'host.name', 'message']
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const retry = getService('retry');
+ const browser = getService('browser');
const PageObjects = getPageObjects(['discover', 'observabilityLogExplorer', 'settings']);
describe('Columns selection initialization and update', () => {
@@ -31,11 +32,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('when the log explorer loads', () => {
it("should initialize the table columns to logs' default selection", async () => {
await PageObjects.observabilityLogExplorer.navigateTo();
+ await browser.refresh();
await retry.try(async () => {
// did this work?
// no, different ids
// await PageObjects.discover.refreshFieldList();
+
expect(await PageObjects.discover.getColumnHeaders()).to.eql(defaultLogColumns);
});
});
From 7319b1894d7fda0cfe9a8632986985019866bd1d Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 12 Nov 2023 23:23:13 -0600
Subject: [PATCH 046/168] cleanup and functional test fix
---
.../server/rest_api_routes/internal/fields.ts | 96 +------------------
.../rest_api_routes/internal/fields_for.ts | 6 +-
.../test/functional/apps/maps/group4/index.js | 6 +-
.../columns_selection.ts | 10 +-
4 files changed, 13 insertions(+), 105 deletions(-)
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index e80ea74387213..8a8bc13333c18 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -7,10 +7,7 @@
*/
import { createHash } from 'crypto';
-import { estypes } from '@elastic/elasticsearch';
-import { schema } from '@kbn/config-schema';
import { IRouter, RequestHandler, StartServicesAccessor, KibanaRequest } from '@kbn/core/server';
-// import { FullValidationConfig } from '@kbn/core-http-server';
import { unwrapEtag } from '../../../common/utils';
import { IndexPatternsFetcher } from '../../fetcher';
import type {
@@ -19,98 +16,7 @@ import type {
} from '../../types';
import type { FieldDescriptorRestResponse } from '../route_types';
import { FIELDS_PATH as path } from '../../../common/constants';
-
-/**
- * Accepts one of the following:
- * 1. An array of field names
- * 2. A JSON-stringified array of field names
- * 3. A single field name (not comma-separated)
- * @returns an array of field names
- * @param fields
- */
-export const parseFields = (fields: string | string[]): string[] => {
- if (Array.isArray(fields)) return fields;
- try {
- return JSON.parse(fields);
- } catch (e) {
- if (!fields.includes(',')) return [fields];
- throw new Error(
- 'metaFields should be an array of field names, a JSON-stringified array of field names, or a single field name'
- );
- }
-};
-
-type IBody = { index_filter?: estypes.QueryDslQueryContainer } | undefined;
-interface IQuery {
- pattern: string;
- meta_fields: string | string[];
- type?: string;
- rollup_index?: string;
- allow_no_index?: boolean;
- include_unmapped?: boolean;
- fields?: string[];
-}
-
-const querySchema = schema.object({
- pattern: schema.string(),
- meta_fields: schema.oneOf([schema.string(), schema.arrayOf(schema.string())], {
- defaultValue: [],
- }),
- type: schema.maybe(schema.string()),
- rollup_index: schema.maybe(schema.string()),
- allow_no_index: schema.maybe(schema.boolean()),
- include_unmapped: schema.maybe(schema.boolean()),
- fields: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])),
-});
-
-/**
-const fieldSubTypeSchema = schema.object({
- multi: schema.maybe(schema.object({ parent: schema.string() })),
- nested: schema.maybe(schema.object({ path: schema.string() })),
-});
-
-/*
-const FieldDescriptorSchema = schema.object({
- aggregatable: schema.boolean(),
- name: schema.string(),
- readFromDocValues: schema.boolean(),
- searchable: schema.boolean(),
- type: schema.string(),
- esTypes: schema.maybe(schema.arrayOf(schema.string())),
- subType: fieldSubTypeSchema,
- metadata_field: schema.maybe(schema.boolean()),
- fixedInterval: schema.maybe(schema.arrayOf(schema.string())),
- timeZone: schema.maybe(schema.arrayOf(schema.string())),
- timeSeriesMetric: schema.maybe(
- schema.oneOf([
- schema.literal('histogram'),
- schema.literal('summary'),
- schema.literal('counter'),
- schema.literal('gauge'),
- schema.literal('position'),
- ])
- ),
- timeSeriesDimension: schema.maybe(schema.boolean()),
- conflictDescriptions: schema.maybe(
- schema.recordOf(schema.string(), schema.arrayOf(schema.string()))
- ),
-});
-
-/*
-const validate: FullValidationConfig = {
- request: {
- query: querySchema,
- },
- response: {
- 200: {
- body: schema.object({
- fields: schema.arrayOf(FieldDescriptorSchema),
- indices: schema.arrayOf(schema.string()),
- }),
- },
- },
-};
-*/
+import { parseFields, IBody, IQuery, querySchema } from './fields_for';
function calculateHash(srcBuffer: Buffer) {
const hash = createHash('sha1');
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
index 15d761935c0a7..58016cb6ee899 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
@@ -41,8 +41,8 @@ export const parseFields = (fields: string | string[]): string[] => {
const access = 'internal';
-type IBody = { index_filter?: estypes.QueryDslQueryContainer } | undefined;
-interface IQuery {
+export type IBody = { index_filter?: estypes.QueryDslQueryContainer } | undefined;
+export interface IQuery {
pattern: string;
meta_fields: string | string[];
type?: string;
@@ -52,7 +52,7 @@ interface IQuery {
fields?: string[];
}
-const querySchema = schema.object({
+export const querySchema = schema.object({
pattern: schema.string(),
meta_fields: schema.oneOf([schema.string(), schema.arrayOf(schema.string())], {
defaultValue: [],
diff --git a/x-pack/test/functional/apps/maps/group4/index.js b/x-pack/test/functional/apps/maps/group4/index.js
index 4186670bb9b73..b18800d16f196 100644
--- a/x-pack/test/functional/apps/maps/group4/index.js
+++ b/x-pack/test/functional/apps/maps/group4/index.js
@@ -52,7 +52,11 @@ export default function ({ loadTestFile, getService, getPageObjects }) {
});
await browser.setWindowSize(1600, 1000);
- await security.testUser.setRoles(['kibana_admin']); // necessary to refresh field list
+ await security.testUser.setRoles([
+ 'kibana_admin',
+ 'test_logstash_reader',
+ 'kibana_sample_admin',
+ ]); // necessary to refresh field list
await PageObjects.common.navigateToApp('discover');
await PageObjects.discover.refreshFieldList(); // refreshes field list cache from previous tests
});
diff --git a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
index 81198bab7ae63..1f2ee69b0308c 100644
--- a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
+++ b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
@@ -13,7 +13,6 @@ const defaultLogColumns = ['@timestamp', 'service.name', 'host.name', 'message']
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const retry = getService('retry');
- const browser = getService('browser');
const PageObjects = getPageObjects(['discover', 'observabilityLogExplorer', 'settings']);
describe('Columns selection initialization and update', () => {
@@ -21,6 +20,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await esArchiver.load(
'x-pack/test/functional/es_archives/observability_log_explorer/data_streams'
);
+
+ await PageObjects.settings.navigateTo();
+ await PageObjects.settings.createIndexPattern('logs-*-*', '@timestamp');
+ await PageObjects.settings.refreshDataViewFieldList();
});
after(async () => {
@@ -32,13 +35,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('when the log explorer loads', () => {
it("should initialize the table columns to logs' default selection", async () => {
await PageObjects.observabilityLogExplorer.navigateTo();
- await browser.refresh();
await retry.try(async () => {
- // did this work?
- // no, different ids
- // await PageObjects.discover.refreshFieldList();
-
expect(await PageObjects.discover.getColumnHeaders()).to.eql(defaultLogColumns);
});
});
From 45b3dcad524fb3e421f317da25f68ea0f92775ea Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 13 Nov 2023 09:03:06 -0600
Subject: [PATCH 047/168] don't cache empty responses
---
.../data_views/server/rest_api_routes/internal/fields.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index 8a8bc13333c18..cf4e0e0ddf766 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -81,11 +81,13 @@ const handler: (
// todo examine how long this takes
const cacheMaxAge = await uiSettings.get('data_views:cache_max_age');
- if (cacheMaxAge) {
+ if (cacheMaxAge && fields.length) {
const stale = 365 * 24 * 60 * 60 - cacheMaxAge;
headers[
'cache-control'
] = `private, max-age=${cacheMaxAge}, stale-while-revalidate=${stale}`;
+ } else {
+ headers['cache-control'] = 'private, no-cache';
}
const ifNoneMatch = request.headers['if-none-match'];
From 4b4266f3cb1c8f6e002d80c9bd3a991d5da8861b Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 13 Nov 2023 10:23:02 -0600
Subject: [PATCH 048/168] fix functional tests by removing unneeded code
---
x-pack/test/functional/apps/maps/group4/index.js | 8 +++++---
.../apps/observability_log_explorer/columns_selection.ts | 2 ++
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/x-pack/test/functional/apps/maps/group4/index.js b/x-pack/test/functional/apps/maps/group4/index.js
index b18800d16f196..0a8926158dbfd 100644
--- a/x-pack/test/functional/apps/maps/group4/index.js
+++ b/x-pack/test/functional/apps/maps/group4/index.js
@@ -5,14 +5,14 @@
* 2.0.
*/
-export default function ({ loadTestFile, getService, getPageObjects }) {
+export default function ({ loadTestFile, getService }) {
const kibanaServer = getService('kibanaServer');
const esArchiver = getService('esArchiver');
const browser = getService('browser');
const log = getService('log');
const supertest = getService('supertest');
- const security = getService('security');
- const PageObjects = getPageObjects(['discover', 'common']);
+ // const security = getService('security');
+ // const PageObjects = getPageObjects(['discover', 'common']);
describe('maps app', function () {
this.tags(['skipFirefox']);
@@ -52,6 +52,7 @@ export default function ({ loadTestFile, getService, getPageObjects }) {
});
await browser.setWindowSize(1600, 1000);
+ /*
await security.testUser.setRoles([
'kibana_admin',
'test_logstash_reader',
@@ -59,6 +60,7 @@ export default function ({ loadTestFile, getService, getPageObjects }) {
]); // necessary to refresh field list
await PageObjects.common.navigateToApp('discover');
await PageObjects.discover.refreshFieldList(); // refreshes field list cache from previous tests
+ */
});
after(async () => {
diff --git a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
index 1f2ee69b0308c..83384c4d8ed63 100644
--- a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
+++ b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
@@ -21,9 +21,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'x-pack/test/functional/es_archives/observability_log_explorer/data_streams'
);
+ /*
await PageObjects.settings.navigateTo();
await PageObjects.settings.createIndexPattern('logs-*-*', '@timestamp');
await PageObjects.settings.refreshDataViewFieldList();
+ */
});
after(async () => {
From 2f11c36587c231175145832dbdb1d6691062d62b Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 13 Nov 2023 13:24:42 -0600
Subject: [PATCH 049/168] cleanup
---
src/plugins/data_views/common/utils.ts | 2 +-
.../server/rest_api_routes/internal/fields.ts | 1 -
test/functional/apps/discover/group3/_sidebar.ts | 15 +--------------
.../data_views/_index_pattern_results_sort.ts | 1 -
.../e2e/automated_response_actions/form.cy.ts | 3 ---
.../feature_controls/discover_security.ts | 5 -----
.../index_pattern/creation_index_pattern.ts | 1 -
.../discover/search_source_alert.ts | 1 +
.../functional/tests/discover_integration.ts | 1 -
9 files changed, 3 insertions(+), 27 deletions(-)
diff --git a/src/plugins/data_views/common/utils.ts b/src/plugins/data_views/common/utils.ts
index 507f90e764c5e..b77696e15ba79 100644
--- a/src/plugins/data_views/common/utils.ts
+++ b/src/plugins/data_views/common/utils.ts
@@ -29,7 +29,7 @@ export async function findByName(client: PersistenceAPI, name: string) {
}
export function unwrapEtag(ifNoneMatch: string) {
- let requestHash = (ifNoneMatch as string).slice(1, -1);
+ let requestHash = ifNoneMatch.slice(1, -1);
if (requestHash.indexOf('-') > -1) {
requestHash = requestHash.split('-')[0];
}
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index cf4e0e0ddf766..a6ea905829cf4 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -78,7 +78,6 @@ const handler: (
'user-hash': (await getUserId()(request)) || '',
};
- // todo examine how long this takes
const cacheMaxAge = await uiSettings.get('data_views:cache_max_age');
if (cacheMaxAge && fields.length) {
diff --git a/test/functional/apps/discover/group3/_sidebar.ts b/test/functional/apps/discover/group3/_sidebar.ts
index 218ee9570b520..84a76bd5314e9 100644
--- a/test/functional/apps/discover/group3/_sidebar.ts
+++ b/test/functional/apps/discover/group3/_sidebar.ts
@@ -495,8 +495,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
- // console.log('######################## await timeout');
- // await new Promise((r) => setTimeout(r, 10000 * 60));
expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be(
'0 available fields. 0 empty fields. 0 meta fields.'
);
@@ -531,10 +529,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
await browser.refresh();
- // here
- await PageObjects.settings.refreshDataViewFieldList('with-timefield');
- await PageObjects.common.navigateToApp('discover');
- await PageObjects.discover.waitUntilSearchingHasFinished();
+ await PageObjects.discover.refreshFieldList();
await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be(
@@ -555,12 +550,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
- // console.log('######################## await timeout');
- // await new Promise((r) => setTimeout(r, 1000 * 300));
- // todo - comapre to main. This looks correct in this branch
expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be(
'0 available fields. 7 empty fields. 3 meta fields.'
- // '0 available fields. 13 empty fields. 0 empty fields. 3 meta fields.'
);
await testSubjects.existOrFail(
`${PageObjects.unifiedFieldList.getSidebarSectionSelector(
@@ -584,8 +575,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await esArchiver.unload(
'test/functional/fixtures/es_archiver/index_pattern_without_timefield'
);
- // console.log('######################## await timeout');
- // await new Promise((r) => setTimeout(r, 1000 * 30));
});
it('should work when filters change', async () => {
@@ -766,8 +755,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
- // console.log('######################## await timeout');
- // await new Promise((r) => setTimeout(r, 1000 * 30));
expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be(
'0 available fields. 7 empty fields. 3 meta fields.'
);
diff --git a/test/functional/apps/management/data_views/_index_pattern_results_sort.ts b/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
index aef25d91634e5..8a94f96827a35 100644
--- a/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
+++ b/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
@@ -68,7 +68,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('field list pagination', function () {
const EXPECTED_FIELD_COUNT = 85;
it('makelogs data should have expected number of fields', async function () {
- // did this work?
await testSubjects.click('refreshDataViewButton');
await retry.try(async function () {
const TabCount = await PageObjects.settings.getFieldsTabCount();
diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts
index bf60ac20a4fe6..27458ef09e15b 100644
--- a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts
+++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts
@@ -5,7 +5,6 @@
* 2.0.
*/
-// import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
import {
addEndpointResponseAction,
fillUpNewRule,
@@ -186,9 +185,7 @@ describe(
});
it('All response action controls are disabled', () => {
- // cy.intercept('GET', `${FIELDS_PATH}*`).as('getFieldsForWildcard');
visitRuleActions(ruleId);
- // cy.wait('@getFieldsForWildcard');
cy.getByTestSubj('edit-rule-actions-tab').click();
cy.getByTestSubj('response-actions-wrapper').within(() => {
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index fa01fc5b8d57f..ee810f7ddebfb 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -31,7 +31,6 @@ export default function (ctx: FtrProviderContext) {
'spaceSelector',
'header',
'unifiedFieldList',
- 'settings',
]);
const testSubjects = getService('testSubjects');
const appsMenu = getService('appsMenu');
@@ -448,10 +447,6 @@ export default function (ctx: FtrProviderContext) {
it('allows to access only via a permitted index alias', async () => {
await globalNav.badgeExistsOrFail('Read only');
- // this doesn't work since the user doesn't have access
- // await PageObjects.settings.refreshDataViewFieldList('logstash-*');
- // await PageObjects.common.navigateToApp('discover');
-
// can't access logstash index directly
await PageObjects.discover.selectIndexPattern('logstash-*');
await PageObjects.header.waitUntilLoadingHasFinished();
diff --git a/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts b/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts
index 2b873b5bfae25..7384b5bae2c9a 100644
--- a/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts
+++ b/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts
@@ -835,7 +835,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await transform.testExecution.logTestStep('should navigate to discover');
await transform.table.clickTransformRowAction(testData.transformId, 'Discover');
await pageObjects.discover.waitUntilSearchingHasFinished();
- // did this work?
await pageObjects.discover.refreshFieldList();
if (testData.discoverAdjustSuperDatePicker) {
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 9982a8cf1ad3d..403522855a7e2 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -308,6 +308,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('Search source Alert', () => {
before(async () => {
+ // todo try removing this
await kibanaServer.uiSettings.replace({
'data_views:fields_max_cache': '0',
});
diff --git a/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts b/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts
index cac4c36852b56..a132c493de83a 100644
--- a/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts
+++ b/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts
@@ -104,7 +104,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
beforeEach(async () => {
await PageObjects.common.navigateToApp('discover');
await PageObjects.discover.selectIndexPattern('logstash-*');
- // did this fix a test?
await PageObjects.discover.refreshFieldList();
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.header.waitUntilLoadingHasFinished();
From b0f930e377fd7a145796dfa650e91884379a76f3 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 13 Nov 2023 15:09:56 -0600
Subject: [PATCH 050/168] remove console.log statements
---
src/plugins/data_views/common/data_views/data_views.ts | 10 +---------
.../public/data_views/data_views_api_client.ts | 2 --
2 files changed, 1 insertion(+), 11 deletions(-)
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index edfb68249e837..cf3f049355c2f 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -542,7 +542,7 @@ export class DataViewsService {
forceRefresh: boolean = false
) => {
const metaFields = await this.config.get(META_FIELDS);
- const result = await this.apiClient.getFieldsForWildcard({
+ return await this.apiClient.getFieldsForWildcard({
type: dataView.type,
rollupIndex: dataView?.typeMeta?.params?.rollup_index,
allowNoIndex: true,
@@ -550,14 +550,6 @@ export class DataViewsService {
metaFields,
forceRefresh,
});
-
- // todo
- console.log(
- 'getFieldsAndIndicesForDataView result',
- dataView.getIndexPattern(),
- JSON.stringify(result.fields, undefined, 2)
- );
- return result;
};
private getFieldsAndIndicesForWildcard = async (options: GetFieldsOptions) => {
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index e9e774fa119a1..8b39ab76727f1 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -56,8 +56,6 @@ export class DataViewsApiClient implements IDataViewsApiClient {
headers: { 'user-hash': userId },
});
- console.log('User id:', userId);
-
return request.catch((resp) => {
if (resp.body.statusCode === 404 && resp.body.attributes?.code === 'no_matching_indices') {
throw new DataViewMissingIndices(resp.body.message);
From 208f64346f99d0e08a44bf9dd19d5b7e21cf05c6 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 13 Nov 2023 19:39:21 -0600
Subject: [PATCH 051/168] use hash instead of userid
---
src/plugins/data_views/common/utils.ts | 7 +++++++
.../public/data_views/data_views_api_client.ts | 5 ++++-
src/plugins/data_views/public/index.ts | 1 +
.../server/rest_api_routes/internal/fields.ts | 17 +++++++----------
4 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/src/plugins/data_views/common/utils.ts b/src/plugins/data_views/common/utils.ts
index b77696e15ba79..cc4d4fd9a1b7f 100644
--- a/src/plugins/data_views/common/utils.ts
+++ b/src/plugins/data_views/common/utils.ts
@@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
+import { createHash } from 'crypto';
import type { PersistenceAPI } from './types';
/**
@@ -35,3 +36,9 @@ export function unwrapEtag(ifNoneMatch: string) {
}
return requestHash;
}
+
+export function calculateHash(srcBuffer: Buffer) {
+ const hash = createHash('sha1');
+ hash.update(srcBuffer);
+ return hash.digest('hex');
+}
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index 8b39ab76727f1..2bcb79c24e323 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -7,6 +7,7 @@
*/
import { HttpSetup, HttpResponse } from '@kbn/core/public';
+import { calculateHash } from '../../common/utils';
import { DataViewMissingIndices } from '../../common/lib';
import { GetFieldsOptions, IDataViewsApiClient } from '../../common';
import { FieldsForWildcardResponse } from '../../common/types';
@@ -45,6 +46,8 @@ export class DataViewsApiClient implements IDataViewsApiClient {
const cacheOptions = forceRefresh ? { cache: 'no-cache' as RequestCache } : {};
const userId = await this.getCurrentUserId();
+ const userHash = userId ? calculateHash(Buffer.from(userId)) : '';
+
const request = body
? this.http.post(url, { query, body, version, asResponse })
: this.http.fetch(url, {
@@ -53,7 +56,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
...cacheOptions,
asResponse,
rawResponse,
- headers: { 'user-hash': userId },
+ headers: { 'user-hash': userHash },
});
return request.catch((resp) => {
diff --git a/src/plugins/data_views/public/index.ts b/src/plugins/data_views/public/index.ts
index f690552b5a147..96380665548dd 100644
--- a/src/plugins/data_views/public/index.ts
+++ b/src/plugins/data_views/public/index.ts
@@ -67,6 +67,7 @@ export type {
DataViewsContract,
HasDataViewsResponse,
IndicesViaSearchResponse,
+ UserIdGetter,
} from './types';
// Export plugin after all other imports
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index a6ea905829cf4..6ed385d1f7758 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -6,9 +6,8 @@
* Side Public License, v 1.
*/
-import { createHash } from 'crypto';
import { IRouter, RequestHandler, StartServicesAccessor, KibanaRequest } from '@kbn/core/server';
-import { unwrapEtag } from '../../../common/utils';
+import { unwrapEtag, calculateHash } from '../../../common/utils';
import { IndexPatternsFetcher } from '../../fetcher';
import type {
DataViewsServerPluginStart,
@@ -18,17 +17,11 @@ import type { FieldDescriptorRestResponse } from '../route_types';
import { FIELDS_PATH as path } from '../../../common/constants';
import { parseFields, IBody, IQuery, querySchema } from './fields_for';
-function calculateHash(srcBuffer: Buffer) {
- const hash = createHash('sha1');
- hash.update(srcBuffer);
- return hash.digest('hex');
-}
-
const handler: (
isRollupsEnabled: () => boolean,
getUserId: () => (kibanaRequest: KibanaRequest) => Promise
) => RequestHandler<{}, IQuery, IBody> =
- (isRollupsEnabled, getUserId) => async (context, request, response) => {
+ (isRollupsEnabled, getUserIdGetter) => async (context, request, response) => {
const core = await context.core;
const uiSettings = core.uiSettings.client;
const { asCurrentUser } = core.elasticsearch.client;
@@ -71,11 +64,15 @@ const handler: (
const etag = calculateHash(Buffer.from(JSON.stringify(body)));
+ const getUserId = getUserIdGetter();
+ const userId = await getUserId(request);
+ const userHash = userId ? calculateHash(Buffer.from(userId)) : '';
+
const headers: Record = {
'content-type': 'application/json',
etag,
vary: 'accept-encoding, user-hash',
- 'user-hash': (await getUserId()(request)) || '',
+ 'user-hash': userHash,
};
const cacheMaxAge = await uiSettings.get('data_views:cache_max_age');
From e101dbaf0f478ab8268e1fbe08c93b9e789faa3e Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 13 Nov 2023 21:08:05 -0600
Subject: [PATCH 052/168] fix browser bundle size
---
src/plugins/data_views/common/utils.ts | 7 -------
.../public/data_views/data_views_api_client.ts | 11 +++++++++--
.../server/rest_api_routes/internal/fields.ts | 9 ++++++++-
3 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/src/plugins/data_views/common/utils.ts b/src/plugins/data_views/common/utils.ts
index cc4d4fd9a1b7f..b77696e15ba79 100644
--- a/src/plugins/data_views/common/utils.ts
+++ b/src/plugins/data_views/common/utils.ts
@@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
-import { createHash } from 'crypto';
import type { PersistenceAPI } from './types';
/**
@@ -36,9 +35,3 @@ export function unwrapEtag(ifNoneMatch: string) {
}
return requestHash;
}
-
-export function calculateHash(srcBuffer: Buffer) {
- const hash = createHash('sha1');
- hash.update(srcBuffer);
- return hash.digest('hex');
-}
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index 2bcb79c24e323..e0052ff459c4f 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -7,7 +7,6 @@
*/
import { HttpSetup, HttpResponse } from '@kbn/core/public';
-import { calculateHash } from '../../common/utils';
import { DataViewMissingIndices } from '../../common/lib';
import { GetFieldsOptions, IDataViewsApiClient } from '../../common';
import { FieldsForWildcardResponse } from '../../common/types';
@@ -16,6 +15,14 @@ import { FIELDS_FOR_WILDCARD_PATH, FIELDS_PATH } from '../../common/constants';
const API_BASE_URL: string = `/api/index_patterns/`;
const version = '1';
+async function sha1(str: string) {
+ const enc = new TextEncoder();
+ const hash = await crypto.subtle.digest('SHA-1', enc.encode(str));
+ return Array.from(new Uint8Array(hash))
+ .map((v) => v.toString(16).padStart(2, '0'))
+ .join('');
+}
+
/**
* Data Views API Client - client implementation
*/
@@ -46,7 +53,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
const cacheOptions = forceRefresh ? { cache: 'no-cache' as RequestCache } : {};
const userId = await this.getCurrentUserId();
- const userHash = userId ? calculateHash(Buffer.from(userId)) : '';
+ const userHash = userId ? await sha1(userId) : '';
const request = body
? this.http.post(url, { query, body, version, asResponse })
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index 6ed385d1f7758..2838c47668b5b 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -6,8 +6,9 @@
* Side Public License, v 1.
*/
+import { createHash } from 'crypto';
import { IRouter, RequestHandler, StartServicesAccessor, KibanaRequest } from '@kbn/core/server';
-import { unwrapEtag, calculateHash } from '../../../common/utils';
+import { unwrapEtag } from '../../../common/utils';
import { IndexPatternsFetcher } from '../../fetcher';
import type {
DataViewsServerPluginStart,
@@ -17,6 +18,12 @@ import type { FieldDescriptorRestResponse } from '../route_types';
import { FIELDS_PATH as path } from '../../../common/constants';
import { parseFields, IBody, IQuery, querySchema } from './fields_for';
+export function calculateHash(srcBuffer: Buffer) {
+ const hash = createHash('sha1');
+ hash.update(srcBuffer);
+ return hash.digest('hex');
+}
+
const handler: (
isRollupsEnabled: () => boolean,
getUserId: () => (kibanaRequest: KibanaRequest) => Promise
From eb2e989d1bb54cf37defcef14b91c18748d5d991 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 13 Nov 2023 22:05:22 -0600
Subject: [PATCH 053/168] add integration tests
---
.../apis/data_views/fields_route/cache.ts | 65 +++++
.../apis/data_views/fields_route/conflicts.ts | 81 ++++++
.../apis/data_views/fields_route/index.ts | 18 ++
.../apis/data_views/fields_route/params.ts | 148 +++++++++++
.../apis/data_views/fields_route/response.ts | 231 ++++++++++++++++++
test/api_integration/apis/data_views/index.ts | 1 +
6 files changed, 544 insertions(+)
create mode 100644 test/api_integration/apis/data_views/fields_route/cache.ts
create mode 100644 test/api_integration/apis/data_views/fields_route/conflicts.ts
create mode 100644 test/api_integration/apis/data_views/fields_route/index.ts
create mode 100644 test/api_integration/apis/data_views/fields_route/params.ts
create mode 100644 test/api_integration/apis/data_views/fields_route/response.ts
diff --git a/test/api_integration/apis/data_views/fields_route/cache.ts b/test/api_integration/apis/data_views/fields_route/cache.ts
new file mode 100644
index 0000000000000..4e852949405cf
--- /dev/null
+++ b/test/api_integration/apis/data_views/fields_route/cache.ts
@@ -0,0 +1,65 @@
+/*
+ * 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 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 or the Server
+ * Side Public License, v 1.
+ */
+
+import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
+import { INITIAL_REST_VERSION_INTERNAL } from '@kbn/data-views-plugin/server/constants';
+import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default function ({ getService }: FtrProviderContext) {
+ const esArchiver = getService('esArchiver');
+ const supertest = getService('supertest');
+
+ describe('cache headers', () => {
+ before(() =>
+ esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index')
+ );
+ after(() =>
+ esArchiver.unload('test/api_integration/fixtures/es_archiver/index_patterns/basic_index')
+ );
+
+ it('are present', async () => {
+ const response = await supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ include_unmapped: true,
+ });
+
+ const cacheControlHeader = response.get('cache-control');
+
+ expect(cacheControlHeader).to.contain('max-age');
+ expect(cacheControlHeader).to.contain('stale-while-revalidate');
+ expect(response.get('vary')).to.equal('accept-encoding, user-hash');
+ expect(response.get('etag')).to.not.be.empty();
+ expect(response.get('user-hash')).to.equal('');
+ });
+
+ it('returns 304 on matching etag', async () => {
+ const response = await supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ include_unmapped: true,
+ });
+
+ await supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .set('If-None-Match', response.get('etag'))
+ .query({
+ pattern: '*',
+ include_unmapped: true,
+ })
+ .expect(304);
+ });
+ });
+}
diff --git a/test/api_integration/apis/data_views/fields_route/conflicts.ts b/test/api_integration/apis/data_views/fields_route/conflicts.ts
new file mode 100644
index 0000000000000..9ad861272c4cd
--- /dev/null
+++ b/test/api_integration/apis/data_views/fields_route/conflicts.ts
@@ -0,0 +1,81 @@
+/*
+ * 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 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 or the Server
+ * Side Public License, v 1.
+ */
+
+import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
+import { INITIAL_REST_VERSION_INTERNAL } from '@kbn/data-views-plugin/server/constants';
+import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default function ({ getService }: FtrProviderContext) {
+ const supertest = getService('supertest');
+ const esArchiver = getService('esArchiver');
+
+ describe('conflicts', () => {
+ before(() =>
+ esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/conflicts')
+ );
+ after(() =>
+ esArchiver.unload('test/api_integration/fixtures/es_archiver/index_patterns/conflicts')
+ );
+
+ it('flags fields with mismatched types as conflicting', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({ pattern: 'logs-*' })
+ .expect(200)
+ .then((resp) => {
+ expect(resp.body).to.eql({
+ fields: [
+ {
+ name: '@timestamp',
+ type: 'date',
+ esTypes: ['date'],
+ aggregatable: true,
+ searchable: true,
+ readFromDocValues: true,
+ metadata_field: false,
+ },
+ {
+ name: 'number_conflict',
+ type: 'number',
+ esTypes: ['float', 'integer'],
+ aggregatable: true,
+ searchable: true,
+ readFromDocValues: true,
+ metadata_field: false,
+ },
+ {
+ name: 'string_conflict',
+ type: 'string',
+ esTypes: ['keyword', 'text'],
+ aggregatable: true,
+ searchable: true,
+ readFromDocValues: true,
+ metadata_field: false,
+ },
+ {
+ name: 'success',
+ type: 'conflict',
+ esTypes: ['keyword', 'boolean'],
+ aggregatable: true,
+ searchable: true,
+ readFromDocValues: false,
+ conflictDescriptions: {
+ boolean: ['logs-2017.01.02'],
+ keyword: ['logs-2017.01.01'],
+ },
+ metadata_field: false,
+ },
+ ],
+ indices: ['logs-2017.01.01', 'logs-2017.01.02'],
+ });
+ }));
+ });
+}
diff --git a/test/api_integration/apis/data_views/fields_route/index.ts b/test/api_integration/apis/data_views/fields_route/index.ts
new file mode 100644
index 0000000000000..4b03c2b58afbe
--- /dev/null
+++ b/test/api_integration/apis/data_views/fields_route/index.ts
@@ -0,0 +1,18 @@
+/*
+ * 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 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 or the Server
+ * Side Public License, v 1.
+ */
+
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default function ({ loadTestFile }: FtrProviderContext) {
+ describe('data_views/fields route', () => {
+ loadTestFile(require.resolve('./params'));
+ loadTestFile(require.resolve('./conflicts'));
+ loadTestFile(require.resolve('./response'));
+ loadTestFile(require.resolve('./cache'));
+ });
+}
diff --git a/test/api_integration/apis/data_views/fields_route/params.ts b/test/api_integration/apis/data_views/fields_route/params.ts
new file mode 100644
index 0000000000000..29d6c06e3a60b
--- /dev/null
+++ b/test/api_integration/apis/data_views/fields_route/params.ts
@@ -0,0 +1,148 @@
+/*
+ * 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 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 or the Server
+ * Side Public License, v 1.
+ */
+
+import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
+import { INITIAL_REST_VERSION_INTERNAL } from '@kbn/data-views-plugin/server/constants';
+import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default function ({ getService }: FtrProviderContext) {
+ const esArchiver = getService('esArchiver');
+ const supertest = getService('supertest');
+ const randomness = getService('randomness');
+
+ describe('params', () => {
+ before(() =>
+ esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index')
+ );
+ after(() =>
+ esArchiver.unload('test/api_integration/fixtures/es_archiver/index_patterns/basic_index')
+ );
+
+ it('requires a pattern query param', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({})
+ .expect(400));
+
+ it('accepts include_unmapped param', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ include_unmapped: true,
+ })
+ .expect(200));
+
+ it('rejects unexpected query params', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: randomness.word(),
+ [randomness.word()]: randomness.word(),
+ })
+ .expect(400));
+
+ describe('fields', () => {
+ it('accepts a JSON formatted fields query param', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ fields: JSON.stringify(['baz']),
+ })
+ .expect(200));
+
+ it('accepts meta_fields query param in string array', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ fields: ['baz', 'foo'],
+ })
+ .expect(200));
+
+ it('accepts single array fields query param', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ fields: ['baz'],
+ })
+ .expect(200));
+
+ it('accepts single fields query param', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ fields: 'baz',
+ })
+ .expect(200));
+
+ it('rejects a comma-separated list of fields', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ fields: 'foo,bar',
+ })
+ .expect(400));
+ });
+
+ describe('meta_fields', () => {
+ it('accepts a JSON formatted meta_fields query param', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ meta_fields: JSON.stringify(['meta']),
+ })
+ .expect(200));
+
+ it('accepts meta_fields query param in string array', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ meta_fields: ['_id', 'meta'],
+ })
+ .expect(200));
+
+ it('accepts single meta_fields query param', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ meta_fields: ['_id'],
+ })
+ .expect(200));
+
+ it('rejects a comma-separated list of meta_fields', () =>
+ supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: '*',
+ meta_fields: 'foo,bar',
+ })
+ .expect(400));
+ });
+ });
+}
diff --git a/test/api_integration/apis/data_views/fields_route/response.ts b/test/api_integration/apis/data_views/fields_route/response.ts
new file mode 100644
index 0000000000000..47c8814b0c4b0
--- /dev/null
+++ b/test/api_integration/apis/data_views/fields_route/response.ts
@@ -0,0 +1,231 @@
+/*
+ * 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 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 or the Server
+ * Side Public License, v 1.
+ */
+
+import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
+import { INITIAL_REST_VERSION_INTERNAL } from '@kbn/data-views-plugin/server/constants';
+import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
+import expect from '@kbn/expect';
+import { sortBy } from 'lodash';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default function ({ getService }: FtrProviderContext) {
+ const esArchiver = getService('esArchiver');
+ const supertest = getService('supertest');
+
+ const ensureFieldsAreSorted = (resp: { body: { fields: { name: string } } }) => {
+ expect(resp.body.fields).to.eql(sortBy(resp.body.fields, 'name'));
+ };
+
+ const testFields = [
+ {
+ type: 'boolean',
+ esTypes: ['boolean'],
+ searchable: true,
+ aggregatable: true,
+ name: 'bar',
+ readFromDocValues: true,
+ metadata_field: false,
+ },
+ {
+ type: 'string',
+ esTypes: ['text'],
+ searchable: true,
+ aggregatable: false,
+ name: 'baz',
+ readFromDocValues: false,
+ metadata_field: false,
+ },
+ {
+ type: 'string',
+ esTypes: ['keyword'],
+ searchable: true,
+ aggregatable: true,
+ name: 'baz.keyword',
+ readFromDocValues: true,
+ subType: { multi: { parent: 'baz' } },
+ metadata_field: false,
+ },
+ {
+ type: 'number',
+ esTypes: ['long'],
+ searchable: true,
+ aggregatable: true,
+ name: 'foo',
+ readFromDocValues: true,
+ metadata_field: false,
+ },
+ {
+ aggregatable: true,
+ esTypes: ['keyword'],
+ name: 'nestedField.child',
+ readFromDocValues: true,
+ searchable: true,
+ subType: {
+ nested: {
+ path: 'nestedField',
+ },
+ },
+ type: 'string',
+ metadata_field: false,
+ },
+ ];
+
+ describe('fields route response', () => {
+ before(() =>
+ esArchiver.load('test/api_integration/fixtures/es_archiver/index_patterns/basic_index')
+ );
+ after(() =>
+ esArchiver.unload('test/api_integration/fixtures/es_archiver/index_patterns/basic_index')
+ );
+
+ it('returns a flattened version of the fields in es', async () => {
+ await supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({ pattern: 'basic_index' })
+ .expect(200, {
+ fields: testFields,
+ indices: ['basic_index'],
+ })
+ .then(ensureFieldsAreSorted);
+ });
+
+ it('returns a single field as requested', async () => {
+ await supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({ pattern: 'basic_index', fields: JSON.stringify(['bar']) })
+ .expect(200, {
+ fields: [testFields[0]],
+ indices: ['basic_index'],
+ });
+ });
+
+ it('always returns a field for all passed meta fields', async () => {
+ await supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: 'basic_index',
+ meta_fields: JSON.stringify(['_id', '_source', 'crazy_meta_field']),
+ })
+ .expect(200, {
+ fields: [
+ {
+ aggregatable: false,
+ name: '_id',
+ esTypes: ['_id'],
+ readFromDocValues: false,
+ searchable: true,
+ type: 'string',
+ metadata_field: true,
+ },
+ {
+ aggregatable: false,
+ name: '_source',
+ esTypes: ['_source'],
+ readFromDocValues: false,
+ searchable: false,
+ type: '_source',
+ metadata_field: true,
+ },
+ {
+ type: 'boolean',
+ esTypes: ['boolean'],
+ searchable: true,
+ aggregatable: true,
+ name: 'bar',
+ readFromDocValues: true,
+ metadata_field: false,
+ },
+ {
+ aggregatable: false,
+ name: 'baz',
+ esTypes: ['text'],
+ readFromDocValues: false,
+ searchable: true,
+ type: 'string',
+ metadata_field: false,
+ },
+ {
+ type: 'string',
+ esTypes: ['keyword'],
+ searchable: true,
+ aggregatable: true,
+ name: 'baz.keyword',
+ readFromDocValues: true,
+ subType: { multi: { parent: 'baz' } },
+ metadata_field: false,
+ },
+ {
+ aggregatable: false,
+ name: 'crazy_meta_field',
+ readFromDocValues: false,
+ searchable: false,
+ type: 'string',
+ metadata_field: true,
+ },
+ {
+ type: 'number',
+ esTypes: ['long'],
+ searchable: true,
+ aggregatable: true,
+ name: 'foo',
+ readFromDocValues: true,
+ metadata_field: false,
+ },
+ {
+ aggregatable: true,
+ esTypes: ['keyword'],
+ name: 'nestedField.child',
+ readFromDocValues: true,
+ searchable: true,
+ subType: {
+ nested: {
+ path: 'nestedField',
+ },
+ },
+ type: 'string',
+ metadata_field: false,
+ },
+ ],
+ indices: ['basic_index'],
+ })
+ .then(ensureFieldsAreSorted);
+ });
+
+ it('returns fields when one pattern exists and the other does not', async () => {
+ await supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({ pattern: 'bad_index,basic_index' })
+ .expect(200, {
+ fields: testFields,
+ indices: ['basic_index'],
+ });
+ });
+
+ it('returns 404 when neither exists', async () => {
+ await supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({ pattern: 'bad_index,bad_index_2' })
+ .expect(404);
+ });
+
+ it('returns 404 when no patterns exist', async () => {
+ await supertest
+ .get(FIELDS_PATH)
+ .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
+ .query({
+ pattern: 'bad_index',
+ })
+ .expect(404);
+ });
+ });
+}
diff --git a/test/api_integration/apis/data_views/index.ts b/test/api_integration/apis/data_views/index.ts
index a6589d5680b3d..654421937f44b 100644
--- a/test/api_integration/apis/data_views/index.ts
+++ b/test/api_integration/apis/data_views/index.ts
@@ -23,5 +23,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./has_user_index_pattern'));
loadTestFile(require.resolve('./swap_references'));
loadTestFile(require.resolve('./resolve_index'));
+ loadTestFile(require.resolve('./fields_route'));
});
}
From 121c2e86ab6ef124a4c8d4249c3f4d4593e3db24 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 13 Nov 2023 22:14:06 -0600
Subject: [PATCH 054/168] update refresh button text
---
.../unified_search/public/dataview_picker/change_dataview.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
index 1a90b47103988..f1e19be1c72ce 100644
--- a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
+++ b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
@@ -231,7 +231,7 @@ export function ChangeDataView({
}}
>
{i18n.translate('unifiedSearch.query.queryBar.indexPattern.refreshFieldButton', {
- defaultMessage: 'Refresh field list',
+ defaultMessage: 'Refresh field list for this data view',
})}
,
From aa3503bd5e30cc4f7c9c03074678e71649369753 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 13 Nov 2023 22:56:46 -0600
Subject: [PATCH 055/168] increase bundle limit
---
packages/kbn-optimizer/limits.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml
index 68521a9b35d12..fb5b7c0aaad23 100644
--- a/packages/kbn-optimizer/limits.yml
+++ b/packages/kbn-optimizer/limits.yml
@@ -32,7 +32,7 @@ pageLoadAssetSize:
dataViewEditor: 28082
dataViewFieldEditor: 27000
dataViewManagement: 5100
- dataViews: 48800
+ dataViews: 50000
dataVisualizer: 27530
devTools: 38637
discover: 99999
From 773411839a9ea0fba22b2c6a0a3ea85e561cada4 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 14 Nov 2023 08:15:32 -0600
Subject: [PATCH 056/168] skip flakey test
---
test/functional/apps/management/data_views/_scripted_fields.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/functional/apps/management/data_views/_scripted_fields.ts b/test/functional/apps/management/data_views/_scripted_fields.ts
index 2c70161a3bc43..a85947730f3fd 100644
--- a/test/functional/apps/management/data_views/_scripted_fields.ts
+++ b/test/functional/apps/management/data_views/_scripted_fields.ts
@@ -152,7 +152,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.common.setTime({ from, to });
});
- it('should see scripted field value in Discover', async function () {
+ it.skip('should see scripted field value in Discover', async function () {
await PageObjects.common.navigateToApp('discover');
await retry.try(async function () {
From 247bcaaefc060ac70c3b85b73ac77b53c49c8e55 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 14 Nov 2023 09:28:48 -0600
Subject: [PATCH 057/168] skip flakey test
---
.../functional/apps/management/data_views/_scripted_fields.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/functional/apps/management/data_views/_scripted_fields.ts b/test/functional/apps/management/data_views/_scripted_fields.ts
index a85947730f3fd..d284d06547d90 100644
--- a/test/functional/apps/management/data_views/_scripted_fields.ts
+++ b/test/functional/apps/management/data_views/_scripted_fields.ts
@@ -145,14 +145,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- describe('discover scripted field', async () => {
+ describe.skip('discover scripted field', async () => {
before(async () => {
const from = 'Sep 17, 2015 @ 06:31:44.000';
const to = 'Sep 18, 2015 @ 18:31:44.000';
await PageObjects.common.setTime({ from, to });
});
- it.skip('should see scripted field value in Discover', async function () {
+ it('should see scripted field value in Discover', async function () {
await PageObjects.common.navigateToApp('discover');
await retry.try(async function () {
From 66836bd059c444fcb284b79ad7d3d8f2b3218064 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 14 Nov 2023 10:10:20 -0600
Subject: [PATCH 058/168] skip flaky test
---
test/functional/apps/management/data_views/_scripted_fields.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/functional/apps/management/data_views/_scripted_fields.ts b/test/functional/apps/management/data_views/_scripted_fields.ts
index d284d06547d90..a9cf454331456 100644
--- a/test/functional/apps/management/data_views/_scripted_fields.ts
+++ b/test/functional/apps/management/data_views/_scripted_fields.ts
@@ -226,7 +226,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- describe('creating and using Painless string scripted fields', function describeIndexTests() {
+ describe.skip('creating and using Painless string scripted fields', function describeIndexTests() {
const scriptedPainlessFieldName2 = 'painString';
before(async () => {
From 387b2036414a3dbc77a9f09e6c5c49732d35e6f2 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 14 Nov 2023 16:10:46 -0600
Subject: [PATCH 059/168] update snapshot
---
.../services/log_views/log_views_client.test.ts | 4 ++--
x-pack/test/functional/apps/maps/group4/index.js | 12 ------------
.../observability_log_explorer/columns_selection.ts | 8 +-------
3 files changed, 3 insertions(+), 21 deletions(-)
diff --git a/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts
index 4d863667235a8..e2741bea55931 100644
--- a/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts
+++ b/x-pack/plugins/logs_shared/server/services/log_views/log_views_client.test.ts
@@ -276,8 +276,8 @@ describe('LogViewsClient class', () => {
},
"fields": FldList [],
"flattenHit": [Function],
- "getEtag": [Function],
"getAllowHidden": [Function],
+ "getEtag": [Function],
"getFieldAttrs": [Function],
"getIndexPattern": [Function],
"getName": [Function],
@@ -302,8 +302,8 @@ describe('LogViewsClient class', () => {
},
},
"scriptedFields": Array [],
- "setEtag": [Function],
"setAllowHidden": [Function],
+ "setEtag": [Function],
"setFieldFormat": [Function],
"setIndexPattern": [Function],
"shortDotsEnable": false,
diff --git a/x-pack/test/functional/apps/maps/group4/index.js b/x-pack/test/functional/apps/maps/group4/index.js
index 0a8926158dbfd..6af1369928d98 100644
--- a/x-pack/test/functional/apps/maps/group4/index.js
+++ b/x-pack/test/functional/apps/maps/group4/index.js
@@ -11,8 +11,6 @@ export default function ({ loadTestFile, getService }) {
const browser = getService('browser');
const log = getService('log');
const supertest = getService('supertest');
- // const security = getService('security');
- // const PageObjects = getPageObjects(['discover', 'common']);
describe('maps app', function () {
this.tags(['skipFirefox']);
@@ -51,16 +49,6 @@ export default function ({ loadTestFile, getService }) {
defaultIndex: 'c698b940-e149-11e8-a35a-370a8516603a',
});
await browser.setWindowSize(1600, 1000);
-
- /*
- await security.testUser.setRoles([
- 'kibana_admin',
- 'test_logstash_reader',
- 'kibana_sample_admin',
- ]); // necessary to refresh field list
- await PageObjects.common.navigateToApp('discover');
- await PageObjects.discover.refreshFieldList(); // refreshes field list cache from previous tests
- */
});
after(async () => {
diff --git a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
index 83384c4d8ed63..7738d3b97b2bc 100644
--- a/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
+++ b/x-pack/test/functional/apps/observability_log_explorer/columns_selection.ts
@@ -13,19 +13,13 @@ const defaultLogColumns = ['@timestamp', 'service.name', 'host.name', 'message']
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const retry = getService('retry');
- const PageObjects = getPageObjects(['discover', 'observabilityLogExplorer', 'settings']);
+ const PageObjects = getPageObjects(['discover', 'observabilityLogExplorer']);
describe('Columns selection initialization and update', () => {
before(async () => {
await esArchiver.load(
'x-pack/test/functional/es_archives/observability_log_explorer/data_streams'
);
-
- /*
- await PageObjects.settings.navigateTo();
- await PageObjects.settings.createIndexPattern('logs-*-*', '@timestamp');
- await PageObjects.settings.refreshDataViewFieldList();
- */
});
after(async () => {
From 99b03af22ee29a28712f58356925e76074aa8be6 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 14 Nov 2023 18:07:12 -0600
Subject: [PATCH 060/168] skip scripted field test, its being flaky
---
test/functional/apps/management/data_views/_scripted_fields.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/functional/apps/management/data_views/_scripted_fields.ts b/test/functional/apps/management/data_views/_scripted_fields.ts
index a9cf454331456..f7324e9b83934 100644
--- a/test/functional/apps/management/data_views/_scripted_fields.ts
+++ b/test/functional/apps/management/data_views/_scripted_fields.ts
@@ -330,7 +330,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- describe('creating and using Painless boolean scripted fields', function describeIndexTests() {
+ describe.skip('creating and using Painless boolean scripted fields', function describeIndexTests() {
const scriptedPainlessFieldName2 = 'painBool';
before(async () => {
From 4246c60a9364e0958dd09ebc647c19d1155fec1d Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 14 Nov 2023 19:00:25 -0600
Subject: [PATCH 061/168] skip scripted field test, its being flaky
---
test/functional/apps/management/data_views/_scripted_fields.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/functional/apps/management/data_views/_scripted_fields.ts b/test/functional/apps/management/data_views/_scripted_fields.ts
index f7324e9b83934..1116a482a77f1 100644
--- a/test/functional/apps/management/data_views/_scripted_fields.ts
+++ b/test/functional/apps/management/data_views/_scripted_fields.ts
@@ -44,7 +44,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'unifiedFieldList',
]);
- describe('scripted fields', function () {
+ describe.skip('scripted fields', function () {
this.tags(['skipFirefox']);
before(async function () {
From 42bd2f41f21bf49031bef64b4c44531486c60660 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 14 Nov 2023 21:14:09 -0600
Subject: [PATCH 062/168] refactor security / data view plugin dependency
---
src/plugins/data_views/kibana.jsonc | 1 +
src/plugins/data_views/server/plugin.ts | 25 ++++++++++++++++++++----
src/plugins/data_views/server/types.ts | 1 -
x-pack/plugins/security/server/plugin.ts | 16 +--------------
4 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/src/plugins/data_views/kibana.jsonc b/src/plugins/data_views/kibana.jsonc
index 7595f8e68b3c4..7789383b48ba4 100644
--- a/src/plugins/data_views/kibana.jsonc
+++ b/src/plugins/data_views/kibana.jsonc
@@ -18,6 +18,7 @@
"requiredBundles": [
"kibanaUtils"
],
+ "runtimePluginDependencies" : ["security"],
"extraPublicDirs": [
"common"
]
diff --git a/src/plugins/data_views/server/plugin.ts b/src/plugins/data_views/server/plugin.ts
index bdb1ac192d5a8..91746655e7521 100644
--- a/src/plugins/data_views/server/plugin.ts
+++ b/src/plugins/data_views/server/plugin.ts
@@ -6,7 +6,15 @@
* Side Public License, v 1.
*/
-import { CoreSetup, CoreStart, Logger, Plugin, PluginInitializerContext } from '@kbn/core/server';
+import {
+ CoreSetup,
+ CoreStart,
+ Logger,
+ Plugin,
+ PluginInitializerContext,
+ KibanaRequest,
+} from '@kbn/core/server';
+import { SecurityPluginStart } from '@kbn/security-plugin/server';
import { dataViewsServiceFactory } from './data_views_service_factory';
import { registerRoutes } from './routes';
import { dataViewSavedObjectType } from './saved_objects';
@@ -51,6 +59,18 @@ export class DataViewsServerPlugin
core.capabilities.registerProvider(capabilitiesProvider);
core.uiSettings.register(cacheMaxAge);
const dataViewRestCounter = usageCollection?.createUsageCounter('dataViewsRestApi');
+ core.plugins.onStart<{ security: SecurityPluginStart }>('security').then(({ security }) => {
+ if (security.found) {
+ const getUserId = async function getUserId(
+ request: KibanaRequest
+ ): Promise {
+ return security.contract.authc.getCurrentUser(request)?.profile_uid;
+ };
+ this.getUserId = getUserId;
+ } else {
+ throw new Error('Security plugin is not available, but is required for Data Views plugin');
+ }
+ });
registerRoutes({
http: core.http,
@@ -77,9 +97,6 @@ export class DataViewsServerPlugin
return {
enableRollups: () => (this.rollupsEnabled = true),
- setGetUserId: (getUserId: GetUserId) => {
- this.getUserId = getUserId;
- },
};
}
diff --git a/src/plugins/data_views/server/types.ts b/src/plugins/data_views/server/types.ts
index 1fe900dc58113..2222e7d77a681 100644
--- a/src/plugins/data_views/server/types.ts
+++ b/src/plugins/data_views/server/types.ts
@@ -61,7 +61,6 @@ export interface DataViewsServerPluginStart {
*/
export interface DataViewsServerPluginSetup {
enableRollups: () => void;
- setGetUserId: (getUserId: GetUserId) => void;
}
/**
diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts
index e87881b1a824e..2e3f5199d584c 100644
--- a/x-pack/plugins/security/server/plugin.ts
+++ b/x-pack/plugins/security/server/plugin.ts
@@ -244,14 +244,7 @@ export class SecurityPlugin
public setup(
core: CoreSetup,
- {
- features,
- licensing,
- taskManager,
- usageCollection,
- spaces,
- dataViews,
- }: PluginSetupDependencies
+ { features, licensing, taskManager, usageCollection, spaces }: PluginSetupDependencies
) {
this.kibanaIndexName = core.savedObjects.getDefaultIndex();
const config$ = this.initializerContext.config.create>().pipe(
@@ -268,13 +261,6 @@ export class SecurityPlugin
const config = this.getConfig();
const kibanaIndexName = this.getKibanaIndexName();
- async function getUserId(request: KibanaRequest): Promise {
- const [, , security] = await core.getStartServices();
- return security.authc.getCurrentUser(request)?.profile_uid;
- }
-
- dataViews.setGetUserId(getUserId);
-
// A subset of `start` services we need during `setup`.
const startServicesPromise = core.getStartServices().then(([coreServices, depsServices]) => ({
elasticsearch: coreServices.elasticsearch,
From 6693cf681f3b8d966a34e330df1cea5d0a1ac9ad Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Wed, 15 Nov 2023 03:22:12 +0000
Subject: [PATCH 063/168] [CI] Auto-commit changed files from 'node
scripts/lint_ts_projects --fix'
---
src/plugins/data_views/tsconfig.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/plugins/data_views/tsconfig.json b/src/plugins/data_views/tsconfig.json
index e5613323bc222..cf3d7aa75e551 100644
--- a/src/plugins/data_views/tsconfig.json
+++ b/src/plugins/data_views/tsconfig.json
@@ -33,6 +33,7 @@
"@kbn/object-versioning",
"@kbn/core-saved-objects-server",
"@kbn/logging",
+ "@kbn/security-plugin",
],
"exclude": [
"target/**/*",
From 7b384d4841dabfc42e1b796711c3a35b8f574eab Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 14 Nov 2023 21:29:40 -0600
Subject: [PATCH 064/168] Revert "refactor security / data view plugin
dependency"
This reverts commit 42bd2f41f21bf49031bef64b4c44531486c60660.
---
src/plugins/data_views/kibana.jsonc | 1 -
src/plugins/data_views/server/plugin.ts | 25 ++++--------------------
src/plugins/data_views/server/types.ts | 1 +
x-pack/plugins/security/server/plugin.ts | 16 ++++++++++++++-
4 files changed, 20 insertions(+), 23 deletions(-)
diff --git a/src/plugins/data_views/kibana.jsonc b/src/plugins/data_views/kibana.jsonc
index 7789383b48ba4..7595f8e68b3c4 100644
--- a/src/plugins/data_views/kibana.jsonc
+++ b/src/plugins/data_views/kibana.jsonc
@@ -18,7 +18,6 @@
"requiredBundles": [
"kibanaUtils"
],
- "runtimePluginDependencies" : ["security"],
"extraPublicDirs": [
"common"
]
diff --git a/src/plugins/data_views/server/plugin.ts b/src/plugins/data_views/server/plugin.ts
index 91746655e7521..bdb1ac192d5a8 100644
--- a/src/plugins/data_views/server/plugin.ts
+++ b/src/plugins/data_views/server/plugin.ts
@@ -6,15 +6,7 @@
* Side Public License, v 1.
*/
-import {
- CoreSetup,
- CoreStart,
- Logger,
- Plugin,
- PluginInitializerContext,
- KibanaRequest,
-} from '@kbn/core/server';
-import { SecurityPluginStart } from '@kbn/security-plugin/server';
+import { CoreSetup, CoreStart, Logger, Plugin, PluginInitializerContext } from '@kbn/core/server';
import { dataViewsServiceFactory } from './data_views_service_factory';
import { registerRoutes } from './routes';
import { dataViewSavedObjectType } from './saved_objects';
@@ -59,18 +51,6 @@ export class DataViewsServerPlugin
core.capabilities.registerProvider(capabilitiesProvider);
core.uiSettings.register(cacheMaxAge);
const dataViewRestCounter = usageCollection?.createUsageCounter('dataViewsRestApi');
- core.plugins.onStart<{ security: SecurityPluginStart }>('security').then(({ security }) => {
- if (security.found) {
- const getUserId = async function getUserId(
- request: KibanaRequest
- ): Promise {
- return security.contract.authc.getCurrentUser(request)?.profile_uid;
- };
- this.getUserId = getUserId;
- } else {
- throw new Error('Security plugin is not available, but is required for Data Views plugin');
- }
- });
registerRoutes({
http: core.http,
@@ -97,6 +77,9 @@ export class DataViewsServerPlugin
return {
enableRollups: () => (this.rollupsEnabled = true),
+ setGetUserId: (getUserId: GetUserId) => {
+ this.getUserId = getUserId;
+ },
};
}
diff --git a/src/plugins/data_views/server/types.ts b/src/plugins/data_views/server/types.ts
index 2222e7d77a681..1fe900dc58113 100644
--- a/src/plugins/data_views/server/types.ts
+++ b/src/plugins/data_views/server/types.ts
@@ -61,6 +61,7 @@ export interface DataViewsServerPluginStart {
*/
export interface DataViewsServerPluginSetup {
enableRollups: () => void;
+ setGetUserId: (getUserId: GetUserId) => void;
}
/**
diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts
index 2e3f5199d584c..e87881b1a824e 100644
--- a/x-pack/plugins/security/server/plugin.ts
+++ b/x-pack/plugins/security/server/plugin.ts
@@ -244,7 +244,14 @@ export class SecurityPlugin
public setup(
core: CoreSetup,
- { features, licensing, taskManager, usageCollection, spaces }: PluginSetupDependencies
+ {
+ features,
+ licensing,
+ taskManager,
+ usageCollection,
+ spaces,
+ dataViews,
+ }: PluginSetupDependencies
) {
this.kibanaIndexName = core.savedObjects.getDefaultIndex();
const config$ = this.initializerContext.config.create>().pipe(
@@ -261,6 +268,13 @@ export class SecurityPlugin
const config = this.getConfig();
const kibanaIndexName = this.getKibanaIndexName();
+ async function getUserId(request: KibanaRequest): Promise {
+ const [, , security] = await core.getStartServices();
+ return security.authc.getCurrentUser(request)?.profile_uid;
+ }
+
+ dataViews.setGetUserId(getUserId);
+
// A subset of `start` services we need during `setup`.
const startServicesPromise = core.getStartServices().then(([coreServices, depsServices]) => ({
elasticsearch: coreServices.elasticsearch,
From b009721abd6f625335f6adeb187db9c471cd9803 Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Wed, 15 Nov 2023 03:41:09 +0000
Subject: [PATCH 065/168] [CI] Auto-commit changed files from 'node
scripts/lint_ts_projects --fix'
---
src/plugins/data_views/tsconfig.json | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/plugins/data_views/tsconfig.json b/src/plugins/data_views/tsconfig.json
index cf3d7aa75e551..e5613323bc222 100644
--- a/src/plugins/data_views/tsconfig.json
+++ b/src/plugins/data_views/tsconfig.json
@@ -33,7 +33,6 @@
"@kbn/object-versioning",
"@kbn/core-saved-objects-server",
"@kbn/logging",
- "@kbn/security-plugin",
],
"exclude": [
"target/**/*",
From 5c582327feecda80d5cf8b92c9ae03c7b03e35a5 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 14 Nov 2023 22:35:57 -0600
Subject: [PATCH 066/168] remove circ dependency
---
src/plugins/data_views/tsconfig.json | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/plugins/data_views/tsconfig.json b/src/plugins/data_views/tsconfig.json
index cf3d7aa75e551..e5613323bc222 100644
--- a/src/plugins/data_views/tsconfig.json
+++ b/src/plugins/data_views/tsconfig.json
@@ -33,7 +33,6 @@
"@kbn/object-versioning",
"@kbn/core-saved-objects-server",
"@kbn/logging",
- "@kbn/security-plugin",
],
"exclude": [
"target/**/*",
From 6ea9098ae910f896fa881b8c520efa409bda6051 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 14 Nov 2023 23:38:37 -0600
Subject: [PATCH 067/168] disable flaky test
---
.../management/data_views/_scripted_fields_classic_table.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/functional/apps/management/data_views/_scripted_fields_classic_table.ts b/test/functional/apps/management/data_views/_scripted_fields_classic_table.ts
index 0ca095811c0b4..7cbda9f04353f 100644
--- a/test/functional/apps/management/data_views/_scripted_fields_classic_table.ts
+++ b/test/functional/apps/management/data_views/_scripted_fields_classic_table.ts
@@ -109,7 +109,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- describe('creating and using Painless numeric scripted fields', function describeIndexTests() {
+ describe.skip('creating and using Painless numeric scripted fields', function describeIndexTests() {
const scriptedPainlessFieldName = 'ram_Pain1';
it('should create scripted field', async function () {
From 864d9ef49e11fdaa58f8d2412f1edffb08860a43 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 15 Nov 2023 08:04:02 -0600
Subject: [PATCH 068/168] remove discover refresh button and turn off cache
---
src/plugins/data_views/server/ui_settings.ts | 2 +-
.../public/dataview_picker/change_dataview.tsx | 17 -----------------
test/functional/page_objects/discover_page.ts | 5 +++--
3 files changed, 4 insertions(+), 20 deletions(-)
diff --git a/src/plugins/data_views/server/ui_settings.ts b/src/plugins/data_views/server/ui_settings.ts
index b276d440a06f4..99175f0137dc9 100644
--- a/src/plugins/data_views/server/ui_settings.ts
+++ b/src/plugins/data_views/server/ui_settings.ts
@@ -14,7 +14,7 @@ export const cacheMaxAge = {
name: i18n.translate('dataViews.advancedSettings.cacheMaxAgeTitle', {
defaultMessage: 'Field cache max age',
}),
- value: 300,
+ value: 0,
description: i18n.translate('dataViews.advancedSettings.cacheMaxAgeText', {
defaultMessage:
"Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching. A hard reload of Kibana may be necessary for your browser to pick up the new setting.",
diff --git a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
index f1e19be1c72ce..e1565f1ff6b0d 100644
--- a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
+++ b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
@@ -217,23 +217,6 @@ export function ChangeDataView({
) : (
),
- {
- const dataView = await dataViews.get(currentDataViewId!);
- await dataViews.refreshFields(dataView, undefined, true);
- if (onEditDataView) {
- onEditDataView(dataView);
- }
- setPopoverIsOpen(false);
- }}
- >
- {i18n.translate('unifiedSearch.query.queryBar.indexPattern.refreshFieldButton', {
- defaultMessage: 'Refresh field list for this data view',
- })}
- ,
);
}
diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts
index 0d9bdd9b5c338..903b8875405a1 100644
--- a/test/functional/page_objects/discover_page.ts
+++ b/test/functional/page_objects/discover_page.ts
@@ -433,9 +433,10 @@ export class DiscoverPageObject extends FtrService {
});
}
+ // disabled while `data_views:cache_max_age` ui setting is set to zero
public async refreshFieldList() {
- await this.clickIndexPatternActions();
- await this.testSubjects.click('data-view-refresh-fields');
+ // await this.clickIndexPatternActions();
+ // await this.testSubjects.click('data-view-refresh-fields');
}
public async clickAddNewField() {
From 2d7ab2f5297b4ba6eecb0055cd570ff77fd31e29 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 15 Nov 2023 09:11:08 -0600
Subject: [PATCH 069/168] fix api integration test
---
test/api_integration/apis/data_views/fields_route/cache.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/test/api_integration/apis/data_views/fields_route/cache.ts b/test/api_integration/apis/data_views/fields_route/cache.ts
index 4e852949405cf..727a64fdfa061 100644
--- a/test/api_integration/apis/data_views/fields_route/cache.ts
+++ b/test/api_integration/apis/data_views/fields_route/cache.ts
@@ -24,7 +24,8 @@ export default function ({ getService }: FtrProviderContext) {
esArchiver.unload('test/api_integration/fixtures/es_archiver/index_patterns/basic_index')
);
- it('are present', async () => {
+ // disabled since caching is disabled. Try to load uiSettings so this test can be enabled
+ it.skip('are present', async () => {
const response = await supertest
.get(FIELDS_PATH)
.set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
From dbee9016f70168682fa63873d1060dae93ba5673 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 15 Nov 2023 16:47:28 -0600
Subject: [PATCH 070/168] cleanup
---
.../data_views/public/data_views/data_views_api_client.ts | 7 -------
src/plugins/data_views/server/ui_settings.ts | 2 +-
test/functional/apps/discover/group3/_sidebar.ts | 2 --
.../discover_ml_uptime/discover/search_source_alert.ts | 8 --------
4 files changed, 1 insertion(+), 18 deletions(-)
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index 43d670136a586..2612ddcf98bb0 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -46,10 +46,6 @@ export class DataViewsApiClient implements IDataViewsApiClient {
forceRefresh?: boolean
): Promise | undefined> {
const asResponse = true;
- // circle back to this, will likely need changes to any code that loads fields
- // setting to true skips automatic json parsing
- // const rawResponse = true;
- const rawResponse = false;
const cacheOptions = forceRefresh ? { cache: 'no-cache' as RequestCache } : {};
const userId = await this.getCurrentUserId();
@@ -62,7 +58,6 @@ export class DataViewsApiClient implements IDataViewsApiClient {
version,
...cacheOptions,
asResponse,
- rawResponse,
headers: { 'user-hash': userHash },
});
@@ -129,8 +124,6 @@ export class DataViewsApiClient implements IDataViewsApiClient {
this._getUrl(['has_user_index_pattern'])
);
- // const body = await response?.response?.json();
- // return body?.result ?? false;
return response?.body?.result ?? false;
}
}
diff --git a/src/plugins/data_views/server/ui_settings.ts b/src/plugins/data_views/server/ui_settings.ts
index 99175f0137dc9..b4abf665709b5 100644
--- a/src/plugins/data_views/server/ui_settings.ts
+++ b/src/plugins/data_views/server/ui_settings.ts
@@ -12,7 +12,7 @@ import { schema } from '@kbn/config-schema';
export const cacheMaxAge = {
'data_views:cache_max_age': {
name: i18n.translate('dataViews.advancedSettings.cacheMaxAgeTitle', {
- defaultMessage: 'Field cache max age',
+ defaultMessage: 'Field cache max age (in seconds)',
}),
value: 0,
description: i18n.translate('dataViews.advancedSettings.cacheMaxAgeText', {
diff --git a/test/functional/apps/discover/group3/_sidebar.ts b/test/functional/apps/discover/group3/_sidebar.ts
index 84a76bd5314e9..259ac5066e5d6 100644
--- a/test/functional/apps/discover/group3/_sidebar.ts
+++ b/test/functional/apps/discover/group3/_sidebar.ts
@@ -286,7 +286,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- //
describe('renders field groups', function () {
it('should show field list groups excluding subfields', async function () {
await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
@@ -477,7 +476,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
});
- //
it('should work correctly for a data view for a missing index', async function () {
// but we are skipping importing the index itself
await kibanaServer.importExport.load(
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 403522855a7e2..929e582d36191 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -308,10 +308,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('Search source Alert', () => {
before(async () => {
- // todo try removing this
- await kibanaServer.uiSettings.replace({
- 'data_views:fields_max_cache': '0',
- });
await security.testUser.setRoles(['discover_alert']);
log.debug('create source indices');
@@ -335,9 +331,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await deleteConnector(connectorId);
await security.testUser.restoreDefaults();
await kibanaServer.savedObjects.cleanStandardList();
- await kibanaServer.uiSettings.replace({
- 'data_views:fields_max_cache': '300',
- });
});
it('should create an alert when there is no data view', async () => {
@@ -406,7 +399,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await checkInitialRuleParamsState(SOURCE_DATA_VIEW, true);
});
- // this test fails with caching in place
it('should navigate to alert results via link provided in notification', async () => {
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
From 80249e55e0d12f6af4abb6d9573c72638a1d57a4 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 15 Nov 2023 20:45:03 -0600
Subject: [PATCH 071/168] remove skips
---
.../apps/management/data_views/_scripted_fields.ts | 8 ++++----
.../data_views/_scripted_fields_classic_table.ts | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/test/functional/apps/management/data_views/_scripted_fields.ts b/test/functional/apps/management/data_views/_scripted_fields.ts
index 1116a482a77f1..2c70161a3bc43 100644
--- a/test/functional/apps/management/data_views/_scripted_fields.ts
+++ b/test/functional/apps/management/data_views/_scripted_fields.ts
@@ -44,7 +44,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'unifiedFieldList',
]);
- describe.skip('scripted fields', function () {
+ describe('scripted fields', function () {
this.tags(['skipFirefox']);
before(async function () {
@@ -145,7 +145,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- describe.skip('discover scripted field', async () => {
+ describe('discover scripted field', async () => {
before(async () => {
const from = 'Sep 17, 2015 @ 06:31:44.000';
const to = 'Sep 18, 2015 @ 18:31:44.000';
@@ -226,7 +226,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- describe.skip('creating and using Painless string scripted fields', function describeIndexTests() {
+ describe('creating and using Painless string scripted fields', function describeIndexTests() {
const scriptedPainlessFieldName2 = 'painString';
before(async () => {
@@ -330,7 +330,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- describe.skip('creating and using Painless boolean scripted fields', function describeIndexTests() {
+ describe('creating and using Painless boolean scripted fields', function describeIndexTests() {
const scriptedPainlessFieldName2 = 'painBool';
before(async () => {
diff --git a/test/functional/apps/management/data_views/_scripted_fields_classic_table.ts b/test/functional/apps/management/data_views/_scripted_fields_classic_table.ts
index 7cbda9f04353f..0ca095811c0b4 100644
--- a/test/functional/apps/management/data_views/_scripted_fields_classic_table.ts
+++ b/test/functional/apps/management/data_views/_scripted_fields_classic_table.ts
@@ -109,7 +109,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- describe.skip('creating and using Painless numeric scripted fields', function describeIndexTests() {
+ describe('creating and using Painless numeric scripted fields', function describeIndexTests() {
const scriptedPainlessFieldName = 'ram_Pain1';
it('should create scripted field', async function () {
From cd4049b76e69aae8700a8824bfc2b6b20581182e Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Fri, 17 Nov 2023 00:01:54 +0000
Subject: [PATCH 072/168] [CI] Auto-commit changed files from 'node
scripts/eslint --no-cache --fix'
---
.../public/data_views/data_views_api_client.test.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.test.ts b/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
index fcf7694ea5793..6aada9616737b 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
@@ -17,7 +17,9 @@ describe('IndexPatternsApiClient', () => {
beforeEach(() => {
fetchSpy = jest.spyOn(http, 'fetch').mockImplementation(() => Promise.resolve({}));
- indexPatternsApiClient = new DataViewsApiClient(http as HttpSetup, () => Promise.resolve(undefined));
+ indexPatternsApiClient = new DataViewsApiClient(http as HttpSetup, () =>
+ Promise.resolve(undefined)
+ );
});
test('uses the right URI to fetch fields for wildcard', async function () {
From e03a3ec0ca2b136014a720fa2aa9b2a789ebe71e Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 21 Nov 2023 10:29:03 -0600
Subject: [PATCH 073/168] reenable cache but only for classic environment
---
src/plugins/data_views/common/types.ts | 1 +
src/plugins/data_views/server/constants.ts | 2 ++
src/plugins/data_views/server/index.ts | 6 ++++++
src/plugins/data_views/server/plugin.ts | 9 ++++++++-
.../data_views/server/rest_api_routes/internal/fields.ts | 6 +++++-
src/plugins/data_views/server/ui_settings.ts | 3 ++-
6 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/src/plugins/data_views/common/types.ts b/src/plugins/data_views/common/types.ts
index 43e1ec991776f..7fb7ddedbccd4 100644
--- a/src/plugins/data_views/common/types.ts
+++ b/src/plugins/data_views/common/types.ts
@@ -544,4 +544,5 @@ export interface HasDataService {
export interface ClientConfigType {
scriptedFieldsEnabled?: boolean;
+ fieldListCachingEnabled?: boolean;
}
diff --git a/src/plugins/data_views/server/constants.ts b/src/plugins/data_views/server/constants.ts
index 040a321978e17..f204fffe8fc6e 100644
--- a/src/plugins/data_views/server/constants.ts
+++ b/src/plugins/data_views/server/constants.ts
@@ -93,3 +93,5 @@ export const INITIAL_REST_VERSION = '2023-10-31';
*/
export const INITIAL_REST_VERSION_INTERNAL = '1';
+
+export const DEFAULT_FIELD_CACHE_FRESHNESS = 5;
diff --git a/src/plugins/data_views/server/index.ts b/src/plugins/data_views/server/index.ts
index 0e4034105d8bf..c1070e1cce541 100644
--- a/src/plugins/data_views/server/index.ts
+++ b/src/plugins/data_views/server/index.ts
@@ -47,6 +47,12 @@ const configSchema = schema.object({
schema.boolean({ defaultValue: false }),
schema.never()
),
+ fieldListCachingEnabled: schema.conditional(
+ schema.contextRef('serverless'),
+ true,
+ schema.boolean({ defaultValue: false }),
+ schema.never()
+ ),
});
type ConfigType = TypeOf;
diff --git a/src/plugins/data_views/server/plugin.ts b/src/plugins/data_views/server/plugin.ts
index bdb1ac192d5a8..c037545429247 100644
--- a/src/plugins/data_views/server/plugin.ts
+++ b/src/plugins/data_views/server/plugin.ts
@@ -49,7 +49,14 @@ export class DataViewsServerPlugin
) {
core.savedObjects.registerType(dataViewSavedObjectType);
core.capabilities.registerProvider(capabilitiesProvider);
- core.uiSettings.register(cacheMaxAge);
+
+ const config = this.initializerContext.config.get();
+
+ // add conditional
+ if (config.fieldListCachingEnabled) {
+ core.uiSettings.register(cacheMaxAge);
+ }
+
const dataViewRestCounter = usageCollection?.createUsageCounter('dataViewsRestApi');
registerRoutes({
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index 2838c47668b5b..fc56c10e92bfd 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -17,6 +17,7 @@ import type {
import type { FieldDescriptorRestResponse } from '../route_types';
import { FIELDS_PATH as path } from '../../../common/constants';
import { parseFields, IBody, IQuery, querySchema } from './fields_for';
+import { DEFAULT_FIELD_CACHE_FRESHNESS } from '../../constants';
export function calculateHash(srcBuffer: Buffer) {
const hash = createHash('sha1');
@@ -82,7 +83,10 @@ const handler: (
'user-hash': userHash,
};
- const cacheMaxAge = await uiSettings.get('data_views:cache_max_age');
+ // field cache is configurable in classic environment but not on serverless
+ const cacheMaxAge =
+ (await uiSettings.get('data_views:cache_max_age')) ||
+ DEFAULT_FIELD_CACHE_FRESHNESS;
if (cacheMaxAge && fields.length) {
const stale = 365 * 24 * 60 * 60 - cacheMaxAge;
diff --git a/src/plugins/data_views/server/ui_settings.ts b/src/plugins/data_views/server/ui_settings.ts
index b4abf665709b5..7e4dabc441bf9 100644
--- a/src/plugins/data_views/server/ui_settings.ts
+++ b/src/plugins/data_views/server/ui_settings.ts
@@ -8,13 +8,14 @@
import { i18n } from '@kbn/i18n';
import { schema } from '@kbn/config-schema';
+import { DEFAULT_FIELD_CACHE_FRESHNESS } from './constants';
export const cacheMaxAge = {
'data_views:cache_max_age': {
name: i18n.translate('dataViews.advancedSettings.cacheMaxAgeTitle', {
defaultMessage: 'Field cache max age (in seconds)',
}),
- value: 0,
+ value: DEFAULT_FIELD_CACHE_FRESHNESS,
description: i18n.translate('dataViews.advancedSettings.cacheMaxAgeText', {
defaultMessage:
"Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching. A hard reload of Kibana may be necessary for your browser to pick up the new setting.",
From 5c69712ed10ad66a374f41abaea47e1d6e018afc Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 22 Nov 2023 00:19:49 -0600
Subject: [PATCH 074/168] type cleanup
---
src/plugins/data_views/common/data_views/data_view.ts | 2 +-
src/plugins/data_views/common/data_views/data_views.ts | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/plugins/data_views/common/data_views/data_view.ts b/src/plugins/data_views/common/data_views/data_view.ts
index 7e33e3f16b97e..55c709f31e596 100644
--- a/src/plugins/data_views/common/data_views/data_view.ts
+++ b/src/plugins/data_views/common/data_views/data_view.ts
@@ -81,7 +81,7 @@ export class DataView extends AbstractDataView implements DataViewBase {
getEtag = () => this.etag;
- setEtag = (etag: string) => (this.etag = etag);
+ setEtag = (etag: string | undefined) => (this.etag = etag);
/**
* Returns scripted fields
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index 27d77b39a8e52..fd2b2b5e8d1ff 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -577,7 +577,7 @@ export class DataViewsService {
if (indexPattern.getEtag() && etag === indexPattern.getEtag()) {
return;
} else {
- indexPattern.setEtag(etag!);
+ indexPattern.setEtag(etag);
}
fields.forEach((field) => (field.isMapped = true));
@@ -862,7 +862,7 @@ export class DataViewsService {
: {};
const indexPattern = await this.createFromSpec(spec, true, displayErrors);
- indexPattern.setEtag(etag!);
+ indexPattern.setEtag(etag);
indexPattern.matchedIndices = indices;
indexPattern.resetOriginalSavedObjectBody();
return indexPattern;
From 377a5a65b1a601f01f6be620710625cf2af305a8 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 22 Nov 2023 14:04:16 -0600
Subject: [PATCH 075/168] remove user hash from server response
---
.../data_views/server/rest_api_routes/internal/fields.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index fc56c10e92bfd..715ace2975584 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -72,15 +72,15 @@ const handler: (
const etag = calculateHash(Buffer.from(JSON.stringify(body)));
- const getUserId = getUserIdGetter();
- const userId = await getUserId(request);
- const userHash = userId ? calculateHash(Buffer.from(userId)) : '';
+ // const getUserId = getUserIdGetter();
+ // const userId = await getUserId(request);
+ // const userHash = userId ? calculateHash(Buffer.from(userId)) : '';
const headers: Record = {
'content-type': 'application/json',
etag,
vary: 'accept-encoding, user-hash',
- 'user-hash': userHash,
+ // 'user-hash': userHash,
};
// field cache is configurable in classic environment but not on serverless
From 1a9a450af4ddd037517092ef5629683dce569b11 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 22 Nov 2023 15:59:33 -0600
Subject: [PATCH 076/168] remove server side user hash header
---
src/plugins/data_views/server/plugin.ts | 6 ------
.../server/rest_api_routes/internal/fields.ts | 19 +++++--------------
src/plugins/data_views/server/routes.ts | 6 ++----
src/plugins/data_views/server/types.ts | 3 ---
x-pack/plugins/security/server/plugin.ts | 18 +-----------------
5 files changed, 8 insertions(+), 44 deletions(-)
diff --git a/src/plugins/data_views/server/plugin.ts b/src/plugins/data_views/server/plugin.ts
index c037545429247..828736feaaa93 100644
--- a/src/plugins/data_views/server/plugin.ts
+++ b/src/plugins/data_views/server/plugin.ts
@@ -21,7 +21,6 @@ import {
DataViewsServerPluginStart,
DataViewsServerPluginSetupDependencies,
DataViewsServerPluginStartDependencies,
- GetUserId,
} from './types';
import { DataViewsStorage } from './content_management';
import { cacheMaxAge } from './ui_settings';
@@ -37,7 +36,6 @@ export class DataViewsServerPlugin
{
private readonly logger: Logger;
private rollupsEnabled: boolean = false;
- private getUserId: GetUserId = async () => undefined;
constructor(private readonly initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get('dataView');
@@ -64,7 +62,6 @@ export class DataViewsServerPlugin
getStartServices: core.getStartServices,
isRollupsEnabled: () => this.rollupsEnabled,
dataViewRestCounter,
- getUserIdGetter: () => this.getUserId,
});
expressions.registerFunction(getIndexPatternLoad({ getStartServices: core.getStartServices }));
@@ -84,9 +81,6 @@ export class DataViewsServerPlugin
return {
enableRollups: () => (this.rollupsEnabled = true),
- setGetUserId: (getUserId: GetUserId) => {
- this.getUserId = getUserId;
- },
};
}
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index 715ace2975584..c711ae405a647 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -7,7 +7,7 @@
*/
import { createHash } from 'crypto';
-import { IRouter, RequestHandler, StartServicesAccessor, KibanaRequest } from '@kbn/core/server';
+import { IRouter, RequestHandler, StartServicesAccessor } from '@kbn/core/server';
import { unwrapEtag } from '../../../common/utils';
import { IndexPatternsFetcher } from '../../fetcher';
import type {
@@ -25,11 +25,8 @@ export function calculateHash(srcBuffer: Buffer) {
return hash.digest('hex');
}
-const handler: (
- isRollupsEnabled: () => boolean,
- getUserId: () => (kibanaRequest: KibanaRequest) => Promise
-) => RequestHandler<{}, IQuery, IBody> =
- (isRollupsEnabled, getUserIdGetter) => async (context, request, response) => {
+const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, IBody> =
+ (isRollupsEnabled) => async (context, request, response) => {
const core = await context.core;
const uiSettings = core.uiSettings.client;
const { asCurrentUser } = core.elasticsearch.client;
@@ -72,15 +69,10 @@ const handler: (
const etag = calculateHash(Buffer.from(JSON.stringify(body)));
- // const getUserId = getUserIdGetter();
- // const userId = await getUserId(request);
- // const userHash = userId ? calculateHash(Buffer.from(userId)) : '';
-
const headers: Record = {
'content-type': 'application/json',
etag,
vary: 'accept-encoding, user-hash',
- // 'user-hash': userHash,
};
// field cache is configurable in classic environment but not on serverless
@@ -137,8 +129,7 @@ export const registerFields = async (
DataViewsServerPluginStartDependencies,
DataViewsServerPluginStart
>,
- isRollupsEnabled: () => boolean,
- getUserId: () => (request: KibanaRequest) => Promise
+ isRollupsEnabled: () => boolean
) => {
- router.get({ path, validate: { query: querySchema } }, handler(isRollupsEnabled, getUserId));
+ router.get({ path, validate: { query: querySchema } }, handler(isRollupsEnabled));
};
diff --git a/src/plugins/data_views/server/routes.ts b/src/plugins/data_views/server/routes.ts
index 4acc09aafe2ab..d6ee36927ff80 100644
--- a/src/plugins/data_views/server/routes.ts
+++ b/src/plugins/data_views/server/routes.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { HttpServiceSetup, StartServicesAccessor, KibanaRequest } from '@kbn/core/server';
+import { HttpServiceSetup, StartServicesAccessor } from '@kbn/core/server';
import { UsageCounter } from '@kbn/usage-collection-plugin/server';
import { routes } from './rest_api_routes/public';
import type { DataViewsServerPluginStart, DataViewsServerPluginStartDependencies } from './types';
@@ -24,7 +24,6 @@ interface RegisterRoutesArgs {
>;
isRollupsEnabled: () => boolean;
dataViewRestCounter?: UsageCounter;
- getUserIdGetter: () => (request: KibanaRequest) => Promise;
}
export function registerRoutes({
@@ -32,7 +31,6 @@ export function registerRoutes({
getStartServices,
dataViewRestCounter,
isRollupsEnabled,
- getUserIdGetter,
}: RegisterRoutesArgs) {
const router = http.createRouter();
@@ -40,6 +38,6 @@ export function registerRoutes({
registerExistingIndicesPath(router);
registerFieldForWildcard(router, getStartServices, isRollupsEnabled);
- registerFields(router, getStartServices, isRollupsEnabled, getUserIdGetter);
+ registerFields(router, getStartServices, isRollupsEnabled);
registerHasDataViewsRoute(router);
}
diff --git a/src/plugins/data_views/server/types.ts b/src/plugins/data_views/server/types.ts
index 1fe900dc58113..6bf438dc634bd 100644
--- a/src/plugins/data_views/server/types.ts
+++ b/src/plugins/data_views/server/types.ts
@@ -18,8 +18,6 @@ import { FieldFormatsSetup, FieldFormatsStart } from '@kbn/field-formats-plugin/
import type { ContentManagementServerSetup } from '@kbn/content-management-plugin/server';
import { DataViewsService } from '../common';
-export type GetUserId = (request: KibanaRequest) => Promise;
-
/**
* Data Views service factory
*/
@@ -61,7 +59,6 @@ export interface DataViewsServerPluginStart {
*/
export interface DataViewsServerPluginSetup {
enableRollups: () => void;
- setGetUserId: (getUserId: GetUserId) => void;
}
/**
diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts
index e87881b1a824e..341ab79e97e5b 100644
--- a/x-pack/plugins/security/server/plugin.ts
+++ b/x-pack/plugins/security/server/plugin.ts
@@ -18,7 +18,6 @@ import type {
Plugin,
PluginInitializerContext,
} from '@kbn/core/server';
-import type { DataViewsServerPluginSetup } from '@kbn/data-views-plugin/server';
import type {
PluginSetupContract as FeaturesPluginSetup,
PluginStartContract as FeaturesPluginStart,
@@ -119,7 +118,6 @@ export interface PluginSetupDependencies {
taskManager: TaskManagerSetupContract;
usageCollection?: UsageCollectionSetup;
spaces?: SpacesPluginSetup;
- dataViews: DataViewsServerPluginSetup;
}
export interface PluginStartDependencies {
@@ -244,14 +242,7 @@ export class SecurityPlugin
public setup(
core: CoreSetup,
- {
- features,
- licensing,
- taskManager,
- usageCollection,
- spaces,
- dataViews,
- }: PluginSetupDependencies
+ { features, licensing, taskManager, usageCollection, spaces }: PluginSetupDependencies
) {
this.kibanaIndexName = core.savedObjects.getDefaultIndex();
const config$ = this.initializerContext.config.create>().pipe(
@@ -268,13 +259,6 @@ export class SecurityPlugin
const config = this.getConfig();
const kibanaIndexName = this.getKibanaIndexName();
- async function getUserId(request: KibanaRequest): Promise {
- const [, , security] = await core.getStartServices();
- return security.authc.getCurrentUser(request)?.profile_uid;
- }
-
- dataViews.setGetUserId(getUserId);
-
// A subset of `start` services we need during `setup`.
const startServicesPromise = core.getStartServices().then(([coreServices, depsServices]) => ({
elasticsearch: coreServices.elasticsearch,
From 5971b41217fb798392f55e4ced91250663952e74 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 22 Nov 2023 16:10:52 -0600
Subject: [PATCH 077/168] typefix
---
src/plugins/data_views/server/index.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/plugins/data_views/server/index.ts b/src/plugins/data_views/server/index.ts
index c1070e1cce541..591870bbad029 100644
--- a/src/plugins/data_views/server/index.ts
+++ b/src/plugins/data_views/server/index.ts
@@ -16,7 +16,6 @@ export type {
DataViewsServerPluginStart,
DataViewsServerPluginSetupDependencies,
DataViewsServerPluginStartDependencies,
- GetUserId,
} from './types';
import { PluginInitializerContext } from '@kbn/core/server';
From fd7adb23c53ec7a7adbf2ea3366d3e5f0450cfba Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 22 Nov 2023 17:43:51 -0600
Subject: [PATCH 078/168] remove unneeded functional test changes
---
test/functional/apps/discover/group3/_sidebar.ts | 2 --
test/functional/page_objects/discover_page.ts | 6 ------
x-pack/plugins/security/server/plugin.test.ts | 3 ---
.../creation/index_pattern/creation_index_pattern.ts | 1 -
.../creation_runtime_mappings.ts | 4 +---
.../apps/discover_ml_uptime/discover/search_source_alert.ts | 1 -
.../functional/tests/discover_integration.ts | 1 -
7 files changed, 1 insertion(+), 17 deletions(-)
diff --git a/test/functional/apps/discover/group3/_sidebar.ts b/test/functional/apps/discover/group3/_sidebar.ts
index 259ac5066e5d6..01e357b7f01e6 100644
--- a/test/functional/apps/discover/group3/_sidebar.ts
+++ b/test/functional/apps/discover/group3/_sidebar.ts
@@ -17,7 +17,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'discover',
'timePicker',
'header',
- 'settings',
'unifiedSearch',
'unifiedFieldList',
]);
@@ -527,7 +526,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
await browser.refresh();
- await PageObjects.discover.refreshFieldList();
await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
expect(await PageObjects.unifiedFieldList.getSidebarAriaDescription()).to.be(
diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts
index 903b8875405a1..6005bbd2de7ad 100644
--- a/test/functional/page_objects/discover_page.ts
+++ b/test/functional/page_objects/discover_page.ts
@@ -433,12 +433,6 @@ export class DiscoverPageObject extends FtrService {
});
}
- // disabled while `data_views:cache_max_age` ui setting is set to zero
- public async refreshFieldList() {
- // await this.clickIndexPatternActions();
- // await this.testSubjects.click('data-view-refresh-fields');
- }
-
public async clickAddNewField() {
await this.retry.try(async () => {
await this.testSubjects.click('indexPattern-add-field');
diff --git a/x-pack/plugins/security/server/plugin.test.ts b/x-pack/plugins/security/server/plugin.test.ts
index 0426a1fd674eb..e838016e94524 100644
--- a/x-pack/plugins/security/server/plugin.test.ts
+++ b/x-pack/plugins/security/server/plugin.test.ts
@@ -51,9 +51,6 @@ describe('Security Plugin', () => {
licensing: { license$: of({}), featureUsage: { register: jest.fn() } },
features: featuresPluginMock.createSetup(),
taskManager: taskManagerMock.createSetup(),
- dataViews: {
- setGetUserId: jest.fn(),
- },
} as unknown as PluginSetupDependencies;
mockCoreStart = coreMock.createStart();
diff --git a/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts b/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts
index 7384b5bae2c9a..69406c5830421 100644
--- a/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts
+++ b/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts
@@ -835,7 +835,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await transform.testExecution.logTestStep('should navigate to discover');
await transform.table.clickTransformRowAction(testData.transformId, 'Discover');
await pageObjects.discover.waitUntilSearchingHasFinished();
- await pageObjects.discover.refreshFieldList();
if (testData.discoverAdjustSuperDatePicker) {
await transform.testExecution.logTestStep(
diff --git a/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts b/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts
index f975dec539622..3f0adc5783893 100644
--- a/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts
+++ b/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts
@@ -19,10 +19,9 @@ import {
PivotTransformTestData,
} from '../../helpers';
-export default function ({ getPageObjects, getService }: FtrProviderContext) {
+export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const transform = getService('transform');
- const PageObjects = getPageObjects(['discover']);
const runtimeMappings = {
rt_airline_lower: {
@@ -447,7 +446,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await transform.testExecution.logTestStep('redirects to Discover page');
await transform.wizard.redirectToDiscover();
- await PageObjects.discover.refreshFieldList();
if (isLatestTransformTestData(testData)) {
const fromTime = 'Feb 7, 2016 @ 00:00:00.000';
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 929e582d36191..6b668f75d56d3 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -211,7 +211,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.discover.clickNewSearchButton(); // reset params
await PageObjects.discover.selectIndexPattern(OUTPUT_DATA_VIEW);
- await PageObjects.discover.refreshFieldList();
let ruleId: string;
if (type === 'name') {
diff --git a/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts b/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts
index a132c493de83a..8258b4570ed9b 100644
--- a/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts
+++ b/x-pack/test/saved_object_tagging/functional/tests/discover_integration.ts
@@ -104,7 +104,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
beforeEach(async () => {
await PageObjects.common.navigateToApp('discover');
await PageObjects.discover.selectIndexPattern('logstash-*');
- await PageObjects.discover.refreshFieldList();
await PageObjects.timePicker.setDefaultAbsoluteRange();
await PageObjects.header.waitUntilLoadingHasFinished();
});
From 55b8191b510ad8a1e174e606ec0f6794d3d8fe89 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 26 Nov 2023 20:47:08 -0600
Subject: [PATCH 079/168] implement versioned router on fields endpoint
---
.../data_views/data_views_api_client.ts | 2 ++
.../apis/data_views/fields_route/cache.ts | 30 ++++++++-----------
.../apis/data_views/fields_route/conflicts.ts | 4 +--
.../apis/data_views/fields_route/params.ts | 28 ++++++++---------
.../apis/data_views/fields_route/response.ts | 20 ++++++-------
5 files changed, 39 insertions(+), 45 deletions(-)
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index 2612ddcf98bb0..c65db9e5c736f 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -92,6 +92,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
allowHidden,
} = options;
const path = indexFilter ? FIELDS_FOR_WILDCARD_PATH : FIELDS_PATH;
+ const versionQueryParam = indexFilter ? {} : { apiVersion: version };
return this._request(
path,
@@ -104,6 +105,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
include_unmapped: includeUnmapped,
fields,
allow_hidden: allowHidden,
+ ...versionQueryParam,
},
indexFilter ? JSON.stringify({ index_filter: indexFilter }) : undefined,
forceRefresh
diff --git a/test/api_integration/apis/data_views/fields_route/cache.ts b/test/api_integration/apis/data_views/fields_route/cache.ts
index 727a64fdfa061..f5b33de590c3b 100644
--- a/test/api_integration/apis/data_views/fields_route/cache.ts
+++ b/test/api_integration/apis/data_views/fields_route/cache.ts
@@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
-import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
import { INITIAL_REST_VERSION_INTERNAL } from '@kbn/data-views-plugin/server/constants';
import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
import expect from '@kbn/expect';
@@ -24,15 +23,12 @@ export default function ({ getService }: FtrProviderContext) {
esArchiver.unload('test/api_integration/fixtures/es_archiver/index_patterns/basic_index')
);
- // disabled since caching is disabled. Try to load uiSettings so this test can be enabled
- it.skip('are present', async () => {
- const response = await supertest
- .get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
- .query({
- pattern: '*',
- include_unmapped: true,
- });
+ it('are present', async () => {
+ const response = await supertest.get(FIELDS_PATH).query({
+ pattern: '*',
+ include_unmapped: true,
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
+ });
const cacheControlHeader = response.get('cache-control');
@@ -44,21 +40,19 @@ export default function ({ getService }: FtrProviderContext) {
});
it('returns 304 on matching etag', async () => {
- const response = await supertest
- .get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
- .query({
- pattern: '*',
- include_unmapped: true,
- });
+ const response = await supertest.get(FIELDS_PATH).query({
+ pattern: '*',
+ include_unmapped: true,
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
+ });
await supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.set('If-None-Match', response.get('etag'))
.query({
pattern: '*',
include_unmapped: true,
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(304);
});
diff --git a/test/api_integration/apis/data_views/fields_route/conflicts.ts b/test/api_integration/apis/data_views/fields_route/conflicts.ts
index 9ad861272c4cd..026ca58b6dba4 100644
--- a/test/api_integration/apis/data_views/fields_route/conflicts.ts
+++ b/test/api_integration/apis/data_views/fields_route/conflicts.ts
@@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
-import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
import { INITIAL_REST_VERSION_INTERNAL } from '@kbn/data-views-plugin/server/constants';
import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
import expect from '@kbn/expect';
@@ -27,8 +26,7 @@ export default function ({ getService }: FtrProviderContext) {
it('flags fields with mismatched types as conflicting', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
- .query({ pattern: 'logs-*' })
+ .query({ pattern: 'logs-*', apiVersion: INITIAL_REST_VERSION_INTERNAL })
.expect(200)
.then((resp) => {
expect(resp.body).to.eql({
diff --git a/test/api_integration/apis/data_views/fields_route/params.ts b/test/api_integration/apis/data_views/fields_route/params.ts
index 29d6c06e3a60b..7d111936426bb 100644
--- a/test/api_integration/apis/data_views/fields_route/params.ts
+++ b/test/api_integration/apis/data_views/fields_route/params.ts
@@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
-import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
import { INITIAL_REST_VERSION_INTERNAL } from '@kbn/data-views-plugin/server/constants';
import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
import { FtrProviderContext } from '../../../ftr_provider_context';
@@ -27,27 +26,28 @@ export default function ({ getService }: FtrProviderContext) {
it('requires a pattern query param', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
- .query({})
+ .query({
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
+ })
.expect(400));
it('accepts include_unmapped param', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: '*',
include_unmapped: true,
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(200));
it('rejects unexpected query params', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: randomness.word(),
[randomness.word()]: randomness.word(),
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(400));
@@ -55,50 +55,50 @@ export default function ({ getService }: FtrProviderContext) {
it('accepts a JSON formatted fields query param', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: '*',
fields: JSON.stringify(['baz']),
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(200));
it('accepts meta_fields query param in string array', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: '*',
fields: ['baz', 'foo'],
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(200));
it('accepts single array fields query param', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: '*',
fields: ['baz'],
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(200));
it('accepts single fields query param', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: '*',
fields: 'baz',
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(200));
it('rejects a comma-separated list of fields', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: '*',
fields: 'foo,bar',
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(400));
});
@@ -107,40 +107,40 @@ export default function ({ getService }: FtrProviderContext) {
it('accepts a JSON formatted meta_fields query param', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: '*',
meta_fields: JSON.stringify(['meta']),
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(200));
it('accepts meta_fields query param in string array', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: '*',
meta_fields: ['_id', 'meta'],
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(200));
it('accepts single meta_fields query param', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: '*',
meta_fields: ['_id'],
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(200));
it('rejects a comma-separated list of meta_fields', () =>
supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: '*',
meta_fields: 'foo,bar',
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(400));
});
diff --git a/test/api_integration/apis/data_views/fields_route/response.ts b/test/api_integration/apis/data_views/fields_route/response.ts
index 47c8814b0c4b0..2c6aeb8d75ab7 100644
--- a/test/api_integration/apis/data_views/fields_route/response.ts
+++ b/test/api_integration/apis/data_views/fields_route/response.ts
@@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
-import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
import { INITIAL_REST_VERSION_INTERNAL } from '@kbn/data-views-plugin/server/constants';
import { FIELDS_PATH } from '@kbn/data-views-plugin/common/constants';
import expect from '@kbn/expect';
@@ -86,11 +85,11 @@ export default function ({ getService }: FtrProviderContext) {
it('returns a flattened version of the fields in es', async () => {
await supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({ pattern: 'basic_index' })
.expect(200, {
fields: testFields,
indices: ['basic_index'],
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.then(ensureFieldsAreSorted);
});
@@ -98,8 +97,11 @@ export default function ({ getService }: FtrProviderContext) {
it('returns a single field as requested', async () => {
await supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
- .query({ pattern: 'basic_index', fields: JSON.stringify(['bar']) })
+ .query({
+ pattern: 'basic_index',
+ fields: JSON.stringify(['bar']),
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
+ })
.expect(200, {
fields: [testFields[0]],
indices: ['basic_index'],
@@ -109,10 +111,10 @@ export default function ({ getService }: FtrProviderContext) {
it('always returns a field for all passed meta fields', async () => {
await supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: 'basic_index',
meta_fields: JSON.stringify(['_id', '_source', 'crazy_meta_field']),
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(200, {
fields: [
@@ -202,8 +204,7 @@ export default function ({ getService }: FtrProviderContext) {
it('returns fields when one pattern exists and the other does not', async () => {
await supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
- .query({ pattern: 'bad_index,basic_index' })
+ .query({ pattern: 'bad_index,basic_index', apiVersion: INITIAL_REST_VERSION_INTERNAL })
.expect(200, {
fields: testFields,
indices: ['basic_index'],
@@ -213,17 +214,16 @@ export default function ({ getService }: FtrProviderContext) {
it('returns 404 when neither exists', async () => {
await supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
- .query({ pattern: 'bad_index,bad_index_2' })
+ .query({ pattern: 'bad_index,bad_index_2', apiVersion: INITIAL_REST_VERSION_INTERNAL })
.expect(404);
});
it('returns 404 when no patterns exist', async () => {
await supertest
.get(FIELDS_PATH)
- .set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION_INTERNAL)
.query({
pattern: 'bad_index',
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.expect(404);
});
From 89c4ff29e57e3c6d2fa54932e327b26bd040b912 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 26 Nov 2023 22:02:23 -0600
Subject: [PATCH 080/168] fix fields route
---
.../data_views/server/rest_api_routes/internal/fields.ts | 9 +++++++--
.../server/rest_api_routes/internal/fields_for.ts | 2 +-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index c711ae405a647..b55b742535479 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -16,7 +16,7 @@ import type {
} from '../../types';
import type { FieldDescriptorRestResponse } from '../route_types';
import { FIELDS_PATH as path } from '../../../common/constants';
-import { parseFields, IBody, IQuery, querySchema } from './fields_for';
+import { parseFields, IBody, IQuery, querySchema, validate } from './fields_for';
import { DEFAULT_FIELD_CACHE_FRESHNESS } from '../../constants';
export function calculateHash(srcBuffer: Buffer) {
@@ -131,5 +131,10 @@ export const registerFields = async (
>,
isRollupsEnabled: () => boolean
) => {
- router.get({ path, validate: { query: querySchema } }, handler(isRollupsEnabled));
+ router.versioned
+ .get({ path, access: 'internal', enableQueryVersion: true })
+ .addVersion(
+ { version: '1', validate: { request: { query: querySchema }, response: validate.response } },
+ handler(isRollupsEnabled)
+ );
};
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
index 7931dcce51e37..3c89cdef17955 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts
@@ -97,7 +97,7 @@ const FieldDescriptorSchema = schema.object({
),
});
-const validate: FullValidationConfig = {
+export const validate: FullValidationConfig = {
request: {
query: querySchema,
// not available to get request
From 6efa5f1766e11c281640ecd18a5d801ab583a4e2 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 26 Nov 2023 23:15:03 -0600
Subject: [PATCH 081/168] fix test
---
test/api_integration/apis/data_views/fields_route/response.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/test/api_integration/apis/data_views/fields_route/response.ts b/test/api_integration/apis/data_views/fields_route/response.ts
index 2c6aeb8d75ab7..880206f6fb498 100644
--- a/test/api_integration/apis/data_views/fields_route/response.ts
+++ b/test/api_integration/apis/data_views/fields_route/response.ts
@@ -85,11 +85,10 @@ export default function ({ getService }: FtrProviderContext) {
it('returns a flattened version of the fields in es', async () => {
await supertest
.get(FIELDS_PATH)
- .query({ pattern: 'basic_index' })
+ .query({ pattern: 'basic_index', apiVersion: INITIAL_REST_VERSION_INTERNAL })
.expect(200, {
fields: testFields,
indices: ['basic_index'],
- apiVersion: INITIAL_REST_VERSION_INTERNAL,
})
.then(ensureFieldsAreSorted);
});
From c5c993ee7af0590829000cc2c23be04ebde7e867 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 27 Nov 2023 00:03:09 -0600
Subject: [PATCH 082/168] add performance journey
---
x-pack/test/scalability/apis/api.fields.json | 50 ++++++++++++++++++++
1 file changed, 50 insertions(+)
create mode 100644 x-pack/test/scalability/apis/api.fields.json
diff --git a/x-pack/test/scalability/apis/api.fields.json b/x-pack/test/scalability/apis/api.fields.json
new file mode 100644
index 0000000000000..7e60dcdf6c4d6
--- /dev/null
+++ b/x-pack/test/scalability/apis/api.fields.json
@@ -0,0 +1,50 @@
+{
+ "journeyName": "GET /internal/data_views/fields",
+ "scalabilitySetup": {
+ "responseTimeThreshold": {
+ "threshold1": 5000,
+ "threshold2": 10000,
+ "threshold3": 20000
+ },
+ "warmup": [
+ {
+ "action": "constantUsersPerSec",
+ "userCount": 1,
+ "duration": "30s"
+ }
+ ],
+ "test": [
+ {
+ "action": "rampUsersPerSec",
+ "minUsersCount": 1,
+ "maxUsersCount": 7,
+ "duration": "140s"
+ }
+ ],
+ "maxDuration": "5m"
+ },
+ "testData": {
+ "esArchives": ["test/functional/fixtures/es_archiver/many_fields"]
+ },
+ "streams": [
+ {
+ "requests": [
+ {
+ "http": {
+ "method": "GET",
+ "path": "/internal/data_views/fields",
+ "query": "?pattern=indices*&apiVersion=1",
+ "headers": {
+ "Cookie": "",
+ "Kbn-Version": "",
+ "Accept-Encoding": "gzip, deflate, br",
+ "Content-Type": "application/json",
+ "x-elastic-internal-origin": "kibana"
+ },
+ "statusCode": 200
+ }
+ }
+ ]
+ }
+ ]
+}
From 6d7212a29140145ee533d365381e2ccf3438423f Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 27 Nov 2023 00:20:59 -0600
Subject: [PATCH 083/168] remove one serialization
---
.../data_views/server/rest_api_routes/internal/fields.ts | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index b55b742535479..454035f3b812f 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -67,7 +67,9 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
indices,
};
- const etag = calculateHash(Buffer.from(JSON.stringify(body)));
+ const bodyAsString = JSON.stringify(body);
+
+ const etag = calculateHash(Buffer.from(bodyAsString));
const headers: Record = {
'content-type': 'application/json',
@@ -100,7 +102,7 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
}
return response.ok({
- body,
+ body: bodyAsString,
headers,
});
} catch (error) {
From ed73b7b7bb11416c322e41cbc5e04d905b5cadf8 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 27 Nov 2023 07:56:05 -0600
Subject: [PATCH 084/168] fix api integration test
---
test/api_integration/apis/data_views/fields_route/cache.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/test/api_integration/apis/data_views/fields_route/cache.ts b/test/api_integration/apis/data_views/fields_route/cache.ts
index f5b33de590c3b..978c048ee8b8e 100644
--- a/test/api_integration/apis/data_views/fields_route/cache.ts
+++ b/test/api_integration/apis/data_views/fields_route/cache.ts
@@ -36,7 +36,6 @@ export default function ({ getService }: FtrProviderContext) {
expect(cacheControlHeader).to.contain('stale-while-revalidate');
expect(response.get('vary')).to.equal('accept-encoding, user-hash');
expect(response.get('etag')).to.not.be.empty();
- expect(response.get('user-hash')).to.equal('');
});
it('returns 304 on matching etag', async () => {
From cdeec6877e718696ce82bf6f389fb43b36ae1301 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 29 Nov 2023 23:20:52 -0600
Subject: [PATCH 085/168] add performance journeys
---
src/plugins/data_views/server/plugin.ts | 1 -
.../apis/api.fields.32_fields.json | 50 +++++++++++++++++++
...ields.json => api.fields.6800_fields.json} | 2 +-
3 files changed, 51 insertions(+), 2 deletions(-)
create mode 100644 x-pack/test/scalability/apis/api.fields.32_fields.json
rename x-pack/test/scalability/apis/{api.fields.json => api.fields.6800_fields.json} (94%)
diff --git a/src/plugins/data_views/server/plugin.ts b/src/plugins/data_views/server/plugin.ts
index 828736feaaa93..2da7d128b837a 100644
--- a/src/plugins/data_views/server/plugin.ts
+++ b/src/plugins/data_views/server/plugin.ts
@@ -50,7 +50,6 @@ export class DataViewsServerPlugin
const config = this.initializerContext.config.get();
- // add conditional
if (config.fieldListCachingEnabled) {
core.uiSettings.register(cacheMaxAge);
}
diff --git a/x-pack/test/scalability/apis/api.fields.32_fields.json b/x-pack/test/scalability/apis/api.fields.32_fields.json
new file mode 100644
index 0000000000000..03837b238e44e
--- /dev/null
+++ b/x-pack/test/scalability/apis/api.fields.32_fields.json
@@ -0,0 +1,50 @@
+{
+ "journeyName": "GET /internal/data_views/fields - 32 fields",
+ "scalabilitySetup": {
+ "responseTimeThreshold": {
+ "threshold1": 5000,
+ "threshold2": 10000,
+ "threshold3": 20000
+ },
+ "warmup": [
+ {
+ "action": "constantUsersPerSec",
+ "userCount": 10,
+ "duration": "30s"
+ }
+ ],
+ "test": [
+ {
+ "action": "rampUsersPerSec",
+ "minUsersCount": 10,
+ "maxUsersCount": 375,
+ "duration": "140s"
+ }
+ ],
+ "maxDuration": "5m"
+ },
+ "testData": {
+ "esArchives": ["test/functional/fixtures/es_archiver/kibana_sample_data_flights"]
+ },
+ "streams": [
+ {
+ "requests": [
+ {
+ "http": {
+ "method": "GET",
+ "path": "/internal/data_views/fields",
+ "query": "?pattern=kibana*&apiVersion=1",
+ "headers": {
+ "Cookie": "",
+ "Kbn-Version": "",
+ "Accept-Encoding": "gzip, deflate, br",
+ "Content-Type": "application/json",
+ "x-elastic-internal-origin": "kibana"
+ },
+ "statusCode": 200
+ }
+ }
+ ]
+ }
+ ]
+}
diff --git a/x-pack/test/scalability/apis/api.fields.json b/x-pack/test/scalability/apis/api.fields.6800_fields.json
similarity index 94%
rename from x-pack/test/scalability/apis/api.fields.json
rename to x-pack/test/scalability/apis/api.fields.6800_fields.json
index 7e60dcdf6c4d6..362eaa211acae 100644
--- a/x-pack/test/scalability/apis/api.fields.json
+++ b/x-pack/test/scalability/apis/api.fields.6800_fields.json
@@ -1,5 +1,5 @@
{
- "journeyName": "GET /internal/data_views/fields",
+ "journeyName": "GET /internal/data_views/fields - 6800 fields",
"scalabilitySetup": {
"responseTimeThreshold": {
"threshold1": 5000,
From 26d3d6de42c5b0fcdcc3df7c7643b6fa6f13cb69 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Thu, 30 Nov 2023 22:38:54 +0100
Subject: [PATCH 086/168] Add new fields to list with correct types
---
.../src/hooks/use_existing_fields.ts | 22 ++++++++++++-
.../src/hooks/use_grouped_fields.ts | 32 +++++++++++++------
.../field_existing/field_existing_utils.ts | 11 +++++--
.../field_existing/load_field_existing.ts | 3 +-
4 files changed, 54 insertions(+), 14 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
index d099a6f2b85e2..588e0f60384b3 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
@@ -15,6 +15,7 @@ import { type DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { DataView, DataViewsContract } from '@kbn/data-views-plugin/common';
import { getEsQueryConfig } from '@kbn/data-service/src/es_query';
import { reportPerformanceMetricEvent } from '@kbn/ebt-tools';
+import { DataViewField } from '@kbn/data-views-plugin/common';
import { loadFieldExisting } from '../services/field_existing';
import { ExistenceFetchStatus } from '../types';
@@ -24,6 +25,8 @@ const generateId = htmlIdGenerator();
export interface ExistingFieldsInfo {
fetchStatus: ExistenceFetchStatus;
existingFieldsByFieldNameMap: Record;
+ newFieldsByFieldNameMap: Record;
+ newFields?: DataViewField[];
numberOfFetches: number;
hasDataViewRestrictions?: boolean;
}
@@ -54,12 +57,14 @@ export interface ExistingFieldsReader {
hasFieldData: (dataViewId: string, fieldName: string) => boolean;
getFieldsExistenceStatus: (dataViewId: string) => ExistenceFetchStatus;
isFieldsExistenceInfoUnavailable: (dataViewId: string) => boolean;
+ getNewFields: (dataViewId: string) => DataViewField[];
}
const initialData: ExistingFieldsByDataViewMap = {};
const unknownInfo: ExistingFieldsInfo = {
fetchStatus: ExistenceFetchStatus.unknown,
existingFieldsByFieldNameMap: {},
+ newFieldsByFieldNameMap: {},
numberOfFetches: 0,
};
@@ -157,6 +162,7 @@ export const useExistingFieldsFetcher = (
}
info.existingFieldsByFieldNameMap = booleanMap(existingFieldNames);
+ info.newFields = result.newFields;
info.fetchStatus = ExistenceFetchStatus.succeeded;
} catch (error) {
info.fetchStatus = ExistenceFetchStatus.failed;
@@ -286,6 +292,19 @@ export const useExistingFieldsReader: () => ExistingFieldsReader = () => {
[existingFieldsByDataViewMap]
);
+ const getNewFields = useCallback(
+ (dataViewId: string) => {
+ const info = existingFieldsByDataViewMap[dataViewId];
+
+ if (info?.fetchStatus === ExistenceFetchStatus.succeeded) {
+ return info?.newFields ?? [];
+ }
+
+ return [];
+ },
+ [existingFieldsByDataViewMap]
+ );
+
const getFieldsExistenceInfo = useCallback(
(dataViewId: string) => {
return dataViewId ? existingFieldsByDataViewMap[dataViewId] : unknownInfo;
@@ -321,8 +340,9 @@ export const useExistingFieldsReader: () => ExistingFieldsReader = () => {
hasFieldData,
getFieldsExistenceStatus,
isFieldsExistenceInfoUnavailable,
+ getNewFields,
}),
- [hasFieldData, getFieldsExistenceStatus, isFieldsExistenceInfoUnavailable]
+ [hasFieldData, getFieldsExistenceStatus, isFieldsExistenceInfoUnavailable, getNewFields]
);
};
diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
index f51f9b0fffb2d..7822e71244d10 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
@@ -120,13 +120,23 @@ export function useGroupedFields({
};
const selectedFields = sortedSelectedFields || [];
- const sortedFields = [...(allFields || [])].sort(sortFields);
+ const newFields = dataViewId ? fieldsExistenceReader.getNewFields(dataViewId) : [];
+ console.log({ newFields });
+ const fieldsToSort =
+ allFields && newFields.length
+ ? allFields.map((field) => {
+ return (dataView?.getFieldByName(field.name) as unknown as T) ?? field;
+ })
+ : allFields;
+ const sortedFields = [...(fieldsToSort || [])].sort(sortFields);
+
const groupedFields = {
...getDefaultFieldGroups(),
...groupBy(sortedFields, (field) => {
if (!sortedSelectedFields && onSelectedFieldFilter && onSelectedFieldFilter(field)) {
selectedFields.push(field);
}
+
if (onSupportedFieldFilter && !onSupportedFieldFilter(field)) {
return 'skippedFields';
}
@@ -311,18 +321,19 @@ export function useGroupedFields({
return fieldGroupDefinitions;
}, [
+ sortedSelectedFields,
allFields,
- onSupportedFieldFilter,
- onSelectedFieldFilter,
- onOverrideFieldGroupDetails,
- dataView,
- dataViewId,
- hasFieldDataHandler,
- fieldsExistenceInfoUnavailable,
+ popularFieldsLimit,
isAffectedByGlobalFilter,
isAffectedByTimeFilter,
- popularFieldsLimit,
- sortedSelectedFields,
+ dataViewId,
+ fieldsExistenceInfoUnavailable,
+ onOverrideFieldGroupDetails,
+ hasFieldDataHandler,
+ fieldsExistenceReader,
+ onSelectedFieldFilter,
+ onSupportedFieldFilter,
+ dataView,
]);
const fieldGroups: FieldListGroups = useMemo(() => {
@@ -403,5 +414,6 @@ function getDefaultFieldGroups() {
metaFields: [],
unmappedFields: [],
skippedFields: [],
+ newFields: [],
};
}
diff --git a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
index 2aa6137ffb1fb..0a487368748cf 100644
--- a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
+++ b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
@@ -7,7 +7,7 @@
*/
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
-import { RuntimeField } from '@kbn/data-views-plugin/common';
+import { DataViewField, RuntimeField } from '@kbn/data-views-plugin/common';
import type { DataViewsContract, DataView, FieldSpec } from '@kbn/data-views-plugin/common';
import type { IKibanaSearchRequest } from '@kbn/data-plugin/common';
@@ -49,15 +49,22 @@ export async function fetchFieldExistence({
metaFields: string[];
dataViewsService: DataViewsContract;
}) {
- const allFields = buildFieldList(dataView, metaFields);
const existingFieldList = await dataViewsService.getFieldsForIndexPattern(dataView, {
// filled in by data views service
pattern: '',
indexFilter: toQuery(timeFieldName, fromDate, toDate, dslQuery),
});
+ const newFields = existingFieldList
+ .filter((field) => dataView.getFieldByName(field.name) === undefined)
+ .map((field) => dataView.getFieldByName(field.name) ?? new DataViewField(field));
+ if (newFields.length) {
+ await dataViewsService.refreshFields(dataView, false);
+ }
+ const allFields = buildFieldList(dataView, metaFields);
return {
indexPatternTitle: dataView.title,
existingFieldNames: existingFields(existingFieldList, allFields),
+ newFields,
};
}
diff --git a/packages/kbn-unified-field-list/src/services/field_existing/load_field_existing.ts b/packages/kbn-unified-field-list/src/services/field_existing/load_field_existing.ts
index 796062bc60559..889c92008554b 100644
--- a/packages/kbn-unified-field-list/src/services/field_existing/load_field_existing.ts
+++ b/packages/kbn-unified-field-list/src/services/field_existing/load_field_existing.ts
@@ -9,7 +9,7 @@
import { IUiSettingsClient } from '@kbn/core/public';
import { type DataPublicPluginStart } from '@kbn/data-plugin/public';
import { UI_SETTINGS } from '@kbn/data-service/src/constants';
-import type { DataView, DataViewsContract } from '@kbn/data-views-plugin/common';
+import type { DataView, DataViewField, DataViewsContract } from '@kbn/data-views-plugin/common';
import { lastValueFrom } from 'rxjs';
import { fetchFieldExistence } from './field_existing_utils';
@@ -27,6 +27,7 @@ interface FetchFieldExistenceParams {
export type LoadFieldExistingHandler = (params: FetchFieldExistenceParams) => Promise<{
existingFieldNames: string[];
indexPatternTitle: string;
+ newFields?: DataViewField[];
}>;
export const loadFieldExisting: LoadFieldExistingHandler = async ({
From 7b999db6641a1919a09d3ee4aec052be9d9200c6 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Fri, 1 Dec 2023 09:36:14 +0100
Subject: [PATCH 087/168] Improve code
---
.../src/hooks/use_grouped_fields.test.tsx | 3 +++
.../kbn-unified-field-list/src/hooks/use_grouped_fields.ts | 1 -
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.test.tsx b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.test.tsx
index 053e7d912d375..78b34329e0bf0 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.test.tsx
+++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.test.tsx
@@ -96,6 +96,7 @@ describe('UnifiedFieldList useGroupedFields()', () => {
? ExistenceFetchStatus.succeeded
: ExistenceFetchStatus.unknown,
isFieldsExistenceInfoUnavailable: (dataViewId) => dataViewId !== props.dataViewId,
+ getNewFields: () => [],
})
);
@@ -156,6 +157,7 @@ describe('UnifiedFieldList useGroupedFields()', () => {
? ExistenceFetchStatus.succeeded
: ExistenceFetchStatus.unknown,
isFieldsExistenceInfoUnavailable: (dataViewId) => dataViewId !== props.dataViewId,
+ getNewFields: () => [],
})
);
@@ -438,6 +440,7 @@ describe('UnifiedFieldList useGroupedFields()', () => {
? ExistenceFetchStatus.succeeded
: ExistenceFetchStatus.unknown,
isFieldsExistenceInfoUnavailable: (dataViewId) => dataViewId !== knownDataViewId,
+ getNewFields: () => [],
})
);
diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
index 7822e71244d10..731eb63dd7934 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
@@ -121,7 +121,6 @@ export function useGroupedFields({
const selectedFields = sortedSelectedFields || [];
const newFields = dataViewId ? fieldsExistenceReader.getNewFields(dataViewId) : [];
- console.log({ newFields });
const fieldsToSort =
allFields && newFields.length
? allFields.map((field) => {
From 3a6c239cb35b64871f1bea7080bec7c8183ce154 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Fri, 1 Dec 2023 09:46:44 +0100
Subject: [PATCH 088/168] Remove redundant newFieldsByFieldNameMap
---
.../kbn-unified-field-list/src/hooks/use_existing_fields.ts | 2 --
1 file changed, 2 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
index 588e0f60384b3..f756b4cc19126 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
@@ -25,7 +25,6 @@ const generateId = htmlIdGenerator();
export interface ExistingFieldsInfo {
fetchStatus: ExistenceFetchStatus;
existingFieldsByFieldNameMap: Record;
- newFieldsByFieldNameMap: Record;
newFields?: DataViewField[];
numberOfFetches: number;
hasDataViewRestrictions?: boolean;
@@ -64,7 +63,6 @@ const initialData: ExistingFieldsByDataViewMap = {};
const unknownInfo: ExistingFieldsInfo = {
fetchStatus: ExistenceFetchStatus.unknown,
existingFieldsByFieldNameMap: {},
- newFieldsByFieldNameMap: {},
numberOfFetches: 0,
};
From 3fa136908494ac59c8b0e1817550044647e819e0 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 1 Dec 2023 22:53:55 -0600
Subject: [PATCH 089/168] update setting text
---
src/plugins/data_views/server/ui_settings.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_views/server/ui_settings.ts b/src/plugins/data_views/server/ui_settings.ts
index 7e4dabc441bf9..3ba489a4b6b28 100644
--- a/src/plugins/data_views/server/ui_settings.ts
+++ b/src/plugins/data_views/server/ui_settings.ts
@@ -18,7 +18,7 @@ export const cacheMaxAge = {
value: DEFAULT_FIELD_CACHE_FRESHNESS,
description: i18n.translate('dataViews.advancedSettings.cacheMaxAgeText', {
defaultMessage:
- "Sets the 'max-age' cache header value for data view fields API requests. A value of 0 will disable caching. A hard reload of Kibana may be necessary for your browser to pick up the new setting.",
+ 'Sets how long data view fields API requests are cached in seconds. A value of 0 turns off caching. Modifying this value may not take immediate effect, users need to clear browser cache or wait until the current cache expires. To see immediate changes, try a hard reload of Kibana.',
}),
schema: schema.number(),
},
From f40eb1d6fbc46dbf8816e8c8a6f84cf12ef8113c Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 2 Dec 2023 00:28:55 -0600
Subject: [PATCH 090/168] use new method for security dependency
---
docs/concepts/data-views.asciidoc | 12 ++++++++++++
src/plugins/data_views/kibana.jsonc | 1 +
src/plugins/data_views/public/mocks.ts | 1 -
src/plugins/data_views/public/plugin.ts | 16 +++++++++++++---
src/plugins/data_views/public/types.ts | 1 -
test/functional/page_objects/settings_page.ts | 1 +
x-pack/plugins/security/public/plugin.tsx | 10 ----------
7 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/docs/concepts/data-views.asciidoc b/docs/concepts/data-views.asciidoc
index 992741be518a7..56b1df33803b3 100644
--- a/docs/concepts/data-views.asciidoc
+++ b/docs/concepts/data-views.asciidoc
@@ -172,3 +172,15 @@ WARNING: Deleting a {data-source} breaks all visualizations, saved searches, and
. Find the {data-source} that you want to delete, and then
click image:management/index-patterns/images/delete.png[Delete icon] in the *Actions* column.
+
+[float]
+[[data-view-field-cache]]
+=== {data-source} field cache
+
+The browser caches {data-source} field lists for increased performance. This is particularly impactful
+for {data-sources} with a high field count that span a large number of indices and clusters. The field
+list will be updated every couple of minutes in typical {kib} usage. Alternatively, the {data-source}
+management detail page provides a refresh button that gets an updated field list. A force reload of {kib}
+will do the same.
+
+The field list may be impacted by changes in indices and user permissions.
\ No newline at end of file
diff --git a/src/plugins/data_views/kibana.jsonc b/src/plugins/data_views/kibana.jsonc
index 7595f8e68b3c4..7789383b48ba4 100644
--- a/src/plugins/data_views/kibana.jsonc
+++ b/src/plugins/data_views/kibana.jsonc
@@ -18,6 +18,7 @@
"requiredBundles": [
"kibanaUtils"
],
+ "runtimePluginDependencies" : ["security"],
"extraPublicDirs": [
"common"
]
diff --git a/src/plugins/data_views/public/mocks.ts b/src/plugins/data_views/public/mocks.ts
index 0edea939ab8df..e9d5b487b8b00 100644
--- a/src/plugins/data_views/public/mocks.ts
+++ b/src/plugins/data_views/public/mocks.ts
@@ -13,7 +13,6 @@ export type Start = jest.Mocked>;
const createSetupContract = (): Setup => ({
enableRollups: jest.fn(),
- setUserIdGetter: jest.fn(),
});
const createStartContract = (): Start => {
diff --git a/src/plugins/data_views/public/plugin.ts b/src/plugins/data_views/public/plugin.ts
index 72603ceb8246c..6d8d2d9fde217 100644
--- a/src/plugins/data_views/public/plugin.ts
+++ b/src/plugins/data_views/public/plugin.ts
@@ -8,6 +8,7 @@
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public';
import { i18n } from '@kbn/i18n';
+import type { SecurityPluginStart } from '@kbn/security-plugin-types-public';
import { getIndexPatternLoad } from './expressions';
import type { ClientConfigType } from '../common/types';
import {
@@ -62,11 +63,20 @@ export class DataViewsPublicPlugin
}),
});
+ core.plugins.onStart<{ security: SecurityPluginStart }>('security').then(({ security }) => {
+ if (security.found) {
+ const getUserId = async function getUserId(): Promise {
+ const currentUser = await security.contract.authc.getCurrentUser();
+ return currentUser?.profile_uid;
+ };
+ this.userIdGetter = getUserId;
+ } else {
+ throw new Error('Security plugin is not available, but is required for Data Views plugin');
+ }
+ });
+
return {
enableRollups: () => (this.rollupsEnabled = true),
- setUserIdGetter: (userIdGetter: UserIdGetter) => {
- this.userIdGetter = userIdGetter;
- },
};
}
diff --git a/src/plugins/data_views/public/types.ts b/src/plugins/data_views/public/types.ts
index d01e606b968e3..98db0382f641f 100644
--- a/src/plugins/data_views/public/types.ts
+++ b/src/plugins/data_views/public/types.ts
@@ -113,7 +113,6 @@ export type UserIdGetter = () => Promise;
*/
export interface DataViewsPublicPluginSetup {
enableRollups: () => void;
- setUserIdGetter: (userIdGetter: UserIdGetter) => void;
}
export interface DataViewsServicePublic extends DataViewsServicePublicMethods {
diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts
index 6b3840faad3f4..d0994451cabdb 100644
--- a/test/functional/page_objects/settings_page.ts
+++ b/test/functional/page_objects/settings_page.ts
@@ -491,6 +491,7 @@ export class SettingsPageObject extends FtrService {
await this.testSubjects.click(`detail-link-${dataViewName}`);
}
await this.testSubjects.click('refreshDataViewButton');
+ // todo - await on refresh button being available again
}
async allowHiddenClick() {
diff --git a/x-pack/plugins/security/public/plugin.tsx b/x-pack/plugins/security/public/plugin.tsx
index 6208d487e408a..be0abf3f828b8 100644
--- a/x-pack/plugins/security/public/plugin.tsx
+++ b/x-pack/plugins/security/public/plugin.tsx
@@ -166,16 +166,6 @@ export class SecurityPlugin
this.anonymousAccessService.setup({ share });
}
- const userIdGetter = async () => {
- const [, , security] = await core.getStartServices();
- const { profile_uid: profileUid } = await (
- security as SecurityPluginStart
- ).authc.getCurrentUser();
- return profileUid;
- };
-
- dataViews?.setUserIdGetter(userIdGetter);
-
return {
authc: this.authc,
license,
From cf7c8933d74f43fa95c24c84a5760e8ac0631108 Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Sat, 2 Dec 2023 06:35:33 +0000
Subject: [PATCH 091/168] [CI] Auto-commit changed files from 'node
scripts/lint_ts_projects --fix'
---
src/plugins/data_views/tsconfig.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/plugins/data_views/tsconfig.json b/src/plugins/data_views/tsconfig.json
index e5613323bc222..1d414cb98ee95 100644
--- a/src/plugins/data_views/tsconfig.json
+++ b/src/plugins/data_views/tsconfig.json
@@ -33,6 +33,7 @@
"@kbn/object-versioning",
"@kbn/core-saved-objects-server",
"@kbn/logging",
+ "@kbn/security-plugin-types-public",
],
"exclude": [
"target/**/*",
From 9b719cc000c291fadf5d7be99ac51d77800da2d7 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 2 Dec 2023 09:58:16 -0600
Subject: [PATCH 092/168] Revert "use new method for security dependency"
This reverts commit f40eb1d6fbc46dbf8816e8c8a6f84cf12ef8113c.
---
docs/concepts/data-views.asciidoc | 12 ------------
src/plugins/data_views/kibana.jsonc | 1 -
src/plugins/data_views/public/mocks.ts | 1 +
src/plugins/data_views/public/plugin.ts | 16 +++-------------
src/plugins/data_views/public/types.ts | 1 +
test/functional/page_objects/settings_page.ts | 1 -
x-pack/plugins/security/public/plugin.tsx | 10 ++++++++++
7 files changed, 15 insertions(+), 27 deletions(-)
diff --git a/docs/concepts/data-views.asciidoc b/docs/concepts/data-views.asciidoc
index 56b1df33803b3..992741be518a7 100644
--- a/docs/concepts/data-views.asciidoc
+++ b/docs/concepts/data-views.asciidoc
@@ -172,15 +172,3 @@ WARNING: Deleting a {data-source} breaks all visualizations, saved searches, and
. Find the {data-source} that you want to delete, and then
click image:management/index-patterns/images/delete.png[Delete icon] in the *Actions* column.
-
-[float]
-[[data-view-field-cache]]
-=== {data-source} field cache
-
-The browser caches {data-source} field lists for increased performance. This is particularly impactful
-for {data-sources} with a high field count that span a large number of indices and clusters. The field
-list will be updated every couple of minutes in typical {kib} usage. Alternatively, the {data-source}
-management detail page provides a refresh button that gets an updated field list. A force reload of {kib}
-will do the same.
-
-The field list may be impacted by changes in indices and user permissions.
\ No newline at end of file
diff --git a/src/plugins/data_views/kibana.jsonc b/src/plugins/data_views/kibana.jsonc
index 7789383b48ba4..7595f8e68b3c4 100644
--- a/src/plugins/data_views/kibana.jsonc
+++ b/src/plugins/data_views/kibana.jsonc
@@ -18,7 +18,6 @@
"requiredBundles": [
"kibanaUtils"
],
- "runtimePluginDependencies" : ["security"],
"extraPublicDirs": [
"common"
]
diff --git a/src/plugins/data_views/public/mocks.ts b/src/plugins/data_views/public/mocks.ts
index e9d5b487b8b00..0edea939ab8df 100644
--- a/src/plugins/data_views/public/mocks.ts
+++ b/src/plugins/data_views/public/mocks.ts
@@ -13,6 +13,7 @@ export type Start = jest.Mocked>;
const createSetupContract = (): Setup => ({
enableRollups: jest.fn(),
+ setUserIdGetter: jest.fn(),
});
const createStartContract = (): Start => {
diff --git a/src/plugins/data_views/public/plugin.ts b/src/plugins/data_views/public/plugin.ts
index 6d8d2d9fde217..72603ceb8246c 100644
--- a/src/plugins/data_views/public/plugin.ts
+++ b/src/plugins/data_views/public/plugin.ts
@@ -8,7 +8,6 @@
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public';
import { i18n } from '@kbn/i18n';
-import type { SecurityPluginStart } from '@kbn/security-plugin-types-public';
import { getIndexPatternLoad } from './expressions';
import type { ClientConfigType } from '../common/types';
import {
@@ -63,20 +62,11 @@ export class DataViewsPublicPlugin
}),
});
- core.plugins.onStart<{ security: SecurityPluginStart }>('security').then(({ security }) => {
- if (security.found) {
- const getUserId = async function getUserId(): Promise {
- const currentUser = await security.contract.authc.getCurrentUser();
- return currentUser?.profile_uid;
- };
- this.userIdGetter = getUserId;
- } else {
- throw new Error('Security plugin is not available, but is required for Data Views plugin');
- }
- });
-
return {
enableRollups: () => (this.rollupsEnabled = true),
+ setUserIdGetter: (userIdGetter: UserIdGetter) => {
+ this.userIdGetter = userIdGetter;
+ },
};
}
diff --git a/src/plugins/data_views/public/types.ts b/src/plugins/data_views/public/types.ts
index 98db0382f641f..d01e606b968e3 100644
--- a/src/plugins/data_views/public/types.ts
+++ b/src/plugins/data_views/public/types.ts
@@ -113,6 +113,7 @@ export type UserIdGetter = () => Promise;
*/
export interface DataViewsPublicPluginSetup {
enableRollups: () => void;
+ setUserIdGetter: (userIdGetter: UserIdGetter) => void;
}
export interface DataViewsServicePublic extends DataViewsServicePublicMethods {
diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts
index d0994451cabdb..6b3840faad3f4 100644
--- a/test/functional/page_objects/settings_page.ts
+++ b/test/functional/page_objects/settings_page.ts
@@ -491,7 +491,6 @@ export class SettingsPageObject extends FtrService {
await this.testSubjects.click(`detail-link-${dataViewName}`);
}
await this.testSubjects.click('refreshDataViewButton');
- // todo - await on refresh button being available again
}
async allowHiddenClick() {
diff --git a/x-pack/plugins/security/public/plugin.tsx b/x-pack/plugins/security/public/plugin.tsx
index be0abf3f828b8..6208d487e408a 100644
--- a/x-pack/plugins/security/public/plugin.tsx
+++ b/x-pack/plugins/security/public/plugin.tsx
@@ -166,6 +166,16 @@ export class SecurityPlugin
this.anonymousAccessService.setup({ share });
}
+ const userIdGetter = async () => {
+ const [, , security] = await core.getStartServices();
+ const { profile_uid: profileUid } = await (
+ security as SecurityPluginStart
+ ).authc.getCurrentUser();
+ return profileUid;
+ };
+
+ dataViews?.setUserIdGetter(userIdGetter);
+
return {
authc: this.authc,
license,
From ccd243a663e85df5d264032766161b5d7d7f574c Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Sat, 2 Dec 2023 16:04:39 +0000
Subject: [PATCH 093/168] [CI] Auto-commit changed files from 'node
scripts/lint_ts_projects --fix'
---
src/plugins/data_views/tsconfig.json | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/plugins/data_views/tsconfig.json b/src/plugins/data_views/tsconfig.json
index 1d414cb98ee95..e5613323bc222 100644
--- a/src/plugins/data_views/tsconfig.json
+++ b/src/plugins/data_views/tsconfig.json
@@ -33,7 +33,6 @@
"@kbn/object-versioning",
"@kbn/core-saved-objects-server",
"@kbn/logging",
- "@kbn/security-plugin-types-public",
],
"exclude": [
"target/**/*",
From 9ec277309b7e60d0a9d98cba8ddcbed208b5f89b Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 2 Dec 2023 12:55:33 -0600
Subject: [PATCH 094/168] Revert "Revert "use new method for security
dependency""
This reverts commit 9b719cc000c291fadf5d7be99ac51d77800da2d7.
---
docs/concepts/data-views.asciidoc | 12 ++++++++++++
src/plugins/data_views/kibana.jsonc | 1 +
src/plugins/data_views/public/mocks.ts | 1 -
src/plugins/data_views/public/plugin.ts | 16 +++++++++++++---
src/plugins/data_views/public/types.ts | 1 -
test/functional/page_objects/settings_page.ts | 1 +
x-pack/plugins/security/public/plugin.tsx | 10 ----------
7 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/docs/concepts/data-views.asciidoc b/docs/concepts/data-views.asciidoc
index 992741be518a7..56b1df33803b3 100644
--- a/docs/concepts/data-views.asciidoc
+++ b/docs/concepts/data-views.asciidoc
@@ -172,3 +172,15 @@ WARNING: Deleting a {data-source} breaks all visualizations, saved searches, and
. Find the {data-source} that you want to delete, and then
click image:management/index-patterns/images/delete.png[Delete icon] in the *Actions* column.
+
+[float]
+[[data-view-field-cache]]
+=== {data-source} field cache
+
+The browser caches {data-source} field lists for increased performance. This is particularly impactful
+for {data-sources} with a high field count that span a large number of indices and clusters. The field
+list will be updated every couple of minutes in typical {kib} usage. Alternatively, the {data-source}
+management detail page provides a refresh button that gets an updated field list. A force reload of {kib}
+will do the same.
+
+The field list may be impacted by changes in indices and user permissions.
\ No newline at end of file
diff --git a/src/plugins/data_views/kibana.jsonc b/src/plugins/data_views/kibana.jsonc
index 7595f8e68b3c4..7789383b48ba4 100644
--- a/src/plugins/data_views/kibana.jsonc
+++ b/src/plugins/data_views/kibana.jsonc
@@ -18,6 +18,7 @@
"requiredBundles": [
"kibanaUtils"
],
+ "runtimePluginDependencies" : ["security"],
"extraPublicDirs": [
"common"
]
diff --git a/src/plugins/data_views/public/mocks.ts b/src/plugins/data_views/public/mocks.ts
index 0edea939ab8df..e9d5b487b8b00 100644
--- a/src/plugins/data_views/public/mocks.ts
+++ b/src/plugins/data_views/public/mocks.ts
@@ -13,7 +13,6 @@ export type Start = jest.Mocked>;
const createSetupContract = (): Setup => ({
enableRollups: jest.fn(),
- setUserIdGetter: jest.fn(),
});
const createStartContract = (): Start => {
diff --git a/src/plugins/data_views/public/plugin.ts b/src/plugins/data_views/public/plugin.ts
index 72603ceb8246c..6d8d2d9fde217 100644
--- a/src/plugins/data_views/public/plugin.ts
+++ b/src/plugins/data_views/public/plugin.ts
@@ -8,6 +8,7 @@
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public';
import { i18n } from '@kbn/i18n';
+import type { SecurityPluginStart } from '@kbn/security-plugin-types-public';
import { getIndexPatternLoad } from './expressions';
import type { ClientConfigType } from '../common/types';
import {
@@ -62,11 +63,20 @@ export class DataViewsPublicPlugin
}),
});
+ core.plugins.onStart<{ security: SecurityPluginStart }>('security').then(({ security }) => {
+ if (security.found) {
+ const getUserId = async function getUserId(): Promise {
+ const currentUser = await security.contract.authc.getCurrentUser();
+ return currentUser?.profile_uid;
+ };
+ this.userIdGetter = getUserId;
+ } else {
+ throw new Error('Security plugin is not available, but is required for Data Views plugin');
+ }
+ });
+
return {
enableRollups: () => (this.rollupsEnabled = true),
- setUserIdGetter: (userIdGetter: UserIdGetter) => {
- this.userIdGetter = userIdGetter;
- },
};
}
diff --git a/src/plugins/data_views/public/types.ts b/src/plugins/data_views/public/types.ts
index d01e606b968e3..98db0382f641f 100644
--- a/src/plugins/data_views/public/types.ts
+++ b/src/plugins/data_views/public/types.ts
@@ -113,7 +113,6 @@ export type UserIdGetter = () => Promise;
*/
export interface DataViewsPublicPluginSetup {
enableRollups: () => void;
- setUserIdGetter: (userIdGetter: UserIdGetter) => void;
}
export interface DataViewsServicePublic extends DataViewsServicePublicMethods {
diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts
index 6b3840faad3f4..d0994451cabdb 100644
--- a/test/functional/page_objects/settings_page.ts
+++ b/test/functional/page_objects/settings_page.ts
@@ -491,6 +491,7 @@ export class SettingsPageObject extends FtrService {
await this.testSubjects.click(`detail-link-${dataViewName}`);
}
await this.testSubjects.click('refreshDataViewButton');
+ // todo - await on refresh button being available again
}
async allowHiddenClick() {
diff --git a/x-pack/plugins/security/public/plugin.tsx b/x-pack/plugins/security/public/plugin.tsx
index 6208d487e408a..be0abf3f828b8 100644
--- a/x-pack/plugins/security/public/plugin.tsx
+++ b/x-pack/plugins/security/public/plugin.tsx
@@ -166,16 +166,6 @@ export class SecurityPlugin
this.anonymousAccessService.setup({ share });
}
- const userIdGetter = async () => {
- const [, , security] = await core.getStartServices();
- const { profile_uid: profileUid } = await (
- security as SecurityPluginStart
- ).authc.getCurrentUser();
- return profileUid;
- };
-
- dataViews?.setUserIdGetter(userIdGetter);
-
return {
authc: this.authc,
license,
From c51b7d2d7c622d2acb8683d556b708d8ab55d74f Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Sat, 2 Dec 2023 19:03:49 +0000
Subject: [PATCH 095/168] [CI] Auto-commit changed files from 'node
scripts/lint_ts_projects --fix'
---
src/plugins/data_views/tsconfig.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/plugins/data_views/tsconfig.json b/src/plugins/data_views/tsconfig.json
index e5613323bc222..1d414cb98ee95 100644
--- a/src/plugins/data_views/tsconfig.json
+++ b/src/plugins/data_views/tsconfig.json
@@ -33,6 +33,7 @@
"@kbn/object-versioning",
"@kbn/core-saved-objects-server",
"@kbn/logging",
+ "@kbn/security-plugin-types-public",
],
"exclude": [
"target/**/*",
From 6d5df9d983b37c6557ec6a0f2ff8b97c33b72928 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 2 Dec 2023 14:44:15 -0600
Subject: [PATCH 096/168] add loading text for button, better button push test
logic
---
.../edit_index_pattern/index_header/index_header.tsx | 9 +++++++--
test/functional/page_objects/settings_page.ts | 12 +++++++++++-
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
index cf1ce9faedb55..44d8888b98afc 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
@@ -58,6 +58,10 @@ const refreshLabel = i18n.translate('indexPatternManagement.editDataView.refresh
defaultMessage: 'Refresh',
});
+const isLoadingLabel = i18n.translate('indexPatternManagement.editDataView.refreshLabel', {
+ defaultMessage: 'Loading...',
+});
+
export const IndexHeader: React.FC = ({
defaultIndex,
indexPattern,
@@ -79,9 +83,10 @@ export const IndexHeader: React.FC = ({
iconType="refresh"
aria-label={refreshAriaLabel}
data-test-subj="refreshDataViewButton"
- disabled={isRefreshing}
+ isLoading={isRefreshing}
+ isDisabled={isRefreshing}
>
- {refreshLabel}
+ {isRefreshing ? isLoadingLabel : refreshLabel}
,
canSave && (
diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts
index d0994451cabdb..fde7e2343f10f 100644
--- a/test/functional/page_objects/settings_page.ts
+++ b/test/functional/page_objects/settings_page.ts
@@ -491,7 +491,17 @@ export class SettingsPageObject extends FtrService {
await this.testSubjects.click(`detail-link-${dataViewName}`);
}
await this.testSubjects.click('refreshDataViewButton');
- // todo - await on refresh button being available again
+ await this.retry.try(async () => {
+ const btn = await this.testSubjects.find('refreshDataViewButton');
+ const disabled = await btn.getAttribute('disabled');
+ expect(disabled).to.be('true');
+ });
+
+ await this.retry.try(async () => {
+ const btn = await this.testSubjects.find('refreshDataViewButton');
+ const disabled = await btn.getAttribute('disabled');
+ expect(disabled).to.be('');
+ });
}
async allowHiddenClick() {
From 3f7fb79cccb24ccab670dd3c14921eca8c2d0814 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 2 Dec 2023 17:27:02 -0600
Subject: [PATCH 097/168] fix i18n name
---
.../components/edit_index_pattern/index_header/index_header.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
index 44d8888b98afc..cd03e4b0aa54f 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
@@ -58,7 +58,7 @@ const refreshLabel = i18n.translate('indexPatternManagement.editDataView.refresh
defaultMessage: 'Refresh',
});
-const isLoadingLabel = i18n.translate('indexPatternManagement.editDataView.refreshLabel', {
+const isLoadingLabel = i18n.translate('indexPatternManagement.editDataView.refreshLoading', {
defaultMessage: 'Loading...',
});
From 3c1ab442b26beea2a67cf9141bdba5e8c229123c Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 2 Dec 2023 18:39:44 -0600
Subject: [PATCH 098/168] wait on field list refresh
---
test/functional/page_objects/settings_page.ts | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts
index fde7e2343f10f..d1c49c89923b7 100644
--- a/test/functional/page_objects/settings_page.ts
+++ b/test/functional/page_objects/settings_page.ts
@@ -491,16 +491,15 @@ export class SettingsPageObject extends FtrService {
await this.testSubjects.click(`detail-link-${dataViewName}`);
}
await this.testSubjects.click('refreshDataViewButton');
- await this.retry.try(async () => {
- const btn = await this.testSubjects.find('refreshDataViewButton');
- const disabled = await btn.getAttribute('disabled');
- expect(disabled).to.be('true');
- });
+ // wait for refresh to start
+ await new Promise((r) => setTimeout(r, 500));
+
+ // wait for refresh to finish
await this.retry.try(async () => {
const btn = await this.testSubjects.find('refreshDataViewButton');
const disabled = await btn.getAttribute('disabled');
- expect(disabled).to.be('');
+ expect(disabled).to.be(null);
});
}
From fdcd16cf44eb4c5f5ffe892960fb00e415b1b1c2 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 2 Dec 2023 18:47:08 -0600
Subject: [PATCH 099/168] add refresh button push to serverless index filter
test
---
.../common/management/data_views/_index_pattern_filter.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts
index 9da55f122114c..2dba717645ff2 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts
@@ -171,6 +171,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.clickIndexPatternLogstash();
+ await PageObjects.settings.refreshDataViewFieldList();
+
await testSubjects.existOrFail('dataViewMappingConflict');
expect(await PageObjects.settings.getFieldTypes()).to.eql([
From 53f1f19b7e7dd689e725763a9c10a623e21255b8 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 2 Dec 2023 21:24:46 -0600
Subject: [PATCH 100/168] fix ml alert test
---
.../apps/discover_ml_uptime/discover/search_source_alert.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 6b668f75d56d3..d9ed0604ff55c 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -210,6 +210,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.clickNewSearchButton(); // reset params
+ await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
+ await PageObjects.common.navigateToApp('discover');
+
await PageObjects.discover.selectIndexPattern(OUTPUT_DATA_VIEW);
let ruleId: string;
From ebd04c7088827980a7c27b714def6476ce635b3b Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 2 Dec 2023 22:29:16 -0600
Subject: [PATCH 101/168] fix discover security functional test
---
.../apps/discover/feature_controls/discover_security.ts | 3 +++
.../apps/discover_ml_uptime/discover/search_source_alert.ts | 1 +
2 files changed, 4 insertions(+)
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index ee810f7ddebfb..ef0efbcc6fb31 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -31,6 +31,7 @@ export default function (ctx: FtrProviderContext) {
'spaceSelector',
'header',
'unifiedFieldList',
+ 'settings',
]);
const testSubjects = getService('testSubjects');
const appsMenu = getService('appsMenu');
@@ -448,6 +449,8 @@ export default function (ctx: FtrProviderContext) {
await globalNav.badgeExistsOrFail('Read only');
// can't access logstash index directly
+ await PageObjects.settings.refreshDataViewFieldList('logstash-*');
+ await PageObjects.common.navigateToApp('discover');
await PageObjects.discover.selectIndexPattern('logstash-*');
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.existOrFail('discoverNoResultsCheckIndices');
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index d9ed0604ff55c..cdf25a28ad099 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -210,6 +210,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.clickNewSearchButton(); // reset params
+ // todo this didn't work
await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
await PageObjects.common.navigateToApp('discover');
From 46c9ee753b5f1cc78ed0d3e6be9537c24af3078f Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 2 Dec 2023 23:46:59 -0600
Subject: [PATCH 102/168] functional test fix attempts
---
.../apps/discover/feature_controls/discover_security.ts | 6 ++++--
.../apps/discover_ml_uptime/discover/search_source_alert.ts | 2 ++
.../test_suites/search/cases/attachment_framework.ts | 3 +++
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index ef0efbcc6fb31..d9e0834f9e2cd 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -449,8 +449,10 @@ export default function (ctx: FtrProviderContext) {
await globalNav.badgeExistsOrFail('Read only');
// can't access logstash index directly
- await PageObjects.settings.refreshDataViewFieldList('logstash-*');
- await PageObjects.common.navigateToApp('discover');
+ // swapping index patterns so we get an updated field list
+ await new Promise((resolve) => setTimeout(resolve, 5000));
+ await PageObjects.discover.selectIndexPattern('alias-logstash-discover');
+ //
await PageObjects.discover.selectIndexPattern('logstash-*');
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.existOrFail('discoverNoResultsCheckIndices');
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index cdf25a28ad099..5cdd190458f96 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -403,6 +403,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should navigate to alert results via link provided in notification', async () => {
+ // todo did this work?
+ await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
diff --git a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
index 3cf087eb1ae9b..c7252bebffd80 100644
--- a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
+++ b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
@@ -16,6 +16,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
const svlSearchNavigation = getService('svlSearchNavigation');
const svlCommonNavigation = getPageObject('svlCommonNavigation');
const svlCommonPage = getPageObject('svlCommonPage');
+ const settings = getPageObject('settings');
describe('persistable attachment', () => {
before(async () => {
@@ -33,6 +34,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json'
);
+ await settings.refreshDataViewFieldList('logstash-*');
+
await svlSearchNavigation.navigateToLandingPage();
await svlCommonNavigation.sidenav.clickLink({ deepLinkId: 'dashboards' });
From 60b0675f73e34ad45db5e8203c736ab54a549c91 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 3 Dec 2023 00:38:51 -0600
Subject: [PATCH 103/168] another attempt at fixing the discover security test
---
.../apps/discover/feature_controls/discover_security.ts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index d9e0834f9e2cd..93a62c370d561 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -452,6 +452,10 @@ export default function (ctx: FtrProviderContext) {
// swapping index patterns so we get an updated field list
await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.discover.selectIndexPattern('alias-logstash-discover');
+ await new Promise((resolve) => setTimeout(resolve, 1000));
+ await PageObjects.discover.selectIndexPattern('logstash-*');
+ await new Promise((resolve) => setTimeout(resolve, 1000));
+ await PageObjects.discover.selectIndexPattern('alias-logstash-discover');
//
await PageObjects.discover.selectIndexPattern('logstash-*');
await PageObjects.header.waitUntilLoadingHasFinished();
From b563acdd9c1c1d88ca55d9db045ed904fb6a4cd1 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 3 Dec 2023 10:03:16 -0600
Subject: [PATCH 104/168] add some debugging to hopefully help with remaining
errors
---
src/plugins/data_views/common/data_views/data_views.ts | 5 +++++
.../data_views/public/data_views/data_views_api_client.ts | 1 +
2 files changed, 6 insertions(+)
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index fd2b2b5e8d1ff..2aa28d2e3a927 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -923,6 +923,7 @@ export class DataViewsService {
displayErrors: boolean = true,
refreshFields = false
): Promise => {
+ console.log('DEBUG: get data view', id);
const dataViewFromCache = this.dataViewCache.get(id)?.then(async (dataView) => {
if (dataView && refreshFields) {
await this.refreshFields(dataView, displayErrors);
@@ -939,6 +940,10 @@ export class DataViewsService {
this.dataViewCache.clear(id);
});
+ indexPatternPromise.then((indexPattern) => {
+ console.log('DEBUG: get data view resolved', id, indexPattern.getIndexPattern());
+ });
+
return indexPatternPromise;
};
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index c65db9e5c736f..5e90cf220fc2a 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -110,6 +110,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
indexFilter ? JSON.stringify({ index_filter: indexFilter }) : undefined,
forceRefresh
).then((response) => {
+ console.log('DEBUG: api_client', pattern, JSON.stringify(response?.body, null, 2));
return {
indices: response?.body?.indices || [],
fields: response?.body?.fields || [],
From b1453754dc06a1c55011d38f67936acf69ef7e0d Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 3 Dec 2023 16:54:13 -0600
Subject: [PATCH 105/168] a little more debugging
---
.../apps/discover/feature_controls/discover_security.ts | 7 +++++--
.../discover_ml_uptime/discover/search_source_alert.ts | 9 ++++-----
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index 93a62c370d561..d8c26060716bf 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -11,6 +11,7 @@ import { getSavedQuerySecurityUtils } from '../../saved_query_management/utils/s
export default function (ctx: FtrProviderContext) {
const { getPageObjects, getService } = ctx;
+ const log = getService('log');
const savedQuerySecurityUtils = getSavedQuerySecurityUtils(ctx);
const esArchiver = getService('esArchiver');
const esSupertest = getService('esSupertest');
@@ -450,12 +451,14 @@ export default function (ctx: FtrProviderContext) {
// can't access logstash index directly
// swapping index patterns so we get an updated field list
+ log.debug('DEBUG a bunch of data view switching');
await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.discover.selectIndexPattern('alias-logstash-discover');
- await new Promise((resolve) => setTimeout(resolve, 1000));
+ await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.discover.selectIndexPattern('logstash-*');
- await new Promise((resolve) => setTimeout(resolve, 1000));
+ await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.discover.selectIndexPattern('alias-logstash-discover');
+ log.debug('DEBUG a bunch of data view switching done');
//
await PageObjects.discover.selectIndexPattern('logstash-*');
await PageObjects.header.waitUntilLoadingHasFinished();
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 5cdd190458f96..777bec2788ae0 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -209,11 +209,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.common.navigateToApp('discover');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.clickNewSearchButton(); // reset params
-
- // todo this didn't work
- await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
- await PageObjects.common.navigateToApp('discover');
-
await PageObjects.discover.selectIndexPattern(OUTPUT_DATA_VIEW);
let ruleId: string;
@@ -404,7 +399,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should navigate to alert results via link provided in notification', async () => {
// todo did this work?
+ log.debug('DATA VIEW REFRESH');
+ await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
+ await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
+ log.debug('DATA VIEW REFRESH COMPLETE');
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
From eb0604da3294423505887b488400b493969db156 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 3 Dec 2023 18:09:44 -0600
Subject: [PATCH 106/168] a little more debugging
---
.../apps/discover_ml_uptime/discover/search_source_alert.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 777bec2788ae0..2431ce7f7a6b7 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -399,11 +399,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should navigate to alert results via link provided in notification', async () => {
// todo did this work?
- log.debug('DATA VIEW REFRESH');
+ log.write('DATA VIEW REFRESH');
await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
- log.debug('DATA VIEW REFRESH COMPLETE');
+ log.write('DATA VIEW REFRESH COMPLETE');
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
From 6216b37e2f8dbde31b0422935043c462fc9332be Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 3 Dec 2023 23:52:15 -0600
Subject: [PATCH 107/168] attempt to fix lens functional test with additional
data view refresh
---
.../apps/discover_ml_uptime/discover/search_source_alert.ts | 2 ++
.../functional/test_suites/search/cases/attachment_framework.ts | 1 +
2 files changed, 3 insertions(+)
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 2431ce7f7a6b7..8b48c0e04b5b1 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -210,6 +210,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.clickNewSearchButton(); // reset params
await PageObjects.discover.selectIndexPattern(OUTPUT_DATA_VIEW);
+ // this fixed it before
+ // await PageObjects.discover.refreshFieldList();
let ruleId: string;
if (type === 'name') {
diff --git a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
index c7252bebffd80..e786f5c7e7ec8 100644
--- a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
+++ b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
@@ -34,6 +34,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json'
);
+ await settings.refreshDataViewFieldList('log*');
await settings.refreshDataViewFieldList('logstash-*');
await svlSearchNavigation.navigateToLandingPage();
From 307a16d9fb4059aad0c3aaedd4ff88c9b689754b Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Mon, 4 Dec 2023 17:06:38 +0100
Subject: [PATCH 108/168] Add multi field support
---
.../field_list_sidebar.tsx | 46 +++++++++++--------
.../src/hooks/use_grouped_fields.ts | 10 ++--
2 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
index 4bc54069336b0..e1e72ca0a9aa9 100644
--- a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
+++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
@@ -191,25 +191,6 @@ export const UnifiedFieldListSidebarComponent: React.FC {
- if (
- searchMode !== 'documents' ||
- !useNewFieldsApi ||
- stateService.creationOptions.disableMultiFieldsGroupingByParent
- ) {
- setMultiFieldsMap(undefined); // we don't have to calculate multifields in this case
- } else {
- setMultiFieldsMap(calculateMultiFields(allFields, selectedFieldsState.selectedFieldsMap));
- }
- }, [
- stateService.creationOptions.disableMultiFieldsGroupingByParent,
- selectedFieldsState.selectedFieldsMap,
- allFields,
- useNewFieldsApi,
- setMultiFieldsMap,
- searchMode,
- ]);
-
const popularFieldsLimit = useMemo(
() => core.uiSettings.get(FIELDS_LIMIT_SETTING),
[core.uiSettings]
@@ -226,7 +207,11 @@ export const UnifiedFieldListSidebarComponent: React.FC({
+ const {
+ fieldListFiltersProps,
+ fieldListGroupedProps,
+ allFields: allFieldsModified,
+ } = useGroupedFields({
dataViewId: (searchMode === 'documents' && dataView?.id) || null, // passing `null` for text-based queries
allFields,
popularFieldsLimit:
@@ -245,6 +230,27 @@ export const UnifiedFieldListSidebarComponent: React.FC {
+ if (
+ searchMode !== 'documents' ||
+ !useNewFieldsApi ||
+ stateService.creationOptions.disableMultiFieldsGroupingByParent
+ ) {
+ setMultiFieldsMap(undefined); // we don't have to calculate multifields in this case
+ } else {
+ setMultiFieldsMap(
+ calculateMultiFields(allFieldsModified, selectedFieldsState.selectedFieldsMap)
+ );
+ }
+ }, [
+ stateService.creationOptions.disableMultiFieldsGroupingByParent,
+ selectedFieldsState.selectedFieldsMap,
+ allFieldsModified,
+ useNewFieldsApi,
+ setMultiFieldsMap,
+ searchMode,
+ ]);
+
const renderFieldItem: FieldListGroupedProps['renderFieldItem'] = useCallback(
({ field, groupName, groupIndex, itemIndex, fieldSearchHighlight }) => (
diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
index 731eb63dd7934..87b9ab5187139 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
@@ -7,7 +7,7 @@
*/
import { groupBy } from 'lodash';
-import { useEffect, useMemo, useState } from 'react';
+import { useEffect, useMemo, useState, useRef } from 'react';
import { i18n } from '@kbn/i18n';
import { type CoreStart } from '@kbn/core-lifecycle-browser';
import { type DataView, type DataViewField } from '@kbn/data-views-plugin/common';
@@ -52,6 +52,7 @@ export interface GroupedFieldsResult {
fieldsExistInIndex: boolean;
screenReaderDescriptionId?: string;
};
+ allFields: T[] | null; // `null` is for loading indicator
}
export function useGroupedFields({
@@ -73,6 +74,7 @@ export function useGroupedFields({
getCustomFieldType,
onSupportedFieldFilter,
});
+ const fieldsToSort = useRef(allFields);
const onFilterFieldList = fieldListFilters.onFilterField;
const [dataView, setDataView] = useState(null);
const isAffectedByTimeFilter = Boolean(dataView?.timeFieldName);
@@ -121,13 +123,14 @@ export function useGroupedFields({
const selectedFields = sortedSelectedFields || [];
const newFields = dataViewId ? fieldsExistenceReader.getNewFields(dataViewId) : [];
- const fieldsToSort =
+ fieldsToSort.current =
allFields && newFields.length
? allFields.map((field) => {
return (dataView?.getFieldByName(field.name) as unknown as T) ?? field;
})
: allFields;
- const sortedFields = [...(fieldsToSort || [])].sort(sortFields);
+
+ const sortedFields = [...(fieldsToSort.current || [])].sort(sortFields);
const groupedFields = {
...getDefaultFieldGroups(),
@@ -391,6 +394,7 @@ export function useGroupedFields({
return {
fieldListGroupedProps,
fieldListFiltersProps: fieldListFilters.fieldListFiltersProps,
+ allFields: fieldsToSort.current,
};
}
From af83362507c45c2765bec1915b8dd8211c971496 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 5 Dec 2023 13:16:27 -0600
Subject: [PATCH 109/168] fix discover alert functional test
---
src/plugins/data_views/common/data_views/data_views.ts | 5 -----
test/functional/page_objects/settings_page.ts | 3 +--
.../discover_ml_uptime/discover/search_source_alert.ts | 9 +--------
.../discover_ml_uptime/discover/search_source_alert.ts | 8 ++++++--
4 files changed, 8 insertions(+), 17 deletions(-)
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index 2aa28d2e3a927..fd2b2b5e8d1ff 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -923,7 +923,6 @@ export class DataViewsService {
displayErrors: boolean = true,
refreshFields = false
): Promise => {
- console.log('DEBUG: get data view', id);
const dataViewFromCache = this.dataViewCache.get(id)?.then(async (dataView) => {
if (dataView && refreshFields) {
await this.refreshFields(dataView, displayErrors);
@@ -940,10 +939,6 @@ export class DataViewsService {
this.dataViewCache.clear(id);
});
- indexPatternPromise.then((indexPattern) => {
- console.log('DEBUG: get data view resolved', id, indexPattern.getIndexPattern());
- });
-
return indexPatternPromise;
};
diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts
index d1c49c89923b7..92b6a4eebf3a8 100644
--- a/test/functional/page_objects/settings_page.ts
+++ b/test/functional/page_objects/settings_page.ts
@@ -485,8 +485,7 @@ export class SettingsPageObject extends FtrService {
async refreshDataViewFieldList(dataViewName?: string) {
if (dataViewName) {
- await this.navigateTo();
- await this.clickKibanaIndexPatterns();
+ await this.common.navigateToApp('management/kibana/dataViews');
await this.header.waitUntilLoadingHasFinished();
await this.testSubjects.click(`detail-link-${dataViewName}`);
}
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 8b48c0e04b5b1..6b668f75d56d3 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -209,9 +209,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.common.navigateToApp('discover');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.clickNewSearchButton(); // reset params
+
await PageObjects.discover.selectIndexPattern(OUTPUT_DATA_VIEW);
- // this fixed it before
- // await PageObjects.discover.refreshFieldList();
let ruleId: string;
if (type === 'name') {
@@ -400,12 +399,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should navigate to alert results via link provided in notification', async () => {
- // todo did this work?
- log.write('DATA VIEW REFRESH');
- await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
- await new Promise((resolve) => setTimeout(resolve, 5000));
- await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
- log.write('DATA VIEW REFRESH COMPLETE');
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
diff --git a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
index f683e02237996..3c431190c8abb 100644
--- a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
@@ -238,6 +238,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
};
const openAlertResults = async (value: string, type: 'id' | 'name' = 'name') => {
+ await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
await PageObjects.common.navigateToApp('discover');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.clickNewSearchButton(); // reset params
@@ -378,9 +379,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// should not have data view selected by default
const dataViewSelector = await testSubjects.find('selectDataViewExpression');
- // TODO: Serverless Security has an existing data view by default
+ // TODO: Serverless Security and Search have an existing data view by default
const dataViewSelectorText = await dataViewSelector.getVisibleText();
- if (!dataViewSelectorText.includes('.alerts-security')) {
+ if (
+ !dataViewSelectorText.includes('.alerts-security') &&
+ !dataViewSelectorText.includes('default:all-data')
+ ) {
expect(await dataViewSelector.getVisibleText()).to.eql('DATA VIEW\nSelect a data view');
}
From 1d0dcd5e788a73b39a4918058ac548e2118e00e5 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 5 Dec 2023 21:00:52 -0600
Subject: [PATCH 110/168] get fresh field list vith data view swapping.
---
.../apps/discover/feature_controls/discover_security.ts | 8 ++++----
.../discover_ml_uptime/discover/search_source_alert.ts | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index d8c26060716bf..be105c4467696 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -11,7 +11,6 @@ import { getSavedQuerySecurityUtils } from '../../saved_query_management/utils/s
export default function (ctx: FtrProviderContext) {
const { getPageObjects, getService } = ctx;
- const log = getService('log');
const savedQuerySecurityUtils = getSavedQuerySecurityUtils(ctx);
const esArchiver = getService('esArchiver');
const esSupertest = getService('esSupertest');
@@ -451,15 +450,16 @@ export default function (ctx: FtrProviderContext) {
// can't access logstash index directly
// swapping index patterns so we get an updated field list
- log.debug('DEBUG a bunch of data view switching');
+ await new Promise((resolve) => setTimeout(resolve, 5000));
+ await PageObjects.discover.selectIndexPattern('logstash-*');
await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.discover.selectIndexPattern('alias-logstash-discover');
await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.discover.selectIndexPattern('logstash-*');
await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.discover.selectIndexPattern('alias-logstash-discover');
- log.debug('DEBUG a bunch of data view switching done');
- //
+
+ await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.discover.selectIndexPattern('logstash-*');
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.existOrFail('discoverNoResultsCheckIndices');
diff --git a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
index 3c431190c8abb..ef9a62018fbe7 100644
--- a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
@@ -238,8 +238,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
};
const openAlertResults = async (value: string, type: 'id' | 'name' = 'name') => {
- await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
- await PageObjects.common.navigateToApp('discover');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.clickNewSearchButton(); // reset params
@@ -448,6 +446,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should navigate to alert results via link provided in notification', async () => {
+ await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
+ await PageObjects.common.navigateToApp('discover');
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
From 797f6ce508c71c832292e868f6aa1015427af415 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 5 Dec 2023 22:31:39 -0600
Subject: [PATCH 111/168] fix discover alert functional test
---
.../common/discover_ml_uptime/discover/search_source_alert.ts | 2 +-
.../test_suites/search/cases/attachment_framework.ts | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
index ef9a62018fbe7..d2e8f863d5fe9 100644
--- a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
@@ -238,6 +238,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
};
const openAlertResults = async (value: string, type: 'id' | 'name' = 'name') => {
+ await PageObjects.common.navigateToApp('discover');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.clickNewSearchButton(); // reset params
@@ -447,7 +448,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should navigate to alert results via link provided in notification', async () => {
await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
- await PageObjects.common.navigateToApp('discover');
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
diff --git a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
index e786f5c7e7ec8..26e0812400283 100644
--- a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
+++ b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
@@ -16,7 +16,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
const svlSearchNavigation = getService('svlSearchNavigation');
const svlCommonNavigation = getPageObject('svlCommonNavigation');
const svlCommonPage = getPageObject('svlCommonPage');
- const settings = getPageObject('settings');
+ // const settings = getPageObject('settings');
describe('persistable attachment', () => {
before(async () => {
@@ -34,8 +34,10 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json'
);
+ /*
await settings.refreshDataViewFieldList('log*');
await settings.refreshDataViewFieldList('logstash-*');
+ */
await svlSearchNavigation.navigateToLandingPage();
From 913bedbc3fdc7545861f3553f8d85c2670b70891 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 5 Dec 2023 23:34:37 -0600
Subject: [PATCH 112/168] fix discover alert functional test
---
.../apps/discover_ml_uptime/discover/search_source_alert.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 6b668f75d56d3..bffa564fba774 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -399,6 +399,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should navigate to alert results via link provided in notification', async () => {
+ await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
From 3f58ecdc347c9ab7da118b3e3bb8972126d3dea6 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 6 Dec 2023 15:49:58 -0600
Subject: [PATCH 113/168] fix functional test
---
.../data_views/public/data_views/data_views_api_client.ts | 1 -
.../test_suites/search/cases/attachment_framework.ts | 7 ++-----
2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index 5e90cf220fc2a..c65db9e5c736f 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -110,7 +110,6 @@ export class DataViewsApiClient implements IDataViewsApiClient {
indexFilter ? JSON.stringify({ index_filter: indexFilter }) : undefined,
forceRefresh
).then((response) => {
- console.log('DEBUG: api_client', pattern, JSON.stringify(response?.body, null, 2));
return {
indices: response?.body?.indices || [],
fields: response?.body?.fields || [],
diff --git a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
index 26e0812400283..e74262f60ac3e 100644
--- a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
+++ b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
@@ -16,7 +16,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
const svlSearchNavigation = getService('svlSearchNavigation');
const svlCommonNavigation = getPageObject('svlCommonNavigation');
const svlCommonPage = getPageObject('svlCommonPage');
- // const settings = getPageObject('settings');
+ const settings = getPageObject('settings');
describe('persistable attachment', () => {
before(async () => {
@@ -34,10 +34,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json'
);
- /*
- await settings.refreshDataViewFieldList('log*');
- await settings.refreshDataViewFieldList('logstash-*');
- */
+ await settings.refreshDataViewFieldList('default:all-data');
await svlSearchNavigation.navigateToLandingPage();
From 08a3ea8ea313198004d19dd4e83ea1da73a51d9c Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Wed, 6 Dec 2023 17:59:31 -0600
Subject: [PATCH 114/168] cleanup
---
src/plugins/data_views/common/data_views/data_views.ts | 2 +-
.../apps/discover/feature_controls/discover_security.ts | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index fd2b2b5e8d1ff..f694bcccb9009 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -544,7 +544,7 @@ export class DataViewsService {
forceRefresh: boolean = false
) => {
const metaFields = await this.config.get(META_FIELDS);
- return await this.apiClient.getFieldsForWildcard({
+ return this.apiClient.getFieldsForWildcard({
type: dataView.type,
rollupIndex: dataView?.typeMeta?.params?.rollup_index,
allowNoIndex: true,
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index be105c4467696..0db9064f9cc4e 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -450,6 +450,8 @@ export default function (ctx: FtrProviderContext) {
// can't access logstash index directly
// swapping index patterns so we get an updated field list
+ // this is necessary since we don't have access to data view management
+ // nor can we force reload the browser in a test
await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.discover.selectIndexPattern('logstash-*');
await new Promise((resolve) => setTimeout(resolve, 5000));
From b73f727e7dad44f31597721aea0382ef3a615adb Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Thu, 7 Dec 2023 15:33:55 -0600
Subject: [PATCH 115/168] Update docs/concepts/data-views.asciidoc
Co-authored-by: amyjtechwriter <61687663+amyjtechwriter@users.noreply.github.com>
---
docs/concepts/data-views.asciidoc | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/docs/concepts/data-views.asciidoc b/docs/concepts/data-views.asciidoc
index 56b1df33803b3..2eba42aed3051 100644
--- a/docs/concepts/data-views.asciidoc
+++ b/docs/concepts/data-views.asciidoc
@@ -179,8 +179,7 @@ click image:management/index-patterns/images/delete.png[Delete icon] in the *Act
The browser caches {data-source} field lists for increased performance. This is particularly impactful
for {data-sources} with a high field count that span a large number of indices and clusters. The field
-list will be updated every couple of minutes in typical {kib} usage. Alternatively, the {data-source}
-management detail page provides a refresh button that gets an updated field list. A force reload of {kib}
-will do the same.
+list is updated every couple of minutes in typical {kib} usage. Alternatively, use the refresh button on the {data-source}
+management detail page to get an updated field list. A force reload of {kib} has the same effect.
The field list may be impacted by changes in indices and user permissions.
\ No newline at end of file
From 9c4e41679d47479f191f24219a5c76ca501f051d Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Thu, 7 Dec 2023 19:57:56 -0600
Subject: [PATCH 116/168] better rendering of refresh button
---
.../index_header/index_header.tsx | 25 ++++++++++---------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
index cd03e4b0aa54f..8a3792c6fb333 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
@@ -77,28 +77,29 @@ export const IndexHeader: React.FC = ({
{indexPattern.getName()}}
rightSideItems={[
- {refreshTooltip}}>
-
- {isRefreshing ? isLoadingLabel : refreshLabel}
-
- ,
canSave && (
{editTooltip}
),
+ {refreshTooltip}}>
+
+ {isRefreshing ? isLoadingLabel : refreshLabel}
+
+ ,
defaultIndex !== indexPattern.id && setDefault && canSave && indexPattern.isPersisted() && (
Date: Sat, 9 Dec 2023 14:30:04 +0100
Subject: [PATCH 117/168] Add support for Lens
---
.../src/hooks/use_grouped_fields.ts | 36 ++++++++++++-------
.../datasources/form_based/datapanel.tsx | 32 ++++++++++-------
.../datasources/text_based/datapanel.tsx | 2 ++
3 files changed, 46 insertions(+), 24 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
index 87b9ab5187139..8da8646da8e5c 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
@@ -41,6 +41,7 @@ export interface GroupedFieldsParams {
onOverrideFieldGroupDetails?: OverrideFieldGroupDetails;
onSupportedFieldFilter?: (field: T) => boolean;
onSelectedFieldFilter?: (field: T) => boolean;
+ isCompatibleField?: (fields: DataViewField) => boolean;
}
export interface GroupedFieldsResult {
@@ -53,6 +54,7 @@ export interface GroupedFieldsResult {
screenReaderDescriptionId?: string;
};
allFields: T[] | null; // `null` is for loading indicator
+ hasNewFields: boolean;
}
export function useGroupedFields({
@@ -66,6 +68,7 @@ export function useGroupedFields({
onOverrideFieldGroupDetails,
onSupportedFieldFilter,
onSelectedFieldFilter,
+ isCompatibleField,
}: GroupedFieldsParams): GroupedFieldsResult {
const fieldsExistenceReader = useExistingFieldsReader();
const fieldListFilters = useFieldFilters({
@@ -74,7 +77,8 @@ export function useGroupedFields({
getCustomFieldType,
onSupportedFieldFilter,
});
- const fieldsToSort = useRef(allFields);
+ const allFieldsInclNew = useRef(allFields);
+ const hasNewFields = useRef(false);
const onFilterFieldList = fieldListFilters.onFilterField;
const [dataView, setDataView] = useState(null);
const isAffectedByTimeFilter = Boolean(dataView?.timeFieldName);
@@ -122,16 +126,23 @@ export function useGroupedFields({
};
const selectedFields = sortedSelectedFields || [];
- const newFields = dataViewId ? fieldsExistenceReader.getNewFields(dataViewId) : [];
- fieldsToSort.current =
- allFields && newFields.length
- ? allFields.map((field) => {
- return (dataView?.getFieldByName(field.name) as unknown as T) ?? field;
- })
- : allFields;
-
- const sortedFields = [...(fieldsToSort.current || [])].sort(sortFields);
+ const newFields = dataViewId
+ ? fieldsExistenceReader
+ .getNewFields(dataViewId)
+ .filter((field) => (isCompatibleField ? isCompatibleField(field) : true))
+ : [];
+ // remove fields from allFields that are available in newFields, because they can be provided in unmapped state
+ const allFieldsWithoutNewFields = !newFields.length
+ ? allFields
+ : allFields?.filter((field) => !newFields.find((newField) => newField.name === field.name));
+ // append new fields to the end of the list allFieldsWithoutNewFields
+ const allFieldsWithNewFields = allFieldsWithoutNewFields
+ ? [...allFieldsWithoutNewFields, ...newFields]
+ : newFields;
+ const sortedFields = [...((allFieldsWithNewFields as unknown as T[]) || [])].sort(sortFields);
+ allFieldsInclNew.current = sortedFields;
+ hasNewFields.current = Boolean(newFields.length);
const groupedFields = {
...getDefaultFieldGroups(),
...groupBy(sortedFields, (field) => {
@@ -336,6 +347,7 @@ export function useGroupedFields({
onSelectedFieldFilter,
onSupportedFieldFilter,
dataView,
+ isCompatibleField,
]);
const fieldGroups: FieldListGroups = useMemo(() => {
@@ -394,7 +406,8 @@ export function useGroupedFields({
return {
fieldListGroupedProps,
fieldListFiltersProps: fieldListFilters.fieldListFiltersProps,
- allFields: fieldsToSort.current,
+ allFields: allFieldsInclNew.current,
+ hasNewFields: hasNewFields.current,
};
}
@@ -417,6 +430,5 @@ function getDefaultFieldGroups() {
metaFields: [],
unmappedFields: [],
skippedFields: [],
- newFields: [],
};
}
diff --git a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
index 53a26693b7a7a..58c4e1bddaa27 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
+++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
@@ -28,6 +28,7 @@ import {
useGroupedFields,
} from '@kbn/unified-field-list';
import { ChartsPluginSetup } from '@kbn/charts-plugin/public';
+import { isFieldLensCompatible } from '@kbn/visualization-ui-components';
import type {
DatasourceDataPanelProps,
FramePublicAPI,
@@ -249,18 +250,20 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
}
}, []);
- const { fieldListFiltersProps, fieldListGroupedProps } = useGroupedFields({
- dataViewId: currentIndexPatternId,
- allFields,
- services: {
- dataViews,
- core,
- },
- isAffectedByGlobalFilter: Boolean(filters.length),
- onSupportedFieldFilter,
- onSelectedFieldFilter,
- onOverrideFieldGroupDetails,
- });
+ const { fieldListFiltersProps, fieldListGroupedProps, hasNewFields } =
+ useGroupedFields({
+ dataViewId: currentIndexPatternId,
+ allFields,
+ services: {
+ dataViews,
+ core,
+ },
+ isAffectedByGlobalFilter: Boolean(filters.length),
+ onSupportedFieldFilter,
+ onSelectedFieldFilter,
+ onOverrideFieldGroupDetails,
+ isCompatibleField: isFieldLensCompatible,
+ });
const closeFieldEditor = useRef<() => void | undefined>();
@@ -296,6 +299,11 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
frame.dataViews.indexPatterns,
data.search.session,
]);
+ useEffect(() => {
+ if (hasNewFields) {
+ refreshFieldList();
+ }
+ }, [hasNewFields, refreshFieldList]);
const editField = useMemo(
() =>
diff --git a/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx
index 113125484cddf..ac62636ad50c1 100644
--- a/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx
+++ b/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx
@@ -24,6 +24,7 @@ import {
GetCustomFieldType,
useGroupedFields,
} from '@kbn/unified-field-list';
+import { isFieldLensCompatible } from '@kbn/visualization-ui-components';
import type { DatasourceDataPanelProps } from '../../types';
import type { TextBasedPrivateState } from './types';
import { getStateFromAggregateQuery } from './utils';
@@ -105,6 +106,7 @@ export function TextBasedDataPanel({
getCustomFieldType,
onSelectedFieldFilter,
onOverrideFieldGroupDetails,
+ isCompatibleField: isFieldLensCompatible,
});
const renderFieldItem: FieldListGroupedProps['renderFieldItem'] = useCallback(
From dc9fa0e12261039dc72942708d3ec422ebe02d90 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 10 Dec 2023 22:08:21 -0600
Subject: [PATCH 118/168] cleanup
---
.../components/edit_index_pattern/edit_index_pattern.tsx | 1 -
x-pack/plugins/security/public/plugin.tsx | 8 ++------
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
index 839d04665ae09..20855e4dbbc0c 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
@@ -252,7 +252,6 @@ export const EditIndexPattern = withRouter(
refreshIndexPatternClick={async () => {
setIsRefreshing(true);
await dataViews.refreshFields(indexPattern, false, true);
- setFields(indexPattern.getNonScriptedFields());
setRefreshCount(refreshCount + 1); // rerender field list
setIsRefreshing(false);
}}
diff --git a/x-pack/plugins/security/public/plugin.tsx b/x-pack/plugins/security/public/plugin.tsx
index be0abf3f828b8..1927ebb21d8e1 100644
--- a/x-pack/plugins/security/public/plugin.tsx
+++ b/x-pack/plugins/security/public/plugin.tsx
@@ -13,10 +13,7 @@ import type {
Plugin,
PluginInitializerContext,
} from '@kbn/core/public';
-import type {
- DataViewsPublicPluginSetup,
- DataViewsPublicPluginStart,
-} from '@kbn/data-views-plugin/public';
+import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import type { FeaturesPluginStart } from '@kbn/features-plugin/public';
import type { HomePublicPluginSetup } from '@kbn/home-plugin/public';
import { i18n } from '@kbn/i18n';
@@ -51,7 +48,6 @@ export interface PluginSetupDependencies {
management?: ManagementSetup;
share?: SharePluginSetup;
cloud?: CloudSetup;
- dataViews?: DataViewsPublicPluginSetup;
}
export interface PluginStartDependencies {
@@ -94,7 +90,7 @@ export class SecurityPlugin
public setup(
core: CoreSetup,
- { cloud, home, licensing, management, share, dataViews }: PluginSetupDependencies
+ { cloud, home, licensing, management, share }: PluginSetupDependencies
): SecurityPluginSetup {
const { license } = this.securityLicenseService.setup({ license$: licensing.license$ });
From 985ed118d81d1394ae6a182cf74e1b8bf0e29f09 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Mon, 11 Dec 2023 08:09:46 -0600
Subject: [PATCH 119/168] better caching, add tests
---
.../common/data_views/data_views.test.ts | 13 +++++++
.../common/data_views/data_views.ts | 6 ++--
.../server/rest_api_routes/internal/fields.ts | 10 ++++--
.../apis/data_views/fields_route/cache.ts | 34 +++++++++++++++++++
4 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/src/plugins/data_views/common/data_views/data_views.test.ts b/src/plugins/data_views/common/data_views/data_views.test.ts
index e95e5c6736d17..4d0fa196e9ccc 100644
--- a/src/plugins/data_views/common/data_views/data_views.test.ts
+++ b/src/plugins/data_views/common/data_views/data_views.test.ts
@@ -158,10 +158,23 @@ describe('IndexPatterns', () => {
test('force field refresh', async () => {
const id = '1';
+ // make sure initial load and subsequent reloads use same params
+ const args = {
+ allowHidden: undefined,
+ allowNoIndex: true,
+ indexFilter: undefined,
+ metaFields: false,
+ pattern: 'something',
+ rollupIndex: undefined,
+ type: undefined,
+ };
+
await indexPatterns.get(id);
expect(apiClient.getFieldsForWildcard).toBeCalledTimes(1);
+ expect(apiClient.getFieldsForWildcard).toBeCalledWith(args);
await indexPatterns.get(id, undefined, true);
expect(apiClient.getFieldsForWildcard).toBeCalledTimes(2);
+ expect(apiClient.getFieldsForWildcard).toBeCalledWith(args);
});
test('getFieldsForWildcard called with allowNoIndex set to true as default ', async () => {
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index f694bcccb9009..dfdb8025b182c 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -536,7 +536,9 @@ export class DataViewsService {
...options,
pattern: indexPattern.title as string,
allowHidden:
- (indexPattern as DataViewSpec).allowHidden || (indexPattern as DataView)?.getAllowHidden(),
+ (indexPattern as DataViewSpec).allowHidden ||
+ (indexPattern as DataView)?.getAllowHidden() ||
+ undefined,
});
private getFieldsAndIndicesForDataView = async (
@@ -551,7 +553,7 @@ export class DataViewsService {
pattern: dataView.getIndexPattern(),
metaFields,
forceRefresh,
- allowHidden: dataView.getAllowHidden(),
+ allowHidden: dataView.getAllowHidden() || undefined,
});
};
diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
index 454035f3b812f..cee8efc8b6d1d 100644
--- a/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
+++ b/src/plugins/data_views/server/rest_api_routes/internal/fields.ts
@@ -78,9 +78,13 @@ const handler: (isRollupsEnabled: () => boolean) => RequestHandler<{}, IQuery, I
};
// field cache is configurable in classic environment but not on serverless
- const cacheMaxAge =
- (await uiSettings.get('data_views:cache_max_age')) ||
- DEFAULT_FIELD_CACHE_FRESHNESS;
+ let cacheMaxAge = DEFAULT_FIELD_CACHE_FRESHNESS;
+ const cacheMaxAgeSetting = await uiSettings.get(
+ 'data_views:cache_max_age'
+ );
+ if (cacheMaxAgeSetting !== undefined) {
+ cacheMaxAge = cacheMaxAgeSetting;
+ }
if (cacheMaxAge && fields.length) {
const stale = 365 * 24 * 60 * 60 - cacheMaxAge;
diff --git a/test/api_integration/apis/data_views/fields_route/cache.ts b/test/api_integration/apis/data_views/fields_route/cache.ts
index 978c048ee8b8e..c97be4b7411f3 100644
--- a/test/api_integration/apis/data_views/fields_route/cache.ts
+++ b/test/api_integration/apis/data_views/fields_route/cache.ts
@@ -14,6 +14,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
+ const kibanaServer = getService('kibanaServer');
describe('cache headers', () => {
before(() =>
@@ -32,12 +33,34 @@ export default function ({ getService }: FtrProviderContext) {
const cacheControlHeader = response.get('cache-control');
+ expect(cacheControlHeader).to.contain('private');
expect(cacheControlHeader).to.contain('max-age');
expect(cacheControlHeader).to.contain('stale-while-revalidate');
expect(response.get('vary')).to.equal('accept-encoding, user-hash');
expect(response.get('etag')).to.not.be.empty();
});
+ it('no-cache when data_views:cache_max_age set to zero', async () => {
+ await kibanaServer.uiSettings.update({ 'data_views:cache_max_age': 0 });
+
+ const response = await supertest.get(FIELDS_PATH).query({
+ pattern: 'b*',
+ include_unmapped: true,
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
+ });
+
+ const cacheControlHeader = response.get('cache-control');
+
+ expect(cacheControlHeader).to.contain('private');
+ expect(cacheControlHeader).to.contain('no-cache');
+ expect(cacheControlHeader).to.not.contain('max-age');
+ expect(cacheControlHeader).to.not.contain('stale-while-revalidate');
+ expect(response.get('vary')).to.equal('accept-encoding, user-hash');
+ expect(response.get('etag')).to.not.be.empty();
+
+ kibanaServer.uiSettings.replace({ 'data_views:cache_max_age': 5 });
+ });
+
it('returns 304 on matching etag', async () => {
const response = await supertest.get(FIELDS_PATH).query({
pattern: '*',
@@ -55,5 +78,16 @@ export default function ({ getService }: FtrProviderContext) {
})
.expect(304);
});
+
+ it('handles empty field lists', async () => {
+ const response = await supertest.get(FIELDS_PATH).query({
+ pattern: 'xyz',
+ include_unmapped: true,
+ apiVersion: INITIAL_REST_VERSION_INTERNAL,
+ allow_no_index: true,
+ });
+
+ expect(response.body.fields).to.be.empty();
+ });
});
}
From 15cc582977bb76e683d223e8a9167add0264471d Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Wed, 13 Dec 2023 19:11:49 +0100
Subject: [PATCH 120/168] Add functional test
---
.../discover/group4/_field_list_new_fields.ts | 86 +++++++++++++++++++
test/functional/apps/discover/group4/index.ts | 1 +
2 files changed, 87 insertions(+)
create mode 100644 test/functional/apps/discover/group4/_field_list_new_fields.ts
diff --git a/test/functional/apps/discover/group4/_field_list_new_fields.ts b/test/functional/apps/discover/group4/_field_list_new_fields.ts
new file mode 100644
index 0000000000000..3c24bcf613ae4
--- /dev/null
+++ b/test/functional/apps/discover/group4/_field_list_new_fields.ts
@@ -0,0 +1,86 @@
+/*
+ * 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 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 or the Server
+ * Side Public License, v 1.
+ */
+
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../ftr_provider_context';
+
+export default function ({ getService, getPageObjects }: FtrProviderContext) {
+ const esArchiver = getService('esArchiver');
+ const kibanaServer = getService('kibanaServer');
+ const security = getService('security');
+ const es = getService('es');
+ const retry = getService('retry');
+ const queryBar = getService('queryBar');
+ const PageObjects = getPageObjects(['common', 'discover', 'timePicker', 'unifiedFieldList']);
+
+ describe('Field list new fields in background handling', function () {
+ before(async () => {
+ await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']);
+ await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover.json');
+ await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional');
+
+ await PageObjects.common.navigateToApp('discover');
+ await PageObjects.timePicker.setCommonlyUsedTime('This_week');
+ });
+
+ after(async () => {
+ await kibanaServer.savedObjects.cleanStandardList();
+ await esArchiver.unload('x-pack/test/functional/es_archives/logstash_functional');
+ await es.transport.request({
+ path: '/my-index-000001',
+ method: 'DELETE',
+ });
+ });
+
+ it('Check that new ingested fields are added to the available fields section', async function () {
+ const initialPattern = 'my-index-';
+ await es.transport.request({
+ path: '/my-index-000001/_doc',
+ method: 'POST',
+ body: {
+ '@timestamp': new Date().toISOString(),
+ a: 'GET /search HTTP/1.1 200 1070000',
+ },
+ });
+
+ await PageObjects.discover.createAdHocDataView(initialPattern, true);
+
+ await retry.waitFor('current data view to get updated', async () => {
+ return (await PageObjects.discover.getCurrentlySelectedDataView()) === `${initialPattern}*`;
+ });
+ await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
+
+ expect(await PageObjects.discover.getHitCountInt()).to.be(1);
+ expect(await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('available')).to.eql([
+ '@timestamp',
+ 'a',
+ ]);
+
+ await es.transport.request({
+ path: '/my-index-000001/_doc',
+ method: 'POST',
+ body: {
+ '@timestamp': new Date().toISOString(),
+ b: 'GET /search HTTP/1.1 200 1070000',
+ },
+ });
+
+ await retry.waitFor('the new record was found', async () => {
+ await queryBar.submitQuery();
+ await PageObjects.unifiedFieldList.waitUntilSidebarHasLoaded();
+ return (await PageObjects.discover.getHitCountInt()) === 2;
+ });
+
+ expect(await PageObjects.unifiedFieldList.getSidebarSectionFieldNames('available')).to.eql([
+ '@timestamp',
+ 'a',
+ 'b',
+ ]);
+ });
+ });
+}
diff --git a/test/functional/apps/discover/group4/index.ts b/test/functional/apps/discover/group4/index.ts
index 1aab3db2bfc43..656a116551db8 100644
--- a/test/functional/apps/discover/group4/index.ts
+++ b/test/functional/apps/discover/group4/index.ts
@@ -33,5 +33,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./_context_encoded_url_params'));
loadTestFile(require.resolve('./_hide_announcements'));
loadTestFile(require.resolve('./_data_view_edit'));
+ loadTestFile(require.resolve('./_field_list_new_fields'));
});
}
From 065a50c9da9b3e1ae2e3c6e2aa4abf38d6e97acf Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Thu, 14 Dec 2023 06:06:19 +0100
Subject: [PATCH 121/168] Add documentation
---
.../src/services/field_existing/field_existing_utils.ts | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
index 0a487368748cf..e4dab136c5a52 100644
--- a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
+++ b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
@@ -54,15 +54,20 @@ export async function fetchFieldExistence({
pattern: '',
indexFilter: toQuery(timeFieldName, fromDate, toDate, dslQuery),
});
+
+ // take care of fields of existingFieldList, that are not yet available
+ // in the given data view. Those fields we consider as new fields,
+ // that were ingested after the data view was loaded
const newFields = existingFieldList
.filter((field) => dataView.getFieldByName(field.name) === undefined)
.map((field) => dataView.getFieldByName(field.name) ?? new DataViewField(field));
+ // refresh the data view in case there are new fields
if (newFields.length) {
await dataViewsService.refreshFields(dataView, false);
}
const allFields = buildFieldList(dataView, metaFields);
return {
- indexPatternTitle: dataView.title,
+ indexPatternTitle: dataView.getIndexPattern(),
existingFieldNames: existingFields(existingFieldList, allFields),
newFields,
};
From e9fd00eecc06b6cc287c039d302e307fec9c7831 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Thu, 14 Dec 2023 10:12:32 +0100
Subject: [PATCH 122/168] Improve code
---
.../src/hooks/use_grouped_fields.ts | 30 +++++++++----------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
index 8da8646da8e5c..c079b6b9503e9 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
@@ -77,7 +77,7 @@ export function useGroupedFields({
getCustomFieldType,
onSupportedFieldFilter,
});
- const allFieldsInclNew = useRef(allFields);
+ const allFieldsToReturn = useRef(allFields);
const hasNewFields = useRef(false);
const onFilterFieldList = fieldListFilters.onFilterField;
const [dataView, setDataView] = useState(null);
@@ -126,22 +126,22 @@ export function useGroupedFields({
};
const selectedFields = sortedSelectedFields || [];
+
+ // Taking care of new fields that were ingested after the selected data view was loaded
+ // Those replace existing fields if updated, or are added to the list
const newFields = dataViewId
- ? fieldsExistenceReader
- .getNewFields(dataViewId)
- .filter((field) => (isCompatibleField ? isCompatibleField(field) : true))
+ ? fieldsExistenceReader.getNewFields(dataViewId).filter(isCompatibleField || (() => true))
+ : [];
+ // Filtering out fields that e.g. Discover provides by analyzing the resultset, that are not part of the loaded DataView
+ // These can be replaced by the new fields, which are mapped correctly, and therefore can be used in the right way
+ const allFieldsExlNew = allFields
+ ? allFields.filter((field) => !newFields.some((newField) => newField.name === field.name))
: [];
- // remove fields from allFields that are available in newFields, because they can be provided in unmapped state
- const allFieldsWithoutNewFields = !newFields.length
- ? allFields
- : allFields?.filter((field) => !newFields.find((newField) => newField.name === field.name));
- // append new fields to the end of the list allFieldsWithoutNewFields
- const allFieldsWithNewFields = allFieldsWithoutNewFields
- ? [...allFieldsWithoutNewFields, ...newFields]
- : newFields;
- const sortedFields = [...((allFieldsWithNewFields as unknown as T[]) || [])].sort(sortFields);
- allFieldsInclNew.current = sortedFields;
+ const allFieldsInclNew = [...allFieldsExlNew, ...newFields] as unknown as T[];
+
+ const sortedFields = allFieldsInclNew.sort(sortFields);
+ allFieldsToReturn.current = sortedFields;
hasNewFields.current = Boolean(newFields.length);
const groupedFields = {
...getDefaultFieldGroups(),
@@ -406,7 +406,7 @@ export function useGroupedFields({
return {
fieldListGroupedProps,
fieldListFiltersProps: fieldListFilters.fieldListFiltersProps,
- allFields: allFieldsInclNew.current,
+ allFields: allFieldsToReturn.current,
hasNewFields: hasNewFields.current,
};
}
From 454592c884f3194c9149296feb6740e652c14417 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Fri, 15 Dec 2023 09:45:19 +0100
Subject: [PATCH 123/168] Add Lens test
---
.../apps/lens/group2/fields_list.ts | 50 ++++++++++++++++++-
1 file changed, 48 insertions(+), 2 deletions(-)
diff --git a/x-pack/test/functional/apps/lens/group2/fields_list.ts b/x-pack/test/functional/apps/lens/group2/fields_list.ts
index 4e1f771d0b042..79baafe6100a6 100644
--- a/x-pack/test/functional/apps/lens/group2/fields_list.ts
+++ b/x-pack/test/functional/apps/lens/group2/fields_list.ts
@@ -9,13 +9,15 @@ import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
- const PageObjects = getPageObjects(['visualize', 'lens', 'common', 'header']);
+ const PageObjects = getPageObjects(['visualize', 'lens', 'common', 'header', 'timePicker']);
const find = getService('find');
const log = getService('log');
const testSubjects = getService('testSubjects');
const filterBar = getService('filterBar');
const fieldEditor = getService('fieldEditor');
const retry = getService('retry');
+ const es = getService('es');
+ const queryBar = getService('queryBar');
describe('lens fields list tests', () => {
for (const datasourceType of ['form-based', 'ad-hoc', 'ad-hoc-no-timefield']) {
@@ -48,7 +50,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
});
});
-
it('should show all fields as available', async () => {
expect(
await (await testSubjects.find('lnsIndexPatternAvailableFields-count')).getVisibleText()
@@ -231,5 +232,50 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
}
});
}
+
+ describe(`update field list test`, () => {
+ before(async () => {
+ await es.transport.request({
+ path: '/field-update-test/_doc',
+ method: 'POST',
+ body: {
+ '@timestamp': new Date().toISOString(),
+ oldField: 10,
+ },
+ });
+ await PageObjects.visualize.navigateToNewVisualization();
+ await PageObjects.visualize.clickVisType('lens');
+ await PageObjects.timePicker.setCommonlyUsedTime('This_week');
+
+ await PageObjects.lens.createAdHocDataView('field-update-test', true);
+ await retry.try(async () => {
+ const selectedPattern = await PageObjects.lens.getDataPanelIndexPattern();
+ expect(selectedPattern).to.eql('field-update-test*');
+ });
+ });
+ after(async () => {
+ await es.transport.request({
+ path: '/field-update-test',
+ method: 'DELETE',
+ });
+ });
+
+ it('should show new fields Available fields', async () => {
+ await es.transport.request({
+ path: '/field-update-test/_doc',
+ method: 'POST',
+ body: {
+ '@timestamp': new Date().toISOString(),
+ oldField: 10,
+ newField: 20,
+ },
+ });
+ await PageObjects.lens.waitForField('oldField');
+ await queryBar.setQuery('oldField: 10');
+ await queryBar.submitQuery();
+ await PageObjects.header.waitUntilLoadingHasFinished();
+ await PageObjects.lens.waitForField('newField');
+ });
+ });
});
}
From 75cc2355c61ac0dde3066972f11fd7b827adb2cc Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Fri, 15 Dec 2023 13:08:28 +0100
Subject: [PATCH 124/168] Improve Lens code preventing an endless loop of
update
---
.../plugins/lens/public/datasources/form_based/datapanel.tsx | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
index 58c4e1bddaa27..1d7b3603482c8 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
+++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
@@ -299,11 +299,14 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
frame.dataViews.indexPatterns,
data.search.session,
]);
+
useEffect(() => {
if (hasNewFields) {
refreshFieldList();
}
- }, [hasNewFields, refreshFieldList]);
+ // Preventing a race condition, making sure refreshFieldList is just executed once when hasNewFields is true
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [hasNewFields]);
const editField = useMemo(
() =>
From 3a746002e7b11ce77277a2d75eb3ae3555aa7a0c Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Tue, 19 Dec 2023 07:58:30 +0100
Subject: [PATCH 125/168] Update
packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
Co-authored-by: Julia Rechkunova
---
.../kbn-unified-field-list/src/hooks/use_existing_fields.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
index f756b4cc19126..dba018e59a86b 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
@@ -15,7 +15,7 @@ import { type DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { DataView, DataViewsContract } from '@kbn/data-views-plugin/common';
import { getEsQueryConfig } from '@kbn/data-service/src/es_query';
import { reportPerformanceMetricEvent } from '@kbn/ebt-tools';
-import { DataViewField } from '@kbn/data-views-plugin/common';
+import type { DataViewField } from '@kbn/data-views-plugin/common';
import { loadFieldExisting } from '../services/field_existing';
import { ExistenceFetchStatus } from '../types';
From 15e5168f8ea9ad54d0f404a3ef225ea0bbb53b1e Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Tue, 19 Dec 2023 07:58:57 +0100
Subject: [PATCH 126/168] Update
packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
Co-authored-by: Julia Rechkunova
---
packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
index c079b6b9503e9..0d7f92983c230 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
@@ -41,7 +41,7 @@ export interface GroupedFieldsParams {
onOverrideFieldGroupDetails?: OverrideFieldGroupDetails;
onSupportedFieldFilter?: (field: T) => boolean;
onSelectedFieldFilter?: (field: T) => boolean;
- isCompatibleField?: (fields: DataViewField) => boolean;
+ isCompatibleField?: (field: DataViewField) => boolean;
}
export interface GroupedFieldsResult {
From 139b65165a75a7eae384aa02091ce2e183da94d9 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Tue, 19 Dec 2023 07:59:17 +0100
Subject: [PATCH 127/168] Update
packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
Co-authored-by: Julia Rechkunova
---
.../src/services/field_existing/field_existing_utils.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
index e4dab136c5a52..912ef361dd9a8 100644
--- a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
+++ b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
@@ -7,7 +7,7 @@
*/
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
-import { DataViewField, RuntimeField } from '@kbn/data-views-plugin/common';
+import { type DataViewField, RuntimeField } from '@kbn/data-views-plugin/common';
import type { DataViewsContract, DataView, FieldSpec } from '@kbn/data-views-plugin/common';
import type { IKibanaSearchRequest } from '@kbn/data-plugin/common';
From ab514e4c4fcc44459bfb7539dad4a3b0fb55650e Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Tue, 19 Dec 2023 08:00:34 +0100
Subject: [PATCH 128/168] Update
packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
Co-authored-by: Julia Rechkunova
---
.../src/services/field_existing/field_existing_utils.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
index 912ef361dd9a8..75ac7b159f113 100644
--- a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
+++ b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
@@ -59,8 +59,8 @@ export async function fetchFieldExistence({
// in the given data view. Those fields we consider as new fields,
// that were ingested after the data view was loaded
const newFields = existingFieldList
- .filter((field) => dataView.getFieldByName(field.name) === undefined)
- .map((field) => dataView.getFieldByName(field.name) ?? new DataViewField(field));
+ .filter((field) => !dataView.getFieldByName(field.name))
+ .map((field) => new DataViewField(field));
// refresh the data view in case there are new fields
if (newFields.length) {
await dataViewsService.refreshFields(dataView, false);
From b424159790279852eec8d655172b2ee6060c5ef0 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Wed, 20 Dec 2023 09:54:32 +0100
Subject: [PATCH 129/168] Improve code
---
.../field_list_sidebar.tsx | 46 ++++-----
.../src/hooks/use_existing_fields.ts | 14 ++-
.../src/hooks/use_grouped_fields.ts | 36 +++----
.../field_existing/field_existing_utils.ts | 30 +++---
.../field_existing/load_field_existing.ts | 4 +-
.../lens/public/data_views_service/loader.ts | 94 ++++++++++---------
.../datasources/form_based/datapanel.tsx | 10 +-
.../datasources/text_based/datapanel.tsx | 2 -
8 files changed, 129 insertions(+), 107 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
index e1e72ca0a9aa9..256d6a8f148fc 100644
--- a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
+++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
@@ -22,7 +22,7 @@ import {
useEuiTheme,
} from '@elastic/eui';
import { ToolbarButton } from '@kbn/shared-ux-button-toolbar';
-import { type DataViewField } from '@kbn/data-views-plugin/public';
+import { DataViewField } from '@kbn/data-views-plugin/common';
import { getDataViewFieldSubtypeMulti } from '@kbn/es-query/src/utils';
import { FIELDS_LIMIT_SETTING, SEARCH_FIELDS_FROM_SOURCE } from '@kbn/discover-utils';
import { FieldList } from '../../components/field_list';
@@ -207,28 +207,28 @@ export const UnifiedFieldListSidebarComponent: React.FC({
- dataViewId: (searchMode === 'documents' && dataView?.id) || null, // passing `null` for text-based queries
- allFields,
- popularFieldsLimit:
- searchMode !== 'documents' || stateService.creationOptions.disablePopularFields
- ? 0
- : popularFieldsLimit,
- isAffectedByGlobalFilter,
- services: {
- dataViews,
- core,
- },
- sortedSelectedFields: onSelectedFieldFilter ? undefined : selectedFieldsState.selectedFields,
- onSelectedFieldFilter,
- onSupportedFieldFilter:
- stateService.creationOptions.onSupportedFieldFilter ?? onSupportedFieldFilter,
- onOverrideFieldGroupDetails: stateService.creationOptions.onOverrideFieldGroupDetails,
- });
+ const { fieldListFiltersProps, fieldListGroupedProps, allFieldsModified } =
+ useGroupedFields({
+ dataViewId: (searchMode === 'documents' && dataView?.id) || null, // passing `null` for text-based queries
+ allFields,
+ popularFieldsLimit:
+ searchMode !== 'documents' || stateService.creationOptions.disablePopularFields
+ ? 0
+ : popularFieldsLimit,
+ isAffectedByGlobalFilter,
+ services: {
+ dataViews,
+ core,
+ },
+ sortedSelectedFields: onSelectedFieldFilter ? undefined : selectedFieldsState.selectedFields,
+ onSelectedFieldFilter,
+ onSupportedFieldFilter:
+ stateService.creationOptions.onSupportedFieldFilter ?? onSupportedFieldFilter,
+ onOverrideFieldGroupDetails: stateService.creationOptions.onOverrideFieldGroupDetails,
+ getNewFieldsBySpec: (fieldSpecArr) => {
+ return fieldSpecArr.map((fieldSpec) => new DataViewField(fieldSpec));
+ },
+ });
useEffect(() => {
if (
diff --git a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
index dba018e59a86b..7826c815b9af3 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
@@ -12,10 +12,9 @@ import { BehaviorSubject } from 'rxjs';
import type { CoreStart } from '@kbn/core/public';
import type { AggregateQuery, EsQueryConfig, Filter, Query } from '@kbn/es-query';
import { type DataPublicPluginStart } from '@kbn/data-plugin/public';
-import type { DataView, DataViewsContract } from '@kbn/data-views-plugin/common';
+import type { DataView, DataViewsContract, FieldSpec } from '@kbn/data-views-plugin/common';
import { getEsQueryConfig } from '@kbn/data-service/src/es_query';
import { reportPerformanceMetricEvent } from '@kbn/ebt-tools';
-import type { DataViewField } from '@kbn/data-views-plugin/common';
import { loadFieldExisting } from '../services/field_existing';
import { ExistenceFetchStatus } from '../types';
@@ -25,7 +24,7 @@ const generateId = htmlIdGenerator();
export interface ExistingFieldsInfo {
fetchStatus: ExistenceFetchStatus;
existingFieldsByFieldNameMap: Record;
- newFields?: DataViewField[];
+ newFields?: FieldSpec[];
numberOfFetches: number;
hasDataViewRestrictions?: boolean;
}
@@ -56,7 +55,7 @@ export interface ExistingFieldsReader {
hasFieldData: (dataViewId: string, fieldName: string) => boolean;
getFieldsExistenceStatus: (dataViewId: string) => ExistenceFetchStatus;
isFieldsExistenceInfoUnavailable: (dataViewId: string) => boolean;
- getNewFields: (dataViewId: string) => DataViewField[];
+ getNewFields: (dataViewId: string) => FieldSpec[];
}
const initialData: ExistingFieldsByDataViewMap = {};
@@ -255,7 +254,12 @@ export const useExistingFieldsFetcher = (
);
};
-export const useExistingFieldsReader: () => ExistingFieldsReader = () => {
+export const useExistingFieldsReader: () => {
+ getFieldsExistenceStatus: (dataViewId: string) => ExistenceFetchStatus;
+ isFieldsExistenceInfoUnavailable: (dataViewId: string) => boolean;
+ getNewFields: (dataViewId: string) => FieldSpec[];
+ hasFieldData: (dataViewId: string, fieldName: string) => boolean;
+} = () => {
const mountedRef = useRef(true);
const [existingFieldsByDataViewMap, setExistingFieldsByDataViewMap] =
useState(globalMap$.getValue());
diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
index 0d7f92983c230..bfc32be695120 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
@@ -10,7 +10,7 @@ import { groupBy } from 'lodash';
import { useEffect, useMemo, useState, useRef } from 'react';
import { i18n } from '@kbn/i18n';
import { type CoreStart } from '@kbn/core-lifecycle-browser';
-import { type DataView, type DataViewField } from '@kbn/data-views-plugin/common';
+import type { DataView, DataViewField, FieldSpec } from '@kbn/data-views-plugin/common';
import { type DataViewsContract } from '@kbn/data-views-plugin/public';
import {
type FieldListGroups,
@@ -41,7 +41,7 @@ export interface GroupedFieldsParams {
onOverrideFieldGroupDetails?: OverrideFieldGroupDetails;
onSupportedFieldFilter?: (field: T) => boolean;
onSelectedFieldFilter?: (field: T) => boolean;
- isCompatibleField?: (field: DataViewField) => boolean;
+ getNewFieldsBySpec?: (field: FieldSpec[], dataView: DataView | null) => T[];
}
export interface GroupedFieldsResult {
@@ -53,7 +53,7 @@ export interface GroupedFieldsResult {
fieldsExistInIndex: boolean;
screenReaderDescriptionId?: string;
};
- allFields: T[] | null; // `null` is for loading indicator
+ allFieldsModified: T[] | null; // `null` is for loading indicator
hasNewFields: boolean;
}
@@ -68,7 +68,7 @@ export function useGroupedFields({
onOverrideFieldGroupDetails,
onSupportedFieldFilter,
onSelectedFieldFilter,
- isCompatibleField,
+ getNewFieldsBySpec,
}: GroupedFieldsParams): GroupedFieldsResult {
const fieldsExistenceReader = useExistingFieldsReader();
const fieldListFilters = useFieldFilters({
@@ -129,20 +129,24 @@ export function useGroupedFields({
// Taking care of new fields that were ingested after the selected data view was loaded
// Those replace existing fields if updated, or are added to the list
- const newFields = dataViewId
- ? fieldsExistenceReader.getNewFields(dataViewId).filter(isCompatibleField || (() => true))
- : [];
+ const newFields =
+ dataViewId && getNewFieldsBySpec
+ ? getNewFieldsBySpec(fieldsExistenceReader.getNewFields(dataViewId), dataView)
+ : [];
// Filtering out fields that e.g. Discover provides by analyzing the resultset, that are not part of the loaded DataView
// These can be replaced by the new fields, which are mapped correctly, and therefore can be used in the right way
- const allFieldsExlNew = allFields
- ? allFields.filter((field) => !newFields.some((newField) => newField.name === field.name))
- : [];
+ const allFieldsExlNew =
+ allFields && newFields.length
+ ? allFields.filter((field) => !newFields.some((newField) => newField.name === field.name))
+ : allFields;
- const allFieldsInclNew = [...allFieldsExlNew, ...newFields] as unknown as T[];
-
- const sortedFields = allFieldsInclNew.sort(sortFields);
- allFieldsToReturn.current = sortedFields;
+ const allFieldsInclNew = newFields.length
+ ? [...(allFieldsExlNew || []), ...newFields]
+ : allFields || [];
+ allFieldsToReturn.current = newFields.length ? allFieldsInclNew : allFields;
hasNewFields.current = Boolean(newFields.length);
+ const sortedFields = [...allFieldsInclNew].sort(sortFields);
+
const groupedFields = {
...getDefaultFieldGroups(),
...groupBy(sortedFields, (field) => {
@@ -347,7 +351,7 @@ export function useGroupedFields({
onSelectedFieldFilter,
onSupportedFieldFilter,
dataView,
- isCompatibleField,
+ getNewFieldsBySpec,
]);
const fieldGroups: FieldListGroups = useMemo(() => {
@@ -406,7 +410,7 @@ export function useGroupedFields({
return {
fieldListGroupedProps,
fieldListFiltersProps: fieldListFilters.fieldListFiltersProps,
- allFields: allFieldsToReturn.current,
+ allFieldsModified: allFieldsToReturn.current,
hasNewFields: hasNewFields.current,
};
}
diff --git a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
index 75ac7b159f113..41a1e53a33849 100644
--- a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
+++ b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
@@ -7,7 +7,7 @@
*/
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
-import { type DataViewField, RuntimeField } from '@kbn/data-views-plugin/common';
+import type { DataViewField, RuntimeField } from '@kbn/data-views-plugin/common';
import type { DataViewsContract, DataView, FieldSpec } from '@kbn/data-views-plugin/common';
import type { IKibanaSearchRequest } from '@kbn/data-plugin/common';
@@ -58,9 +58,7 @@ export async function fetchFieldExistence({
// take care of fields of existingFieldList, that are not yet available
// in the given data view. Those fields we consider as new fields,
// that were ingested after the data view was loaded
- const newFields = existingFieldList
- .filter((field) => !dataView.getFieldByName(field.name))
- .map((field) => new DataViewField(field));
+ const newFields = existingFieldList.filter((field) => !dataView.getFieldByName(field.name));
// refresh the data view in case there are new fields
if (newFields.length) {
await dataViewsService.refreshFields(dataView, false);
@@ -78,19 +76,23 @@ export async function fetchFieldExistence({
*/
export function buildFieldList(indexPattern: DataView, metaFields: string[]): Field[] {
return indexPattern.fields.map((field) => {
- return {
- name: field.name,
- isScript: !!field.scripted,
- lang: field.lang,
- script: field.script,
- // id is a special case - it doesn't show up in the meta field list,
- // but as it's not part of source, it has to be handled separately.
- isMeta: metaFields?.includes(field.name) || field.name === '_id',
- runtimeField: !field.isMapped ? field.runtimeField : undefined,
- };
+ return buildField(field, metaFields);
});
}
+export function buildField(field: DataViewField, metaFields: string[]): Field {
+ return {
+ name: field.name,
+ isScript: !!field.scripted,
+ lang: field.lang,
+ script: field.script,
+ // id is a special case - it doesn't show up in the meta field list,
+ // but as it's not part of source, it has to be handled separately.
+ isMeta: metaFields?.includes(field.name) || field.name === '_id',
+ runtimeField: !field.isMapped ? field.runtimeField : undefined,
+ };
+}
+
function toQuery(
timeFieldName: string | undefined,
fromDate: string | undefined,
diff --git a/packages/kbn-unified-field-list/src/services/field_existing/load_field_existing.ts b/packages/kbn-unified-field-list/src/services/field_existing/load_field_existing.ts
index 889c92008554b..590bc46eff573 100644
--- a/packages/kbn-unified-field-list/src/services/field_existing/load_field_existing.ts
+++ b/packages/kbn-unified-field-list/src/services/field_existing/load_field_existing.ts
@@ -9,7 +9,7 @@
import { IUiSettingsClient } from '@kbn/core/public';
import { type DataPublicPluginStart } from '@kbn/data-plugin/public';
import { UI_SETTINGS } from '@kbn/data-service/src/constants';
-import type { DataView, DataViewField, DataViewsContract } from '@kbn/data-views-plugin/common';
+import type { DataView, DataViewsContract, FieldSpec } from '@kbn/data-views-plugin/common';
import { lastValueFrom } from 'rxjs';
import { fetchFieldExistence } from './field_existing_utils';
@@ -27,7 +27,7 @@ interface FetchFieldExistenceParams {
export type LoadFieldExistingHandler = (params: FetchFieldExistenceParams) => Promise<{
existingFieldNames: string[];
indexPatternTitle: string;
- newFields?: DataViewField[];
+ newFields?: FieldSpec[];
}>;
export const loadFieldExisting: LoadFieldExistingHandler = async ({
diff --git a/x-pack/plugins/lens/public/data_views_service/loader.ts b/x-pack/plugins/lens/public/data_views_service/loader.ts
index 784c97d832e34..00bd291ef9c24 100644
--- a/x-pack/plugins/lens/public/data_views_service/loader.ts
+++ b/x-pack/plugins/lens/public/data_views_service/loader.ts
@@ -6,7 +6,12 @@
*/
import { isFieldLensCompatible } from '@kbn/visualization-ui-components';
-import type { DataViewsContract, DataView, DataViewSpec } from '@kbn/data-views-plugin/public';
+import {
+ DataViewsContract,
+ DataView,
+ DataViewSpec,
+ DataViewField,
+} from '@kbn/data-views-plugin/public';
import { keyBy } from 'lodash';
import { IndexPattern, IndexPatternField, IndexPatternMap, IndexPatternRef } from '../types';
import { documentField } from '../datasources/form_based/document_field';
@@ -29,49 +34,9 @@ export function convertDataViewIntoLensIndexPattern(
dataView: DataView,
restrictionRemapper: (name: string) => string = onRestrictionMapping
): IndexPattern {
- const metaKeys = new Set(dataView.metaFields);
const newFields = dataView.fields
.filter(isFieldLensCompatible)
- .map((field): IndexPatternField => {
- // Convert the getters on the index pattern service into plain JSON
- const base = {
- name: field.name,
- displayName: field.displayName,
- type: field.type,
- aggregatable: field.aggregatable,
- filterable: field.filterable,
- searchable: field.searchable,
- meta: metaKeys.has(field.name),
- esTypes: field.esTypes,
- scripted: field.scripted,
- isMapped: field.isMapped,
- customLabel: field.customLabel,
- runtimeField: field.runtimeField,
- runtime: Boolean(field.runtimeField),
- timeSeriesDimension: field.timeSeriesDimension,
- timeSeriesMetric: field.timeSeriesMetric,
- timeSeriesRollup: field.isRolledUpField,
- partiallyApplicableFunctions: field.isRolledUpField
- ? {
- percentile: true,
- percentile_rank: true,
- median: true,
- last_value: true,
- unique_count: true,
- standard_deviation: true,
- }
- : undefined,
- };
-
- // Simplifies tests by hiding optional properties instead of undefined
- return base.scripted
- ? {
- ...base,
- lang: field.lang,
- script: field.script,
- }
- : base;
- })
+ .map((field) => buildIndexPatternField(field, dataView))
.concat(documentField);
const { typeMeta, title, name, timeFieldName, fieldFormatMap } = dataView;
@@ -113,6 +78,51 @@ export function convertDataViewIntoLensIndexPattern(
};
}
+export function buildIndexPatternField(
+ field: DataViewField,
+ dataView: DataView | null
+): IndexPatternField {
+ const meta = dataView?.metaFields.includes(field.name);
+ // Convert the getters on the index pattern service into plain JSON
+ const base = {
+ name: field.name,
+ displayName: field.displayName,
+ type: field.type,
+ aggregatable: field.aggregatable,
+ filterable: field.filterable,
+ searchable: field.searchable,
+ meta,
+ esTypes: field.esTypes,
+ scripted: field.scripted,
+ isMapped: field.isMapped,
+ customLabel: field.customLabel,
+ runtimeField: field.runtimeField,
+ runtime: Boolean(field.runtimeField),
+ timeSeriesDimension: field.timeSeriesDimension,
+ timeSeriesMetric: field.timeSeriesMetric,
+ timeSeriesRollup: field.isRolledUpField,
+ partiallyApplicableFunctions: field.isRolledUpField
+ ? {
+ percentile: true,
+ percentile_rank: true,
+ median: true,
+ last_value: true,
+ unique_count: true,
+ standard_deviation: true,
+ }
+ : undefined,
+ };
+
+ // Simplifies tests by hiding optional properties instead of undefined
+ return base.scripted
+ ? {
+ ...base,
+ lang: field.lang,
+ script: field.script,
+ }
+ : base;
+}
+
export async function loadIndexPatternRefs(
dataViews: MinimalDataViewsContract
): Promise {
diff --git a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
index 1d7b3603482c8..5108cfbf8019a 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
+++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
@@ -13,7 +13,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import type { CoreStart } from '@kbn/core/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
-import { type DataView } from '@kbn/data-plugin/common';
+import { type DataView, DataViewField } from '@kbn/data-plugin/common';
import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
import { IndexPatternFieldEditorStart } from '@kbn/data-view-field-editor-plugin/public';
import { VISUALIZE_GEO_FIELD_TRIGGER } from '@kbn/ui-actions-plugin/public';
@@ -28,7 +28,7 @@ import {
useGroupedFields,
} from '@kbn/unified-field-list';
import { ChartsPluginSetup } from '@kbn/charts-plugin/public';
-import { isFieldLensCompatible } from '@kbn/visualization-ui-components';
+import { buildIndexPatternField } from '../../data_views_service/loader';
import type {
DatasourceDataPanelProps,
FramePublicAPI,
@@ -262,7 +262,11 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
onSupportedFieldFilter,
onSelectedFieldFilter,
onOverrideFieldGroupDetails,
- isCompatibleField: isFieldLensCompatible,
+ getNewFieldsBySpec: (spec, dataView) => {
+ return spec.map((fieldSpec) =>
+ buildIndexPatternField(new DataViewField(fieldSpec), dataView)
+ );
+ },
});
const closeFieldEditor = useRef<() => void | undefined>();
diff --git a/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx
index ac62636ad50c1..113125484cddf 100644
--- a/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx
+++ b/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx
@@ -24,7 +24,6 @@ import {
GetCustomFieldType,
useGroupedFields,
} from '@kbn/unified-field-list';
-import { isFieldLensCompatible } from '@kbn/visualization-ui-components';
import type { DatasourceDataPanelProps } from '../../types';
import type { TextBasedPrivateState } from './types';
import { getStateFromAggregateQuery } from './utils';
@@ -106,7 +105,6 @@ export function TextBasedDataPanel({
getCustomFieldType,
onSelectedFieldFilter,
onOverrideFieldGroupDetails,
- isCompatibleField: isFieldLensCompatible,
});
const renderFieldItem: FieldListGroupedProps['renderFieldItem'] = useCallback(
From 30dfec6cc0a971a298beb17c9eaa1587e3b8e0f8 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Wed, 20 Dec 2023 17:09:56 +0100
Subject: [PATCH 130/168] Add isFieldLensCompatible for new fields in Lens
---
.../public/datasources/form_based/datapanel.tsx | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
index 5108cfbf8019a..6ee8483658e68 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
+++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
@@ -13,7 +13,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import type { CoreStart } from '@kbn/core/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
-import { type DataView, DataViewField } from '@kbn/data-plugin/common';
+import { type DataView, DataViewField, FieldSpec } from '@kbn/data-plugin/common';
import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
import { IndexPatternFieldEditorStart } from '@kbn/data-view-field-editor-plugin/public';
import { VISUALIZE_GEO_FIELD_TRIGGER } from '@kbn/ui-actions-plugin/public';
@@ -28,6 +28,7 @@ import {
useGroupedFields,
} from '@kbn/unified-field-list';
import { ChartsPluginSetup } from '@kbn/charts-plugin/public';
+import { isFieldLensCompatible } from '@kbn/visualization-ui-components';
import { buildIndexPatternField } from '../../data_views_service/loader';
import type {
DatasourceDataPanelProps,
@@ -263,9 +264,13 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
onSelectedFieldFilter,
onOverrideFieldGroupDetails,
getNewFieldsBySpec: (spec, dataView) => {
- return spec.map((fieldSpec) =>
- buildIndexPatternField(new DataViewField(fieldSpec), dataView)
- );
+ return spec.reduce((result: IndexPatternField[], fieldSpec: FieldSpec) => {
+ const field = new DataViewField(fieldSpec);
+ if (isFieldLensCompatible(field)) {
+ result.push(buildIndexPatternField(field, dataView));
+ }
+ return result;
+ }, []);
},
});
From f747c2e945cb383f8ed04e54a82ff1abc95d20a5 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Thu, 21 Dec 2023 07:10:11 +0100
Subject: [PATCH 131/168] Improve multi field code
---
.../field_list_item.tsx | 18 +++++---
.../field_list_sidebar.tsx | 41 +++++++++----------
2 files changed, 32 insertions(+), 27 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx b/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx
index 745d463b28386..306d348855202 100644
--- a/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx
+++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx
@@ -67,9 +67,14 @@ function getCommonFieldItemButtonProps({
};
}
+export interface FieldListMultiField {
+ field: DataViewField;
+ isSelected: boolean;
+}
+
interface MultiFieldsProps {
stateService: UnifiedFieldListSidebarContainerStateService;
- multiFields: NonNullable;
+ multiFields: NonNullable;
toggleDisplay: (field: DataViewField) => void;
alwaysShowActionButton: boolean;
size: FieldItemButtonProps['size'];
@@ -163,9 +168,9 @@ export interface UnifiedFieldListItemProps {
*/
trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void;
/**
- * Multi fields for the current field
+ * Get multi fields for the given field
*/
- multiFields?: Array<{ field: DataViewField; isSelected: boolean }>;
+ getMultiFields?: (field: DataViewField) => FieldListMultiField[] | undefined;
/**
* Callback to edit a field from data view
* @param fieldName name of the field to edit
@@ -212,7 +217,7 @@ function UnifiedFieldListItemComponent({
isEmpty,
isSelected,
trackUiMetric,
- multiFields,
+ getMultiFields,
onEditField,
onDeleteField,
workspaceSelectedFieldNames,
@@ -253,8 +258,6 @@ function UnifiedFieldListItemComponent({
[onAddFieldToWorkspace, onRemoveFieldFromWorkspace, closePopover]
);
- const rawMultiFields = useMemo(() => multiFields?.map((f) => f.field), [multiFields]);
-
const customPopoverHeaderProps: Partial = useMemo(() => {
const dataTestSubjPrefix =
stateService.creationOptions.dataTestSubj?.fieldListItemPopoverHeaderDataTestSubjPrefix;
@@ -275,6 +278,9 @@ function UnifiedFieldListItemComponent({
}, [field.name, stateService.creationOptions]);
const renderPopover = () => {
+ const multiFields = getMultiFields?.(field);
+ const rawMultiFields = multiFields?.map((f) => f.field);
+
return (
<>
(
INITIAL_SELECTED_FIELDS_RESULT
);
- const [multiFieldsMap, setMultiFieldsMap] = useState<
- Map> | undefined
- >(undefined);
useEffect(() => {
const result = getSelectedFields({
@@ -230,27 +228,28 @@ export const UnifiedFieldListSidebarComponent: React.FC {
+ const useMultiFields = useMemo(() => {
if (
searchMode !== 'documents' ||
!useNewFieldsApi ||
stateService.creationOptions.disableMultiFieldsGroupingByParent
) {
- setMultiFieldsMap(undefined); // we don't have to calculate multifields in this case
+ return false;
} else {
- setMultiFieldsMap(
- calculateMultiFields(allFieldsModified, selectedFieldsState.selectedFieldsMap)
- );
+ return true;
}
}, [
stateService.creationOptions.disableMultiFieldsGroupingByParent,
- selectedFieldsState.selectedFieldsMap,
- allFieldsModified,
useNewFieldsApi,
- setMultiFieldsMap,
searchMode,
]);
+ const getMultiFieldsByField = useCallback(
+ (field: DataViewField) =>
+ getMultiFieldsByParent(field, allFieldsModified, selectedFieldsState.selectedFieldsMap),
+ [allFieldsModified, selectedFieldsState.selectedFieldsMap]
+ );
+
const renderFieldItem: FieldListGroupedProps['renderFieldItem'] = useCallback(
({ field, groupName, groupIndex, itemIndex, fieldSearchHighlight }) => (
@@ -267,7 +266,7 @@ export const UnifiedFieldListSidebarComponent: React.FC>();
+ const result: FieldListMultiField[] = [];
allFields.forEach((field) => {
const subTypeMulti = getDataViewFieldSubtypeMulti(field);
const parent = subTypeMulti?.multi.parent;
- if (!parent) {
+ if (!parent || parent !== parentField.name) {
return;
}
const multiField = {
field,
isSelected: Boolean(selectedFieldsMap?.[field.name]),
};
- const value = map.get(parent) ?? [];
- value.push(multiField);
- map.set(parent, value);
+ result.push(multiField);
});
- return map;
+ return result.length ? result : undefined;
}
From 9ed0c495247bbf63d742effa90260b31570c08ef Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Thu, 21 Dec 2023 08:50:45 +0100
Subject: [PATCH 132/168] Improve code
---
.../field_list_sidebar.tsx | 24 +++++--------------
1 file changed, 6 insertions(+), 18 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
index 3ed0e7dcbf68b..a98b8567aad78 100644
--- a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
+++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
@@ -223,26 +223,14 @@ export const UnifiedFieldListSidebarComponent: React.FC {
- return fieldSpecArr.map((fieldSpec) => new DataViewField(fieldSpec));
- },
+ getNewFieldsBySpec: (fieldSpecArr) =>
+ fieldSpecArr.map((fieldSpec) => new DataViewField(fieldSpec)),
});
- const useMultiFields = useMemo(() => {
- if (
- searchMode !== 'documents' ||
- !useNewFieldsApi ||
- stateService.creationOptions.disableMultiFieldsGroupingByParent
- ) {
- return false;
- } else {
- return true;
- }
- }, [
- stateService.creationOptions.disableMultiFieldsGroupingByParent,
- useNewFieldsApi,
- searchMode,
- ]);
+ const useMultiFields =
+ searchMode === 'documents' &&
+ useNewFieldsApi &&
+ !stateService.creationOptions.disableMultiFieldsGroupingByParent;
const getMultiFieldsByField = useCallback(
(field: DataViewField) =>
From 5420c7708910b945b85434bd5549f0a559301016 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Thu, 21 Dec 2023 08:51:05 +0100
Subject: [PATCH 133/168] Remove redundant field list refreshing
---
.../public/dataview_picker/change_dataview.tsx | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
index 9076bcb37c7df..2d857de608834 100644
--- a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
+++ b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx
@@ -307,12 +307,6 @@ export function ChangeDataView({
isTextBasedLangSelected={isTextBasedLangSelected}
setPopoverIsOpen={setPopoverIsOpen}
onChangeDataView={async (newId) => {
- try {
- // refreshing the field list
- await dataViews.get(newId, false, true);
- } catch (e) {
- //
- }
setSelectedDataViewId(newId);
setPopoverIsOpen(false);
if (isTextBasedLangSelected && !isTextLangTransitionModalDismissed) {
From f340fae4cae5bfe9533fd3c8bcf082248c58b8b3 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Fri, 22 Dec 2023 12:09:49 +0100
Subject: [PATCH 134/168] Undo multi field changes
---
.../field_list_item.tsx | 18 +++----
.../field_list_sidebar.tsx | 54 +++++++++++--------
2 files changed, 39 insertions(+), 33 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx b/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx
index 306d348855202..745d463b28386 100644
--- a/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx
+++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx
@@ -67,14 +67,9 @@ function getCommonFieldItemButtonProps({
};
}
-export interface FieldListMultiField {
- field: DataViewField;
- isSelected: boolean;
-}
-
interface MultiFieldsProps {
stateService: UnifiedFieldListSidebarContainerStateService;
- multiFields: NonNullable;
+ multiFields: NonNullable;
toggleDisplay: (field: DataViewField) => void;
alwaysShowActionButton: boolean;
size: FieldItemButtonProps['size'];
@@ -168,9 +163,9 @@ export interface UnifiedFieldListItemProps {
*/
trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void;
/**
- * Get multi fields for the given field
+ * Multi fields for the current field
*/
- getMultiFields?: (field: DataViewField) => FieldListMultiField[] | undefined;
+ multiFields?: Array<{ field: DataViewField; isSelected: boolean }>;
/**
* Callback to edit a field from data view
* @param fieldName name of the field to edit
@@ -217,7 +212,7 @@ function UnifiedFieldListItemComponent({
isEmpty,
isSelected,
trackUiMetric,
- getMultiFields,
+ multiFields,
onEditField,
onDeleteField,
workspaceSelectedFieldNames,
@@ -258,6 +253,8 @@ function UnifiedFieldListItemComponent({
[onAddFieldToWorkspace, onRemoveFieldFromWorkspace, closePopover]
);
+ const rawMultiFields = useMemo(() => multiFields?.map((f) => f.field), [multiFields]);
+
const customPopoverHeaderProps: Partial = useMemo(() => {
const dataTestSubjPrefix =
stateService.creationOptions.dataTestSubj?.fieldListItemPopoverHeaderDataTestSubjPrefix;
@@ -278,9 +275,6 @@ function UnifiedFieldListItemComponent({
}, [field.name, stateService.creationOptions]);
const renderPopover = () => {
- const multiFields = getMultiFields?.(field);
- const rawMultiFields = multiFields?.map((f) => f.field);
-
return (
<>
(
INITIAL_SELECTED_FIELDS_RESULT
);
+ const [multiFieldsMap, setMultiFieldsMap] = useState<
+ Map> | undefined
+ >(undefined);
useEffect(() => {
const result = getSelectedFields({
@@ -227,16 +229,26 @@ export const UnifiedFieldListSidebarComponent: React.FC new DataViewField(fieldSpec)),
});
- const useMultiFields =
- searchMode === 'documents' &&
- useNewFieldsApi &&
- !stateService.creationOptions.disableMultiFieldsGroupingByParent;
-
- const getMultiFieldsByField = useCallback(
- (field: DataViewField) =>
- getMultiFieldsByParent(field, allFieldsModified, selectedFieldsState.selectedFieldsMap),
- [allFieldsModified, selectedFieldsState.selectedFieldsMap]
- );
+ useEffect(() => {
+ if (
+ searchMode !== 'documents' ||
+ !useNewFieldsApi ||
+ stateService.creationOptions.disableMultiFieldsGroupingByParent
+ ) {
+ setMultiFieldsMap(undefined); // we don't have to calculate multifields in this case
+ } else {
+ setMultiFieldsMap(
+ calculateMultiFields(allFieldsModified, selectedFieldsState.selectedFieldsMap)
+ );
+ }
+ }, [
+ stateService.creationOptions.disableMultiFieldsGroupingByParent,
+ selectedFieldsState.selectedFieldsMap,
+ allFieldsModified,
+ useNewFieldsApi,
+ setMultiFieldsMap,
+ searchMode,
+ ]);
const renderFieldItem: FieldListGroupedProps['renderFieldItem'] = useCallback(
({ field, groupName, groupIndex, itemIndex, fieldSearchHighlight }) => (
@@ -254,7 +266,7 @@ export const UnifiedFieldListSidebarComponent: React.FC>();
allFields.forEach((field) => {
const subTypeMulti = getDataViewFieldSubtypeMulti(field);
const parent = subTypeMulti?.multi.parent;
- if (!parent || parent !== parentField.name) {
+ if (!parent) {
return;
}
const multiField = {
field,
isSelected: Boolean(selectedFieldsMap?.[field.name]),
};
- result.push(multiField);
+ const value = map.get(parent) ?? [];
+ value.push(multiField);
+ map.set(parent, value);
});
- return result.length ? result : undefined;
+ return map;
}
From 26c4d72c10ff4f4f3a70209a679625eba20d2bec Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Fri, 22 Dec 2023 15:20:42 +0100
Subject: [PATCH 135/168] Address feedback
---
.../field_list_sidebar.tsx | 9 ++-
.../src/hooks/use_existing_fields.ts | 9 +--
.../src/hooks/use_grouped_fields.ts | 61 ++++++++-----------
.../src/hooks/use_new_fields.ts | 51 ++++++++++++++++
4 files changed, 83 insertions(+), 47 deletions(-)
create mode 100644 packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
index 7b4e69b3ea739..17ebe5b19286f 100644
--- a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
+++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
@@ -22,7 +22,7 @@ import {
useEuiTheme,
} from '@elastic/eui';
import { ToolbarButton } from '@kbn/shared-ux-button-toolbar';
-import { DataViewField } from '@kbn/data-views-plugin/common';
+import { DataViewField, FieldSpec } from '@kbn/data-views-plugin/common';
import { getDataViewFieldSubtypeMulti } from '@kbn/es-query/src/utils';
import { FIELDS_LIMIT_SETTING, SEARCH_FIELDS_FROM_SOURCE } from '@kbn/discover-utils';
import { FieldList } from '../../components/field_list';
@@ -225,8 +225,7 @@ export const UnifiedFieldListSidebarComponent: React.FC
- fieldSpecArr.map((fieldSpec) => new DataViewField(fieldSpec)),
+ getNewFieldsBySpec,
});
useEffect(() => {
@@ -461,3 +460,7 @@ function calculateMultiFields(
});
return map;
}
+
+function getNewFieldsBySpec(fieldSpecArr: FieldSpec[]): DataViewField[] {
+ return fieldSpecArr.map((fieldSpec) => new DataViewField(fieldSpec));
+}
diff --git a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
index 7826c815b9af3..a733643008b11 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
@@ -120,7 +120,7 @@ export const useExistingFieldsFetcher = (
setActiveRequests((value) => value + 1);
- const hasRestrictions = Boolean(dataView.getAggregationRestrictions?.());
+ const hasRestrictions = Boolean(dataView?.getAggregationRestrictions?.());
const info: ExistingFieldsInfo = {
...unknownInfo,
numberOfFetches,
@@ -254,12 +254,7 @@ export const useExistingFieldsFetcher = (
);
};
-export const useExistingFieldsReader: () => {
- getFieldsExistenceStatus: (dataViewId: string) => ExistenceFetchStatus;
- isFieldsExistenceInfoUnavailable: (dataViewId: string) => boolean;
- getNewFields: (dataViewId: string) => FieldSpec[];
- hasFieldData: (dataViewId: string, fieldName: string) => boolean;
-} = () => {
+export const useExistingFieldsReader: () => ExistingFieldsReader = () => {
const mountedRef = useRef(true);
const [existingFieldsByDataViewMap, setExistingFieldsByDataViewMap] =
useState(globalMap$.getValue());
diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
index bfc32be695120..381803ac74345 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
@@ -7,11 +7,12 @@
*/
import { groupBy } from 'lodash';
-import { useEffect, useMemo, useState, useRef } from 'react';
+import { useEffect, useMemo, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { type CoreStart } from '@kbn/core-lifecycle-browser';
import type { DataView, DataViewField, FieldSpec } from '@kbn/data-views-plugin/common';
import { type DataViewsContract } from '@kbn/data-views-plugin/public';
+import { useNewFields } from './use_new_fields';
import {
type FieldListGroups,
type FieldsGroup,
@@ -41,7 +42,7 @@ export interface GroupedFieldsParams {
onOverrideFieldGroupDetails?: OverrideFieldGroupDetails;
onSupportedFieldFilter?: (field: T) => boolean;
onSelectedFieldFilter?: (field: T) => boolean;
- getNewFieldsBySpec?: (field: FieldSpec[], dataView: DataView | null) => T[];
+ getNewFieldsBySpec?: (fields: FieldSpec[], dataView: DataView | null) => T[];
}
export interface GroupedFieldsResult {
@@ -77,8 +78,7 @@ export function useGroupedFields({
getCustomFieldType,
onSupportedFieldFilter,
});
- const allFieldsToReturn = useRef(allFields);
- const hasNewFields = useRef(false);
+
const onFilterFieldList = fieldListFilters.onFilterField;
const [dataView, setDataView] = useState(null);
const isAffectedByTimeFilter = Boolean(dataView?.timeFieldName);
@@ -107,6 +107,13 @@ export function useGroupedFields({
// if field existence information changed, reload the data view too
}, [dataViewId, services.dataViews, setDataView, hasFieldDataHandler]);
+ const { allFieldsModified, hasNewFields } = useNewFields({
+ dataView,
+ allFields,
+ getNewFieldsBySpec,
+ fieldsExistenceReader,
+ });
+
// important when switching from a known dataViewId to no data view (like in text-based queries)
useEffect(() => {
if (dataView && !dataViewId) {
@@ -127,25 +134,7 @@ export function useGroupedFields({
const selectedFields = sortedSelectedFields || [];
- // Taking care of new fields that were ingested after the selected data view was loaded
- // Those replace existing fields if updated, or are added to the list
- const newFields =
- dataViewId && getNewFieldsBySpec
- ? getNewFieldsBySpec(fieldsExistenceReader.getNewFields(dataViewId), dataView)
- : [];
- // Filtering out fields that e.g. Discover provides by analyzing the resultset, that are not part of the loaded DataView
- // These can be replaced by the new fields, which are mapped correctly, and therefore can be used in the right way
- const allFieldsExlNew =
- allFields && newFields.length
- ? allFields.filter((field) => !newFields.some((newField) => newField.name === field.name))
- : allFields;
-
- const allFieldsInclNew = newFields.length
- ? [...(allFieldsExlNew || []), ...newFields]
- : allFields || [];
- allFieldsToReturn.current = newFields.length ? allFieldsInclNew : allFields;
- hasNewFields.current = Boolean(newFields.length);
- const sortedFields = [...allFieldsInclNew].sort(sortFields);
+ const sortedFields = [...(allFieldsModified || [])].sort(sortFields);
const groupedFields = {
...getDefaultFieldGroups(),
@@ -338,20 +327,18 @@ export function useGroupedFields({
return fieldGroupDefinitions;
}, [
- sortedSelectedFields,
- allFields,
- popularFieldsLimit,
- isAffectedByGlobalFilter,
- isAffectedByTimeFilter,
- dataViewId,
- fieldsExistenceInfoUnavailable,
- onOverrideFieldGroupDetails,
- hasFieldDataHandler,
- fieldsExistenceReader,
- onSelectedFieldFilter,
+ allFieldsModified,
onSupportedFieldFilter,
+ onSelectedFieldFilter,
+ onOverrideFieldGroupDetails,
dataView,
- getNewFieldsBySpec,
+ dataViewId,
+ hasFieldDataHandler,
+ fieldsExistenceInfoUnavailable,
+ isAffectedByGlobalFilter,
+ isAffectedByTimeFilter,
+ popularFieldsLimit,
+ sortedSelectedFields,
]);
const fieldGroups: FieldListGroups = useMemo(() => {
@@ -410,8 +397,8 @@ export function useGroupedFields({
return {
fieldListGroupedProps,
fieldListFiltersProps: fieldListFilters.fieldListFiltersProps,
- allFieldsModified: allFieldsToReturn.current,
- hasNewFields: hasNewFields.current,
+ allFieldsModified,
+ hasNewFields,
};
}
diff --git a/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
new file mode 100644
index 0000000000000..5f16ad63a1101
--- /dev/null
+++ b/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
@@ -0,0 +1,51 @@
+/*
+ * 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 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 or the Server
+ * Side Public License, v 1.
+ */
+
+import { useMemo } from 'react';
+import type { DataView, DataViewField } from '@kbn/data-views-plugin/common';
+import { ExistingFieldsReader, type FieldListItem, GroupedFieldsParams } from '../..';
+
+/**
+ * This hook is used to get the new fields of previous fields for wildcards request, and merges those
+ * with the existing fields.
+ * @param dataView
+ * @param allFields
+ * @param getNewFieldsBySpec
+ * @param fieldsExistenceReader
+ */
+export function useNewFields({
+ dataView,
+ allFields,
+ getNewFieldsBySpec,
+ fieldsExistenceReader,
+}: {
+ dataView?: DataView | null;
+ allFields: GroupedFieldsParams['allFields'];
+ getNewFieldsBySpec: GroupedFieldsParams['getNewFieldsBySpec'];
+ fieldsExistenceReader: ExistingFieldsReader;
+}) {
+ const newFields =
+ allFields && dataView?.id && getNewFieldsBySpec
+ ? getNewFieldsBySpec(fieldsExistenceReader.getNewFields(dataView?.id), dataView)
+ : null;
+ const hasNewFields = Boolean(allFields && newFields && newFields.length > 0);
+
+ const allFieldsModified = useMemo(() => {
+ if (!allFields || !newFields?.length) return allFields;
+ // Filtering out fields that e.g. Discover provides with fields that were provided by the previous fieldsForWildcards request
+ // These can be replaced by the new fields, which are mapped correctly, and therefore can be used in the right way
+ const allFieldsExlNew =
+ allFields && newFields
+ ? allFields.filter((field) => !newFields.some((newField) => newField.name === field.name))
+ : allFields;
+
+ return newFields ? [...allFieldsExlNew, ...newFields] : allFields;
+ }, [newFields, allFields]);
+
+ return { allFieldsModified, hasNewFields };
+}
From 921a59825b51f1d68e7c99438a78c660d4a3ec4b Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Fri, 22 Dec 2023 15:48:44 +0100
Subject: [PATCH 136/168] Address review feedback
---
packages/kbn-unified-field-list/src/hooks/use_new_fields.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
index 5f16ad63a1101..a03b319858738 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
@@ -36,7 +36,7 @@ export function useNewFields({
const hasNewFields = Boolean(allFields && newFields && newFields.length > 0);
const allFieldsModified = useMemo(() => {
- if (!allFields || !newFields?.length) return allFields;
+ if (!allFields || !newFields?.length || !dataView) return allFields;
// Filtering out fields that e.g. Discover provides with fields that were provided by the previous fieldsForWildcards request
// These can be replaced by the new fields, which are mapped correctly, and therefore can be used in the right way
const allFieldsExlNew =
From ec55f89b965903975b541f9d2bb7f7fadd446490 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Fri, 22 Dec 2023 15:49:50 +0100
Subject: [PATCH 137/168] Fix error
---
packages/kbn-unified-field-list/src/hooks/use_new_fields.ts | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
index a03b319858738..b866aea306d2b 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
@@ -13,10 +13,6 @@ import { ExistingFieldsReader, type FieldListItem, GroupedFieldsParams } from '.
/**
* This hook is used to get the new fields of previous fields for wildcards request, and merges those
* with the existing fields.
- * @param dataView
- * @param allFields
- * @param getNewFieldsBySpec
- * @param fieldsExistenceReader
*/
export function useNewFields({
dataView,
@@ -45,7 +41,7 @@ export function useNewFields({
: allFields;
return newFields ? [...allFieldsExlNew, ...newFields] : allFields;
- }, [newFields, allFields]);
+ }, [newFields, allFields, dataView]);
return { allFieldsModified, hasNewFields };
}
From c76c87e375c9e639e86b9fa4cf802f55d7ddc497 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Fri, 22 Dec 2023 15:57:07 +0100
Subject: [PATCH 138/168] Add useMemo for new fields
---
packages/kbn-unified-field-list/src/hooks/use_new_fields.ts | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
index b866aea306d2b..ee18f31363fab 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
@@ -25,10 +25,12 @@ export function useNewFields({
getNewFieldsBySpec: GroupedFieldsParams['getNewFieldsBySpec'];
fieldsExistenceReader: ExistingFieldsReader;
}) {
- const newFields =
- allFields && dataView?.id && getNewFieldsBySpec
+ const newFields = useMemo(() => {
+ return allFields && dataView?.id && getNewFieldsBySpec
? getNewFieldsBySpec(fieldsExistenceReader.getNewFields(dataView?.id), dataView)
: null;
+ }, [allFields, dataView, fieldsExistenceReader, getNewFieldsBySpec]);
+
const hasNewFields = Boolean(allFields && newFields && newFields.length > 0);
const allFieldsModified = useMemo(() => {
From 165c3cde88970ed8f0794e4c1e8ffdc3bd4504f6 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Fri, 22 Dec 2023 16:04:53 +0100
Subject: [PATCH 139/168] Address review feedback
---
.../datasources/form_based/datapanel.tsx | 20 ++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
index 6ee8483658e68..2674293da399a 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
+++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
@@ -263,15 +263,7 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
onSupportedFieldFilter,
onSelectedFieldFilter,
onOverrideFieldGroupDetails,
- getNewFieldsBySpec: (spec, dataView) => {
- return spec.reduce((result: IndexPatternField[], fieldSpec: FieldSpec) => {
- const field = new DataViewField(fieldSpec);
- if (isFieldLensCompatible(field)) {
- result.push(buildIndexPatternField(field, dataView));
- }
- return result;
- }, []);
- },
+ getNewFieldsBySpec,
});
const closeFieldEditor = useRef<() => void | undefined>();
@@ -428,4 +420,14 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
);
};
+function getNewFieldsBySpec(spec: FieldSpec[], dataView: DataView | null) {
+ return spec.reduce((result: IndexPatternField[], fieldSpec: FieldSpec) => {
+ const field = new DataViewField(fieldSpec);
+ if (isFieldLensCompatible(field)) {
+ result.push(buildIndexPatternField(field, dataView));
+ }
+ return result;
+ }, []);
+}
+
export const MemoizedDataPanel = memo(InnerFormBasedDataPanel);
From 07f50583e26932b8ba718346a91131d076b633f7 Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Tue, 2 Jan 2024 06:06:03 +0000
Subject: [PATCH 140/168] [CI] Auto-commit changed files from 'node
scripts/notice'
---
NOTICE.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/NOTICE.txt b/NOTICE.txt
index 45af6e5231783..d02031c4b5a2b 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
Kibana source code with Kibana X-Pack source code
-Copyright 2012-2023 Elasticsearch B.V.
+Copyright 2012-2024 Elasticsearch B.V.
---
Pretty handling of logarithmic axes.
From 9170300a6a04c02cccadceb1dab38c27ed29a7ab Mon Sep 17 00:00:00 2001
From: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Date: Tue, 2 Jan 2024 10:17:40 +0000
Subject: [PATCH 141/168] [CI] Auto-commit changed files from 'node
scripts/notice'
---
NOTICE.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/NOTICE.txt b/NOTICE.txt
index 45af6e5231783..d02031c4b5a2b 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
Kibana source code with Kibana X-Pack source code
-Copyright 2012-2023 Elasticsearch B.V.
+Copyright 2012-2024 Elasticsearch B.V.
---
Pretty handling of logarithmic axes.
From 02a4537c466e228687adaf78d2281740f37faf04 Mon Sep 17 00:00:00 2001
From: Julia Rechkunova
Date: Wed, 3 Jan 2024 14:33:18 +0100
Subject: [PATCH 142/168] [Discover] Small fixes for types and memo deps. Add
tests.
---
.../field_list_sidebar.tsx | 2 +-
.../src/hooks/use_existing_fields.test.tsx | 48 +++++++++++
.../src/hooks/use_existing_fields.ts | 5 +-
.../src/hooks/use_grouped_fields.test.tsx | 78 ++++++++++++++++++
.../src/hooks/use_grouped_fields.ts | 6 +-
.../src/hooks/use_new_fields.test.tsx | 80 +++++++++++++++++++
.../src/hooks/use_new_fields.ts | 47 +++++++----
7 files changed, 243 insertions(+), 23 deletions(-)
create mode 100644 packages/kbn-unified-field-list/src/hooks/use_new_fields.test.tsx
diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
index 17ebe5b19286f..f8438b0917577 100644
--- a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
+++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx
@@ -22,7 +22,7 @@ import {
useEuiTheme,
} from '@elastic/eui';
import { ToolbarButton } from '@kbn/shared-ux-button-toolbar';
-import { DataViewField, FieldSpec } from '@kbn/data-views-plugin/common';
+import { DataViewField, type FieldSpec } from '@kbn/data-views-plugin/common';
import { getDataViewFieldSubtypeMulti } from '@kbn/es-query/src/utils';
import { FIELDS_LIMIT_SETTING, SEARCH_FIELDS_FROM_SOURCE } from '@kbn/discover-utils';
import { FieldList } from '../../components/field_list';
diff --git a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.test.tsx b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.test.tsx
index 7cf22950a4a7d..0af0e4abc8e0d 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.test.tsx
+++ b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.test.tsx
@@ -125,6 +125,7 @@ describe('UnifiedFieldList useExistingFields', () => {
expect(hookReader.result.current.getFieldsExistenceStatus(dataViewId)).toBe(
ExistenceFetchStatus.succeeded
);
+ expect(hookReader.result.current.getNewFields(dataViewId)).toStrictEqual([]);
// does not have existence info => works less restrictive
const anotherDataViewId = 'test-id';
@@ -140,6 +141,7 @@ describe('UnifiedFieldList useExistingFields', () => {
expect(hookReader.result.current.getFieldsExistenceStatus(anotherDataViewId)).toBe(
ExistenceFetchStatus.unknown
);
+ expect(hookReader.result.current.getNewFields(dataViewId)).toStrictEqual([]);
});
it('should work correctly with multiple readers', async () => {
@@ -217,6 +219,7 @@ describe('UnifiedFieldList useExistingFields', () => {
expect(currentResult.isFieldsExistenceInfoUnavailable(dataViewId)).toBe(true);
expect(currentResult.hasFieldData(dataViewId, dataView.fields[0].name)).toBe(true);
expect(currentResult.getFieldsExistenceStatus(dataViewId)).toBe(ExistenceFetchStatus.failed);
+ expect(currentResult.getNewFields(dataViewId)).toStrictEqual([]);
});
it('should work correctly for multiple data views', async () => {
@@ -533,4 +536,49 @@ describe('UnifiedFieldList useExistingFields', () => {
expect(params.onNoData).toHaveBeenCalledTimes(1); // still 1 time
});
+
+ it('should include newFields', async () => {
+ const newFields = [{ name: 'test', type: 'keyword', searchable: true, aggregatable: true }];
+
+ (ExistingFieldsServiceApi.loadFieldExisting as jest.Mock).mockImplementation(
+ async ({ dataView: currentDataView }) => {
+ return {
+ existingFieldNames: [currentDataView.fields[0].name],
+ newFields,
+ };
+ }
+ );
+
+ const params: ExistingFieldsFetcherParams = {
+ dataViews: [dataView],
+ services: mockedServices,
+ fromDate: '2019-01-01',
+ toDate: '2020-01-01',
+ query: { query: '', language: 'lucene' },
+ filters: [],
+ };
+ const hookFetcher = renderHook(useExistingFieldsFetcher, {
+ initialProps: params,
+ });
+
+ const hookReader = renderHook(useExistingFieldsReader);
+ await hookFetcher.waitForNextUpdate();
+
+ expect(ExistingFieldsServiceApi.loadFieldExisting).toHaveBeenCalledWith(
+ expect.objectContaining({
+ fromDate: '2019-01-01',
+ toDate: '2020-01-01',
+ dslQuery,
+ dataView,
+ timeFieldName: dataView.timeFieldName,
+ })
+ );
+
+ expect(hookReader.result.current.getFieldsExistenceStatus(dataView.id!)).toBe(
+ ExistenceFetchStatus.succeeded
+ );
+
+ expect(hookReader.result.current.getNewFields(dataView.id!)).toBe(newFields);
+ expect(hookReader.result.current.getNewFields('another-id')).toStrictEqual([]);
+ });
});
diff --git a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
index a733643008b11..e71d89d6b3626 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
@@ -20,6 +20,7 @@ import { ExistenceFetchStatus } from '../types';
const getBuildEsQueryAsync = async () => (await import('@kbn/es-query')).buildEsQuery;
const generateId = htmlIdGenerator();
+const DEFAULT_EMPTY_NEW_FIELDS: FieldSpec[] = [];
export interface ExistingFieldsInfo {
fetchStatus: ExistenceFetchStatus;
@@ -294,10 +295,10 @@ export const useExistingFieldsReader: () => ExistingFieldsReader = () => {
const info = existingFieldsByDataViewMap[dataViewId];
if (info?.fetchStatus === ExistenceFetchStatus.succeeded) {
- return info?.newFields ?? [];
+ return info?.newFields ?? DEFAULT_EMPTY_NEW_FIELDS;
}
- return [];
+ return DEFAULT_EMPTY_NEW_FIELDS;
},
[existingFieldsByDataViewMap]
);
diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.test.tsx b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.test.tsx
index 78b34329e0bf0..4a937f86bd5c0 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.test.tsx
+++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.test.tsx
@@ -187,6 +187,8 @@ describe('UnifiedFieldList useGroupedFields()', () => {
expect(fieldListGroupedProps.fieldsExistenceStatus).toBe(ExistenceFetchStatus.succeeded);
expect(fieldListGroupedProps.fieldsExistInIndex).toBe(true);
+ expect(result.current.allFieldsModified).toBe(allFields);
+ expect(result.current.hasNewFields).toBe(false);
rerender({
...props,
@@ -200,6 +202,82 @@ describe('UnifiedFieldList useGroupedFields()', () => {
expect(result.current.fieldListGroupedProps.scrollToTopResetCounter).not.toBe(
scrollToTopResetCounter1
);
+ expect(result.current.allFieldsModified).toBe(allFields);
+ expect(result.current.hasNewFields).toBe(false);
+
+ (ExistenceApi.useExistingFieldsReader as jest.Mock).mockRestore();
+ });
+
+ it('should work correctly with new fields', async () => {
+ const props: GroupedFieldsParams = {
+ dataViewId: dataView.id!,
+ allFields,
+ services: mockedServices,
+ getNewFieldsBySpec: (spec) => spec.map((field) => new DataViewField(field)),
+ };
+
+ const newField = { name: 'test', type: 'keyword', searchable: true, aggregatable: true };
+
+ jest.spyOn(ExistenceApi, 'useExistingFieldsReader').mockImplementation(
+ (): ExistingFieldsReader => ({
+ hasFieldData: (dataViewId) => {
+ return dataViewId === props.dataViewId;
+ },
+ getFieldsExistenceStatus: (dataViewId) =>
+ dataViewId === props.dataViewId
+ ? ExistenceFetchStatus.succeeded
+ : ExistenceFetchStatus.unknown,
+ isFieldsExistenceInfoUnavailable: (dataViewId) => dataViewId !== props.dataViewId,
+ getNewFields: () => [newField],
+ })
+ );
+
+ const { result, waitForNextUpdate, rerender } = renderHook(useGroupedFields, {
+ initialProps: props,
+ });
+
+ await waitForNextUpdate();
+
+ let fieldListGroupedProps = result.current.fieldListGroupedProps;
+ const fieldGroups = fieldListGroupedProps.fieldGroups;
+ const scrollToTopResetCounter1 = fieldListGroupedProps.scrollToTopResetCounter;
+
+ expect(
+ Object.keys(fieldGroups!).map(
+ (key) => `${key}-${fieldGroups![key as FieldsGroupNames]?.fields.length}`
+ )
+ ).toStrictEqual([
+ 'SpecialFields-0',
+ 'SelectedFields-0',
+ 'PopularFields-0',
+ 'AvailableFields-25',
+ 'UnmappedFields-1',
+ 'EmptyFields-0',
+ 'MetaFields-3',
+ ]);
+
+ expect(fieldListGroupedProps.fieldsExistenceStatus).toBe(ExistenceFetchStatus.succeeded);
+ expect(fieldListGroupedProps.fieldsExistInIndex).toBe(true);
+ expect(result.current.allFieldsModified).toStrictEqual([
+ ...allFields,
+ new DataViewField(newField),
+ ]);
+ expect(result.current.hasNewFields).toBe(true);
+
+ rerender({
+ ...props,
+ dataViewId: null, // for text-based queries
+ allFields,
+ });
+
+ fieldListGroupedProps = result.current.fieldListGroupedProps;
+ expect(fieldListGroupedProps.fieldsExistenceStatus).toBe(ExistenceFetchStatus.succeeded);
+ expect(fieldListGroupedProps.fieldsExistInIndex).toBe(true);
+ expect(result.current.fieldListGroupedProps.scrollToTopResetCounter).not.toBe(
+ scrollToTopResetCounter1
+ );
+ expect(result.current.allFieldsModified).toBe(allFields);
+ expect(result.current.hasNewFields).toBe(false);
(ExistenceApi.useExistingFieldsReader as jest.Mock).mockRestore();
});
diff --git a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
index a11d897c37199..7853c7e67800b 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_grouped_fields.ts
@@ -10,9 +10,9 @@ import { groupBy } from 'lodash';
import { useEffect, useMemo, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { type CoreStart } from '@kbn/core-lifecycle-browser';
-import type { DataView, DataViewField, FieldSpec } from '@kbn/data-views-plugin/common';
+import type { DataView, DataViewField } from '@kbn/data-views-plugin/common';
import { type DataViewsContract } from '@kbn/data-views-plugin/public';
-import { useNewFields } from './use_new_fields';
+import { type UseNewFieldsParams, useNewFields } from './use_new_fields';
import {
type FieldListGroups,
type FieldsGroup,
@@ -42,7 +42,7 @@ export interface GroupedFieldsParams {
onOverrideFieldGroupDetails?: OverrideFieldGroupDetails;
onSupportedFieldFilter?: (field: T) => boolean;
onSelectedFieldFilter?: (field: T) => boolean;
- getNewFieldsBySpec?: (fields: FieldSpec[], dataView: DataView | null) => T[];
+ getNewFieldsBySpec?: UseNewFieldsParams['getNewFieldsBySpec'];
}
export interface GroupedFieldsResult {
diff --git a/packages/kbn-unified-field-list/src/hooks/use_new_fields.test.tsx b/packages/kbn-unified-field-list/src/hooks/use_new_fields.test.tsx
new file mode 100644
index 0000000000000..2be5d50764bc9
--- /dev/null
+++ b/packages/kbn-unified-field-list/src/hooks/use_new_fields.test.tsx
@@ -0,0 +1,80 @@
+/*
+ * 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 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 or the Server
+ * Side Public License, v 1.
+ */
+
+import { renderHook } from '@testing-library/react-hooks';
+import { stubLogstashDataView as dataView } from '@kbn/data-views-plugin/common/data_view.stub';
+import { DataViewField } from '@kbn/data-views-plugin/common';
+import { useNewFields, type UseNewFieldsParams } from './use_new_fields';
+import { type ExistingFieldsReader } from './use_existing_fields';
+import { ExistenceFetchStatus } from '../types';
+
+const fieldsExistenceReader: ExistingFieldsReader = {
+ hasFieldData: (dataViewId) => {
+ return dataViewId === dataView.id;
+ },
+ getFieldsExistenceStatus: (dataViewId) =>
+ dataViewId === dataView.id ? ExistenceFetchStatus.succeeded : ExistenceFetchStatus.unknown,
+ isFieldsExistenceInfoUnavailable: (dataViewId) => dataViewId !== dataView.id,
+ getNewFields: () => [],
+};
+
+describe('UnifiedFieldList useNewFields()', () => {
+ const allFields = dataView.fields;
+
+ it('should work correctly in loading state', async () => {
+ const props: UseNewFieldsParams = {
+ dataView,
+ allFields: null,
+ fieldsExistenceReader,
+ };
+ const { result } = renderHook(useNewFields, {
+ initialProps: props,
+ });
+
+ expect(result.current.allFieldsModified).toBe(null);
+ expect(result.current.hasNewFields).toBe(false);
+ });
+
+ it('should work correctly with empty new fields', async () => {
+ const props: UseNewFieldsParams = {
+ dataView,
+ allFields,
+ fieldsExistenceReader,
+ };
+ const { result } = renderHook(useNewFields, {
+ initialProps: props,
+ });
+
+ expect(result.current.allFieldsModified).toBe(allFields);
+ expect(result.current.hasNewFields).toBe(false);
+ });
+
+ it('should work correctly with new fields', async () => {
+ const newField = { name: 'test', type: 'keyword', searchable: true, aggregatable: true };
+ const newField2 = { ...newField, name: 'test2' };
+ const props: UseNewFieldsParams = {
+ dataView,
+ allFields,
+ fieldsExistenceReader: {
+ ...fieldsExistenceReader,
+ getNewFields: () => [newField, newField2],
+ },
+ getNewFieldsBySpec: (spec) => spec.map((field) => new DataViewField(field)),
+ };
+ const { result } = renderHook(useNewFields, {
+ initialProps: props,
+ });
+
+ expect(result.current.allFieldsModified).toStrictEqual([
+ ...allFields,
+ new DataViewField(newField),
+ new DataViewField(newField2),
+ ]);
+ expect(result.current.hasNewFields).toBe(true);
+ });
+});
diff --git a/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
index ee18f31363fab..51e143cc524c3 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_new_fields.ts
@@ -7,8 +7,22 @@
*/
import { useMemo } from 'react';
+import type { FieldSpec } from '@kbn/data-views-plugin/common';
import type { DataView, DataViewField } from '@kbn/data-views-plugin/common';
-import { ExistingFieldsReader, type FieldListItem, GroupedFieldsParams } from '../..';
+import type { FieldListItem } from '../types';
+import type { ExistingFieldsReader } from './use_existing_fields';
+
+export interface UseNewFieldsParams {
+ dataView?: DataView | null;
+ allFields: T[] | null; // `null` is for loading indicator
+ getNewFieldsBySpec?: (fields: FieldSpec[], dataView: DataView | null) => T[];
+ fieldsExistenceReader: ExistingFieldsReader;
+}
+
+export interface UseNewFieldsResult {
+ allFieldsModified: T[] | null;
+ hasNewFields: boolean;
+}
/**
* This hook is used to get the new fields of previous fields for wildcards request, and merges those
@@ -19,31 +33,30 @@ export function useNewFields({
allFields,
getNewFieldsBySpec,
fieldsExistenceReader,
-}: {
- dataView?: DataView | null;
- allFields: GroupedFieldsParams['allFields'];
- getNewFieldsBySpec: GroupedFieldsParams['getNewFieldsBySpec'];
- fieldsExistenceReader: ExistingFieldsReader;
-}) {
+}: UseNewFieldsParams): UseNewFieldsResult {
+ const dataViewId = dataView?.id;
+
const newFields = useMemo(() => {
- return allFields && dataView?.id && getNewFieldsBySpec
- ? getNewFieldsBySpec(fieldsExistenceReader.getNewFields(dataView?.id), dataView)
- : null;
+ const newLoadedFields =
+ allFields && dataView?.id && getNewFieldsBySpec
+ ? getNewFieldsBySpec(fieldsExistenceReader.getNewFields(dataView?.id), dataView)
+ : null;
+
+ return newLoadedFields?.length ? newLoadedFields : null;
}, [allFields, dataView, fieldsExistenceReader, getNewFieldsBySpec]);
const hasNewFields = Boolean(allFields && newFields && newFields.length > 0);
const allFieldsModified = useMemo(() => {
- if (!allFields || !newFields?.length || !dataView) return allFields;
+ if (!allFields || !newFields?.length || !dataViewId) return allFields;
// Filtering out fields that e.g. Discover provides with fields that were provided by the previous fieldsForWildcards request
// These can be replaced by the new fields, which are mapped correctly, and therefore can be used in the right way
- const allFieldsExlNew =
- allFields && newFields
- ? allFields.filter((field) => !newFields.some((newField) => newField.name === field.name))
- : allFields;
+ const allFieldsExlNew = allFields.filter(
+ (field) => !newFields.some((newField) => newField.name === field.name)
+ );
- return newFields ? [...allFieldsExlNew, ...newFields] : allFields;
- }, [newFields, allFields, dataView]);
+ return [...allFieldsExlNew, ...newFields];
+ }, [newFields, allFields, dataViewId]);
return { allFieldsModified, hasNewFields };
}
From 04e40bed882e18b359afa4af70589a172ec110d8 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Thu, 4 Jan 2024 23:21:00 -0600
Subject: [PATCH 143/168] cleanup
---
.../edit_index_pattern/edit_index_pattern.tsx | 14 +++----
.../index_header/index_header.tsx | 33 +--------------
.../edit_index_pattern/tabs/tabs.tsx | 40 +++++++++++++++++++
src/plugins/data_views/common/utils.ts | 2 +-
.../data_views/data_views_api_client.ts | 2 +-
src/plugins/data_views/public/plugin.ts | 2 +-
src/plugins/data_views/server/constants.ts | 3 ++
7 files changed, 55 insertions(+), 41 deletions(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
index 20855e4dbbc0c..f850ef4ec3671 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx
@@ -249,15 +249,8 @@ export const EditIndexPattern = withRouter(
deleteIndexPatternClick={() =>
removeHandler([indexPattern as RemoveDataViewProps], {warning}
)
}
- refreshIndexPatternClick={async () => {
- setIsRefreshing(true);
- await dataViews.refreshFields(indexPattern, false, true);
- setRefreshCount(refreshCount + 1); // rerender field list
- setIsRefreshing(false);
- }}
defaultIndex={defaultIndex}
canSave={userEditPermission}
- isRefreshing={isRefreshing}
>
@@ -342,6 +335,13 @@ export const EditIndexPattern = withRouter(
setFields(indexPattern.getNonScriptedFields());
setCompositeRuntimeFields(getCompositeRuntimeFields(indexPattern));
}}
+ refreshIndexPatternClick={async () => {
+ setIsRefreshing(true);
+ await dataViews.refreshFields(indexPattern, false, true);
+ setRefreshCount(refreshCount + 1); // rerender field list
+ setIsRefreshing(false);
+ }}
+ isRefreshing={isRefreshing}
/>
{displayIndexPatternEditor}
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
index 8a3792c6fb333..1d73ef615e26c 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
@@ -8,7 +8,7 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
-import { EuiButton, EuiButtonEmpty, EuiPageHeader, EuiToolTip } from '@elastic/eui';
+import { EuiButton, EuiButtonEmpty, EuiPageHeader } from '@elastic/eui';
import { DataView } from '@kbn/data-views-plugin/public';
interface IndexHeaderProps {
@@ -46,32 +46,14 @@ const removeTooltip = i18n.translate('indexPatternManagement.editDataView.remove
defaultMessage: 'Delete',
});
-const refreshAriaLabel = i18n.translate('indexPatternManagement.editDataView.refreshAria', {
- defaultMessage: 'Refresh',
-});
-
-const refreshTooltip = i18n.translate('indexPatternManagement.editDataView.refreshTooltip', {
- defaultMessage: 'Refresh local copy of data view field list',
-});
-
-const refreshLabel = i18n.translate('indexPatternManagement.editDataView.refreshLabel', {
- defaultMessage: 'Refresh',
-});
-
-const isLoadingLabel = i18n.translate('indexPatternManagement.editDataView.refreshLoading', {
- defaultMessage: 'Loading...',
-});
-
export const IndexHeader: React.FC = ({
defaultIndex,
indexPattern,
setDefault,
editIndexPatternClick,
deleteIndexPatternClick,
- refreshIndexPatternClick,
children,
canSave,
- isRefreshing,
}) => {
return (
= ({
{editTooltip}
),
- {refreshTooltip}}>
-
- {isRefreshing ? isLoadingLabel : refreshLabel}
-
- ,
+ ,
defaultIndex !== indexPattern.id && setDefault && canSave && indexPattern.isPersisted() && (
{
relationships: SavedObjectRelation[];
allowedTypes: SavedObjectManagementTypeInfo[];
compositeRuntimeFields: Record;
+ refreshIndexPatternClick: () => void;
+ isRefreshing?: boolean;
}
interface FilterItems {
@@ -139,6 +143,14 @@ const addFieldButtonLabel = i18n.translate(
}
);
+const refreshAriaLabel = i18n.translate('indexPatternManagement.editDataView.refreshAria', {
+ defaultMessage: 'Refresh',
+});
+
+const refreshTooltip = i18n.translate('indexPatternManagement.editDataView.refreshTooltip', {
+ defaultMessage: 'Refresh local copy of data view field list',
+});
+
const SCHEMA_ITEMS: FilterItems[] = [
{
value: 'runtime',
@@ -159,6 +171,8 @@ export const Tabs: React.FC = ({
relationships,
allowedTypes,
compositeRuntimeFields,
+ refreshIndexPatternClick,
+ isRefreshing,
}) => {
const {
uiSettings,
@@ -323,6 +337,8 @@ export const Tabs: React.FC = ({
[uiSettings]
);
+ const refreshRef = useRef(null);
+
const userEditPermission = dataViews.getCanSaveSync();
const getFilterSection = useCallback(
(type: string) => {
@@ -428,6 +444,28 @@ export const Tabs: React.FC = ({
+
+
+ {refreshTooltip}}>
+ {
+ refreshIndexPatternClick();
+ // clear tooltip focus
+ if (refreshRef.current) {
+ refreshRef.current.blur();
+ }
+ }}
+ iconType="refresh"
+ aria-label={refreshAriaLabel}
+ data-test-subj="refreshDataViewButton"
+ isLoading={isRefreshing}
+ isDisabled={isRefreshing}
+ display="base"
+ size="m"
+ />
+
+
{userEditPermission && (
openFieldEditor()} data-test-subj="addField">
@@ -505,6 +543,8 @@ export const Tabs: React.FC = ({
updateFieldFilter,
updateFieldTypeFilter,
updateSchemaFieldTypeFilter,
+ isRefreshing,
+ refreshIndexPatternClick,
]
);
diff --git a/src/plugins/data_views/common/utils.ts b/src/plugins/data_views/common/utils.ts
index b77696e15ba79..61de24dfcf0c3 100644
--- a/src/plugins/data_views/common/utils.ts
+++ b/src/plugins/data_views/common/utils.ts
@@ -29,7 +29,7 @@ export async function findByName(client: PersistenceAPI, name: string) {
}
export function unwrapEtag(ifNoneMatch: string) {
- let requestHash = ifNoneMatch.slice(1, -1);
+ let requestHash = ifNoneMatch.replace(/^"(.+)"$/, '$1');
if (requestHash.indexOf('-') > -1) {
requestHash = requestHash.split('-')[0];
}
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index c65db9e5c736f..29791d3567761 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -46,7 +46,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
forceRefresh?: boolean
): Promise | undefined> {
const asResponse = true;
- const cacheOptions = forceRefresh ? { cache: 'no-cache' as RequestCache } : {};
+ const cacheOptions: { cache?: RequestCache } = forceRefresh ? { cache: 'no-cache' } : {};
const userId = await this.getCurrentUserId();
const userHash = userId ? await sha1(userId) : '';
diff --git a/src/plugins/data_views/public/plugin.ts b/src/plugins/data_views/public/plugin.ts
index 6d8d2d9fde217..8ff545d8585e1 100644
--- a/src/plugins/data_views/public/plugin.ts
+++ b/src/plugins/data_views/public/plugin.ts
@@ -101,7 +101,7 @@ export class DataViewsPublicPlugin
hasData: this.hasData.start(core),
uiSettings: new UiSettingsPublicToCommon(uiSettings),
savedObjectsClient: new ContentMagementWrapper(contentManagement.client),
- apiClient: new DataViewsApiClient(http, this.userIdGetter),
+ apiClient: new DataViewsApiClient(http, () => this.userIdGetter()),
fieldFormats,
http,
onNotification: (toastInputFields, key) => {
diff --git a/src/plugins/data_views/server/constants.ts b/src/plugins/data_views/server/constants.ts
index f204fffe8fc6e..67235ae3af16d 100644
--- a/src/plugins/data_views/server/constants.ts
+++ b/src/plugins/data_views/server/constants.ts
@@ -94,4 +94,7 @@ export const INITIAL_REST_VERSION = '2023-10-31';
export const INITIAL_REST_VERSION_INTERNAL = '1';
+/**
+ * Default field caps cache max-age in seconds
+ */
export const DEFAULT_FIELD_CACHE_FRESHNESS = 5;
From a01dd651384e0224da862ffc536e85bcd49ea3d2 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 5 Jan 2024 02:15:38 -0600
Subject: [PATCH 144/168] fix display of advanced setting
---
src/plugins/data_views/server/index.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_views/server/index.ts b/src/plugins/data_views/server/index.ts
index 591870bbad029..d8382046183a3 100644
--- a/src/plugins/data_views/server/index.ts
+++ b/src/plugins/data_views/server/index.ts
@@ -50,7 +50,7 @@ const configSchema = schema.object({
schema.contextRef('serverless'),
true,
schema.boolean({ defaultValue: false }),
- schema.never()
+ schema.boolean({ defaultValue: true })
),
});
From f67dc854da4738c28651853340fc36cb37960bf3 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 5 Jan 2024 21:57:48 -0600
Subject: [PATCH 145/168] add functional test to check for presence and absense
of advanced setting
---
.../apps/management/data_views/_cache.ts | 22 +++++++++++++++++++
test/functional/apps/management/index.ts | 1 +
.../common/management/data_views/_cache.ts | 21 ++++++++++++++++++
.../common/management/data_views/index.ts | 1 +
4 files changed, 45 insertions(+)
create mode 100644 test/functional/apps/management/data_views/_cache.ts
create mode 100644 x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
diff --git a/test/functional/apps/management/data_views/_cache.ts b/test/functional/apps/management/data_views/_cache.ts
new file mode 100644
index 0000000000000..f384d253de79d
--- /dev/null
+++ b/test/functional/apps/management/data_views/_cache.ts
@@ -0,0 +1,22 @@
+/*
+ * 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 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 or the Server
+ * Side Public License, v 1.
+ */
+
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default function ({ getService, getPageObjects }: FtrProviderContext) {
+ const PageObjects = getPageObjects(['settings', 'common', 'header']);
+ const find = getService('find');
+
+ describe('"Create Index Pattern" wizard', async function () {
+ await PageObjects.settings.navigateTo();
+ await PageObjects.settings.clickKibanaSettings();
+ const cacheSetting = await find.byCssSelector('#data_views:cache_max_age-group');
+ expect(cacheSetting).to.not.be(undefined);
+ });
+}
diff --git a/test/functional/apps/management/index.ts b/test/functional/apps/management/index.ts
index 85de9b5de0926..7b4a0dd5af000 100644
--- a/test/functional/apps/management/index.ts
+++ b/test/functional/apps/management/index.ts
@@ -21,6 +21,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
await esArchiver.unload('test/functional/fixtures/es_archiver/makelogs');
});
+ loadTestFile(require.resolve('./data_views/_cache'));
loadTestFile(require.resolve('./data_views/_create_index_pattern_wizard'));
loadTestFile(require.resolve('./data_views/_data_view_create_delete'));
loadTestFile(require.resolve('./data_views/_index_pattern_results_sort'));
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
new file mode 100644
index 0000000000000..3696bf9965a7b
--- /dev/null
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
@@ -0,0 +1,21 @@
+/*
+ * 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; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../../ftr_provider_context';
+
+export default function ({ getService, getPageObjects }: FtrProviderContext) {
+ const PageObjects = getPageObjects(['settings', 'common', 'header']);
+ const find = getService('find');
+
+ describe('"Create Index Pattern" wizard', async function () {
+ await PageObjects.settings.navigateTo();
+ await PageObjects.settings.clickKibanaSettings();
+ const cacheSetting = await find.byCssSelector('#data_views:cache_max_age-group');
+ expect(cacheSetting).to.be(undefined);
+ });
+}
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts
index 6a512b6d6e273..cc14ab8d6d526 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts
@@ -23,6 +23,7 @@ export default ({ getService, loadTestFile, getPageObject }: FtrProviderContext)
await esArchiver.unload('test/functional/fixtures/es_archiver/makelogs');
});
+ loadTestFile(require.resolve('./_cache'));
loadTestFile(require.resolve('./serverless'));
loadTestFile(require.resolve('./_data_view_create_delete'));
loadTestFile(require.resolve('./_runtime_fields'));
From 603708e4b47e5937f1cf4bc8d84e456b13e3ce35 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 5 Jan 2024 22:52:19 -0600
Subject: [PATCH 146/168] fix tests, improve buttons?
---
.../edit_index_pattern/tabs/tabs.tsx | 31 ++++++++++++++-----
test/functional/apps/management/index.ts | 2 +-
.../common/management/data_views/index.ts | 2 +-
3 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
index 4927c1d1b5b58..ca60f2742da62 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
@@ -19,7 +19,6 @@ import {
EuiTabbedContentTab,
EuiSpacer,
EuiFieldSearch,
- EuiButton,
EuiFilterSelectItem,
FilterChecked,
EuiToolTip,
@@ -338,6 +337,7 @@ export const Tabs: React.FC = ({
);
const refreshRef = useRef(null);
+ const addFieldRef = useRef(null);
const userEditPermission = dataViews.getCanSaveSync();
const getFilterSection = useCallback(
@@ -445,6 +445,28 @@ export const Tabs: React.FC = ({
+ {userEditPermission && (
+
+ {addFieldButtonLabel}}>
+ {
+ openFieldEditor();
+ // clear tooltip focus
+ if (addFieldRef.current) {
+ addFieldRef.current.blur();
+ }
+ }}
+ data-test-subj="addField"
+ iconType="plus"
+ aria-label={addFieldButtonLabel}
+ />
+
+
+ )}
+
{refreshTooltip}}>
= ({
/>
- {userEditPermission && (
-
- openFieldEditor()} data-test-subj="addField">
- {addFieldButtonLabel}
-
-
- )}
>
)}
{type === TAB_SCRIPTED_FIELDS && scriptedFieldLanguages.length > 0 && (
diff --git a/test/functional/apps/management/index.ts b/test/functional/apps/management/index.ts
index 7b4a0dd5af000..808a4aaccc9c2 100644
--- a/test/functional/apps/management/index.ts
+++ b/test/functional/apps/management/index.ts
@@ -21,7 +21,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
await esArchiver.unload('test/functional/fixtures/es_archiver/makelogs');
});
- loadTestFile(require.resolve('./data_views/_cache'));
loadTestFile(require.resolve('./data_views/_create_index_pattern_wizard'));
loadTestFile(require.resolve('./data_views/_data_view_create_delete'));
loadTestFile(require.resolve('./data_views/_index_pattern_results_sort'));
@@ -48,5 +47,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./data_views/_edit_field'));
loadTestFile(require.resolve('./_files'));
loadTestFile(require.resolve('./_data_view_field_filters'));
+ loadTestFile(require.resolve('./data_views/_cache'));
});
}
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts
index cc14ab8d6d526..69fec71b2ad22 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/index.ts
@@ -23,7 +23,6 @@ export default ({ getService, loadTestFile, getPageObject }: FtrProviderContext)
await esArchiver.unload('test/functional/fixtures/es_archiver/makelogs');
});
- loadTestFile(require.resolve('./_cache'));
loadTestFile(require.resolve('./serverless'));
loadTestFile(require.resolve('./_data_view_create_delete'));
loadTestFile(require.resolve('./_runtime_fields'));
@@ -31,5 +30,6 @@ export default ({ getService, loadTestFile, getPageObject }: FtrProviderContext)
loadTestFile(require.resolve('./_exclude_index_pattern'));
loadTestFile(require.resolve('./_index_pattern_filter'));
loadTestFile(require.resolve('./_edit_field'));
+ loadTestFile(require.resolve('./_cache'));
});
};
From 937366bc3f829ed391fef737cf660c06bd2a1223 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 5 Jan 2024 23:40:56 -0600
Subject: [PATCH 147/168] fix functional tests
---
test/functional/apps/management/data_views/_cache.ts | 5 ++++-
.../test_suites/common/management/data_views/_cache.ts | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/test/functional/apps/management/data_views/_cache.ts b/test/functional/apps/management/data_views/_cache.ts
index f384d253de79d..f6ec9dd427981 100644
--- a/test/functional/apps/management/data_views/_cache.ts
+++ b/test/functional/apps/management/data_views/_cache.ts
@@ -13,8 +13,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['settings', 'common', 'header']);
const find = getService('find');
- describe('"Create Index Pattern" wizard', async function () {
+ before(async () => {
await PageObjects.settings.navigateTo();
+ });
+
+ describe('"Create Index Pattern" wizard', async function () {
await PageObjects.settings.clickKibanaSettings();
const cacheSetting = await find.byCssSelector('#data_views:cache_max_age-group');
expect(cacheSetting).to.not.be(undefined);
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
index 3696bf9965a7b..f654272623dc7 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
@@ -12,8 +12,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['settings', 'common', 'header']);
const find = getService('find');
- describe('"Create Index Pattern" wizard', async function () {
+ before(async () => {
await PageObjects.settings.navigateTo();
+ });
+
+ describe('"Create Index Pattern" wizard', async function () {
await PageObjects.settings.clickKibanaSettings();
const cacheSetting = await find.byCssSelector('#data_views:cache_max_age-group');
expect(cacheSetting).to.be(undefined);
From a6bbc4037bee7881d1db9c59038a23afba8cb936 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 6 Jan 2024 00:26:28 -0600
Subject: [PATCH 148/168] fix functional tests
---
.../apps/management/data_views/_cache.ts | 17 +++++++++--------
.../common/management/data_views/_cache.ts | 16 +++++++++-------
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/test/functional/apps/management/data_views/_cache.ts b/test/functional/apps/management/data_views/_cache.ts
index f6ec9dd427981..f05a8b9bdd3a4 100644
--- a/test/functional/apps/management/data_views/_cache.ts
+++ b/test/functional/apps/management/data_views/_cache.ts
@@ -13,13 +13,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['settings', 'common', 'header']);
const find = getService('find');
- before(async () => {
- await PageObjects.settings.navigateTo();
- });
-
- describe('"Create Index Pattern" wizard', async function () {
- await PageObjects.settings.clickKibanaSettings();
- const cacheSetting = await find.byCssSelector('#data_views:cache_max_age-group');
- expect(cacheSetting).to.not.be(undefined);
+ describe('Data view field caps cache advanced setting', async function () {
+ before(async () => {
+ await PageObjects.settings.navigateTo();
+ });
+ it('should have cache setting', async () => {
+ await PageObjects.settings.clickKibanaSettings();
+ const cacheSetting = await find.byCssSelector('#data_views:cache_max_age-group');
+ expect(cacheSetting).to.not.be(undefined);
+ });
});
}
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
index f654272623dc7..083fe2832537e 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
@@ -12,13 +12,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['settings', 'common', 'header']);
const find = getService('find');
- before(async () => {
- await PageObjects.settings.navigateTo();
- });
+ describe('Data view field caps cache advanced setting', async function () {
+ before(async () => {
+ await PageObjects.settings.navigateTo();
+ });
- describe('"Create Index Pattern" wizard', async function () {
- await PageObjects.settings.clickKibanaSettings();
- const cacheSetting = await find.byCssSelector('#data_views:cache_max_age-group');
- expect(cacheSetting).to.be(undefined);
+ it('should not have cache setting', async () => {
+ await PageObjects.settings.clickKibanaSettings();
+ const cacheSetting = await find.byCssSelector('#data_views:cache_max_age-group');
+ expect(cacheSetting).to.be(undefined);
+ });
});
}
From 15f877130328ae2bafc2630be0070d4dcfe3ba41 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 6 Jan 2024 10:54:29 -0600
Subject: [PATCH 149/168] fix functional tests
---
test/functional/apps/management/data_views/_cache.ts | 2 +-
.../test_suites/common/management/data_views/_cache.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/functional/apps/management/data_views/_cache.ts b/test/functional/apps/management/data_views/_cache.ts
index f05a8b9bdd3a4..c62a78101a864 100644
--- a/test/functional/apps/management/data_views/_cache.ts
+++ b/test/functional/apps/management/data_views/_cache.ts
@@ -19,7 +19,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should have cache setting', async () => {
await PageObjects.settings.clickKibanaSettings();
- const cacheSetting = await find.byCssSelector('#data_views:cache_max_age-group');
+ const cacheSetting = await find.byCssSelector('#data_views\\:cache_max_age-group');
expect(cacheSetting).to.not.be(undefined);
});
});
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
index 083fe2832537e..fbfd8bf813796 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
@@ -19,7 +19,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should not have cache setting', async () => {
await PageObjects.settings.clickKibanaSettings();
- const cacheSetting = await find.byCssSelector('#data_views:cache_max_age-group');
+ const cacheSetting = await find.byCssSelector('#data_views\\:cache_max_age-group');
expect(cacheSetting).to.be(undefined);
});
});
From 290a3ca32664e3b9cb91e449c8d9c4c8fa15ac02 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 6 Jan 2024 13:29:58 -0600
Subject: [PATCH 150/168] fix functional tests
---
test/functional/apps/management/data_views/_cache.ts | 1 -
.../test_suites/common/management/data_views/_cache.ts | 1 -
2 files changed, 2 deletions(-)
diff --git a/test/functional/apps/management/data_views/_cache.ts b/test/functional/apps/management/data_views/_cache.ts
index c62a78101a864..44d384a7dda90 100644
--- a/test/functional/apps/management/data_views/_cache.ts
+++ b/test/functional/apps/management/data_views/_cache.ts
@@ -18,7 +18,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.navigateTo();
});
it('should have cache setting', async () => {
- await PageObjects.settings.clickKibanaSettings();
const cacheSetting = await find.byCssSelector('#data_views\\:cache_max_age-group');
expect(cacheSetting).to.not.be(undefined);
});
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
index fbfd8bf813796..7d5607015495e 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
@@ -18,7 +18,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should not have cache setting', async () => {
- await PageObjects.settings.clickKibanaSettings();
const cacheSetting = await find.byCssSelector('#data_views\\:cache_max_age-group');
expect(cacheSetting).to.be(undefined);
});
From dda0d98c82fafce8011cdd1cb2d79b060d4837b5 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 6 Jan 2024 21:02:12 -0600
Subject: [PATCH 151/168] fix functional tests
---
test/functional/apps/management/data_views/_cache.ts | 1 +
.../test_suites/common/management/data_views/_cache.ts | 1 +
2 files changed, 2 insertions(+)
diff --git a/test/functional/apps/management/data_views/_cache.ts b/test/functional/apps/management/data_views/_cache.ts
index 44d384a7dda90..447e44052bb8d 100644
--- a/test/functional/apps/management/data_views/_cache.ts
+++ b/test/functional/apps/management/data_views/_cache.ts
@@ -16,6 +16,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('Data view field caps cache advanced setting', async function () {
before(async () => {
await PageObjects.settings.navigateTo();
+ await PageObjects.settings.clickKibanaSettings();
});
it('should have cache setting', async () => {
const cacheSetting = await find.byCssSelector('#data_views\\:cache_max_age-group');
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
index 7d5607015495e..650864405088c 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
@@ -15,6 +15,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('Data view field caps cache advanced setting', async function () {
before(async () => {
await PageObjects.settings.navigateTo();
+ await PageObjects.settings.clickKibanaSettings();
});
it('should not have cache setting', async () => {
From f751a4e6c691654ea3ddd006deb6cf232e81acc1 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Tue, 9 Jan 2024 10:56:27 +0100
Subject: [PATCH 152/168] Address review feedback
---
.../src/hooks/use_existing_fields.ts | 2 +-
.../public/data_views_service/loader.test.ts | 37 ++++++++++++++++++-
.../lens/public/data_views_service/loader.ts | 7 ++--
.../datasources/form_based/datapanel.tsx | 4 +-
4 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
index e71d89d6b3626..cd4e9ef05206f 100644
--- a/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
+++ b/packages/kbn-unified-field-list/src/hooks/use_existing_fields.ts
@@ -121,7 +121,7 @@ export const useExistingFieldsFetcher = (
setActiveRequests((value) => value + 1);
- const hasRestrictions = Boolean(dataView?.getAggregationRestrictions?.());
+ const hasRestrictions = Boolean(dataView.getAggregationRestrictions?.());
const info: ExistingFieldsInfo = {
...unknownInfo,
numberOfFetches,
diff --git a/x-pack/plugins/lens/public/data_views_service/loader.test.ts b/x-pack/plugins/lens/public/data_views_service/loader.test.ts
index f91d236986b11..4c648a7782896 100644
--- a/x-pack/plugins/lens/public/data_views_service/loader.test.ts
+++ b/x-pack/plugins/lens/public/data_views_service/loader.test.ts
@@ -5,8 +5,13 @@
* 2.0.
*/
-import { DataViewsContract } from '@kbn/data-views-plugin/public';
-import { ensureIndexPattern, loadIndexPatternRefs, loadIndexPatterns } from './loader';
+import { DataViewsContract, DataViewField } from '@kbn/data-views-plugin/public';
+import {
+ ensureIndexPattern,
+ loadIndexPatternRefs,
+ loadIndexPatterns,
+ buildIndexPatternField,
+} from './loader';
import { sampleIndexPatterns, mockDataViewsService } from './mocks';
import { documentField } from '../datasources/form_based/document_field';
@@ -313,4 +318,32 @@ describe('loader', () => {
expect(onError).not.toHaveBeenCalled();
});
});
+
+ describe('buildIndexPatternField', () => {
+ it('should return a field with the correct name and derived parameters', async () => {
+ const field = buildIndexPatternField({
+ name: 'foo',
+ displayName: 'Foo',
+ type: 'string',
+ aggregatable: true,
+ searchable: true,
+ } as DataViewField);
+ expect(field.name).toEqual('foo');
+ expect(field.meta).toEqual(false);
+ expect(field.runtime).toEqual(false);
+ });
+ it('should return return the right meta field value', async () => {
+ const field = buildIndexPatternField(
+ {
+ name: 'meta',
+ displayName: 'Meta',
+ type: 'string',
+ aggregatable: true,
+ searchable: true,
+ } as DataViewField,
+ new Set(['meta'])
+ );
+ expect(field.meta).toEqual(true);
+ });
+ });
});
diff --git a/x-pack/plugins/lens/public/data_views_service/loader.ts b/x-pack/plugins/lens/public/data_views_service/loader.ts
index 00bd291ef9c24..8a52146991b8d 100644
--- a/x-pack/plugins/lens/public/data_views_service/loader.ts
+++ b/x-pack/plugins/lens/public/data_views_service/loader.ts
@@ -34,9 +34,10 @@ export function convertDataViewIntoLensIndexPattern(
dataView: DataView,
restrictionRemapper: (name: string) => string = onRestrictionMapping
): IndexPattern {
+ const metaKeys = new Set(dataView.metaFields);
const newFields = dataView.fields
.filter(isFieldLensCompatible)
- .map((field) => buildIndexPatternField(field, dataView))
+ .map((field) => buildIndexPatternField(field, metaKeys))
.concat(documentField);
const { typeMeta, title, name, timeFieldName, fieldFormatMap } = dataView;
@@ -80,9 +81,9 @@ export function convertDataViewIntoLensIndexPattern(
export function buildIndexPatternField(
field: DataViewField,
- dataView: DataView | null
+ metaKeys?: Set
): IndexPatternField {
- const meta = dataView?.metaFields.includes(field.name);
+ const meta = metaKeys ? metaKeys.has(field.name) : false;
// Convert the getters on the index pattern service into plain JSON
const base = {
name: field.name,
diff --git a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
index 2674293da399a..b2db83cf0e7c6 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
+++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
@@ -421,10 +421,12 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
};
function getNewFieldsBySpec(spec: FieldSpec[], dataView: DataView | null) {
+ const metaKeys = dataView ? new Set(dataView.metaFields) : undefined;
+
return spec.reduce((result: IndexPatternField[], fieldSpec: FieldSpec) => {
const field = new DataViewField(fieldSpec);
if (isFieldLensCompatible(field)) {
- result.push(buildIndexPatternField(field, dataView));
+ result.push(buildIndexPatternField(field, metaKeys));
}
return result;
}, []);
From d024027cec062a59ae8bbb0b6f15f2a7f00a9320 Mon Sep 17 00:00:00 2001
From: Matthias Wilhelm
Date: Tue, 9 Jan 2024 11:24:09 +0100
Subject: [PATCH 153/168] Apply useLatest feedback
---
.../datasources/form_based/datapanel.tsx | 21 +++++++------------
1 file changed, 7 insertions(+), 14 deletions(-)
diff --git a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
index b2db83cf0e7c6..5d7e928c95594 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
+++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx
@@ -28,6 +28,7 @@ import {
useGroupedFields,
} from '@kbn/unified-field-list';
import { ChartsPluginSetup } from '@kbn/charts-plugin/public';
+import useLatest from 'react-use/lib/useLatest';
import { isFieldLensCompatible } from '@kbn/visualization-ui-components';
import { buildIndexPatternField } from '../../data_views_service/loader';
import type {
@@ -277,7 +278,7 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
};
}, []);
- const refreshFieldList = useCallback(async () => {
+ const refreshFieldList = useLatest(async () => {
if (currentIndexPattern) {
const newlyMappedIndexPattern = await indexPatternService.loadIndexPatterns({
patterns: [currentIndexPattern.id],
@@ -293,21 +294,13 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
}
// start a new session so all charts are refreshed
data.search.session.start();
- }, [
- indexPatternService,
- currentIndexPattern,
- onIndexPatternRefresh,
- frame.dataViews.indexPatterns,
- data.search.session,
- ]);
+ });
useEffect(() => {
if (hasNewFields) {
- refreshFieldList();
+ refreshFieldList.current();
}
- // Preventing a race condition, making sure refreshFieldList is just executed once when hasNewFields is true
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [hasNewFields]);
+ }, [hasNewFields, refreshFieldList]);
const editField = useMemo(
() =>
@@ -321,7 +314,7 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
fieldName,
onSave: () => {
if (indexPatternInstance.isPersisted()) {
- refreshFieldList();
+ refreshFieldList.current();
refetchFieldsExistenceInfo(indexPatternInstance.id);
} else {
indexPatternService.replaceDataViewId(indexPatternInstance);
@@ -353,7 +346,7 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({
fieldName,
onDelete: () => {
if (indexPatternInstance.isPersisted()) {
- refreshFieldList();
+ refreshFieldList.current();
refetchFieldsExistenceInfo(indexPatternInstance.id);
} else {
indexPatternService.replaceDataViewId(indexPatternInstance);
From e628af78405c9715722297e7f9d5c2645e14123e Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 9 Jan 2024 14:20:04 -0600
Subject: [PATCH 154/168] better buttons, better software
---
.../edit_index_pattern/tabs/tabs.tsx | 51 ++++++++-----------
1 file changed, 22 insertions(+), 29 deletions(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
index ca60f2742da62..5ef028a0e3720 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
@@ -22,7 +22,7 @@ import {
EuiFilterSelectItem,
FilterChecked,
EuiToolTip,
- EuiButtonIcon,
+ EuiButton,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { fieldWildcardMatcher } from '@kbn/kibana-utils-plugin/public';
@@ -337,13 +337,12 @@ export const Tabs: React.FC = ({
);
const refreshRef = useRef(null);
- const addFieldRef = useRef(null);
const userEditPermission = dataViews.getCanSaveSync();
const getFilterSection = useCallback(
(type: string) => {
return (
-
+
= ({
-
- {userEditPermission && (
-
- {addFieldButtonLabel}}>
- {
- openFieldEditor();
- // clear tooltip focus
- if (addFieldRef.current) {
- addFieldRef.current.blur();
- }
- }}
- data-test-subj="addField"
- iconType="plus"
- aria-label={addFieldButtonLabel}
- />
-
-
- )}
-
{refreshTooltip}}>
- {
refreshIndexPatternClick();
@@ -483,11 +459,28 @@ export const Tabs: React.FC = ({
data-test-subj="refreshDataViewButton"
isLoading={isRefreshing}
isDisabled={isRefreshing}
- display="base"
size="m"
- />
+ color="success"
+ >
+ Refresh
+
+ {userEditPermission && (
+
+ openFieldEditor()}
+ data-test-subj="addField"
+ iconType="plusInCircle"
+ aria-label={addFieldButtonLabel}
+ color="primary"
+ fill
+ >
+ Add field
+
+
+ )}
>
)}
{type === TAB_SCRIPTED_FIELDS && scriptedFieldLanguages.length > 0 && (
From 66fd722b473d26c2f3fc3677dfc7d88b490171d3 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 9 Jan 2024 14:31:06 -0600
Subject: [PATCH 155/168] fix functional test
---
.../test_suites/common/management/data_views/_cache.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
index 650864405088c..2d7285ff2e344 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
@@ -5,12 +5,11 @@
* 2.0.
*/
-import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['settings', 'common', 'header']);
- const find = getService('find');
+ const testSubjects = getService('testSubjects');
describe('Data view field caps cache advanced setting', async function () {
before(async () => {
@@ -19,8 +18,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should not have cache setting', async () => {
- const cacheSetting = await find.byCssSelector('#data_views\\:cache_max_age-group');
- expect(cacheSetting).to.be(undefined);
+ await testSubjects.missingOrFail(
+ 'advancedSetting-editField-data_views\\:cache_max_age-group'
+ );
});
});
}
From 48d28c930f89a1272fc929c62131e719400b8458 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 9 Jan 2024 16:10:09 -0600
Subject: [PATCH 156/168] fix functional test
---
test/functional/apps/management/data_views/_field_formatter.ts | 3 ++-
.../apps/management/data_views/_index_pattern_filter.ts | 3 ++-
.../apps/management/data_views/_index_pattern_results_sort.ts | 3 ++-
.../apps/discover/feature_controls/discover_security.ts | 3 +++
.../apps/discover_ml_uptime/discover/search_source_alert.ts | 3 ++-
.../common/discover_ml_uptime/discover/search_source_alert.ts | 3 ++-
.../test_suites/common/management/data_views/_cache.ts | 1 -
.../common/management/data_views/_index_pattern_filter.ts | 3 ++-
.../test_suites/search/cases/attachment_framework.ts | 3 ++-
9 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/test/functional/apps/management/data_views/_field_formatter.ts b/test/functional/apps/management/data_views/_field_formatter.ts
index dfcdc0b877581..adec04bf5bb87 100644
--- a/test/functional/apps/management/data_views/_field_formatter.ts
+++ b/test/functional/apps/management/data_views/_field_formatter.ts
@@ -465,7 +465,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.navigateTo();
await PageObjects.settings.clickKibanaIndexPatterns();
await PageObjects.settings.clickIndexPatternByName(indexTitle);
- await PageObjects.settings.refreshDataViewFieldList();
+ // todo checking to see if this is needed after auto update code
+ // await PageObjects.settings.refreshDataViewFieldList();
});
afterEach(async () => {
diff --git a/test/functional/apps/management/data_views/_index_pattern_filter.ts b/test/functional/apps/management/data_views/_index_pattern_filter.ts
index 941451424dfb1..10221320be82b 100644
--- a/test/functional/apps/management/data_views/_index_pattern_filter.ts
+++ b/test/functional/apps/management/data_views/_index_pattern_filter.ts
@@ -170,7 +170,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.clickIndexPatternLogstash();
- await PageObjects.settings.refreshDataViewFieldList();
+ // todo checking to see if this is needed after auto update code
+ // await PageObjects.settings.refreshDataViewFieldList();
await testSubjects.existOrFail('dataViewMappingConflict');
diff --git a/test/functional/apps/management/data_views/_index_pattern_results_sort.ts b/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
index 8a94f96827a35..0172c2a67dc4a 100644
--- a/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
+++ b/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
@@ -68,7 +68,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('field list pagination', function () {
const EXPECTED_FIELD_COUNT = 85;
it('makelogs data should have expected number of fields', async function () {
- await testSubjects.click('refreshDataViewButton');
+ // todo checking to see if this is needed after auto update code
+ // await testSubjects.click('refreshDataViewButton');
await retry.try(async function () {
const TabCount = await PageObjects.settings.getFieldsTabCount();
expect(TabCount).to.be('' + EXPECTED_FIELD_COUNT);
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index 232a241691f4d..9409f8a3e6941 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -452,6 +452,8 @@ export default function (ctx: FtrProviderContext) {
// swapping index patterns so we get an updated field list
// this is necessary since we don't have access to data view management
// nor can we force reload the browser in a test
+ // todo checking to see if this is needed after auto update code
+ /**
await new Promise((resolve) => setTimeout(resolve, 5000));
await PageObjects.discover.selectIndexPattern('logstash-*');
await new Promise((resolve) => setTimeout(resolve, 5000));
@@ -462,6 +464,7 @@ export default function (ctx: FtrProviderContext) {
await PageObjects.discover.selectIndexPattern('alias-logstash-discover');
await new Promise((resolve) => setTimeout(resolve, 5000));
+ */
await PageObjects.discover.selectIndexPattern('logstash-*');
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.existOrFail('discoverNoResultsCheckIndices');
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index bffa564fba774..a095bd2fa8dbc 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -399,7 +399,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should navigate to alert results via link provided in notification', async () => {
- await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
+ // todo checking to see if this is needed after auto update code
+ // await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
diff --git a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
index d2e8f863d5fe9..ba4203a5cb2ac 100644
--- a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
@@ -447,7 +447,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should navigate to alert results via link provided in notification', async () => {
- await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
+ // todo checking to see if this is needed after auto update code
+ // await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
index 2d7285ff2e344..3050ef2456fbf 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_cache.ts
@@ -14,7 +14,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('Data view field caps cache advanced setting', async function () {
before(async () => {
await PageObjects.settings.navigateTo();
- await PageObjects.settings.clickKibanaSettings();
});
it('should not have cache setting', async () => {
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts
index 9b8a51feac10f..b323a2b1b30c9 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts
@@ -174,7 +174,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.clickIndexPatternLogstash();
- await PageObjects.settings.refreshDataViewFieldList();
+ // todo checking to see if this is needed after auto update code
+ // await PageObjects.settings.refreshDataViewFieldList();
await testSubjects.existOrFail('dataViewMappingConflict');
diff --git a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
index e74262f60ac3e..f91b5dd7f0785 100644
--- a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
+++ b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
@@ -34,7 +34,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json'
);
- await settings.refreshDataViewFieldList('default:all-data');
+ // todo checking to see if this is needed after auto update code
+ // await settings.refreshDataViewFieldList('default:all-data');
await svlSearchNavigation.navigateToLandingPage();
From a40cc37c840400bd1de5c6356d08a1de026d64e2 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 9 Jan 2024 17:37:42 -0600
Subject: [PATCH 157/168] partial progress on fixing fields
---
test/functional/apps/discover/group4/_field_list_new_fields.ts | 1 +
test/functional/apps/management/data_views/_field_formatter.ts | 3 +--
x-pack/test/functional/apps/lens/group2/fields_list.ts | 1 +
.../apps/discover_ml_uptime/discover/search_source_alert.ts | 3 +--
.../common/discover_ml_uptime/discover/search_source_alert.ts | 3 +--
.../common/management/data_views/_index_pattern_filter.ts | 3 +--
.../test_suites/search/cases/attachment_framework.ts | 3 +--
7 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/test/functional/apps/discover/group4/_field_list_new_fields.ts b/test/functional/apps/discover/group4/_field_list_new_fields.ts
index 3c24bcf613ae4..1c2058ef2cef4 100644
--- a/test/functional/apps/discover/group4/_field_list_new_fields.ts
+++ b/test/functional/apps/discover/group4/_field_list_new_fields.ts
@@ -37,6 +37,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
+ // todo
it('Check that new ingested fields are added to the available fields section', async function () {
const initialPattern = 'my-index-';
await es.transport.request({
diff --git a/test/functional/apps/management/data_views/_field_formatter.ts b/test/functional/apps/management/data_views/_field_formatter.ts
index adec04bf5bb87..dfcdc0b877581 100644
--- a/test/functional/apps/management/data_views/_field_formatter.ts
+++ b/test/functional/apps/management/data_views/_field_formatter.ts
@@ -465,8 +465,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.navigateTo();
await PageObjects.settings.clickKibanaIndexPatterns();
await PageObjects.settings.clickIndexPatternByName(indexTitle);
- // todo checking to see if this is needed after auto update code
- // await PageObjects.settings.refreshDataViewFieldList();
+ await PageObjects.settings.refreshDataViewFieldList();
});
afterEach(async () => {
diff --git a/x-pack/test/functional/apps/lens/group2/fields_list.ts b/x-pack/test/functional/apps/lens/group2/fields_list.ts
index 79baafe6100a6..b768c922c894b 100644
--- a/x-pack/test/functional/apps/lens/group2/fields_list.ts
+++ b/x-pack/test/functional/apps/lens/group2/fields_list.ts
@@ -260,6 +260,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
+ // todo
it('should show new fields Available fields', async () => {
await es.transport.request({
path: '/field-update-test/_doc',
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index a095bd2fa8dbc..bffa564fba774 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -399,8 +399,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should navigate to alert results via link provided in notification', async () => {
- // todo checking to see if this is needed after auto update code
- // await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
+ await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
diff --git a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
index ba4203a5cb2ac..d2e8f863d5fe9 100644
--- a/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/discover_ml_uptime/discover/search_source_alert.ts
@@ -447,8 +447,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should navigate to alert results via link provided in notification', async () => {
- // todo checking to see if this is needed after auto update code
- // await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
+ await PageObjects.settings.refreshDataViewFieldList(OUTPUT_DATA_VIEW);
await openAlertResults(RULE_NAME);
await checkInitialRuleParamsState(SOURCE_DATA_VIEW);
});
diff --git a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts
index b323a2b1b30c9..9b8a51feac10f 100644
--- a/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/management/data_views/_index_pattern_filter.ts
@@ -174,8 +174,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.clickIndexPatternLogstash();
- // todo checking to see if this is needed after auto update code
- // await PageObjects.settings.refreshDataViewFieldList();
+ await PageObjects.settings.refreshDataViewFieldList();
await testSubjects.existOrFail('dataViewMappingConflict');
diff --git a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
index f91b5dd7f0785..e74262f60ac3e 100644
--- a/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
+++ b/x-pack/test_serverless/functional/test_suites/search/cases/attachment_framework.ts
@@ -34,8 +34,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => {
'x-pack/test/functional/fixtures/kbn_archiver/lens/lens_basic.json'
);
- // todo checking to see if this is needed after auto update code
- // await settings.refreshDataViewFieldList('default:all-data');
+ await settings.refreshDataViewFieldList('default:all-data');
await svlSearchNavigation.navigateToLandingPage();
From 6342b8903bdf78f72513c6beb634e8ab24df801d Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 9 Jan 2024 17:53:26 -0600
Subject: [PATCH 158/168] cleanup and hopefully fix tests related to auto
refresh
---
.../field_existing/field_existing_utils.ts | 2 +-
.../data_views/_index_pattern_results_sort.ts | 3 ---
.../feature_controls/discover_security.ts | 16 ----------------
3 files changed, 1 insertion(+), 20 deletions(-)
diff --git a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
index 41a1e53a33849..5cceb49cb5ecb 100644
--- a/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
+++ b/packages/kbn-unified-field-list/src/services/field_existing/field_existing_utils.ts
@@ -61,7 +61,7 @@ export async function fetchFieldExistence({
const newFields = existingFieldList.filter((field) => !dataView.getFieldByName(field.name));
// refresh the data view in case there are new fields
if (newFields.length) {
- await dataViewsService.refreshFields(dataView, false);
+ await dataViewsService.refreshFields(dataView, false, true);
}
const allFields = buildFieldList(dataView, metaFields);
return {
diff --git a/test/functional/apps/management/data_views/_index_pattern_results_sort.ts b/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
index 0172c2a67dc4a..71dc85eed1f0e 100644
--- a/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
+++ b/test/functional/apps/management/data_views/_index_pattern_results_sort.ts
@@ -12,7 +12,6 @@ import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const kibanaServer = getService('kibanaServer');
const retry = getService('retry');
- const testSubjects = getService('testSubjects');
const PageObjects = getPageObjects(['settings', 'common']);
describe('index result field sort', function describeIndexTests() {
@@ -68,8 +67,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('field list pagination', function () {
const EXPECTED_FIELD_COUNT = 85;
it('makelogs data should have expected number of fields', async function () {
- // todo checking to see if this is needed after auto update code
- // await testSubjects.click('refreshDataViewButton');
await retry.try(async function () {
const TabCount = await PageObjects.settings.getFieldsTabCount();
expect(TabCount).to.be('' + EXPECTED_FIELD_COUNT);
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index 9409f8a3e6941..d0173072a0879 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -449,22 +449,6 @@ export default function (ctx: FtrProviderContext) {
await globalNav.badgeExistsOrFail('Read only');
// can't access logstash index directly
- // swapping index patterns so we get an updated field list
- // this is necessary since we don't have access to data view management
- // nor can we force reload the browser in a test
- // todo checking to see if this is needed after auto update code
- /**
- await new Promise((resolve) => setTimeout(resolve, 5000));
- await PageObjects.discover.selectIndexPattern('logstash-*');
- await new Promise((resolve) => setTimeout(resolve, 5000));
- await PageObjects.discover.selectIndexPattern('alias-logstash-discover');
- await new Promise((resolve) => setTimeout(resolve, 5000));
- await PageObjects.discover.selectIndexPattern('logstash-*');
- await new Promise((resolve) => setTimeout(resolve, 5000));
- await PageObjects.discover.selectIndexPattern('alias-logstash-discover');
-
- await new Promise((resolve) => setTimeout(resolve, 5000));
- */
await PageObjects.discover.selectIndexPattern('logstash-*');
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.existOrFail('discoverNoResultsCheckIndices');
From 8e5ba7e3405fde1b1cea2ab0de46e9f5506ca886 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 9 Jan 2024 19:07:53 -0600
Subject: [PATCH 159/168] remove some comments
---
test/functional/apps/discover/group4/_field_list_new_fields.ts | 1 -
.../apps/management/data_views/_index_pattern_filter.ts | 3 ---
x-pack/test/functional/apps/lens/group2/fields_list.ts | 1 -
3 files changed, 5 deletions(-)
diff --git a/test/functional/apps/discover/group4/_field_list_new_fields.ts b/test/functional/apps/discover/group4/_field_list_new_fields.ts
index 1c2058ef2cef4..3c24bcf613ae4 100644
--- a/test/functional/apps/discover/group4/_field_list_new_fields.ts
+++ b/test/functional/apps/discover/group4/_field_list_new_fields.ts
@@ -37,7 +37,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- // todo
it('Check that new ingested fields are added to the available fields section', async function () {
const initialPattern = 'my-index-';
await es.transport.request({
diff --git a/test/functional/apps/management/data_views/_index_pattern_filter.ts b/test/functional/apps/management/data_views/_index_pattern_filter.ts
index 10221320be82b..81ff2b450755d 100644
--- a/test/functional/apps/management/data_views/_index_pattern_filter.ts
+++ b/test/functional/apps/management/data_views/_index_pattern_filter.ts
@@ -170,9 +170,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.clickIndexPatternLogstash();
- // todo checking to see if this is needed after auto update code
- // await PageObjects.settings.refreshDataViewFieldList();
-
await testSubjects.existOrFail('dataViewMappingConflict');
expect(await PageObjects.settings.getFieldTypes()).to.eql([
diff --git a/x-pack/test/functional/apps/lens/group2/fields_list.ts b/x-pack/test/functional/apps/lens/group2/fields_list.ts
index b768c922c894b..79baafe6100a6 100644
--- a/x-pack/test/functional/apps/lens/group2/fields_list.ts
+++ b/x-pack/test/functional/apps/lens/group2/fields_list.ts
@@ -260,7 +260,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
- // todo
it('should show new fields Available fields', async () => {
await es.transport.request({
path: '/field-update-test/_doc',
From b56cb260f2bff40504bf2b833ed6c5c822fa32e4 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 9 Jan 2024 19:10:57 -0600
Subject: [PATCH 160/168] remve unneeded change
---
docs/concepts/data-views.asciidoc | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/docs/concepts/data-views.asciidoc b/docs/concepts/data-views.asciidoc
index 2eba42aed3051..992741be518a7 100644
--- a/docs/concepts/data-views.asciidoc
+++ b/docs/concepts/data-views.asciidoc
@@ -172,14 +172,3 @@ WARNING: Deleting a {data-source} breaks all visualizations, saved searches, and
. Find the {data-source} that you want to delete, and then
click image:management/index-patterns/images/delete.png[Delete icon] in the *Actions* column.
-
-[float]
-[[data-view-field-cache]]
-=== {data-source} field cache
-
-The browser caches {data-source} field lists for increased performance. This is particularly impactful
-for {data-sources} with a high field count that span a large number of indices and clusters. The field
-list is updated every couple of minutes in typical {kib} usage. Alternatively, use the refresh button on the {data-source}
-management detail page to get an updated field list. A force reload of {kib} has the same effect.
-
-The field list may be impacted by changes in indices and user permissions.
\ No newline at end of file
From 19c06b23b91d8c262f1867207029d652d15bd196 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Tue, 9 Jan 2024 20:34:27 -0600
Subject: [PATCH 161/168] functional test fix
---
.../apps/management/data_views/_index_pattern_filter.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/test/functional/apps/management/data_views/_index_pattern_filter.ts b/test/functional/apps/management/data_views/_index_pattern_filter.ts
index 81ff2b450755d..941451424dfb1 100644
--- a/test/functional/apps/management/data_views/_index_pattern_filter.ts
+++ b/test/functional/apps/management/data_views/_index_pattern_filter.ts
@@ -170,6 +170,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.settings.clickIndexPatternLogstash();
+ await PageObjects.settings.refreshDataViewFieldList();
+
await testSubjects.existOrFail('dataViewMappingConflict');
expect(await PageObjects.settings.getFieldTypes()).to.eql([
From 3bf8c03b1bae43409411921c2586e6ed59f22673 Mon Sep 17 00:00:00 2001
From: Matthew Kime
Date: Wed, 10 Jan 2024 07:33:50 -0600
Subject: [PATCH 162/168] Update
src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
Co-authored-by: Julia Rechkunova
---
.../components/edit_index_pattern/index_header/index_header.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
index 1d73ef615e26c..8b12ed59ed6fd 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
@@ -70,7 +70,6 @@ export const IndexHeader: React.FC = ({
{editTooltip}
),
- ,
defaultIndex !== indexPattern.id && setDefault && canSave && indexPattern.isPersisted() && (
Date: Wed, 10 Jan 2024 07:37:44 -0600
Subject: [PATCH 163/168] translate some text, remove unneeded comma
---
.../edit_index_pattern/index_header/index_header.tsx | 1 -
.../public/components/edit_index_pattern/tabs/tabs.tsx | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
index 1d73ef615e26c..8b12ed59ed6fd 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/index_header/index_header.tsx
@@ -70,7 +70,6 @@ export const IndexHeader: React.FC = ({
{editTooltip}
),
- ,
defaultIndex !== indexPattern.id && setDefault && canSave && indexPattern.isPersisted() && (
= ({
size="m"
color="success"
>
- Refresh
+ {refreshAriaLabel}
@@ -477,7 +477,7 @@ export const Tabs: React.FC = ({
color="primary"
fill
>
- Add field
+ {addFieldButtonLabel}
)}
From 67dbffec384529bb69bbf616698d693447418753 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 12 Jan 2024 00:02:28 -0600
Subject: [PATCH 164/168] fix refresh button in mobile view
---
.../public/components/edit_index_pattern/tabs/tabs.tsx | 1 +
.../apps/discover/feature_controls/discover_security.ts | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
index d66da0160e729..426442bcfb031 100644
--- a/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
+++ b/src/plugins/data_view_management/public/components/edit_index_pattern/tabs/tabs.tsx
@@ -461,6 +461,7 @@ export const Tabs: React.FC = ({
isDisabled={isRefreshing}
size="m"
color="success"
+ className="eui-fullWidth"
>
{refreshAriaLabel}
diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
index d0173072a0879..f8e4e1e6933db 100644
--- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
+++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts
@@ -31,7 +31,6 @@ export default function (ctx: FtrProviderContext) {
'spaceSelector',
'header',
'unifiedFieldList',
- 'settings',
]);
const testSubjects = getService('testSubjects');
const appsMenu = getService('appsMenu');
From 765152d628020f1c219d926392874d33dd642238 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Fri, 12 Jan 2024 00:11:34 -0600
Subject: [PATCH 165/168] restore doc change
---
docs/concepts/data-views.asciidoc | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/docs/concepts/data-views.asciidoc b/docs/concepts/data-views.asciidoc
index 992741be518a7..2eba42aed3051 100644
--- a/docs/concepts/data-views.asciidoc
+++ b/docs/concepts/data-views.asciidoc
@@ -172,3 +172,14 @@ WARNING: Deleting a {data-source} breaks all visualizations, saved searches, and
. Find the {data-source} that you want to delete, and then
click image:management/index-patterns/images/delete.png[Delete icon] in the *Actions* column.
+
+[float]
+[[data-view-field-cache]]
+=== {data-source} field cache
+
+The browser caches {data-source} field lists for increased performance. This is particularly impactful
+for {data-sources} with a high field count that span a large number of indices and clusters. The field
+list is updated every couple of minutes in typical {kib} usage. Alternatively, use the refresh button on the {data-source}
+management detail page to get an updated field list. A force reload of {kib} has the same effect.
+
+The field list may be impacted by changes in indices and user permissions.
\ No newline at end of file
From 416a7856aae3dbe47b5b8fa52481beb9a35871f3 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sat, 13 Jan 2024 20:21:41 -0600
Subject: [PATCH 166/168] better caching, with test
---
.../common/data_views/data_views.ts | 4 +---
.../data_views/data_views_api_client.test.ts | 21 +++++++++++++++++--
.../data_views/data_views_api_client.ts | 4 ++--
3 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index dfdb8025b182c..a244868c0614d 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -536,9 +536,7 @@ export class DataViewsService {
...options,
pattern: indexPattern.title as string,
allowHidden:
- (indexPattern as DataViewSpec).allowHidden ||
- (indexPattern as DataView)?.getAllowHidden() ||
- undefined,
+ (indexPattern as DataViewSpec).allowHidden || (indexPattern as DataView)?.getAllowHidden(),
});
private getFieldsAndIndicesForDataView = async (
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.test.ts b/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
index 6aada9616737b..172a3c2db738a 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
@@ -23,8 +23,25 @@ describe('IndexPatternsApiClient', () => {
});
test('uses the right URI to fetch fields for wildcard', async function () {
- await indexPatternsApiClient.getFieldsForWildcard({ pattern: 'blah' });
+ await indexPatternsApiClient.getFieldsForWildcard({ pattern: 'blah', allowHidden: false });
- expect(fetchSpy).toHaveBeenCalledWith(expectedPath, expect.any(Object));
+ expect(fetchSpy).toHaveBeenCalledWith(expectedPath, {
+ // not sure what asResponse is but the rest of the results are useful
+ asResponse: true,
+ headers: {
+ 'user-hash': '',
+ },
+ query: {
+ allow_hidden: undefined,
+ allow_no_index: undefined,
+ apiVersion: '1',
+ fields: undefined,
+ include_unmapped: undefined,
+ meta_fields: undefined,
+ pattern: 'blah',
+ rollup_index: undefined,
+ type: undefined,
+ },
+ });
});
});
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index 29791d3567761..ae6796f53247a 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -55,7 +55,6 @@ export class DataViewsApiClient implements IDataViewsApiClient {
? this.http.post(url, { query, body, version, asResponse })
: this.http.fetch(url, {
query,
- version,
...cacheOptions,
asResponse,
headers: { 'user-hash': userHash },
@@ -104,7 +103,8 @@ export class DataViewsApiClient implements IDataViewsApiClient {
allow_no_index: allowNoIndex,
include_unmapped: includeUnmapped,
fields,
- allow_hidden: allowHidden,
+ // default to undefined to keep value out of URL params and improve caching
+ allow_hidden: allowHidden || undefined,
...versionQueryParam,
},
indexFilter ? JSON.stringify({ index_filter: indexFilter }) : undefined,
From 99356b310f8233c76d1c8d498f7d12544d2a6f79 Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 14 Jan 2024 13:14:10 -0600
Subject: [PATCH 167/168] undo removal of version header for hasUserDataView
---
.../data_views/public/data_views/data_views_api_client.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts
index ae6796f53247a..65b418642b34f 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts
@@ -55,6 +55,7 @@ export class DataViewsApiClient implements IDataViewsApiClient {
? this.http.post(url, { query, body, version, asResponse })
: this.http.fetch(url, {
query,
+ version,
...cacheOptions,
asResponse,
headers: { 'user-hash': userHash },
From a9315ac6edc230d3393d2b738b21996d5bc76b2b Mon Sep 17 00:00:00 2001
From: Matt Kime
Date: Sun, 14 Jan 2024 15:35:37 -0600
Subject: [PATCH 168/168] fix test
---
.../data_views/public/data_views/data_views_api_client.test.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.test.ts b/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
index 172a3c2db738a..66f025dc07835 100644
--- a/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
+++ b/src/plugins/data_views/public/data_views/data_views_api_client.test.ts
@@ -34,7 +34,7 @@ describe('IndexPatternsApiClient', () => {
query: {
allow_hidden: undefined,
allow_no_index: undefined,
- apiVersion: '1',
+ apiVersion: '1', // version passed through query params for caching
fields: undefined,
include_unmapped: undefined,
meta_fields: undefined,
@@ -42,6 +42,7 @@ describe('IndexPatternsApiClient', () => {
rollup_index: undefined,
type: undefined,
},
+ version: '1', // version header
});
});
});