diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getassavedobjectbody.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getassavedobjectbody.md
index 48d94b84497bd9..cc40ab8bb1173f 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getassavedobjectbody.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getassavedobjectbody.md
@@ -9,33 +9,9 @@ Returns index pattern as saved object body for saving
Signature:
```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;
```
Returns:
-`{
- 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`
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getassavedobjectbody.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getassavedobjectbody.md
index 668d563ff04c0e..f5e87638e2f1ca 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getassavedobjectbody.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getassavedobjectbody.md
@@ -9,33 +9,9 @@ Returns index pattern as saved object body for saving
Signature:
```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;
```
Returns:
-`{
- 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`
diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts
index 1552bed210e8c9..c897cdbce2309a 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts
+++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts
@@ -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';
@@ -318,7 +318,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);
@@ -331,12 +331,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,
};
diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts
index a4f37334c212ee..8715f8feb067a0 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts
+++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts
@@ -230,7 +230,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();
diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts
index 66e66051a6370e..e67e72f295b8ec 100644
--- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts
+++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts
@@ -403,6 +403,12 @@ export class IndexPatternsService {
throw new SavedObjectNotFound(savedObjectType, id, 'management/kibana/indexPatterns');
}
+ return this.initFromSavedObject(savedObject);
+ };
+
+ private initFromSavedObject = async (
+ savedObject: SavedObject
+ ): Promise => {
const spec = this.savedObjectToSpec(savedObject);
const { title, type, typeMeta, runtimeFieldMap } = spec;
spec.fieldAttrs = savedObject.attributes.fieldAttrs
@@ -412,7 +418,7 @@ export class IndexPatternsService {
try {
spec.fields = await this.refreshFieldSpecMap(
spec.fields || {},
- id,
+ savedObject.id,
spec.title as string,
{
pattern: title as string,
@@ -423,6 +429,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
@@ -450,7 +457,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 },
}),
});
}
@@ -516,9 +523,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;
}
/**
@@ -538,15 +545,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 = (await this.savedObjectsClient.create(
+ savedObjectType,
+ body,
+ {
+ id: indexPattern.id,
+ }
+ )) as SavedObject;
+
+ const createdIndexPattern = await this.initFromSavedObject(response);
+ this.indexPatternCache.set(createdIndexPattern.id!, Promise.resolve(createdIndexPattern));
if (this.savedObjectsCache) {
this.savedObjectsCache.push(response as SavedObject);
}
- return indexPattern;
+ return createdIndexPattern;
}
/**
diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md
index 069b0a21c9c774..be6e489b17290d 100644
--- a/src/plugins/data/public/public.api.md
+++ b/src/plugins/data/public/public.api.md
@@ -1336,19 +1336,7 @@ export class IndexPattern implements IIndexPattern {
delay?: string | undefined;
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[];
diff --git a/src/plugins/data/server/index_patterns/routes/create_index_pattern.ts b/src/plugins/data/server/index_patterns/routes/create_index_pattern.ts
index 0be300d1844598..d0767334626229 100644
--- a/src/plugins/data/server/index_patterns/routes/create_index_pattern.ts
+++ b/src/plugins/data/server/index_patterns/routes/create_index_pattern.ts
@@ -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(
diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md
index 8821db0d65f282..8ec412e69d4a10 100644
--- a/src/plugins/data/server/server.api.md
+++ b/src/plugins/data/server/server.api.md
@@ -780,19 +780,7 @@ export class IndexPattern implements IIndexPattern {
delay?: string | undefined;
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[];
diff --git a/test/api_integration/apis/index_patterns/index_pattern_crud/create_index_pattern/main.ts b/test/api_integration/apis/index_patterns/index_pattern_crud/create_index_pattern/main.ts
index 1f94e60430c6b7..91f165dbdda7cc 100644
--- a/test/api_integration/apis/index_patterns/index_pattern_crud/create_index_pattern/main.ts
+++ b/test/api_integration/apis/index_patterns/index_pattern_crud/create_index_pattern/main.ts
@@ -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');
- });
+ after(async () => {
+ await esArchiver.unload('index_patterns/basic_index');
+ });
- 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,
+ 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.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'); // created from es index
+ expect(response.body.index_pattern.fields.bar.type).to.be('boolean');
});
- expect(response.status).to.be(200);
- expect(response.body.index_pattern.title).to.be(title);
+ 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('string');
+ 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.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.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 () => {
diff --git a/test/api_integration/apis/index_patterns/scripted_fields_crud/create_scripted_field/main.ts b/test/api_integration/apis/index_patterns/scripted_fields_crud/create_scripted_field/main.ts
index f9ab482f98b764..a5ed61d8ab9af1 100644
--- a/test/api_integration/apis/index_patterns/scripted_fields_crud/create_scripted_field/main.ts
+++ b/test/api_integration/apis/index_patterns/scripted_fields_crud/create_scripted_field/main.ts
@@ -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,
},