"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.DefaultSLIClient = void 0; var _sloSchema = require("@kbn/slo-schema"); var _std = require("@kbn/std"); var _moment = _interopRequireDefault(require("moment")); var _constants = require("../../assets/constants"); var _errors = require("../../errors"); /* * 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. */ class DefaultSLIClient { constructor(esClient) { this.esClient = esClient; } async fetchSLIDataFrom(slo, instanceId, lookbackWindows) { const sortedLookbackWindows = [...lookbackWindows].sort((a, b) => a.duration.isShorterThan(b.duration) ? 1 : -1); const longestLookbackWindow = sortedLookbackWindows[0]; const longestDateRange = getLookbackDateRange(longestLookbackWindow.duration); if (_sloSchema.occurrencesBudgetingMethodSchema.is(slo.budgetingMethod)) { const result = await this.esClient.search({ ...commonQuery(slo, instanceId, longestDateRange), index: _constants.SLO_DESTINATION_INDEX_PATTERN, aggs: toLookbackWindowsAggregationsQuery(sortedLookbackWindows) }); return handleWindowedResult(result.aggregations, lookbackWindows); } if (_sloSchema.timeslicesBudgetingMethodSchema.is(slo.budgetingMethod)) { const result = await this.esClient.search({ ...commonQuery(slo, instanceId, longestDateRange), index: _constants.SLO_DESTINATION_INDEX_PATTERN, aggs: toLookbackWindowsSlicedAggregationsQuery(slo, sortedLookbackWindows) }); return handleWindowedResult(result.aggregations, lookbackWindows); } (0, _std.assertNever)(slo.budgetingMethod); } } exports.DefaultSLIClient = DefaultSLIClient; function commonQuery(slo, instanceId, dateRange) { const filter = [{ term: { 'slo.id': slo.id } }, { term: { 'slo.revision': slo.revision } }, { range: { '@timestamp': { gte: dateRange.from.toISOString(), lt: dateRange.to.toISOString() } } }]; if (instanceId !== _sloSchema.ALL_VALUE) { filter.push({ term: { 'slo.instanceId': instanceId } }); } return { size: 0, query: { bool: { filter } } }; } function toLookbackWindowsAggregationsQuery(sortedLookbackWindow) { return sortedLookbackWindow.reduce((acc, lookbackWindow) => ({ ...acc, [lookbackWindow.name]: { date_range: { field: '@timestamp', ranges: [{ from: `now-${lookbackWindow.duration.format()}/m`, to: 'now/m' }] }, aggs: { good: { sum: { field: 'slo.numerator' } }, total: { sum: { field: 'slo.denominator' } } } } }), {}); } function toLookbackWindowsSlicedAggregationsQuery(slo, lookbackWindows) { return lookbackWindows.reduce((acc, lookbackWindow) => ({ ...acc, [lookbackWindow.name]: { date_range: { field: '@timestamp', ranges: [{ from: `now-${lookbackWindow.duration.format()}/m`, to: 'now/m' }] }, aggs: { good: { sum: { field: 'slo.isGoodSlice' } }, total: { value_count: { field: 'slo.isGoodSlice' } } } } }), {}); } function handleWindowedResult(aggregations, lookbackWindows) { if (aggregations === undefined) { throw new _errors.InternalQueryError('Invalid aggregation response'); } const indicatorDataPerLookbackWindow = {}; for (const lookbackWindow of lookbackWindows) { var _aggregations$lookbac, _aggregations$lookbac2; const windowAggBuckets = (_aggregations$lookbac = (_aggregations$lookbac2 = aggregations[lookbackWindow.name]) === null || _aggregations$lookbac2 === void 0 ? void 0 : _aggregations$lookbac2.buckets) !== null && _aggregations$lookbac !== void 0 ? _aggregations$lookbac : []; if (!Array.isArray(windowAggBuckets) || windowAggBuckets.length === 0) { throw new _errors.InternalQueryError('Invalid aggregation bucket response'); } const bucket = windowAggBuckets[0]; const good = bucket.good.value; const total = bucket.total.value; if (good === null || total === null) { throw new _errors.InternalQueryError('Invalid aggregation sum bucket response'); } indicatorDataPerLookbackWindow[lookbackWindow.name] = { good, total, dateRange: { from: new Date(bucket.from_as_string), to: new Date(bucket.to_as_string) } }; } return indicatorDataPerLookbackWindow; } function getLookbackDateRange(duration) { const unit = (0, _sloSchema.toMomentUnitOfTime)(duration.unit); const now = _moment.default.utc().startOf('minute'); const from = now.clone().subtract(duration.value, unit); const to = now.clone(); return { from: from.toDate(), to: to.toDate() }; }