mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
* [Index Patterns] Fix return saved index pattern object (#101051) * update docs
This commit is contained in:
parent
abaa442a0f
commit
4202cb42dc
12 changed files with 146 additions and 167 deletions
|
@ -8,26 +8,30 @@
|
|||
|
||||
```typescript
|
||||
getAggregationRestrictions(): Record<string, Record<string, {
|
||||
agg?: string | undefined;
|
||||
agg?: string | undefined; /**
|
||||
* Get last saved saved object fields
|
||||
*/
|
||||
interval?: number | undefined;
|
||||
fixed_interval?: string | undefined;
|
||||
calendar_interval?: string | undefined;
|
||||
delay?: string | undefined; /**
|
||||
delay?: string | undefined;
|
||||
time_zone?: string | undefined; /**
|
||||
* Reset last saved saved object fields. used after saving
|
||||
*/
|
||||
time_zone?: string | undefined;
|
||||
}>> | undefined;
|
||||
```
|
||||
<b>Returns:</b>
|
||||
|
||||
`Record<string, Record<string, {
|
||||
agg?: string | undefined;
|
||||
agg?: string | undefined; /**
|
||||
* Get last saved saved object fields
|
||||
*/
|
||||
interval?: number | undefined;
|
||||
fixed_interval?: string | undefined;
|
||||
calendar_interval?: string | undefined;
|
||||
delay?: string | undefined; /**
|
||||
delay?: string | undefined;
|
||||
time_zone?: string | undefined; /**
|
||||
* Reset last saved saved object fields. used after saving
|
||||
*/
|
||||
time_zone?: string | undefined;
|
||||
}>> | undefined`
|
||||
|
||||
|
|
|
@ -9,33 +9,9 @@ Returns index pattern as saved object body for saving
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
getAsSavedObjectBody(): {
|
||||
fieldAttrs: string | undefined;
|
||||
title: string;
|
||||
timeFieldName: string | undefined;
|
||||
intervalName: string | undefined;
|
||||
sourceFilters: string | undefined;
|
||||
fields: string | undefined;
|
||||
fieldFormatMap: string | undefined;
|
||||
type: string | undefined;
|
||||
typeMeta: string | undefined;
|
||||
allowNoIndex: true | undefined;
|
||||
runtimeFieldMap: string | undefined;
|
||||
};
|
||||
getAsSavedObjectBody(): IndexPatternAttributes;
|
||||
```
|
||||
<b>Returns:</b>
|
||||
|
||||
`{
|
||||
fieldAttrs: string | undefined;
|
||||
title: string;
|
||||
timeFieldName: string | undefined;
|
||||
intervalName: string | undefined;
|
||||
sourceFilters: string | undefined;
|
||||
fields: string | undefined;
|
||||
fieldFormatMap: string | undefined;
|
||||
type: string | undefined;
|
||||
typeMeta: string | undefined;
|
||||
allowNoIndex: true | undefined;
|
||||
runtimeFieldMap: string | undefined;
|
||||
}`
|
||||
`IndexPatternAttributes`
|
||||
|
||||
|
|
|
@ -8,26 +8,30 @@
|
|||
|
||||
```typescript
|
||||
getAggregationRestrictions(): Record<string, Record<string, {
|
||||
agg?: string | undefined;
|
||||
agg?: string | undefined; /**
|
||||
* Get last saved saved object fields
|
||||
*/
|
||||
interval?: number | undefined;
|
||||
fixed_interval?: string | undefined;
|
||||
calendar_interval?: string | undefined;
|
||||
delay?: string | undefined; /**
|
||||
delay?: string | undefined;
|
||||
time_zone?: string | undefined; /**
|
||||
* Reset last saved saved object fields. used after saving
|
||||
*/
|
||||
time_zone?: string | undefined;
|
||||
}>> | undefined;
|
||||
```
|
||||
<b>Returns:</b>
|
||||
|
||||
`Record<string, Record<string, {
|
||||
agg?: string | undefined;
|
||||
agg?: string | undefined; /**
|
||||
* Get last saved saved object fields
|
||||
*/
|
||||
interval?: number | undefined;
|
||||
fixed_interval?: string | undefined;
|
||||
calendar_interval?: string | undefined;
|
||||
delay?: string | undefined; /**
|
||||
delay?: string | undefined;
|
||||
time_zone?: string | undefined; /**
|
||||
* Reset last saved saved object fields. used after saving
|
||||
*/
|
||||
time_zone?: string | undefined;
|
||||
}>> | undefined`
|
||||
|
||||
|
|
|
@ -9,33 +9,9 @@ Returns index pattern as saved object body for saving
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
getAsSavedObjectBody(): {
|
||||
fieldAttrs: string | undefined;
|
||||
title: string;
|
||||
timeFieldName: string | undefined;
|
||||
intervalName: string | undefined;
|
||||
sourceFilters: string | undefined;
|
||||
fields: string | undefined;
|
||||
fieldFormatMap: string | undefined;
|
||||
type: string | undefined;
|
||||
typeMeta: string | undefined;
|
||||
allowNoIndex: true | undefined;
|
||||
runtimeFieldMap: string | undefined;
|
||||
};
|
||||
getAsSavedObjectBody(): IndexPatternAttributes;
|
||||
```
|
||||
<b>Returns:</b>
|
||||
|
||||
`{
|
||||
fieldAttrs: string | undefined;
|
||||
title: string;
|
||||
timeFieldName: string | undefined;
|
||||
intervalName: string | undefined;
|
||||
sourceFilters: string | undefined;
|
||||
fields: string | undefined;
|
||||
fieldFormatMap: string | undefined;
|
||||
type: string | undefined;
|
||||
typeMeta: string | undefined;
|
||||
allowNoIndex: true | undefined;
|
||||
runtimeFieldMap: string | undefined;
|
||||
}`
|
||||
`IndexPatternAttributes`
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import _, { each, reject } from 'lodash';
|
||||
import { FieldAttrs, FieldAttrSet } from '../..';
|
||||
import { FieldAttrs, FieldAttrSet, IndexPatternAttributes } from '../..';
|
||||
import type { RuntimeField } from '../types';
|
||||
import { DuplicateField } from '../../../../kibana_utils/common';
|
||||
|
||||
|
@ -331,7 +331,7 @@ export class IndexPattern implements IIndexPattern {
|
|||
/**
|
||||
* Returns index pattern as saved object body for saving
|
||||
*/
|
||||
getAsSavedObjectBody() {
|
||||
getAsSavedObjectBody(): IndexPatternAttributes {
|
||||
const fieldFormatMap = _.isEmpty(this.fieldFormatMap)
|
||||
? undefined
|
||||
: JSON.stringify(this.fieldFormatMap);
|
||||
|
@ -344,12 +344,10 @@ export class IndexPattern implements IIndexPattern {
|
|||
timeFieldName: this.timeFieldName,
|
||||
intervalName: this.intervalName,
|
||||
sourceFilters: this.sourceFilters ? JSON.stringify(this.sourceFilters) : undefined,
|
||||
fields: this.fields
|
||||
? JSON.stringify(this.fields.filter((field) => field.scripted))
|
||||
: undefined,
|
||||
fields: JSON.stringify(this.fields?.filter((field) => field.scripted) ?? []),
|
||||
fieldFormatMap,
|
||||
type: this.type,
|
||||
typeMeta: this.typeMeta ? JSON.stringify(this.typeMeta) : undefined,
|
||||
type: this.type!,
|
||||
typeMeta: JSON.stringify(this.typeMeta ?? {}),
|
||||
allowNoIndex: this.allowNoIndex ? this.allowNoIndex : undefined,
|
||||
runtimeFieldMap: runtimeFieldMap ? JSON.stringify(runtimeFieldMap) : undefined,
|
||||
};
|
||||
|
|
|
@ -231,7 +231,12 @@ describe('IndexPatterns', () => {
|
|||
|
||||
test('createAndSave', async () => {
|
||||
const title = 'kibana-*';
|
||||
indexPatterns.createSavedObject = jest.fn();
|
||||
|
||||
indexPatterns.createSavedObject = jest.fn(() =>
|
||||
Promise.resolve(({
|
||||
id: 'id',
|
||||
} as unknown) as IndexPattern)
|
||||
);
|
||||
indexPatterns.setDefault = jest.fn();
|
||||
await indexPatterns.createAndSave({ title });
|
||||
expect(indexPatterns.createSavedObject).toBeCalled();
|
||||
|
|
|
@ -407,6 +407,12 @@ export class IndexPatternsService {
|
|||
throw new SavedObjectNotFound(savedObjectType, id, 'management/kibana/indexPatterns');
|
||||
}
|
||||
|
||||
return this.initFromSavedObject(savedObject);
|
||||
};
|
||||
|
||||
private initFromSavedObject = async (
|
||||
savedObject: SavedObject<IndexPatternAttributes>
|
||||
): Promise<IndexPattern> => {
|
||||
const spec = this.savedObjectToSpec(savedObject);
|
||||
const { title, type, typeMeta, runtimeFieldMap } = spec;
|
||||
spec.fieldAttrs = savedObject.attributes.fieldAttrs
|
||||
|
@ -416,7 +422,7 @@ export class IndexPatternsService {
|
|||
try {
|
||||
spec.fields = await this.refreshFieldSpecMap(
|
||||
spec.fields || {},
|
||||
id,
|
||||
savedObject.id,
|
||||
spec.title as string,
|
||||
{
|
||||
pattern: title as string,
|
||||
|
@ -427,6 +433,7 @@ export class IndexPatternsService {
|
|||
},
|
||||
spec.fieldAttrs
|
||||
);
|
||||
|
||||
// CREATE RUNTIME FIELDS
|
||||
for (const [key, value] of Object.entries(runtimeFieldMap || {})) {
|
||||
// do not create runtime field if mapped field exists
|
||||
|
@ -454,7 +461,7 @@ export class IndexPatternsService {
|
|||
this.onError(err, {
|
||||
title: i18n.translate('data.indexPatterns.fetchFieldErrorTitle', {
|
||||
defaultMessage: 'Error fetching fields for index pattern {title} (ID: {id})',
|
||||
values: { id, title },
|
||||
values: { id: savedObject.id, title },
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
@ -548,9 +555,9 @@ export class IndexPatternsService {
|
|||
|
||||
async createAndSave(spec: IndexPatternSpec, override = false, skipFetchFields = false) {
|
||||
const indexPattern = await this.create(spec, skipFetchFields);
|
||||
await this.createSavedObject(indexPattern, override);
|
||||
await this.setDefault(indexPattern.id!);
|
||||
return indexPattern;
|
||||
const createdIndexPattern = await this.createSavedObject(indexPattern, override);
|
||||
await this.setDefault(createdIndexPattern.id!);
|
||||
return createdIndexPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -570,15 +577,20 @@ export class IndexPatternsService {
|
|||
}
|
||||
|
||||
const body = indexPattern.getAsSavedObjectBody();
|
||||
const response = await this.savedObjectsClient.create(savedObjectType, body, {
|
||||
id: indexPattern.id,
|
||||
});
|
||||
indexPattern.id = response.id;
|
||||
this.indexPatternCache.set(indexPattern.id, Promise.resolve(indexPattern));
|
||||
const response: SavedObject<IndexPatternAttributes> = (await this.savedObjectsClient.create(
|
||||
savedObjectType,
|
||||
body,
|
||||
{
|
||||
id: indexPattern.id,
|
||||
}
|
||||
)) as SavedObject<IndexPatternAttributes>;
|
||||
|
||||
const createdIndexPattern = await this.initFromSavedObject(response);
|
||||
this.indexPatternCache.set(createdIndexPattern.id!, Promise.resolve(createdIndexPattern));
|
||||
if (this.savedObjectsCache) {
|
||||
this.savedObjectsCache.push(response as SavedObject<IndexPatternSavedObjectAttrs>);
|
||||
}
|
||||
return indexPattern;
|
||||
return createdIndexPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1330,28 +1330,18 @@ export class IndexPattern implements IIndexPattern {
|
|||
};
|
||||
// (undocumented)
|
||||
getAggregationRestrictions(): Record<string, Record<string, {
|
||||
agg?: string | undefined;
|
||||
agg?: string | undefined; /**
|
||||
* Get last saved saved object fields
|
||||
*/
|
||||
interval?: number | undefined;
|
||||
fixed_interval?: string | undefined;
|
||||
calendar_interval?: string | undefined;
|
||||
delay?: string | undefined; /**
|
||||
delay?: string | undefined;
|
||||
time_zone?: string | undefined; /**
|
||||
* Reset last saved saved object fields. used after saving
|
||||
*/
|
||||
time_zone?: string | undefined;
|
||||
}>> | undefined;
|
||||
getAsSavedObjectBody(): {
|
||||
fieldAttrs: string | undefined;
|
||||
title: string;
|
||||
timeFieldName: string | undefined;
|
||||
intervalName: string | undefined;
|
||||
sourceFilters: string | undefined;
|
||||
fields: string | undefined;
|
||||
fieldFormatMap: string | undefined;
|
||||
type: string | undefined;
|
||||
typeMeta: string | undefined;
|
||||
allowNoIndex: true | undefined;
|
||||
runtimeFieldMap: string | undefined;
|
||||
};
|
||||
getAsSavedObjectBody(): IndexPatternAttributes;
|
||||
// (undocumented)
|
||||
getComputedFields(): {
|
||||
storedFields: string[];
|
||||
|
|
|
@ -15,9 +15,8 @@ import type { DataPluginStart, DataPluginStartDependencies } from '../../plugin'
|
|||
|
||||
const indexPatternSpecSchema = schema.object({
|
||||
title: schema.string(),
|
||||
|
||||
id: schema.maybe(schema.string()),
|
||||
version: schema.maybe(schema.string()),
|
||||
id: schema.maybe(schema.string()),
|
||||
type: schema.maybe(schema.string()),
|
||||
timeFieldName: schema.maybe(schema.string()),
|
||||
sourceFilters: schema.maybe(
|
||||
|
|
|
@ -772,28 +772,18 @@ export class IndexPattern implements IIndexPattern {
|
|||
};
|
||||
// (undocumented)
|
||||
getAggregationRestrictions(): Record<string, Record<string, {
|
||||
agg?: string | undefined;
|
||||
agg?: string | undefined; /**
|
||||
* Get last saved saved object fields
|
||||
*/
|
||||
interval?: number | undefined;
|
||||
fixed_interval?: string | undefined;
|
||||
calendar_interval?: string | undefined;
|
||||
delay?: string | undefined; /**
|
||||
delay?: string | undefined;
|
||||
time_zone?: string | undefined; /**
|
||||
* Reset last saved saved object fields. used after saving
|
||||
*/
|
||||
time_zone?: string | undefined;
|
||||
}>> | undefined;
|
||||
getAsSavedObjectBody(): {
|
||||
fieldAttrs: string | undefined;
|
||||
title: string;
|
||||
timeFieldName: string | undefined;
|
||||
intervalName: string | undefined;
|
||||
sourceFilters: string | undefined;
|
||||
fields: string | undefined;
|
||||
fieldFormatMap: string | undefined;
|
||||
type: string | undefined;
|
||||
typeMeta: string | undefined;
|
||||
allowNoIndex: true | undefined;
|
||||
runtimeFieldMap: string | undefined;
|
||||
};
|
||||
getAsSavedObjectBody(): IndexPatternAttributes;
|
||||
// (undocumented)
|
||||
getComputedFields(): {
|
||||
storedFields: string[];
|
||||
|
|
|
@ -11,6 +11,7 @@ import { FtrProviderContext } from '../../../../ftr_provider_context';
|
|||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
describe('main', () => {
|
||||
it('can create an index_pattern with just a title', async () => {
|
||||
|
@ -45,7 +46,6 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
index_pattern: {
|
||||
title,
|
||||
id,
|
||||
version: 'test-version',
|
||||
type: 'test-type',
|
||||
timeFieldName: 'test-timeFieldName',
|
||||
},
|
||||
|
@ -54,7 +54,6 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(response.status).to.be(200);
|
||||
expect(response.body.index_pattern.title).to.be(title);
|
||||
expect(response.body.index_pattern.id).to.be(id);
|
||||
expect(response.body.index_pattern.version).to.be('test-version');
|
||||
expect(response.body.index_pattern.type).to.be('test-type');
|
||||
expect(response.body.index_pattern.timeFieldName).to.be('test-timeFieldName');
|
||||
});
|
||||
|
@ -77,60 +76,85 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(response.body.index_pattern.sourceFilters[0].value).to.be('foo');
|
||||
});
|
||||
|
||||
it('can specify optional fields attribute when creating an index pattern', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
describe('creating fields', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('index_patterns/basic_index');
|
||||
});
|
||||
|
||||
expect(response.status).to.be(200);
|
||||
expect(response.body.index_pattern.title).to.be(title);
|
||||
expect(response.body.index_pattern.fields.foo.name).to.be('foo');
|
||||
expect(response.body.index_pattern.fields.foo.type).to.be('string');
|
||||
});
|
||||
|
||||
it('can add two fields, one with all fields specified', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: 'string',
|
||||
},
|
||||
bar: {
|
||||
name: 'bar',
|
||||
type: 'number',
|
||||
count: 123,
|
||||
script: '',
|
||||
esTypes: ['test-type'],
|
||||
scripted: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
after(async () => {
|
||||
await esArchiver.unload('index_patterns/basic_index');
|
||||
});
|
||||
|
||||
expect(response.status).to.be(200);
|
||||
expect(response.body.index_pattern.title).to.be(title);
|
||||
it('can specify optional fields attribute when creating an index pattern', async () => {
|
||||
const title = `basic_index*`;
|
||||
const response = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: 'string',
|
||||
scripted: true,
|
||||
script: "doc['field_name'].value",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.body.index_pattern.fields.foo.name).to.be('foo');
|
||||
expect(response.body.index_pattern.fields.foo.type).to.be('string');
|
||||
expect(response.status).to.be(200);
|
||||
expect(response.body.index_pattern.title).to.be(title);
|
||||
expect(response.body.index_pattern.fields.foo.name).to.be('foo');
|
||||
expect(response.body.index_pattern.fields.foo.type).to.be('string');
|
||||
expect(response.body.index_pattern.fields.foo.scripted).to.be(true);
|
||||
expect(response.body.index_pattern.fields.foo.script).to.be("doc['field_name'].value");
|
||||
|
||||
expect(response.body.index_pattern.fields.bar.name).to.be('bar');
|
||||
expect(response.body.index_pattern.fields.bar.type).to.be('number');
|
||||
expect(response.body.index_pattern.fields.bar.count).to.be(123);
|
||||
expect(response.body.index_pattern.fields.bar.script).to.be('');
|
||||
expect(response.body.index_pattern.fields.bar.esTypes[0]).to.be('test-type');
|
||||
expect(response.body.index_pattern.fields.bar.scripted).to.be(true);
|
||||
expect(response.body.index_pattern.fields.bar.name).to.be('bar'); // created from es index
|
||||
expect(response.body.index_pattern.fields.bar.type).to.be('boolean');
|
||||
});
|
||||
|
||||
it('Can add scripted fields, other fields created from es index', async () => {
|
||||
const title = `basic_index*`;
|
||||
const response = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: 'string',
|
||||
},
|
||||
fake: {
|
||||
name: 'fake',
|
||||
type: 'string',
|
||||
},
|
||||
bar: {
|
||||
name: 'bar',
|
||||
type: 'number',
|
||||
count: 123,
|
||||
script: '',
|
||||
esTypes: ['test-type'],
|
||||
scripted: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).to.be(200);
|
||||
expect(response.body.index_pattern.title).to.be(title);
|
||||
|
||||
expect(response.body.index_pattern.fields.foo.name).to.be('foo');
|
||||
expect(response.body.index_pattern.fields.foo.type).to.be('number'); // picked up from index
|
||||
|
||||
expect(response.body.index_pattern.fields.fake).to.be(undefined); // not in index, so not created
|
||||
|
||||
expect(response.body.index_pattern.fields.bar.name).to.be('bar');
|
||||
expect(response.body.index_pattern.fields.bar.type).to.be('number');
|
||||
expect(response.body.index_pattern.fields.bar.count).to.be(123);
|
||||
expect(response.body.index_pattern.fields.bar.script).to.be('');
|
||||
expect(response.body.index_pattern.fields.bar.esTypes[0]).to.be('test-type');
|
||||
expect(response.body.index_pattern.fields.bar.scripted).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('can specify optional typeMeta attribute when creating an index pattern', async () => {
|
||||
|
|
|
@ -25,6 +25,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
it('can create a new scripted field', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
override: true,
|
||||
index_pattern: {
|
||||
title,
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue