diff --git a/x-pack/solutions/observability/plugins/slo/server/services/find_slo_groups.ts b/x-pack/solutions/observability/plugins/slo/server/services/find_slo_groups.ts index e27934180c57c..0d48575ca3a6c 100644 --- a/x-pack/solutions/observability/plugins/slo/server/services/find_slo_groups.ts +++ b/x-pack/solutions/observability/plugins/slo/server/services/find_slo_groups.ts @@ -13,6 +13,7 @@ import { IllegalArgumentError } from '../errors'; import { typedSearch } from '../utils/queries'; import type { EsSummaryDocument } from './summary_transform_generator/helpers/create_temp_summary'; import { getElasticsearchQueryOrThrow, parseStringFilters } from './transform_generators'; +import { excludeStaleSummaryFilter } from './summary_utils'; const DEFAULT_PAGE = 1; const MAX_PER_PAGE = 5000; @@ -59,6 +60,7 @@ export class FindSLOGroups { bool: { filter: [ { term: { spaceId: this.spaceId } }, + ...excludeStaleSummaryFilter(settings, kqlQuery, true), getElasticsearchQueryOrThrow(kqlQuery), ...(parsedFilters.filter ?? []), ], diff --git a/x-pack/solutions/observability/plugins/slo/server/services/summary_search_client/summary_search_client.ts b/x-pack/solutions/observability/plugins/slo/server/services/summary_search_client/summary_search_client.ts index 011501b4dac16..90492accb1538 100644 --- a/x-pack/solutions/observability/plugins/slo/server/services/summary_search_client/summary_search_client.ts +++ b/x-pack/solutions/observability/plugins/slo/server/services/summary_search_client/summary_search_client.ts @@ -5,19 +5,18 @@ * 2.0. */ -import type { estypes } from '@elastic/elasticsearch'; import type { IScopedClusterClient, Logger, SavedObjectsClientContract } from '@kbn/core/server'; import { isCCSRemoteIndexName } from '@kbn/es-query'; import { ALL_VALUE } from '@kbn/slo-schema'; import { assertNever } from '@kbn/std'; import { partition } from 'lodash'; import { SUMMARY_DESTINATION_INDEX_PATTERN } from '../../../common/constants'; -import type { StoredSLOSettings } from '../../domain/models'; import { toHighPrecision } from '../../utils/number'; import { createEsParams, typedSearch } from '../../utils/queries'; import { getSummaryIndices, getSloSettings } from '../slo_settings'; import type { EsSummaryDocument } from '../summary_transform_generator/helpers/create_temp_summary'; import { getElasticsearchQueryOrThrow, parseStringFilters } from '../transform_generators'; +import { excludeStaleSummaryFilter } from '../summary_utils'; import { fromRemoteSummaryDocumentToSloDefinition } from '../unsafe_federated/remote_summary_doc_to_slo'; import { getFlattenedGroupings } from '../utils'; import type { @@ -187,31 +186,7 @@ export class DefaultSummarySearchClient implements SummarySearchClient { } } -function excludeStaleSummaryFilter( - settings: StoredSLOSettings, - kqlFilter: string, - hideStale?: boolean -): estypes.QueryDslQueryContainer[] { - if (kqlFilter.includes('summaryUpdatedAt') || !settings.staleThresholdInHours || !hideStale) { - return []; - } - return [ - { - bool: { - should: [ - { term: { isTempDoc: true } }, - { - range: { - summaryUpdatedAt: { - gte: `now-${settings.staleThresholdInHours}h`, - }, - }, - }, - ], - }, - }, - ]; -} +// excludeStaleSummaryFilter moved to ../summary_utils.ts function getRemoteClusterName(index: string) { if (isCCSRemoteIndexName(index)) { diff --git a/x-pack/solutions/observability/plugins/slo/server/services/summary_utils.test.ts b/x-pack/solutions/observability/plugins/slo/server/services/summary_utils.test.ts new file mode 100644 index 0000000000000..39e7f06094dd5 --- /dev/null +++ b/x-pack/solutions/observability/plugins/slo/server/services/summary_utils.test.ts @@ -0,0 +1,43 @@ +/* + * 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 { excludeStaleSummaryFilter } from './summary_utils'; + +describe('excludeStaleSummaryFilter', () => { + it('returns empty array when kqlFilter contains summaryUpdatedAt', () => { + const settings = { staleThresholdInHours: 24 } as any; + const res = excludeStaleSummaryFilter(settings, 'summaryUpdatedAt:>now-1d', true); + expect(res).toEqual([]); + }); + + it('returns empty array when staleThresholdInHours is falsy', () => { + const settings = { staleThresholdInHours: 0 } as any; + const res = excludeStaleSummaryFilter(settings, '', true); + expect(res).toEqual([]); + }); + + it('returns empty array when hideStale is false', () => { + const settings = { staleThresholdInHours: 12 } as any; + const res = excludeStaleSummaryFilter(settings, '', false); + expect(res).toEqual([]); + }); + + it('returns the expected bool/should filter when conditions met', () => { + const settings = { staleThresholdInHours: 48 } as any; + const res = excludeStaleSummaryFilter(settings, '', true); + expect(res).toHaveLength(1); + const filt = res[0] as any; + expect(filt.bool).toBeDefined(); + expect(Array.isArray(filt.bool.should)).toBe(true); + const [termClause, rangeClause] = filt.bool.should; + expect(termClause).toEqual({ term: { isTempDoc: true } }); + expect(rangeClause).toHaveProperty( + 'range.summaryUpdatedAt.gte', + `now-${settings.staleThresholdInHours}h` + ); + }); +}); diff --git a/x-pack/solutions/observability/plugins/slo/server/services/summary_utils.ts b/x-pack/solutions/observability/plugins/slo/server/services/summary_utils.ts new file mode 100644 index 0000000000000..04d0cd81a47b2 --- /dev/null +++ b/x-pack/solutions/observability/plugins/slo/server/services/summary_utils.ts @@ -0,0 +1,35 @@ +/* + * 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 type { estypes } from '@elastic/elasticsearch'; +import type { StoredSLOSettings } from '../domain/models'; + +export function excludeStaleSummaryFilter( + settings: StoredSLOSettings, + kqlFilter: string, + hideStale?: boolean +): estypes.QueryDslQueryContainer[] { + if (kqlFilter.includes('summaryUpdatedAt') || !settings.staleThresholdInHours || !hideStale) { + return []; + } + return [ + { + bool: { + should: [ + { term: { isTempDoc: true } }, + { + range: { + summaryUpdatedAt: { + gte: `now-${settings.staleThresholdInHours}h`, + }, + }, + }, + ], + }, + }, + ]; +}