* [Data plugin] Wrong caching for Index pattern fields Closes: #84666 * remove can update index_pattern fields test * fix tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> # Conflicts: # src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts
This commit is contained in:
parent
4867610afb
commit
41aab669bc
|
@ -47,7 +47,6 @@ import { IndexPatternMissingIndices } from '../lib';
|
|||
import { findByTitle } from '../utils';
|
||||
import { DuplicateIndexPatternError } from '../errors';
|
||||
|
||||
const indexPatternCache = createIndexPatternCache();
|
||||
const MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS = 3;
|
||||
const savedObjectType = 'index-pattern';
|
||||
|
||||
|
@ -75,6 +74,7 @@ export class IndexPatternsService {
|
|||
private onNotification: OnNotification;
|
||||
private onError: OnError;
|
||||
private onUnsupportedTimePattern: OnUnsupportedTimePattern;
|
||||
private indexPatternCache: ReturnType<typeof createIndexPatternCache>;
|
||||
ensureDefaultIndexPattern: EnsureDefaultIndexPattern;
|
||||
|
||||
constructor({
|
||||
|
@ -98,6 +98,8 @@ export class IndexPatternsService {
|
|||
uiSettings,
|
||||
onRedirectNoIndexPattern
|
||||
);
|
||||
|
||||
this.indexPatternCache = createIndexPatternCache();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,9 +182,9 @@ export class IndexPatternsService {
|
|||
clearCache = (id?: string) => {
|
||||
this.savedObjectsCache = null;
|
||||
if (id) {
|
||||
indexPatternCache.clear(id);
|
||||
this.indexPatternCache.clear(id);
|
||||
} else {
|
||||
indexPatternCache.clearAll();
|
||||
this.indexPatternCache.clearAll();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -468,11 +470,12 @@ export class IndexPatternsService {
|
|||
|
||||
get = async (id: string): Promise<IndexPattern> => {
|
||||
const indexPatternPromise =
|
||||
indexPatternCache.get(id) || indexPatternCache.set(id, this.getSavedObjectAndInit(id));
|
||||
this.indexPatternCache.get(id) ||
|
||||
this.indexPatternCache.set(id, this.getSavedObjectAndInit(id));
|
||||
|
||||
// don't cache failed requests
|
||||
indexPatternPromise.catch(() => {
|
||||
indexPatternCache.clear(id);
|
||||
this.indexPatternCache.clear(id);
|
||||
});
|
||||
|
||||
return indexPatternPromise;
|
||||
|
@ -536,7 +539,7 @@ export class IndexPatternsService {
|
|||
id: indexPattern.id,
|
||||
});
|
||||
indexPattern.id = response.id;
|
||||
indexPatternCache.set(indexPattern.id, Promise.resolve(indexPattern));
|
||||
this.indexPatternCache.set(indexPattern.id, Promise.resolve(indexPattern));
|
||||
return indexPattern;
|
||||
}
|
||||
|
||||
|
@ -619,7 +622,7 @@ export class IndexPatternsService {
|
|||
indexPattern.version = samePattern.version;
|
||||
|
||||
// Clear cache
|
||||
indexPatternCache.clear(indexPattern.id!);
|
||||
this.indexPatternCache.clear(indexPattern.id!);
|
||||
|
||||
// Try the save again
|
||||
return this.updateSavedObject(indexPattern, saveAttempts, ignoreErrors);
|
||||
|
@ -633,7 +636,7 @@ export class IndexPatternsService {
|
|||
* @param indexPatternId: Id of kibana Index Pattern to delete
|
||||
*/
|
||||
async delete(indexPatternId: string) {
|
||||
indexPatternCache.clear(indexPatternId);
|
||||
this.indexPatternCache.clear(indexPatternId);
|
||||
return this.savedObjectsClient.delete('index-pattern', indexPatternId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,8 +22,32 @@ import { FtrProviderContext } from '../../../../ftr_provider_context';
|
|||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
describe('main', () => {
|
||||
const basicIndex = 'ba*ic_index';
|
||||
let indexPattern: any;
|
||||
|
||||
before(async () => {
|
||||
await esArchiver.load('index_patterns/basic_index');
|
||||
|
||||
indexPattern = (
|
||||
await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title: basicIndex,
|
||||
},
|
||||
})
|
||||
).body.index_pattern;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('index_patterns/basic_index');
|
||||
|
||||
if (indexPattern) {
|
||||
await supertest.delete('/api/index_patterns/index_pattern/' + indexPattern.id);
|
||||
}
|
||||
});
|
||||
|
||||
it('can update multiple fields', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
|
@ -171,48 +195,6 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(response3.status).to.be(200);
|
||||
expect(response3.body.index_pattern.fieldAttrs.foo.count).to.be(undefined);
|
||||
});
|
||||
|
||||
it('can set field "count" attribute on an existing field', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: 'string',
|
||||
count: 123,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response1.status).to.be(200);
|
||||
expect(response1.body.index_pattern.fieldAttrs.foo).to.be(undefined);
|
||||
expect(response1.body.index_pattern.fields.foo.count).to.be(123);
|
||||
|
||||
const response2 = await supertest
|
||||
.post(`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/fields`)
|
||||
.send({
|
||||
fields: {
|
||||
foo: {
|
||||
count: 456,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response2.status).to.be(200);
|
||||
expect(response2.body.index_pattern.fieldAttrs.foo).to.be(undefined);
|
||||
expect(response2.body.index_pattern.fields.foo.count).to.be(456);
|
||||
|
||||
const response3 = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}`
|
||||
);
|
||||
|
||||
expect(response3.status).to.be(200);
|
||||
expect(response3.body.index_pattern.fieldAttrs.foo).to.be(undefined);
|
||||
expect(response3.body.index_pattern.fields.foo.count).to.be(456);
|
||||
});
|
||||
});
|
||||
|
||||
describe('customLabel', () => {
|
||||
|
@ -323,46 +305,20 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('can set field "customLabel" attribute on an existing field', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: 'string',
|
||||
count: 123,
|
||||
customLabel: 'foo',
|
||||
},
|
||||
await supertest.post(`/api/index_patterns/index_pattern/${indexPattern.id}/fields`).send({
|
||||
fields: {
|
||||
foo: {
|
||||
customLabel: 'baz',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response1.status).to.be(200);
|
||||
expect(response1.body.index_pattern.fieldAttrs.foo).to.be(undefined);
|
||||
expect(response1.body.index_pattern.fields.foo.customLabel).to.be('foo');
|
||||
|
||||
const response2 = await supertest
|
||||
.post(`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/fields`)
|
||||
.send({
|
||||
fields: {
|
||||
foo: {
|
||||
customLabel: 'baz',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response2.status).to.be(200);
|
||||
expect(response2.body.index_pattern.fieldAttrs.foo).to.be(undefined);
|
||||
expect(response2.body.index_pattern.fields.foo.customLabel).to.be('baz');
|
||||
|
||||
const response3 = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}`
|
||||
const response1 = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${indexPattern.id}`
|
||||
);
|
||||
|
||||
expect(response3.status).to.be(200);
|
||||
expect(response3.body.index_pattern.fieldAttrs.foo).to.be(undefined);
|
||||
expect(response3.body.index_pattern.fields.foo.customLabel).to.be('baz');
|
||||
expect(response1.status).to.be(200);
|
||||
expect(response1.body.index_pattern.fields.foo.customLabel).to.be('baz');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -463,31 +419,8 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('can remove "format" attribute from index_pattern format map', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title,
|
||||
fieldFormats: {
|
||||
foo: {
|
||||
id: 'bar',
|
||||
params: {
|
||||
baz: 'qux',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response1.status).to.be(200);
|
||||
expect(response1.body.index_pattern.fieldFormats.foo).to.eql({
|
||||
id: 'bar',
|
||||
params: {
|
||||
baz: 'qux',
|
||||
},
|
||||
});
|
||||
|
||||
const response2 = await supertest
|
||||
.post(`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/fields`)
|
||||
.post(`/api/index_patterns/index_pattern/${indexPattern.id}/fields`)
|
||||
.send({
|
||||
fields: {
|
||||
foo: {
|
||||
|
@ -500,7 +433,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(response2.body.index_pattern.fieldFormats.foo).to.be(undefined);
|
||||
|
||||
const response3 = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}`
|
||||
`/api/index_patterns/index_pattern/${indexPattern.id}`
|
||||
);
|
||||
|
||||
expect(response3.status).to.be(200);
|
||||
|
|
|
@ -262,44 +262,6 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(response3.body.index_pattern.typeMeta).to.eql({ foo: 'baz' });
|
||||
});
|
||||
|
||||
it('can update index_pattern fields', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
foo: {
|
||||
name: 'foo',
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response1.body.index_pattern.fields.foo.name).to.be('foo');
|
||||
expect(response1.body.index_pattern.fields.foo.type).to.be('string');
|
||||
|
||||
const id = response1.body.index_pattern.id;
|
||||
const response2 = await supertest.post('/api/index_patterns/index_pattern/' + id).send({
|
||||
index_pattern: {
|
||||
fields: {
|
||||
bar: {
|
||||
name: 'bar',
|
||||
type: 'number',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response2.body.index_pattern.fields.bar.name).to.be('bar');
|
||||
expect(response2.body.index_pattern.fields.bar.type).to.be('number');
|
||||
|
||||
const response3 = await supertest.get('/api/index_patterns/index_pattern/' + id);
|
||||
|
||||
expect(response3.body.index_pattern.fields.bar.name).to.be('bar');
|
||||
expect(response3.body.index_pattern.fields.bar.type).to.be('number');
|
||||
});
|
||||
|
||||
it('can update multiple index pattern fields at once', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
|
|
|
@ -21,9 +21,33 @@ import expect from '@kbn/expect';
|
|||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('errors', () => {
|
||||
const basicIndex = 'b*sic_index';
|
||||
let indexPattern: any;
|
||||
|
||||
before(async () => {
|
||||
await esArchiver.load('index_patterns/basic_index');
|
||||
|
||||
indexPattern = (
|
||||
await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title: basicIndex,
|
||||
},
|
||||
})
|
||||
).body.index_pattern;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('index_patterns/basic_index');
|
||||
|
||||
if (indexPattern) {
|
||||
await supertest.delete('/api/index_patterns/index_pattern/' + indexPattern.id);
|
||||
}
|
||||
});
|
||||
|
||||
it('returns 404 error on non-existing index_pattern', async () => {
|
||||
const id = `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-${Date.now()}`;
|
||||
const response = await supertest.delete(
|
||||
|
@ -34,35 +58,16 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('returns 404 error on non-existing scripted field', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title,
|
||||
},
|
||||
});
|
||||
const response2 = await supertest.delete(
|
||||
`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/scripted_field/foo`
|
||||
const response1 = await supertest.delete(
|
||||
`/api/index_patterns/index_pattern/${indexPattern.id}/scripted_field/test`
|
||||
);
|
||||
|
||||
expect(response2.status).to.be(404);
|
||||
expect(response1.status).to.be(404);
|
||||
});
|
||||
|
||||
it('returns error when attempting to delete a field which is not a scripted field', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
foo: {
|
||||
scripted: false,
|
||||
name: 'foo',
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const response2 = await supertest.delete(
|
||||
`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/scripted_field/foo`
|
||||
`/api/index_patterns/index_pattern/${indexPattern.id}/scripted_field/foo`
|
||||
);
|
||||
|
||||
expect(response2.status).to.be(400);
|
||||
|
|
|
@ -21,9 +21,33 @@ import expect from '@kbn/expect';
|
|||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('errors', () => {
|
||||
const basicIndex = '*asic_index';
|
||||
let indexPattern: any;
|
||||
|
||||
before(async () => {
|
||||
await esArchiver.load('index_patterns/basic_index');
|
||||
|
||||
indexPattern = (
|
||||
await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title: basicIndex,
|
||||
},
|
||||
})
|
||||
).body.index_pattern;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('index_patterns/basic_index');
|
||||
|
||||
if (indexPattern) {
|
||||
await supertest.delete('/api/index_patterns/index_pattern/' + indexPattern.id);
|
||||
}
|
||||
});
|
||||
|
||||
it('returns 404 error on non-existing index_pattern', async () => {
|
||||
const id = `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-${Date.now()}`;
|
||||
const response = await supertest.get(
|
||||
|
@ -34,40 +58,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('returns 404 error on non-existing scripted field', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title,
|
||||
},
|
||||
});
|
||||
const response2 = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/scripted_field/foo`
|
||||
const response1 = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${indexPattern.id}/scripted_field/sf`
|
||||
);
|
||||
|
||||
expect(response2.status).to.be(404);
|
||||
});
|
||||
|
||||
it('returns error when attempting to fetch a field which is not a scripted field', async () => {
|
||||
const title = `foo-${Date.now()}-${Math.random()}*`;
|
||||
const response1 = await supertest.post('/api/index_patterns/index_pattern').send({
|
||||
index_pattern: {
|
||||
title,
|
||||
fields: {
|
||||
foo: {
|
||||
scripted: false,
|
||||
name: 'foo',
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const response2 = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${response1.body.index_pattern.id}/scripted_field/foo`
|
||||
);
|
||||
|
||||
expect(response2.status).to.be(400);
|
||||
expect(response2.body.statusCode).to.be(400);
|
||||
expect(response2.body.message).to.be('Only scripted fields can be retrieved.');
|
||||
expect(response1.status).to.be(404);
|
||||
});
|
||||
|
||||
it('returns error when ID is too long', async () => {
|
||||
|
@ -81,5 +76,22 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
'[request params.id]: value has length [1759] but it must have a maximum length of [1000].'
|
||||
);
|
||||
});
|
||||
|
||||
it('returns 404 error on non-existing scripted field', async () => {
|
||||
const response1 = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${indexPattern.id}/scripted_field/test`
|
||||
);
|
||||
expect(response1.status).to.be(404);
|
||||
});
|
||||
|
||||
it('returns error when attempting to fetch a field which is not a scripted field', async () => {
|
||||
const response2 = await supertest.get(
|
||||
`/api/index_patterns/index_pattern/${indexPattern.id}/scripted_field/foo`
|
||||
);
|
||||
|
||||
expect(response2.status).to.be(400);
|
||||
expect(response2.body.statusCode).to.be(400);
|
||||
expect(response2.body.message).to.be('Only scripted fields can be retrieved.');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue