Skip to content

Commit

Permalink
Merge changes with updates from elastic#35262.
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeelmers committed Aug 1, 2019
1 parent 0aab153 commit d50afb3
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 2 deletions.
Expand Up @@ -309,6 +309,41 @@ describe('IndexPattern', () => {
});
});

describe('getIndex', () => {
it('should return the title when there is no intervalName', () => {
expect(indexPattern.getIndex()).toBe(indexPattern.title);
});

it('should convert time-based intervals to wildcards', () => {
const oldTitle = indexPattern.title;
indexPattern.intervalName = 'daily';

indexPattern.title = '[logstash-]YYYY.MM.DD';
expect(indexPattern.getIndex()).toBe('logstash-*');

indexPattern.title = 'YYYY.MM.DD[-logstash]';
expect(indexPattern.getIndex()).toBe('*-logstash');

indexPattern.title = 'YYYY[-logstash-]YYYY.MM.DD';
expect(indexPattern.getIndex()).toBe('*-logstash-*');

indexPattern.title = 'YYYY[-logstash-]YYYY[-foo-]MM.DD';
expect(indexPattern.getIndex()).toBe('*-logstash-*-foo-*');

indexPattern.title = 'YYYY[-logstash-]YYYY[-foo-]MM.DD[-bar]';
expect(indexPattern.getIndex()).toBe('*-logstash-*-foo-*-bar');

indexPattern.title = '[logstash-]YYYY[-foo-]MM.DD[-bar]';
expect(indexPattern.getIndex()).toBe('logstash-*-foo-*-bar');

indexPattern.title = '[logstash]';
expect(indexPattern.getIndex()).toBe('logstash');

indexPattern.title = oldTitle;
delete indexPattern.intervalName;
});
});

it('should handle version conflicts', async () => {
setDocsourcePayload(null, {
_version: 'foo',
Expand Down
Expand Up @@ -19,6 +19,11 @@

import _, { each, reject } from 'lodash';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import React from 'react';
import chrome from 'ui/chrome';

// @ts-ignore
import { SavedObjectNotFound, DuplicateField } from 'ui/errors';
// @ts-ignore
Expand Down Expand Up @@ -57,6 +62,7 @@ export interface StaticIndexPattern {
id?: string;
type?: string;
timeFieldName?: string;
intervalName?: string | null;
}

export class IndexPattern implements StaticIndexPattern {
Expand All @@ -69,6 +75,7 @@ export class IndexPattern implements StaticIndexPattern {
public typeMeta: any;
public fields: FieldList;
public timeFieldName: string | undefined;
public intervalName: string | undefined | null;
public formatHit: any;
public formatField: any;
public flattenHit: any;
Expand Down Expand Up @@ -173,7 +180,7 @@ export class IndexPattern implements StaticIndexPattern {
this.initFields();
}

private updateFromElasticSearch(response: any, forceFieldRefresh: boolean = false) {
private async updateFromElasticSearch(response: any, forceFieldRefresh: boolean = false) {
if (!response.found) {
throw new SavedObjectNotFound(type, this.id, '#/management/kibana/index_pattern');
}
Expand All @@ -192,6 +199,46 @@ export class IndexPattern implements StaticIndexPattern {
this.title = this.id;
}

if (this.isUnsupportedTimePattern()) {
const warningTitle = i18n.translate('common.ui.indexPattern.warningTitle', {
defaultMessage: 'Support for time interval index patterns removed',
});

const warningText = i18n.translate('common.ui.indexPattern.warningText', {
defaultMessage:
'Currently querying all indices matching {index}. {title} should be migrated to a wildcard-based index pattern.',
values: {
title: this.title,
index: this.getIndex(),
},
});

// kbnUrl was added to this service in #35262 before it was de-angularized, and merged in a PR
// directly against the 7.x branch. Index patterns were de-angularized in #39247, and in order
// to preserve the functionality from #35262 we need to get the injector here just for kbnUrl.
// This has all been removed as of 8.0.
const $injector = await chrome.dangerouslyGetActiveInjector();
const kbnUrl = $injector.get('kbnUrl') as any; // `any` because KbnUrl interface doesn't have `getRouteHref`
toastNotifications.addWarning({
title: warningTitle,
text: (
<div>
<p>{warningText}</p>
<EuiFlexGroup justifyContent="flexEnd" gutterSize="s">
<EuiFlexItem grow={false}>
<EuiButton size="s" href={kbnUrl.getRouteHref(this, 'edit')}>
<FormattedMessage
id="common.ui.indexPattern.editIndexPattern"
defaultMessage="Edit index pattern"
/>
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</div>
),
});
}

return this.indexFields(forceFieldRefresh);
}

Expand Down Expand Up @@ -261,6 +308,19 @@ export class IndexPattern implements StaticIndexPattern {
return this;
}

migrate(newTitle: string) {
return this.savedObjectsClient
.update(type, this.id!, {
title: newTitle,
intervalName: null,
})
.then(({ attributes: { title, intervalName } }) => {
this.title = title;
this.intervalName = intervalName;
})
.then(() => this);
}

// Get the source filtering configuration for that index.
getSourceFiltering() {
return {
Expand Down Expand Up @@ -326,10 +386,33 @@ export class IndexPattern implements StaticIndexPattern {
return _.where(this.fields, { scripted: true });
}

getIndex() {
if (!this.isUnsupportedTimePattern()) {
return this.title;
}

// Take a time-based interval index pattern title (like [foo-]YYYY.MM.DD[-bar]) and turn it
// into the actual index (like foo-*-bar) by replacing anything not inside square brackets
// with a *.
const regex = /\[[^\]]*]/g; // Matches text inside brackets
const splits = this.title.split(regex); // e.g. ['', 'YYYY.MM.DD', ''] from the above example
const matches = this.title.match(regex) || []; // e.g. ['[foo-]', '[-bar]'] from the above example
return splits
.map((split, i) => {
const match = i >= matches.length ? '' : matches[i].replace(/[\[\]]/g, '');
return `${split.length ? '*' : ''}${match}`;
})
.join('');
}

isTimeBased(): boolean {
return !!this.timeFieldName && (!this.fields || !!this.getTimeField());
}

isUnsupportedTimePattern(): boolean {
return !!this.intervalName;
}

isTimeNanosBased(): boolean {
const timeField: any = this.getTimeField();
return timeField && timeField.esTypes && timeField.esTypes.indexOf('date_nanos') !== -1;
Expand Down
2 changes: 1 addition & 1 deletion src/legacy/ui/public/index_patterns/fields_fetcher.ts
Expand Up @@ -30,7 +30,7 @@ export const createFieldsFetcher = (
) => {
const fieldFetcher = {
fetch: (options: GetFieldsOptions) => {
return fieldFetcher.fetchForWildcard(indexPattern.title, {
return fieldFetcher.fetchForWildcard(indexPattern.getIndex(), {
...options,
type: indexPattern.type,
params: indexPattern.typeMeta && indexPattern.typeMeta.params,
Expand Down

0 comments on commit d50afb3

Please sign in to comment.