[Lens] Fix rollup related bugs (#75314)
Co-authored-by: Marta Bondyra <marta.bondyra@elastic.co>
This commit is contained in:
parent
eecf4aa71f
commit
ddf99b64db
|
@ -84,6 +84,7 @@ const initialState: IndexPatternPrivateState = {
|
|||
id: '1',
|
||||
title: 'idx1',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -134,6 +135,7 @@ const initialState: IndexPatternPrivateState = {
|
|||
id: '2',
|
||||
title: 'idx2',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -191,6 +193,7 @@ const initialState: IndexPatternPrivateState = {
|
|||
id: '3',
|
||||
title: 'idx3',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -322,8 +325,20 @@ describe('IndexPattern Data Panel', () => {
|
|||
isFirstExistenceFetch: false,
|
||||
currentIndexPatternId: 'a',
|
||||
indexPatterns: {
|
||||
a: { id: 'a', title: 'aaa', timeFieldName: 'atime', fields: [] },
|
||||
b: { id: 'b', title: 'bbb', timeFieldName: 'btime', fields: [] },
|
||||
a: {
|
||||
id: 'a',
|
||||
title: 'aaa',
|
||||
timeFieldName: 'atime',
|
||||
fields: [],
|
||||
hasRestrictions: false,
|
||||
},
|
||||
b: {
|
||||
id: 'b',
|
||||
title: 'bbb',
|
||||
timeFieldName: 'btime',
|
||||
fields: [],
|
||||
hasRestrictions: false,
|
||||
},
|
||||
},
|
||||
layers: {
|
||||
1: {
|
||||
|
|
|
@ -126,6 +126,7 @@ export function IndexPatternDataPanel({
|
|||
title: indexPatterns[id].title,
|
||||
timeFieldName: indexPatterns[id].timeFieldName,
|
||||
fields: indexPatterns[id].fields,
|
||||
hasRestrictions: indexPatterns[id].hasRestrictions,
|
||||
}));
|
||||
|
||||
const dslQuery = buildSafeEsQuery(
|
||||
|
@ -422,6 +423,8 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
|
|||
]
|
||||
);
|
||||
|
||||
const fieldInfoUnavailable = existenceFetchFailed || currentIndexPattern.hasRestrictions;
|
||||
|
||||
return (
|
||||
<ChildDragDropProvider {...dragDropContext}>
|
||||
<EuiFlexGroup
|
||||
|
@ -568,7 +571,7 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
|
|||
initialIsOpen={localState.isAvailableAccordionOpen}
|
||||
id="lnsIndexPatternAvailableFields"
|
||||
label={
|
||||
existenceFetchFailed
|
||||
fieldInfoUnavailable
|
||||
? i18n.translate('xpack.lens.indexPattern.allFieldsLabel', {
|
||||
defaultMessage: 'All fields',
|
||||
})
|
||||
|
@ -577,6 +580,7 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
|
|||
})
|
||||
}
|
||||
exists={true}
|
||||
hideDetails={fieldInfoUnavailable}
|
||||
hasLoaded={!!hasSyncedExistingFields}
|
||||
fieldsCount={filteredFieldGroups.availableFields.length}
|
||||
isFiltered={
|
||||
|
@ -609,7 +613,7 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
|
|||
}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
{!existenceFetchFailed && (
|
||||
{!fieldInfoUnavailable && (
|
||||
<FieldsAccordion
|
||||
initialIsOpen={localState.isEmptyAccordionOpen}
|
||||
isFiltered={
|
||||
|
|
|
@ -42,6 +42,7 @@ const expectedIndexPatterns = {
|
|||
title: 'my-fake-index-pattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasExistence: true,
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -1256,6 +1257,7 @@ describe('IndexPatternDimensionEditorPanel', () => {
|
|||
foo: {
|
||||
id: 'foo',
|
||||
title: 'Foo pattern',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
aggregatable: true,
|
||||
|
|
|
@ -47,6 +47,7 @@ export interface FieldsAccordionProps {
|
|||
renderCallout: JSX.Element;
|
||||
exists: boolean;
|
||||
showExistenceFetchError?: boolean;
|
||||
hideDetails?: boolean;
|
||||
}
|
||||
|
||||
export const InnerFieldsAccordion = function InnerFieldsAccordion({
|
||||
|
@ -61,13 +62,20 @@ export const InnerFieldsAccordion = function InnerFieldsAccordion({
|
|||
fieldProps,
|
||||
renderCallout,
|
||||
exists,
|
||||
hideDetails,
|
||||
showExistenceFetchError,
|
||||
}: FieldsAccordionProps) {
|
||||
const renderField = useCallback(
|
||||
(field: IndexPatternField) => (
|
||||
<FieldItem {...fieldProps} key={field.name} field={field} exists={!!exists} />
|
||||
<FieldItem
|
||||
{...fieldProps}
|
||||
key={field.name}
|
||||
field={field}
|
||||
exists={exists}
|
||||
hideDetails={hideDetails}
|
||||
/>
|
||||
),
|
||||
[fieldProps, exists]
|
||||
[fieldProps, exists, hideDetails]
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -21,6 +21,7 @@ const expectedIndexPatterns = {
|
|||
id: '1',
|
||||
title: 'my-fake-index-pattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -70,6 +71,7 @@ const expectedIndexPatterns = {
|
|||
id: '2',
|
||||
title: 'my-fake-restricted-pattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
|
|
@ -20,6 +20,7 @@ const expectedIndexPatterns = {
|
|||
id: '1',
|
||||
title: 'my-fake-index-pattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -68,6 +69,7 @@ const expectedIndexPatterns = {
|
|||
2: {
|
||||
id: '2',
|
||||
title: 'my-fake-restricted-pattern',
|
||||
hasRestrictions: true,
|
||||
timeFieldName: 'timestamp',
|
||||
fields: [
|
||||
{
|
||||
|
@ -322,6 +324,7 @@ describe('IndexPattern Data Source suggestions', () => {
|
|||
1: {
|
||||
id: '1',
|
||||
title: 'no timefield',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'bytes',
|
||||
|
@ -532,6 +535,7 @@ describe('IndexPattern Data Source suggestions', () => {
|
|||
1: {
|
||||
id: '1',
|
||||
title: 'no timefield',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'bytes',
|
||||
|
@ -1350,6 +1354,7 @@ describe('IndexPattern Data Source suggestions', () => {
|
|||
1: {
|
||||
id: '1',
|
||||
title: 'my-fake-index-pattern',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'field1',
|
||||
|
@ -1493,6 +1498,7 @@ describe('IndexPattern Data Source suggestions', () => {
|
|||
1: {
|
||||
id: '1',
|
||||
title: 'my-fake-index-pattern',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'field1',
|
||||
|
@ -1555,6 +1561,7 @@ describe('IndexPattern Data Source suggestions', () => {
|
|||
1: {
|
||||
id: '1',
|
||||
title: 'my-fake-index-pattern',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'field1',
|
||||
|
|
|
@ -62,6 +62,7 @@ const initialState: IndexPatternPrivateState = {
|
|||
id: '1',
|
||||
title: 'my-fake-index-pattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -103,6 +104,7 @@ const initialState: IndexPatternPrivateState = {
|
|||
'2': {
|
||||
id: '2',
|
||||
title: 'my-fake-restricted-pattern',
|
||||
hasRestrictions: true,
|
||||
timeFieldName: 'timestamp',
|
||||
fields: [
|
||||
{
|
||||
|
@ -160,6 +162,7 @@ const initialState: IndexPatternPrivateState = {
|
|||
id: '3',
|
||||
title: 'my-compatible-pattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
|
|
@ -40,6 +40,7 @@ const indexPattern1 = ({
|
|||
id: '1',
|
||||
title: 'my-fake-index-pattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -105,6 +106,7 @@ const indexPattern2 = ({
|
|||
id: '2',
|
||||
title: 'my-fake-restricted-pattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -733,9 +735,9 @@ describe('loader', () => {
|
|||
dateRange: { fromDate: '1900-01-01', toDate: '2000-01-01' },
|
||||
fetchJson,
|
||||
indexPatterns: [
|
||||
{ id: '1', title: '1', fields: [] },
|
||||
{ id: '2', title: '1', fields: [] },
|
||||
{ id: '3', title: '1', fields: [] },
|
||||
{ id: '1', title: '1', fields: [], hasRestrictions: false },
|
||||
{ id: '2', title: '1', fields: [], hasRestrictions: false },
|
||||
{ id: '3', title: '1', fields: [], hasRestrictions: false },
|
||||
],
|
||||
setState,
|
||||
dslQuery,
|
||||
|
@ -783,9 +785,9 @@ describe('loader', () => {
|
|||
dateRange: { fromDate: '1900-01-01', toDate: '2000-01-01' },
|
||||
fetchJson,
|
||||
indexPatterns: [
|
||||
{ id: '1', title: '1', fields: [] },
|
||||
{ id: '2', title: '1', fields: [] },
|
||||
{ id: 'c', title: '1', fields: [] },
|
||||
{ id: '1', title: '1', fields: [], hasRestrictions: false },
|
||||
{ id: '2', title: '1', fields: [], hasRestrictions: false },
|
||||
{ id: 'c', title: '1', fields: [], hasRestrictions: false },
|
||||
],
|
||||
setState,
|
||||
dslQuery,
|
||||
|
@ -817,6 +819,7 @@ describe('loader', () => {
|
|||
{
|
||||
id: '1',
|
||||
title: '1',
|
||||
hasRestrictions: false,
|
||||
fields: [{ name: 'field1' }, { name: 'field2' }] as IndexPatternField[],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -91,6 +91,7 @@ export async function loadIndexPatterns({
|
|||
timeFieldName,
|
||||
fieldFormatMap,
|
||||
fields: newFields,
|
||||
hasRestrictions: !!typeMeta?.aggs,
|
||||
};
|
||||
|
||||
return {
|
||||
|
@ -334,6 +335,7 @@ export async function syncExistingFields({
|
|||
title: string;
|
||||
fields: IndexPatternField[];
|
||||
timeFieldName?: string | null;
|
||||
hasRestrictions: boolean;
|
||||
}>;
|
||||
fetchJson: HttpSetup['post'];
|
||||
setState: SetState;
|
||||
|
@ -343,6 +345,12 @@ export async function syncExistingFields({
|
|||
showNoDataPopover: () => void;
|
||||
}) {
|
||||
const existenceRequests = indexPatterns.map((pattern) => {
|
||||
if (pattern.hasRestrictions) {
|
||||
return {
|
||||
indexPatternTitle: pattern.title,
|
||||
existingFieldNames: pattern.fields.map((field) => field.name),
|
||||
};
|
||||
}
|
||||
const body: Record<string, string | object> = {
|
||||
dslQuery,
|
||||
fromDate: dateRange.fromDate,
|
||||
|
|
|
@ -11,6 +11,7 @@ export const createMockedIndexPattern = (): IndexPattern => ({
|
|||
id: '1',
|
||||
title: 'my-fake-index-pattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -70,6 +71,7 @@ export const createMockedRestrictedIndexPattern = () => ({
|
|||
id: '2',
|
||||
title: 'my-fake-restricted-pattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
|
|
@ -55,6 +55,7 @@ describe('date_histogram', () => {
|
|||
id: '1',
|
||||
title: 'Mock Indexpattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -69,6 +70,7 @@ describe('date_histogram', () => {
|
|||
2: {
|
||||
id: '2',
|
||||
title: 'Mock Indexpattern 2',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'other_timestamp',
|
||||
|
@ -229,13 +231,50 @@ describe('date_histogram', () => {
|
|||
it('should reflect params correctly', () => {
|
||||
const esAggsConfig = dateHistogramOperation.toEsAggsConfig(
|
||||
state.layers.first.columns.col1 as DateHistogramIndexPatternColumn,
|
||||
'col1'
|
||||
'col1',
|
||||
state.indexPatterns['1']
|
||||
);
|
||||
expect(esAggsConfig).toEqual(
|
||||
expect.objectContaining({
|
||||
params: expect.objectContaining({
|
||||
interval: '42w',
|
||||
field: 'timestamp',
|
||||
useNormalizedEsInterval: true,
|
||||
}),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should not use normalized es interval for rollups', () => {
|
||||
const esAggsConfig = dateHistogramOperation.toEsAggsConfig(
|
||||
state.layers.first.columns.col1 as DateHistogramIndexPatternColumn,
|
||||
'col1',
|
||||
{
|
||||
...state.indexPatterns['1'],
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
displayName: 'timestamp',
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
type: 'date',
|
||||
aggregationRestrictions: {
|
||||
date_histogram: {
|
||||
agg: 'date_histogram',
|
||||
time_zone: 'UTC',
|
||||
calendar_interval: '42w',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
);
|
||||
expect(esAggsConfig).toEqual(
|
||||
expect.objectContaining({
|
||||
params: expect.objectContaining({
|
||||
interval: '42w',
|
||||
field: 'timestamp',
|
||||
useNormalizedEsInterval: false,
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
@ -300,6 +339,7 @@ describe('date_histogram', () => {
|
|||
{
|
||||
title: '',
|
||||
id: '',
|
||||
hasRestrictions: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'dateField',
|
||||
|
@ -343,6 +383,7 @@ describe('date_histogram', () => {
|
|||
{
|
||||
title: '',
|
||||
id: '',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'dateField',
|
||||
|
|
|
@ -119,21 +119,24 @@ export const dateHistogramOperation: OperationDefinition<DateHistogramIndexPatte
|
|||
sourceField: field.name,
|
||||
};
|
||||
},
|
||||
toEsAggsConfig: (column, columnId) => ({
|
||||
id: columnId,
|
||||
enabled: true,
|
||||
type: 'date_histogram',
|
||||
schema: 'segment',
|
||||
params: {
|
||||
field: column.sourceField,
|
||||
time_zone: column.params.timeZone,
|
||||
useNormalizedEsInterval: true,
|
||||
interval: column.params.interval,
|
||||
drop_partials: false,
|
||||
min_doc_count: 0,
|
||||
extended_bounds: {},
|
||||
},
|
||||
}),
|
||||
toEsAggsConfig: (column, columnId, indexPattern) => {
|
||||
const usedField = indexPattern.fields.find((field) => field.name === column.sourceField);
|
||||
return {
|
||||
id: columnId,
|
||||
enabled: true,
|
||||
type: 'date_histogram',
|
||||
schema: 'segment',
|
||||
params: {
|
||||
field: column.sourceField,
|
||||
time_zone: column.params.timeZone,
|
||||
useNormalizedEsInterval: !usedField || !usedField.aggregationRestrictions?.date_histogram,
|
||||
interval: column.params.interval,
|
||||
drop_partials: false,
|
||||
min_doc_count: 0,
|
||||
extended_bounds: {},
|
||||
},
|
||||
};
|
||||
},
|
||||
paramEditor: ({ state, setState, currentColumn: currentColumn, layerId, dateRange, data }) => {
|
||||
const field =
|
||||
currentColumn &&
|
||||
|
|
|
@ -84,7 +84,7 @@ interface BaseOperationDefinitionProps<C extends BaseIndexPatternColumn> {
|
|||
* Function turning a column into an agg config passed to the `esaggs` function
|
||||
* together with the agg configs returned from other columns.
|
||||
*/
|
||||
toEsAggsConfig: (column: C, columnId: string) => unknown;
|
||||
toEsAggsConfig: (column: C, columnId: string, indexPattern: IndexPattern) => unknown;
|
||||
/**
|
||||
* Returns true if the `column` can also be used on `newIndexPattern`.
|
||||
* If this function returns false, the column is removed when switching index pattern
|
||||
|
|
|
@ -68,7 +68,7 @@ function buildMetricOperation<T extends MetricColumn<string>>({
|
|||
sourceField: field.name,
|
||||
};
|
||||
},
|
||||
toEsAggsConfig: (column, columnId) => ({
|
||||
toEsAggsConfig: (column, columnId, _indexPattern) => ({
|
||||
id: columnId,
|
||||
enabled: true,
|
||||
type: column.operationType,
|
||||
|
|
|
@ -13,7 +13,7 @@ import { dataPluginMock } from '../../../../../../../src/plugins/data/public/moc
|
|||
import { createMockedIndexPattern } from '../../mocks';
|
||||
import { TermsIndexPatternColumn } from './terms';
|
||||
import { termsOperation } from './index';
|
||||
import { IndexPatternPrivateState } from '../../types';
|
||||
import { IndexPatternPrivateState, IndexPattern } from '../../types';
|
||||
|
||||
const defaultProps = {
|
||||
storage: {} as IStorageWrapper,
|
||||
|
@ -69,7 +69,8 @@ describe('terms', () => {
|
|||
it('should reflect params correctly', () => {
|
||||
const esAggsConfig = termsOperation.toEsAggsConfig(
|
||||
state.layers.first.columns.col1 as TermsIndexPatternColumn,
|
||||
'col1'
|
||||
'col1',
|
||||
{} as IndexPattern
|
||||
);
|
||||
expect(esAggsConfig).toEqual(
|
||||
expect.objectContaining({
|
||||
|
|
|
@ -95,7 +95,7 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn> = {
|
|||
},
|
||||
};
|
||||
},
|
||||
toEsAggsConfig: (column, columnId) => ({
|
||||
toEsAggsConfig: (column, columnId, _indexPattern) => ({
|
||||
id: columnId,
|
||||
enabled: true,
|
||||
type: 'terms',
|
||||
|
|
|
@ -16,6 +16,7 @@ const expectedIndexPatterns = {
|
|||
id: '1',
|
||||
title: 'my-fake-index-pattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
|
|
@ -570,6 +570,7 @@ describe('state_helpers', () => {
|
|||
const indexPattern: IndexPattern = {
|
||||
id: 'test',
|
||||
title: '',
|
||||
hasRestrictions: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'fieldA',
|
||||
|
|
|
@ -21,7 +21,11 @@ function getExpressionForLayer(
|
|||
}
|
||||
|
||||
function getEsAggsConfig<C extends IndexPatternColumn>(column: C, columnId: string) {
|
||||
return operationDefinitionMap[column.operationType].toEsAggsConfig(column, columnId);
|
||||
return operationDefinitionMap[column.operationType].toEsAggsConfig(
|
||||
column,
|
||||
columnId,
|
||||
indexPattern
|
||||
);
|
||||
}
|
||||
|
||||
const columnEntries = columnOrder.map((colId) => [colId, columns[colId]] as const);
|
||||
|
|
|
@ -19,6 +19,7 @@ export interface IndexPattern {
|
|||
params: unknown;
|
||||
}
|
||||
>;
|
||||
hasRestrictions: boolean;
|
||||
}
|
||||
|
||||
export interface IndexPatternField {
|
||||
|
|
|
@ -31,6 +31,9 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
|
|||
loadTestFile(require.resolve('./dashboard'));
|
||||
loadTestFile(require.resolve('./persistent_context'));
|
||||
loadTestFile(require.resolve('./lens_reporting'));
|
||||
|
||||
// has to be last one in the suite because it overrides saved objects
|
||||
loadTestFile(require.resolve('./rollup'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
75
x-pack/test/functional/apps/lens/rollup.ts
Normal file
75
x-pack/test/functional/apps/lens/rollup.ts
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const PageObjects = getPageObjects(['visualize', 'lens']);
|
||||
const find = getService('find');
|
||||
const listingTable = getService('listingTable');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
describe('lens rollup tests', () => {
|
||||
before(async () => {
|
||||
await esArchiver.loadIfNeeded('lens/rollup/data');
|
||||
await esArchiver.loadIfNeeded('lens/rollup/config');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('lens/rollup/data');
|
||||
await esArchiver.unload('lens/rollup/config');
|
||||
});
|
||||
|
||||
it('should allow creation of lens xy chart', async () => {
|
||||
await PageObjects.visualize.navigateToNewVisualization();
|
||||
await PageObjects.visualize.clickVisType('lens');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
await PageObjects.lens.configureDimension({
|
||||
dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension',
|
||||
operation: 'date_histogram',
|
||||
field: '@timestamp',
|
||||
});
|
||||
|
||||
await PageObjects.lens.configureDimension({
|
||||
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
|
||||
operation: 'sum',
|
||||
field: 'bytes',
|
||||
});
|
||||
|
||||
await PageObjects.lens.configureDimension({
|
||||
dimension: 'lnsXY_splitDimensionPanel > lns-empty-dimension',
|
||||
operation: 'terms',
|
||||
field: 'geo.src',
|
||||
});
|
||||
expect(await find.allByCssSelector('.echLegendItem')).to.have.length(2);
|
||||
|
||||
await PageObjects.lens.save('Afancilenstest');
|
||||
|
||||
// Ensure the visualization shows up in the visualize list, and takes
|
||||
// us back to the visualization as we configured it.
|
||||
await PageObjects.visualize.gotoVisualizationLandingPage();
|
||||
await listingTable.searchForItemWithName('Afancilenstest');
|
||||
await PageObjects.lens.clickVisualizeListItemTitle('Afancilenstest');
|
||||
await PageObjects.lens.goToTimeRange();
|
||||
|
||||
expect(await PageObjects.lens.getTitle()).to.eql('Afancilenstest');
|
||||
|
||||
// .echLegendItem__title is the only viable way of getting the xy chart's
|
||||
// legend item(s), so we're using a class selector here.
|
||||
expect(await find.allByCssSelector('.echLegendItem')).to.have.length(2);
|
||||
});
|
||||
|
||||
it('should allow seamless transition to and from table view', async () => {
|
||||
await PageObjects.lens.switchToVisualization('lnsMetric');
|
||||
await PageObjects.lens.assertMetric('Sum of bytes', '16,788');
|
||||
await PageObjects.lens.switchToVisualization('lnsDatatable');
|
||||
expect(await PageObjects.lens.getDatatableHeaderText()).to.eql('Sum of bytes');
|
||||
expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('16,788');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"type": "doc",
|
||||
"value": {
|
||||
"id": "space:default",
|
||||
"index": ".kibana_1",
|
||||
"source": {
|
||||
"migrationVersion": {
|
||||
"space": "6.6.0"
|
||||
},
|
||||
"references": [],
|
||||
"space": {
|
||||
"_reserved": true,
|
||||
"description": "This is the default space!",
|
||||
"disabledFeatures": [],
|
||||
"name": "Default"
|
||||
},
|
||||
"type": "space"
|
||||
},
|
||||
"type": "_doc"
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"type": "doc",
|
||||
"value": {
|
||||
"id": "index-pattern:lens-rolled-up-data",
|
||||
"index": ".kibana_1",
|
||||
"source": {
|
||||
"index-pattern" : {
|
||||
"title" : "lens_rolled_up_data",
|
||||
"timeFieldName" : "@timestamp",
|
||||
"fields" : "[{\"count\":0,\"name\":\"_source\",\"type\":\"_source\",\"esTypes\":[\"_source\"],\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_id\",\"type\":\"string\",\"esTypes\":[\"_id\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_type\",\"type\":\"string\",\"esTypes\":[\"_type\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_index\",\"type\":\"string\",\"esTypes\":[\"_index\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_score\",\"type\":\"number\",\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"@timestamp\",\"type\":\"date\",\"esTypes\":[\"date\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"bytes\",\"type\":\"number\",\"esTypes\":[\"float\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"geo.src\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]",
|
||||
"type" : "rollup",
|
||||
"typeMeta" : "{\"params\":{\"rollup_index\":\"lens_rolled_up_data\"},\"aggs\":{\"date_histogram\":{\"@timestamp\":{\"agg\":\"date_histogram\",\"fixed_interval\":\"60m\",\"time_zone\":\"UTC\"}},\"sum\":{\"bytes\":{\"agg\":\"sum\"}},\"max\":{\"bytes\":{\"agg\":\"max\"}},\"terms\":{\"geo.src\":{\"agg\":\"terms\"}}}}"
|
||||
},
|
||||
"type" : "index-pattern",
|
||||
"references" : [ ],
|
||||
"migrationVersion" : {
|
||||
"index-pattern" : "7.6.0"
|
||||
},
|
||||
"updated_at" : "2020-08-19T08:39:09.998Z"
|
||||
},
|
||||
"type": "_doc"
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"type": "doc",
|
||||
"value": {
|
||||
"id": "config:8.0.0",
|
||||
"index": ".kibana_1",
|
||||
"source": {
|
||||
"config": {
|
||||
"accessibility:disableAnimations": true,
|
||||
"buildNum": 9007199254740991,
|
||||
"dateFormat:tz": "UTC",
|
||||
"defaultIndex": "logstash-*"
|
||||
},
|
||||
"references": [],
|
||||
"type": "config",
|
||||
"updated_at": "2019-09-04T18:47:24.761Z"
|
||||
},
|
||||
"type": "_doc"
|
||||
}
|
||||
}
|
1294
x-pack/test/functional/es_archives/lens/rollup/config/mappings.json
Normal file
1294
x-pack/test/functional/es_archives/lens/rollup/config/mappings.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"type": "doc",
|
||||
"value": {
|
||||
"index": "lens_rolled_up_data",
|
||||
"id": "lens_rolled_up_data$vuSq1a9Ph2Nq-2yfGpE34g",
|
||||
"source": {
|
||||
"@timestamp.date_histogram.time_zone": "UTC",
|
||||
"@timestamp.date_histogram.timestamp": 1442710800000,
|
||||
"geo.src.terms.value": "CN",
|
||||
"bytes.max.value": 5678.0,
|
||||
"_rollup.version": 2,
|
||||
"bytes.sum.value": 5678.0,
|
||||
"@timestamp.date_histogram.interval": "60m",
|
||||
"geo.src.terms._count": 1,
|
||||
"@timestamp.date_histogram._count": 1,
|
||||
"_rollup.id": "lens_rolled_up_data"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"type": "doc",
|
||||
"value": {
|
||||
"index": "lens_rolled_up_data",
|
||||
"id": "lens_rolled_up_data$QFyUWoecErSYPMrIb6CgZA",
|
||||
"source": {
|
||||
"@timestamp.date_histogram.time_zone": "UTC",
|
||||
"@timestamp.date_histogram.timestamp": 1442710800000,
|
||||
"geo.src.terms.value": "US",
|
||||
"bytes.max.value": 1234.0,
|
||||
"_rollup.version": 2,
|
||||
"bytes.sum.value": 1234.0,
|
||||
"@timestamp.date_histogram.interval": "60m",
|
||||
"geo.src.terms._count": 1,
|
||||
"@timestamp.date_histogram._count": 1,
|
||||
"_rollup.id": "lens_rolled_up_data"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"type": "doc",
|
||||
"value": {
|
||||
"index": "lens_rolled_up_data",
|
||||
"id": "lens_rolled_up_data$cKCjv1OPjYiyv5WPPblohw",
|
||||
"source": {
|
||||
"@timestamp.date_histogram.time_zone": "UTC",
|
||||
"@timestamp.date_histogram.timestamp": 1442714400000,
|
||||
"geo.src.terms.value": "CN",
|
||||
"bytes.max.value": 9876.0,
|
||||
"_rollup.version": 2,
|
||||
"bytes.sum.value": 9876.0,
|
||||
"@timestamp.date_histogram.interval": "60m",
|
||||
"geo.src.terms._count": 1,
|
||||
"@timestamp.date_histogram._count": 1,
|
||||
"_rollup.id": "lens_rolled_up_data"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
{
|
||||
"type": "index",
|
||||
"value": {
|
||||
"index": "lens_rolled_up_data",
|
||||
"mappings": {
|
||||
"_meta": {
|
||||
"_rollup": {
|
||||
"lens_rolled_up_data": {
|
||||
"cron": "0 * * * * ?",
|
||||
"rollup_index": "lens_rolled_up_data",
|
||||
"groups": {
|
||||
"date_histogram": {
|
||||
"fixed_interval": "60m",
|
||||
"field": "@timestamp",
|
||||
"time_zone": "UTC"
|
||||
},
|
||||
"terms": {
|
||||
"fields": ["geo.src", "ip"]
|
||||
}
|
||||
},
|
||||
"id": "lens_rolled_up_data",
|
||||
"metrics": [
|
||||
{
|
||||
"field": "bytes",
|
||||
"metrics": ["sum", "max"]
|
||||
}
|
||||
],
|
||||
"index_pattern": "lens_raw",
|
||||
"timeout": "20s",
|
||||
"page_size": 1000
|
||||
}
|
||||
},
|
||||
"rollup-version": "8.0.0"
|
||||
},
|
||||
"dynamic_templates": [
|
||||
{
|
||||
"strings": {
|
||||
"match_mapping_type": "string",
|
||||
"mapping": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"date_histograms": {
|
||||
"path_match": "*.date_histogram.timestamp",
|
||||
"mapping": {
|
||||
"type": "date"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"@timestamp": {
|
||||
"properties": {
|
||||
"date_histogram": {
|
||||
"properties": {
|
||||
"_count": {
|
||||
"type": "long"
|
||||
},
|
||||
"interval": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"time_zone": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"timestamp": {
|
||||
"type": "date"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"_rollup": {
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"version": {
|
||||
"type": "long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"properties": {
|
||||
"max": {
|
||||
"properties": {
|
||||
"value": {
|
||||
"type": "float"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sum": {
|
||||
"properties": {
|
||||
"value": {
|
||||
"type": "float"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"geo": {
|
||||
"properties": {
|
||||
"src": {
|
||||
"properties": {
|
||||
"terms": {
|
||||
"properties": {
|
||||
"_count": {
|
||||
"type": "long"
|
||||
},
|
||||
"value": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_shards": "1",
|
||||
"number_of_replicas": "0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue