Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TSVB visualizations with no timefield do not render after upgrading from 7.12.1 to 7.13.0 #102494

Merged
merged 2 commits into from
Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ export async function getVisData(
indexPatternsService,
uiSettings,
searchStrategyRegistry: framework.searchStrategyRegistry,
cachedIndexPatternFetcher: getCachedIndexPatternFetcher(
indexPatternsService,
Boolean(panel.use_kibana_indexes)
),
cachedIndexPatternFetcher: getCachedIndexPatternFetcher(indexPatternsService, {
fetchKibanaIndexForStringIndexes: Boolean(panel.use_kibana_indexes),
}),
};

return panel.type === PANEL_TYPES.TABLE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@ import type { IndexPatternValue, FetchedIndexPattern } from '../../../../common/

export const getCachedIndexPatternFetcher = (
indexPatternsService: IndexPatternsService,
fetchKibanaIndexForStringIndexes: boolean = false
globalOptions: {
fetchKibanaIndexForStringIndexes: boolean;
} = {
fetchKibanaIndexForStringIndexes: false,
}
) => {
const cache = new Map();

return async (indexPatternValue: IndexPatternValue): Promise<FetchedIndexPattern> => {
const key = getIndexPatternKey(indexPatternValue);
return async (
indexPatternValue: IndexPatternValue,
fetchKibanaIndexForStringIndexes: boolean = globalOptions.fetchKibanaIndexForStringIndexes
): Promise<FetchedIndexPattern> => {
const key = `${getIndexPatternKey(indexPatternValue)}:${fetchKibanaIndexForStringIndexes}`;

if (cache.has(key)) {
return cache.get(key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('getIntervalAndTimefield(panel, series)', () => {
const panel = { time_field: '@timestamp', interval: 'auto' } as Panel;
const series = {} as Series;

expect(getIntervalAndTimefield(panel, series, index)).toEqual({
expect(getIntervalAndTimefield(panel, index, series)).toEqual({
timeField: '@timestamp',
interval: 'auto',
});
Expand All @@ -30,7 +30,7 @@ describe('getIntervalAndTimefield(panel, series)', () => {
series_time_field: 'time',
} as unknown) as Series;

expect(getIntervalAndTimefield(panel, series, index)).toEqual({
expect(getIntervalAndTimefield(panel, index, series)).toEqual({
timeField: 'time',
interval: '1m',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
*/

import { AUTO_INTERVAL } from '../../../common/constants';
import type { FetchedIndexPattern, Panel, Series } from '../../../common/types';
import { validateField } from '../../../common/fields_utils';

export function getIntervalAndTimefield(panel: Panel, series: Series, index: FetchedIndexPattern) {
import type { FetchedIndexPattern, Panel, Series } from '../../../common/types';

export function getIntervalAndTimefield(panel: Panel, index: FetchedIndexPattern, series?: Series) {
const timeField =
(series.override_index_pattern ? series.series_time_field : panel.time_field) ||
(series?.override_index_pattern ? series.series_time_field : panel.time_field) ||
index.indexPattern?.timeFieldName;

if (panel.use_kibana_indexes) {
Expand All @@ -22,7 +23,7 @@ export function getIntervalAndTimefield(panel: Panel, series: Series, index: Fet
let interval = panel.interval;
let maxBars = panel.max_bars;

if (series.override_index_pattern) {
if (series?.override_index_pattern) {
interval = series.series_interval || AUTO_INTERVAL;
maxBars = series.series_max_bars;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import type {
VisTypeTimeseriesVisDataRequest,
} from '../../types';
import type { Panel } from '../../../common/types';
import { getIntervalAndTimefield } from './get_interval_and_timefield';

export async function getTableData(
requestContext: VisTypeTimeseriesRequestHandlerContext,
Expand Down Expand Up @@ -66,6 +67,18 @@ export async function getTableData(
return panel.pivot_id;
};

const buildSeriesMetaParams = async () => {
let index = panelIndex;

/** This part of code is required to try to get the default timefield for string indices.
* The rest of the functionality available for Kibana indexes should not be active **/
if (!panel.use_kibana_indexes && index.indexPatternString) {
index = await services.cachedIndexPatternFetcher(index.indexPatternString, true);
}

return getIntervalAndTimefield(panel, index);
};

const meta = {
type: panel.type,
uiRestrictions: capabilities.uiRestrictions,
Expand All @@ -78,7 +91,8 @@ export async function getTableData(
services.esQueryConfig,
panelIndex,
capabilities,
services.uiSettings
services.uiSettings,
buildSeriesMetaParams
);

const [resp] = await searchStrategy.search(requestContext, req, [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import { overwrite } from '../../helpers';
import { getBucketSize } from '../../helpers/get_bucket_size';
import { offsetTime } from '../../offset_time';
import { getIntervalAndTimefield } from '../../get_interval_and_timefield';
import { isLastValueTimerangeMode } from '../../helpers/get_timerange_mode';
import { search, UI_SETTINGS } from '../../../../../../../plugins/data/server';

Expand All @@ -22,13 +21,14 @@ export function dateHistogram(
esQueryConfig,
seriesIndex,
capabilities,
uiSettings
uiSettings,
buildSeriesMetaParams
) {
return (next) => async (doc) => {
const maxBarsUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS);
const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET);

const { timeField, interval, maxBars } = getIntervalAndTimefield(panel, series, seriesIndex);
const { timeField, interval, maxBars } = await buildSeriesMetaParams();
const { from, to } = offsetTime(req, series.offset_time);

let bucketInterval;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import { DefaultSearchCapabilities } from '../../../search_strategies/capabilities/default_search_capabilities';
import { dateHistogram } from './date_histogram';
import { getIntervalAndTimefield } from '../../get_interval_and_timefield';
import { UI_SETTINGS } from '../../../../../../data/common';

describe('dateHistogram(req, panel, series)', () => {
Expand All @@ -18,6 +19,7 @@ describe('dateHistogram(req, panel, series)', () => {
let config;
let indexPattern;
let uiSettings;
let buildSeriesMetaParams;

beforeEach(() => {
req = {
Expand All @@ -44,14 +46,24 @@ describe('dateHistogram(req, panel, series)', () => {
uiSettings = {
get: async (key) => (key === UI_SETTINGS.HISTOGRAM_MAX_BARS ? 100 : 50),
};
buildSeriesMetaParams = jest.fn(async () => {
return getIntervalAndTimefield(panel, indexPattern, series);
});
});

test('calls next when finished', async () => {
const next = jest.fn();

await dateHistogram(req, panel, series, config, indexPattern, capabilities, uiSettings)(next)(
{}
);
await dateHistogram(
req,
panel,
series,
config,
indexPattern,
capabilities,
uiSettings,
buildSeriesMetaParams
)(next)({});

expect(next.mock.calls.length).toEqual(1);
});
Expand All @@ -65,7 +77,8 @@ describe('dateHistogram(req, panel, series)', () => {
config,
indexPattern,
capabilities,
uiSettings
uiSettings,
buildSeriesMetaParams
)(next)({});

expect(doc).toEqual({
Expand Down Expand Up @@ -106,7 +119,8 @@ describe('dateHistogram(req, panel, series)', () => {
config,
indexPattern,
capabilities,
uiSettings
uiSettings,
buildSeriesMetaParams
)(next)({});

expect(doc).toEqual({
Expand Down Expand Up @@ -150,7 +164,8 @@ describe('dateHistogram(req, panel, series)', () => {
config,
indexPattern,
capabilities,
uiSettings
uiSettings,
buildSeriesMetaParams
)(next)({});

expect(doc).toEqual({
Expand Down Expand Up @@ -197,7 +212,8 @@ describe('dateHistogram(req, panel, series)', () => {
config,
indexPattern,
capabilities,
uiSettings
uiSettings,
buildSeriesMetaParams
)(next)({});

expect(doc.aggs.test.aggs.timeseries.auto_date_histogram).toBeUndefined();
Expand All @@ -219,7 +235,8 @@ describe('dateHistogram(req, panel, series)', () => {
config,
indexPattern,
capabilities,
uiSettings
uiSettings,
buildSeriesMetaParams
)(next)({});

expect(doc.aggs.test.meta).toMatchInlineSnapshot(`
Expand All @@ -242,7 +259,8 @@ describe('dateHistogram(req, panel, series)', () => {
config,
indexPattern,
capabilities,
uiSettings
uiSettings,
buildSeriesMetaParams
)(next)({});

expect(doc).toEqual({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/

import { getBucketSize } from '../../helpers/get_bucket_size';
import { getIntervalAndTimefield } from '../../get_interval_and_timefield';
import { bucketTransform } from '../../helpers/bucket_transform';
import { overwrite } from '../../helpers';
import { UI_SETTINGS } from '../../../../../../data/common';
Expand Down Expand Up @@ -58,12 +57,13 @@ export function positiveRate(
esQueryConfig,
seriesIndex,
capabilities,
uiSettings
uiSettings,
buildSeriesMetaParams
) {
return (next) => async (doc) => {
const barTargetUiSettings = await uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET);

const { interval } = getIntervalAndTimefield(panel, series, seriesIndex);
const { interval } = await buildSeriesMetaParams();
const { intervalString } = getBucketSize(req, interval, capabilities, barTargetUiSettings);

if (series.metrics.some(filter)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ describe('positiveRate(req, panel, series)', () => {
let series;
let req;
let uiSettings;
let buildSeriesMetaParams;

beforeEach(() => {
panel = {
Expand Down Expand Up @@ -42,6 +43,9 @@ describe('positiveRate(req, panel, series)', () => {
uiSettings = {
get: async () => 50,
};
buildSeriesMetaParams = jest.fn().mockResolvedValue({
interval: 'auto',
});
});

test('calls next when finished', async () => {
Expand All @@ -53,7 +57,8 @@ describe('positiveRate(req, panel, series)', () => {
{},
{},
{ maxBucketsLimit: 2000, getValidTimeInterval: jest.fn(() => '1d') },
uiSettings
uiSettings,
buildSeriesMetaParams
)(next)({});

expect(next.mock.calls.length).toEqual(1);
Expand All @@ -68,7 +73,8 @@ describe('positiveRate(req, panel, series)', () => {
{},
{},
{ maxBucketsLimit: 2000, getValidTimeInterval: jest.fn(() => '1d') },
uiSettings
uiSettings,
buildSeriesMetaParams
)(next)({});

expect(doc).toEqual({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,28 @@
*/

import { offsetTime } from '../../offset_time';
import { getIntervalAndTimefield } from '../../get_interval_and_timefield';
import { esQuery } from '../../../../../../data/server';

export function query(req, panel, series, esQueryConfig, seriesIndex) {
return (next) => (doc) => {
const { timeField } = getIntervalAndTimefield(panel, series, seriesIndex);
export function query(
req,
panel,
series,
esQueryConfig,
seriesIndex,
capabilities,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we add capabilities and uiSettings? They are not used anywhere in the query function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is a disgusting part of processor implementations. This is a function that accepts a sequence of arguments. So it's important for us to keep order

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to add a comment? In order to not confuse us :D

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It happens across all request/response processors. I'll create an issue to fix that

uiSettings,
buildSeriesMetaParams
) {
return (next) => async (doc) => {
const { timeField } = await buildSeriesMetaParams();
const { from, to } = offsetTime(req, series.offset_time);

doc.size = 0;

const ignoreGlobalFilter = panel.ignore_global_filter || series.ignore_global_filter;
const queries = !ignoreGlobalFilter ? req.body.query : [];
const filters = !ignoreGlobalFilter ? req.body.filters : [];

doc.query = esQuery.buildEsQuery(seriesIndex.indexPattern, queries, filters, esQueryConfig);

const timerange = {
Expand Down
Loading