From 8a490fddf5ea499ec34989ea1cdbf12d1e2b3e71 Mon Sep 17 00:00:00 2001 From: kobelb Date: Fri, 21 Aug 2020 10:27:26 -0700 Subject: [PATCH 01/15] Simple benchmark tests for kuery --- .../data/common/es_query/kuery/ast/ast.test.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/plugins/data/common/es_query/kuery/ast/ast.test.ts b/src/plugins/data/common/es_query/kuery/ast/ast.test.ts index 6a69d52d72134..f729a64f874c3 100644 --- a/src/plugins/data/common/es_query/kuery/ast/ast.test.ts +++ b/src/plugins/data/common/es_query/kuery/ast/ast.test.ts @@ -37,6 +37,18 @@ describe('kuery AST API', () => { } as unknown) as IIndexPattern; }); + describe.only('benchmark', () => { + test('blank expression', () => { + fromKueryExpression(' '); + }); + + test('fleet example', () => { + fromKueryExpression( + 'not fleet-agent-actions.attributes.sent_at: * and fleet-agent-actions.attributes.agent_id:1234567' + ); + }); + }); + describe('fromKueryExpression', () => { test('should return a match all "is" function for whitespace', () => { const expected = nodeTypes.function.buildNode('is', '*', '*'); From 0c23f97832bc8364250296eb813b24f87ee4db16 Mon Sep 17 00:00:00 2001 From: kobelb Date: Fri, 21 Aug 2020 11:00:12 -0700 Subject: [PATCH 02/15] Building manually is "better" still not free --- .../common/es_query/kuery/ast/ast.test.ts | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/plugins/data/common/es_query/kuery/ast/ast.test.ts b/src/plugins/data/common/es_query/kuery/ast/ast.test.ts index f729a64f874c3..477d6e9903900 100644 --- a/src/plugins/data/common/es_query/kuery/ast/ast.test.ts +++ b/src/plugins/data/common/es_query/kuery/ast/ast.test.ts @@ -38,14 +38,27 @@ describe('kuery AST API', () => { }); describe.only('benchmark', () => { - test('blank expression', () => { - fromKueryExpression(' '); + test('parsing', () => { + for (let i = 0; i < 100; ++i) { + fromKueryExpression( + 'not fleet-agent-actions.attributes.sent_at: * and fleet-agent-actions.attributes.agent_id:1234567' + ); + } }); - test('fleet example', () => { - fromKueryExpression( - 'not fleet-agent-actions.attributes.sent_at: * and fleet-agent-actions.attributes.agent_id:1234567' - ); + test('manually building', () => { + const sentAt = '*'; + const agentId = '1234567'; + + for (let i = 0; i < 100; ++i) { + nodeTypes.function.buildNode('and', [ + nodeTypes.function.buildNode( + 'not', + nodeTypes.function.buildNode('is', 'fleet-agent-actions.attributes.sent_at', sentAt) + ), + nodeTypes.function.buildNode('is', 'fleet-agent-actions.attributes.agent_id', agentId), + ]); + } }); }); From 334121918d660adabe37a77e4cdebfe40f54f33f Mon Sep 17 00:00:00 2001 From: kobelb Date: Fri, 21 Aug 2020 11:20:49 -0700 Subject: [PATCH 03/15] Building the KueryNode manually --- .../saved_objects/service/lib/filter_utils.ts | 5 +++-- src/core/server/saved_objects/types.ts | 5 ++++- .../server/services/agents/actions.ts | 14 +++++++++++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/core/server/saved_objects/service/lib/filter_utils.ts b/src/core/server/saved_objects/service/lib/filter_utils.ts index 5fbe62a074b29..3a969e2ba87e3 100644 --- a/src/core/server/saved_objects/service/lib/filter_utils.ts +++ b/src/core/server/saved_objects/service/lib/filter_utils.ts @@ -28,11 +28,12 @@ const astFunctionType = ['is', 'range', 'nested']; export const validateConvertFilterToKueryNode = ( allowedTypes: string[], - filter: string, + filter: string | KueryNode, indexMapping: IndexMapping ): KueryNode | undefined => { if (filter && filter.length > 0 && indexMapping) { - const filterKueryNode = esKuery.fromKueryExpression(filter); + const filterKueryNode = + typeof filter === 'string' ? esKuery.fromKueryExpression(filter) : filter; const validationFilterKuery = validateFilterKueryNode({ astFilter: filterKueryNode, diff --git a/src/core/server/saved_objects/types.ts b/src/core/server/saved_objects/types.ts index f9301d6598b1d..60de77ab2d008 100644 --- a/src/core/server/saved_objects/types.ts +++ b/src/core/server/saved_objects/types.ts @@ -37,6 +37,9 @@ import { SavedObjectUnsanitizedDoc } from './serialization'; import { SavedObjectsMigrationLogger } from './migrations/core/migration_logger'; import { SavedObject } from '../../types'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { KueryNode } from '../../../plugins/data/common/es_query/kuery'; + export { SavedObjectAttributes, SavedObjectAttribute, @@ -81,7 +84,7 @@ export interface SavedObjectsFindOptions { searchFields?: string[]; hasReference?: { type: string; id: string }; defaultSearchOperator?: 'AND' | 'OR'; - filter?: string; + filter?: string | KueryNode; namespaces?: string[]; /** An optional ES preference value to be used for the query **/ preference?: string; diff --git a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts index 8d1b320c89ae6..6d11b93998134 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts @@ -9,6 +9,7 @@ import { Agent, AgentAction, AgentActionSOAttributes } from '../../../common/typ import { AGENT_ACTION_SAVED_OBJECT_TYPE } from '../../../common/constants'; import { savedObjectToAgentAction } from './saved_objects'; import { appContextService } from '../app_context'; +import { nodeTypes } from '../../../../../../src/plugins/data/common/es_query/kuery/node_types'; export async function createAgentAction( soClient: SavedObjectsClientContract, @@ -29,9 +30,20 @@ export async function getAgentActionsForCheckin( soClient: SavedObjectsClientContract, agentId: string ): Promise { + const filter = nodeTypes.function.buildNode('and', [ + nodeTypes.function.buildNode( + 'not', + nodeTypes.function.buildNode( + 'is', + `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.sent_at`, + '*' + ) + ), + nodeTypes.function.buildNode('is', 'fleet-agent-actions.attributes.agent_id', agentId), + ]); const res = await soClient.find({ type: AGENT_ACTION_SAVED_OBJECT_TYPE, - filter: `not ${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.sent_at: * and ${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.agent_id:${agentId}`, + filter, }); return Promise.all( From 062aaf24ed8a24d3ee728c097d8c50babc49a6e0 Mon Sep 17 00:00:00 2001 From: kobelb Date: Fri, 21 Aug 2020 11:21:33 -0700 Subject: [PATCH 04/15] Removing benchmark tests --- .../common/es_query/kuery/ast/ast.test.ts | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/src/plugins/data/common/es_query/kuery/ast/ast.test.ts b/src/plugins/data/common/es_query/kuery/ast/ast.test.ts index 477d6e9903900..6a69d52d72134 100644 --- a/src/plugins/data/common/es_query/kuery/ast/ast.test.ts +++ b/src/plugins/data/common/es_query/kuery/ast/ast.test.ts @@ -37,31 +37,6 @@ describe('kuery AST API', () => { } as unknown) as IIndexPattern; }); - describe.only('benchmark', () => { - test('parsing', () => { - for (let i = 0; i < 100; ++i) { - fromKueryExpression( - 'not fleet-agent-actions.attributes.sent_at: * and fleet-agent-actions.attributes.agent_id:1234567' - ); - } - }); - - test('manually building', () => { - const sentAt = '*'; - const agentId = '1234567'; - - for (let i = 0; i < 100; ++i) { - nodeTypes.function.buildNode('and', [ - nodeTypes.function.buildNode( - 'not', - nodeTypes.function.buildNode('is', 'fleet-agent-actions.attributes.sent_at', sentAt) - ), - nodeTypes.function.buildNode('is', 'fleet-agent-actions.attributes.agent_id', agentId), - ]); - } - }); - }); - describe('fromKueryExpression', () => { test('should return a match all "is" function for whitespace', () => { const expected = nodeTypes.function.buildNode('is', '*', '*'); From 8bd226fcc6f91571f939827868e39151a41ab182 Mon Sep 17 00:00:00 2001 From: kobelb Date: Fri, 21 Aug 2020 11:32:28 -0700 Subject: [PATCH 05/15] Another query is building the KueryNode manually --- .../server/services/agents/actions.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts index 6d11b93998134..d759817ba3a94 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts @@ -90,9 +90,26 @@ export async function getAgentActionByIds( } export async function getNewActionsSince(soClient: SavedObjectsClientContract, timestamp: string) { + const filter = nodeTypes.function.buildNode('and', [ + nodeTypes.function.buildNode( + 'not', + nodeTypes.function.buildNode( + 'is', + `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.sent_at`, + '*' + ) + ), + nodeTypes.function.buildNode( + 'range', + `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.created_at`, + { + gte: timestamp, + } + ), + ]); const res = await soClient.find({ type: AGENT_ACTION_SAVED_OBJECT_TYPE, - filter: `not ${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.sent_at: * AND ${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.created_at >= "${timestamp}"`, + filter, }); return res.saved_objects.map(savedObjectToAgentAction); From 070552c2d13a9ec9f61003a0f6e86bd9a70202a4 Mon Sep 17 00:00:00 2001 From: kobelb Date: Fri, 21 Aug 2020 12:49:18 -0700 Subject: [PATCH 06/15] Empty strings are inherently falsy --- src/core/server/saved_objects/service/lib/filter_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/server/saved_objects/service/lib/filter_utils.ts b/src/core/server/saved_objects/service/lib/filter_utils.ts index 3a969e2ba87e3..d19f06d74e419 100644 --- a/src/core/server/saved_objects/service/lib/filter_utils.ts +++ b/src/core/server/saved_objects/service/lib/filter_utils.ts @@ -31,7 +31,7 @@ export const validateConvertFilterToKueryNode = ( filter: string | KueryNode, indexMapping: IndexMapping ): KueryNode | undefined => { - if (filter && filter.length > 0 && indexMapping) { + if (filter && indexMapping) { const filterKueryNode = typeof filter === 'string' ? esKuery.fromKueryExpression(filter) : filter; From 225bb155e83b76bfd33d90049cb57fd4c4393d03 Mon Sep 17 00:00:00 2001 From: kobelb Date: Tue, 25 Aug 2020 13:42:32 -0700 Subject: [PATCH 07/15] No longer reaching into the data plugin, import from the "root" indexes --- src/core/server/saved_objects/types.ts | 2 +- x-pack/plugins/ingest_manager/server/services/agents/actions.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/server/saved_objects/types.ts b/src/core/server/saved_objects/types.ts index 60de77ab2d008..f0cad6d35455a 100644 --- a/src/core/server/saved_objects/types.ts +++ b/src/core/server/saved_objects/types.ts @@ -38,7 +38,7 @@ import { SavedObjectsMigrationLogger } from './migrations/core/migration_logger' import { SavedObject } from '../../types'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { KueryNode } from '../../../plugins/data/common/es_query/kuery'; +import { KueryNode } from '../../../plugins/data/common'; export { SavedObjectAttributes, diff --git a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts index d759817ba3a94..0df2029535619 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts @@ -9,7 +9,7 @@ import { Agent, AgentAction, AgentActionSOAttributes } from '../../../common/typ import { AGENT_ACTION_SAVED_OBJECT_TYPE } from '../../../common/constants'; import { savedObjectToAgentAction } from './saved_objects'; import { appContextService } from '../app_context'; -import { nodeTypes } from '../../../../../../src/plugins/data/common/es_query/kuery/node_types'; +import { nodeTypes } from '../../../../../../src/plugins/data/common'; export async function createAgentAction( soClient: SavedObjectsClientContract, From 0ee4f45264edc5f5e05e6ddcc2dc262e3d41fcae Mon Sep 17 00:00:00 2001 From: kobelb Date: Wed, 26 Aug 2020 11:55:35 -0700 Subject: [PATCH 08/15] Using AGENT_ACTION_SAVED_OBJECT_TYPE everywhere --- .../ingest_manager/server/services/agents/actions.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts index 0df2029535619..cd0dd92131230 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts @@ -39,7 +39,11 @@ export async function getAgentActionsForCheckin( '*' ) ), - nodeTypes.function.buildNode('is', 'fleet-agent-actions.attributes.agent_id', agentId), + nodeTypes.function.buildNode( + 'is', + `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.agent_id`, + agentId + ), ]); const res = await soClient.find({ type: AGENT_ACTION_SAVED_OBJECT_TYPE, From 6da0f32c87cf909bf1e5de23fa2c9224044bcb0a Mon Sep 17 00:00:00 2001 From: kobelb Date: Wed, 26 Aug 2020 12:06:34 -0700 Subject: [PATCH 09/15] Adding SavedObjectsRepository#find unit test for KueryNode --- .../service/lib/repository.test.js | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/core/server/saved_objects/service/lib/repository.test.js b/src/core/server/saved_objects/service/lib/repository.test.js index 4a9fceb9bf357..120433e5d0f79 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.js +++ b/src/core/server/saved_objects/service/lib/repository.test.js @@ -25,6 +25,8 @@ import { encodeHitVersion } from '../../version'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { DocumentMigrator } from '../../migrations/core/document_migrator'; import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { nodeTypes } from '../../../../../plugins/data/common/es_query'; jest.mock('./search_dsl/search_dsl', () => ({ getSearchDsl: jest.fn() })); @@ -2313,7 +2315,7 @@ describe('SavedObjectsRepository', () => { expect(getSearchDslNS.getSearchDsl).toHaveBeenCalledWith(mappings, registry, relevantOpts); }); - it(`accepts KQL filter and passes kueryNode to getSearchDsl`, async () => { + it(`accepts KQL string filter and passes KueryNode to getSearchDsl`, async () => { const findOpts = { namespace, search: 'foo*', @@ -2354,6 +2356,47 @@ describe('SavedObjectsRepository', () => { `); }); + it(`accepts KQL KueryNode filter and passes KueryNode to getSearchDsl`, async () => { + const findOpts = { + namespace, + search: 'foo*', + searchFields: ['foo'], + type: ['dashboard'], + sortField: 'name', + sortOrder: 'desc', + defaultSearchOperator: 'AND', + hasReference: { + type: 'foo', + id: '1', + }, + indexPattern: undefined, + filter: nodeTypes.function.buildNode('is', `dashboard.attributes.otherField`, '*'), + }; + + await findSuccess(findOpts, namespace); + const { kueryNode } = getSearchDslNS.getSearchDsl.mock.calls[0][2]; + expect(kueryNode).toMatchInlineSnapshot(` + Object { + "arguments": Array [ + Object { + "type": "literal", + "value": "dashboard.otherField", + }, + Object { + "type": "wildcard", + "value": "@kuery-wildcard@", + }, + Object { + "type": "literal", + "value": false, + }, + ], + "function": "is", + "type": "function", + } + `); + }); + it(`supports multiple types`, async () => { const types = ['config', 'index-pattern']; await findSuccess({ type: types }); From 7afb589243e22ed25de15269ac6bf81db229de90 Mon Sep 17 00:00:00 2001 From: kobelb Date: Wed, 26 Aug 2020 12:39:19 -0700 Subject: [PATCH 10/15] Adding KQL KueryNode test for validateConvertFilterToKueryNode --- .../saved_objects/service/lib/filter_utils.test.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/core/server/saved_objects/service/lib/filter_utils.test.ts b/src/core/server/saved_objects/service/lib/filter_utils.test.ts index 4d9bcdda3c8ae..6bc403f154444 100644 --- a/src/core/server/saved_objects/service/lib/filter_utils.test.ts +++ b/src/core/server/saved_objects/service/lib/filter_utils.test.ts @@ -83,7 +83,16 @@ const mockMappings = { describe('Filter Utils', () => { describe('#validateConvertFilterToKueryNode', () => { - test('Validate a simple filter', () => { + test('Validate a simple KQL KueryNode filter', () => { + expect( + validateConvertFilterToKueryNode( + ['foo'], + esKuery.nodeTypes.function.buildNode('is', `foo.attributes.title`, 'best', true), + mockMappings + ) + ).toEqual(esKuery.fromKueryExpression('foo.title: "best"')); + }); + test('Validate a simple KQL string filter', () => { expect( validateConvertFilterToKueryNode(['foo'], 'foo.attributes.title: "best"', mockMappings) ).toEqual(esKuery.fromKueryExpression('foo.title: "best"')); From 130d5cf7b4a529c4caa4df7e613709e867873dbc Mon Sep 17 00:00:00 2001 From: kobelb Date: Wed, 26 Aug 2020 12:40:10 -0700 Subject: [PATCH 11/15] /s/KQL string/KQL expression --- src/core/server/saved_objects/service/lib/filter_utils.test.ts | 2 +- src/core/server/saved_objects/service/lib/repository.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/server/saved_objects/service/lib/filter_utils.test.ts b/src/core/server/saved_objects/service/lib/filter_utils.test.ts index 6bc403f154444..626c5e0af25ff 100644 --- a/src/core/server/saved_objects/service/lib/filter_utils.test.ts +++ b/src/core/server/saved_objects/service/lib/filter_utils.test.ts @@ -92,7 +92,7 @@ describe('Filter Utils', () => { ) ).toEqual(esKuery.fromKueryExpression('foo.title: "best"')); }); - test('Validate a simple KQL string filter', () => { + test('Validate a simple KQL expression filter', () => { expect( validateConvertFilterToKueryNode(['foo'], 'foo.attributes.title: "best"', mockMappings) ).toEqual(esKuery.fromKueryExpression('foo.title: "best"')); diff --git a/src/core/server/saved_objects/service/lib/repository.test.js b/src/core/server/saved_objects/service/lib/repository.test.js index 120433e5d0f79..8e1ec33fc60c0 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.js +++ b/src/core/server/saved_objects/service/lib/repository.test.js @@ -2315,7 +2315,7 @@ describe('SavedObjectsRepository', () => { expect(getSearchDslNS.getSearchDsl).toHaveBeenCalledWith(mappings, registry, relevantOpts); }); - it(`accepts KQL string filter and passes KueryNode to getSearchDsl`, async () => { + it(`accepts KQL expression filter and passes KueryNode to getSearchDsl`, async () => { const findOpts = { namespace, search: 'foo*', From 4ebbe98a04166e84f3fcebb569054b9e254c7f4a Mon Sep 17 00:00:00 2001 From: kobelb Date: Wed, 26 Aug 2020 14:10:04 -0700 Subject: [PATCH 12/15] Updating API docs --- ...ibana-plugin-core-public.savedobjectsfindoptions.filter.md | 2 +- .../kibana-plugin-core-public.savedobjectsfindoptions.md | 2 +- ...ibana-plugin-core-server.savedobjectsfindoptions.filter.md | 2 +- .../kibana-plugin-core-server.savedobjectsfindoptions.md | 2 +- src/core/public/public.api.md | 4 +++- src/core/server/server.api.md | 4 +++- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.filter.md b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.filter.md index 900f8e333f337..2c20fe2dab00f 100644 --- a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.filter.md +++ b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.filter.md @@ -7,5 +7,5 @@ Signature: ```typescript -filter?: string; +filter?: string | KueryNode; ``` diff --git a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md index 70ad235fb8971..ef90143364403 100644 --- a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md +++ b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md @@ -17,7 +17,7 @@ export interface SavedObjectsFindOptions | --- | --- | --- | | [defaultSearchOperator](./kibana-plugin-core-public.savedobjectsfindoptions.defaultsearchoperator.md) | 'AND' | 'OR' | | | [fields](./kibana-plugin-core-public.savedobjectsfindoptions.fields.md) | string[] | An array of fields to include in the results | -| [filter](./kibana-plugin-core-public.savedobjectsfindoptions.filter.md) | string | | +| [filter](./kibana-plugin-core-public.savedobjectsfindoptions.filter.md) | string | KueryNode | | | [hasReference](./kibana-plugin-core-public.savedobjectsfindoptions.hasreference.md) | {
type: string;
id: string;
} | | | [namespaces](./kibana-plugin-core-public.savedobjectsfindoptions.namespaces.md) | string[] | | | [page](./kibana-plugin-core-public.savedobjectsfindoptions.page.md) | number | | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.filter.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.filter.md index ae7b7a28bcd09..c98a4fe5e8796 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.filter.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.filter.md @@ -7,5 +7,5 @@ Signature: ```typescript -filter?: string; +filter?: string | KueryNode; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md index 67e931f0cb3b3..5f88761501503 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md @@ -17,7 +17,7 @@ export interface SavedObjectsFindOptions | --- | --- | --- | | [defaultSearchOperator](./kibana-plugin-core-server.savedobjectsfindoptions.defaultsearchoperator.md) | 'AND' | 'OR' | | | [fields](./kibana-plugin-core-server.savedobjectsfindoptions.fields.md) | string[] | An array of fields to include in the results | -| [filter](./kibana-plugin-core-server.savedobjectsfindoptions.filter.md) | string | | +| [filter](./kibana-plugin-core-server.savedobjectsfindoptions.filter.md) | string | KueryNode | | | [hasReference](./kibana-plugin-core-server.savedobjectsfindoptions.hasreference.md) | {
type: string;
id: string;
} | | | [namespaces](./kibana-plugin-core-server.savedobjectsfindoptions.namespaces.md) | string[] | | | [page](./kibana-plugin-core-server.savedobjectsfindoptions.page.md) | number | | diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 17626418cbeeb..4f7f159559fdb 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -1176,8 +1176,10 @@ export interface SavedObjectsFindOptions { // (undocumented) defaultSearchOperator?: 'AND' | 'OR'; fields?: string[]; + // Warning: (ae-forgotten-export) The symbol "KueryNode" needs to be exported by the entry point index.d.ts + // // (undocumented) - filter?: string; + filter?: string | KueryNode; // (undocumented) hasReference?: { type: string; diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 6186906bc3a42..c33cfa6ac5916 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -2299,8 +2299,10 @@ export interface SavedObjectsFindOptions { // (undocumented) defaultSearchOperator?: 'AND' | 'OR'; fields?: string[]; + // Warning: (ae-forgotten-export) The symbol "KueryNode" needs to be exported by the entry point index.d.ts + // // (undocumented) - filter?: string; + filter?: string | KueryNode; // (undocumented) hasReference?: { type: string; From 97e19c0bf37b03f3740fe7c00e0613fbbfe4600a Mon Sep 17 00:00:00 2001 From: kobelb Date: Thu, 27 Aug 2020 08:19:59 -0700 Subject: [PATCH 13/15] Adding micro benchmark --- .../server/services/agents/actions.test.ts | 69 +++++++++++++++++++ .../server/services/agents/actions.ts | 18 ++--- 2 files changed, 78 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts index c739007952389..60d14f8f66372 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts @@ -8,6 +8,7 @@ import { createAgentAction } from './actions'; import { SavedObject } from 'kibana/server'; import { AgentAction } from '../../../common/types/models'; import { savedObjectsClientMock } from 'src/core/server/mocks'; +import { esKuery } from '../../../../../../src/plugins/data/server'; describe('test agent actions services', () => { it('should create a new action', async () => { @@ -35,3 +36,71 @@ describe('test agent actions services', () => { expect(createdAction?.sent_at).toEqual(newAgentAction.sent_at); }); }); + +class Benchmark { + private static NS_PER_SEC = 1e9; + #startTime?: [number, number]; + #elapsed?: [number, number]; + + start() { + if (this.#startTime) { + throw new Error(`Start?? We're started, we can't start again!`); + } + + this.#startTime = process.hrtime(); + } + stop() { + if (this.#startTime == null) { + throw new Error(`Stop?? We haven't even started yet!`); + } + + this.#elapsed = process.hrtime(this.#startTime); + } + + describe() { + if (this.#elapsed == null) { + return `Benchmark is still running`; + } + + return `Benchmark took ${ + this.#elapsed[0] * Benchmark.NS_PER_SEC + this.#elapsed[1] + } nanoseconds`; + } +} + +describe('micro-benchmark', () => { + test('parsing KQL expression', () => { + const b = new Benchmark(); + b.start(); + esKuery.fromKueryExpression( + 'not fleet-agent-actions.attributes.sent_at: * and fleet-agent-actions.attributes.agent_id:1234567' + ); + b.stop(); + console.log(b.describe()); + }); + + test('manually building KueryNode', () => { + const b = new Benchmark(); + b.start(); + esKuery.nodeTypes.function.buildNode('and', [ + esKuery.nodeTypes.function.buildNode( + 'not', + esKuery.nodeTypes.function.buildNode('is', 'fleet-agent-actions.attributes.sent_at', '*') + ), + esKuery.nodeTypes.function.buildNode( + 'is', + 'fleet-agent-actions.attributes.agent_id', + '1234567' + ), + ]); + b.stop(); + console.log(b.describe()); + }); + + test('doing nothing', () => { + const b = new Benchmark(); + b.start(); + b.stop(); + console.log(b.describe()); + }); +}); diff --git a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts index cd0dd92131230..c8bfe223af637 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts @@ -9,7 +9,7 @@ import { Agent, AgentAction, AgentActionSOAttributes } from '../../../common/typ import { AGENT_ACTION_SAVED_OBJECT_TYPE } from '../../../common/constants'; import { savedObjectToAgentAction } from './saved_objects'; import { appContextService } from '../app_context'; -import { nodeTypes } from '../../../../../../src/plugins/data/common'; +import { esKuery } from '../../../../../../src/plugins/data/server'; export async function createAgentAction( soClient: SavedObjectsClientContract, @@ -30,16 +30,16 @@ export async function getAgentActionsForCheckin( soClient: SavedObjectsClientContract, agentId: string ): Promise { - const filter = nodeTypes.function.buildNode('and', [ - nodeTypes.function.buildNode( + const filter = esKuery.nodeTypes.function.buildNode('and', [ + esKuery.nodeTypes.function.buildNode( 'not', - nodeTypes.function.buildNode( + esKuery.nodeTypes.function.buildNode( 'is', `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.sent_at`, '*' ) ), - nodeTypes.function.buildNode( + esKuery.nodeTypes.function.buildNode( 'is', `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.agent_id`, agentId @@ -94,16 +94,16 @@ export async function getAgentActionByIds( } export async function getNewActionsSince(soClient: SavedObjectsClientContract, timestamp: string) { - const filter = nodeTypes.function.buildNode('and', [ - nodeTypes.function.buildNode( + const filter = esKuery.nodeTypes.function.buildNode('and', [ + esKuery.nodeTypes.function.buildNode( 'not', - nodeTypes.function.buildNode( + esKuery.nodeTypes.function.buildNode( 'is', `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.sent_at`, '*' ) ), - nodeTypes.function.buildNode( + esKuery.nodeTypes.function.buildNode( 'range', `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.created_at`, { From aa14f7fcff0644aded25538c3965b3a85aca6aeb Mon Sep 17 00:00:00 2001 From: kobelb Date: Thu, 27 Aug 2020 08:20:16 -0700 Subject: [PATCH 14/15] Revert "Adding micro benchmark" This reverts commit 97e19c0bf37b03f3740fe7c00e0613fbbfe4600a. --- .../server/services/agents/actions.test.ts | 69 ------------------- .../server/services/agents/actions.ts | 18 ++--- 2 files changed, 9 insertions(+), 78 deletions(-) diff --git a/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts index 60d14f8f66372..c739007952389 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts @@ -8,7 +8,6 @@ import { createAgentAction } from './actions'; import { SavedObject } from 'kibana/server'; import { AgentAction } from '../../../common/types/models'; import { savedObjectsClientMock } from 'src/core/server/mocks'; -import { esKuery } from '../../../../../../src/plugins/data/server'; describe('test agent actions services', () => { it('should create a new action', async () => { @@ -36,71 +35,3 @@ describe('test agent actions services', () => { expect(createdAction?.sent_at).toEqual(newAgentAction.sent_at); }); }); - -class Benchmark { - private static NS_PER_SEC = 1e9; - #startTime?: [number, number]; - #elapsed?: [number, number]; - - start() { - if (this.#startTime) { - throw new Error(`Start?? We're started, we can't start again!`); - } - - this.#startTime = process.hrtime(); - } - stop() { - if (this.#startTime == null) { - throw new Error(`Stop?? We haven't even started yet!`); - } - - this.#elapsed = process.hrtime(this.#startTime); - } - - describe() { - if (this.#elapsed == null) { - return `Benchmark is still running`; - } - - return `Benchmark took ${ - this.#elapsed[0] * Benchmark.NS_PER_SEC + this.#elapsed[1] - } nanoseconds`; - } -} - -describe('micro-benchmark', () => { - test('parsing KQL expression', () => { - const b = new Benchmark(); - b.start(); - esKuery.fromKueryExpression( - 'not fleet-agent-actions.attributes.sent_at: * and fleet-agent-actions.attributes.agent_id:1234567' - ); - b.stop(); - console.log(b.describe()); - }); - - test('manually building KueryNode', () => { - const b = new Benchmark(); - b.start(); - esKuery.nodeTypes.function.buildNode('and', [ - esKuery.nodeTypes.function.buildNode( - 'not', - esKuery.nodeTypes.function.buildNode('is', 'fleet-agent-actions.attributes.sent_at', '*') - ), - esKuery.nodeTypes.function.buildNode( - 'is', - 'fleet-agent-actions.attributes.agent_id', - '1234567' - ), - ]); - b.stop(); - console.log(b.describe()); - }); - - test('doing nothing', () => { - const b = new Benchmark(); - b.start(); - b.stop(); - console.log(b.describe()); - }); -}); diff --git a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts index c8bfe223af637..cd0dd92131230 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/actions.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/actions.ts @@ -9,7 +9,7 @@ import { Agent, AgentAction, AgentActionSOAttributes } from '../../../common/typ import { AGENT_ACTION_SAVED_OBJECT_TYPE } from '../../../common/constants'; import { savedObjectToAgentAction } from './saved_objects'; import { appContextService } from '../app_context'; -import { esKuery } from '../../../../../../src/plugins/data/server'; +import { nodeTypes } from '../../../../../../src/plugins/data/common'; export async function createAgentAction( soClient: SavedObjectsClientContract, @@ -30,16 +30,16 @@ export async function getAgentActionsForCheckin( soClient: SavedObjectsClientContract, agentId: string ): Promise { - const filter = esKuery.nodeTypes.function.buildNode('and', [ - esKuery.nodeTypes.function.buildNode( + const filter = nodeTypes.function.buildNode('and', [ + nodeTypes.function.buildNode( 'not', - esKuery.nodeTypes.function.buildNode( + nodeTypes.function.buildNode( 'is', `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.sent_at`, '*' ) ), - esKuery.nodeTypes.function.buildNode( + nodeTypes.function.buildNode( 'is', `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.agent_id`, agentId @@ -94,16 +94,16 @@ export async function getAgentActionByIds( } export async function getNewActionsSince(soClient: SavedObjectsClientContract, timestamp: string) { - const filter = esKuery.nodeTypes.function.buildNode('and', [ - esKuery.nodeTypes.function.buildNode( + const filter = nodeTypes.function.buildNode('and', [ + nodeTypes.function.buildNode( 'not', - esKuery.nodeTypes.function.buildNode( + nodeTypes.function.buildNode( 'is', `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.sent_at`, '*' ) ), - esKuery.nodeTypes.function.buildNode( + nodeTypes.function.buildNode( 'range', `${AGENT_ACTION_SAVED_OBJECT_TYPE}.attributes.created_at`, { From 195a5a166c0164187142470f7ed9b8e249d28553 Mon Sep 17 00:00:00 2001 From: kobelb Date: Mon, 31 Aug 2020 07:13:54 -0700 Subject: [PATCH 15/15] Adding an empty string filters test --- src/core/server/saved_objects/service/lib/filter_utils.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/server/saved_objects/service/lib/filter_utils.test.ts b/src/core/server/saved_objects/service/lib/filter_utils.test.ts index 626c5e0af25ff..60e8aa0afdda4 100644 --- a/src/core/server/saved_objects/service/lib/filter_utils.test.ts +++ b/src/core/server/saved_objects/service/lib/filter_utils.test.ts @@ -83,6 +83,9 @@ const mockMappings = { describe('Filter Utils', () => { describe('#validateConvertFilterToKueryNode', () => { + test('Empty string filters are ignored', () => { + expect(validateConvertFilterToKueryNode(['foo'], '', mockMappings)).toBeUndefined(); + }); test('Validate a simple KQL KueryNode filter', () => { expect( validateConvertFilterToKueryNode(