diff --git a/src/plugins/data/common/data_views/errors/data_view_saved_object_conflict.ts b/src/plugins/data/common/data_views/errors/data_view_saved_object_conflict.ts new file mode 100644 index 0000000000000..3fcb281655727 --- /dev/null +++ b/src/plugins/data/common/data_views/errors/data_view_saved_object_conflict.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export class DataViewSavedObjectConflictError extends Error { + constructor(savedObjectId: string) { + super(`Conflict loading DataView saved object, id: ${savedObjectId}`); + this.name = 'DataViewSavedObjectConflictError'; + } +} diff --git a/src/plugins/data/common/data_views/errors/index.ts b/src/plugins/data/common/data_views/errors/index.ts index 63bd1ac5f5848..20ff90d3fd6cf 100644 --- a/src/plugins/data/common/data_views/errors/index.ts +++ b/src/plugins/data/common/data_views/errors/index.ts @@ -7,3 +7,4 @@ */ export * from './duplicate_index_pattern'; +export * from './data_view_saved_object_conflict'; diff --git a/src/plugins/data/public/data_views/saved_objects_client_wrapper.test.ts b/src/plugins/data/public/data_views/saved_objects_client_wrapper.test.ts new file mode 100644 index 0000000000000..221a18ac7fab7 --- /dev/null +++ b/src/plugins/data/public/data_views/saved_objects_client_wrapper.test.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { SavedObjectsClientPublicToCommon } from './saved_objects_client_wrapper'; +import { savedObjectsServiceMock } from 'src/core/public/mocks'; + +import { DataViewSavedObjectConflictError } from '../../common/data_views'; + +describe('SavedObjectsClientPublicToCommon', () => { + const soClient = savedObjectsServiceMock.createStartContract().client; + + test('get saved object - exactMatch', async () => { + const mockedSavedObject = { + version: 'abc', + }; + soClient.resolve = jest + .fn() + .mockResolvedValue({ outcome: 'exactMatch', saved_object: mockedSavedObject }); + const service = new SavedObjectsClientPublicToCommon(soClient); + const result = await service.get('index-pattern', '1'); + expect(result).toStrictEqual(mockedSavedObject); + }); + + test('get saved object - aliasMatch', async () => { + const mockedSavedObject = { + version: 'def', + }; + soClient.resolve = jest + .fn() + .mockResolvedValue({ outcome: 'aliasMatch', saved_object: mockedSavedObject }); + const service = new SavedObjectsClientPublicToCommon(soClient); + const result = await service.get('index-pattern', '1'); + expect(result).toStrictEqual(mockedSavedObject); + }); + + test('get saved object - conflict', async () => { + const mockedSavedObject = { + version: 'ghi', + }; + + soClient.resolve = jest + .fn() + .mockResolvedValue({ outcome: 'conflict', saved_object: mockedSavedObject }); + const service = new SavedObjectsClientPublicToCommon(soClient); + + await expect(service.get('index-pattern', '1')).rejects.toThrow( + DataViewSavedObjectConflictError + ); + }); +}); diff --git a/src/plugins/data/public/data_views/saved_objects_client_wrapper.ts b/src/plugins/data/public/data_views/saved_objects_client_wrapper.ts index c8e633c6ec878..0d497d1203e2f 100644 --- a/src/plugins/data/public/data_views/saved_objects_client_wrapper.ts +++ b/src/plugins/data/public/data_views/saved_objects_client_wrapper.ts @@ -12,9 +12,10 @@ import { SavedObjectsClientCommon, SavedObjectsClientCommonFindArgs, SavedObject, + DataViewSavedObjectConflictError, } from '../../common/data_views'; -type SOClient = Pick; +type SOClient = Pick; const simpleSavedObjectToSavedObject = (simpleSavedObject: SimpleSavedObject): SavedObject => ({ @@ -33,8 +34,11 @@ export class SavedObjectsClientPublicToCommon implements SavedObjectsClientCommo } async get(type: string, id: string) { - const response = await this.savedObjectClient.get(type, id); - return simpleSavedObjectToSavedObject(response); + const response = await this.savedObjectClient.resolve(type, id); + if (response.outcome === 'conflict') { + throw new DataViewSavedObjectConflictError(id); + } + return simpleSavedObjectToSavedObject(response.saved_object); } async update( type: string, diff --git a/src/plugins/data/server/data_views/saved_objects_client_wrapper.test.ts b/src/plugins/data/server/data_views/saved_objects_client_wrapper.test.ts new file mode 100644 index 0000000000000..bbe857894b3f0 --- /dev/null +++ b/src/plugins/data/server/data_views/saved_objects_client_wrapper.test.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { SavedObjectsClientServerToCommon } from './saved_objects_client_wrapper'; +import { SavedObjectsClientContract } from 'src/core/server'; + +import { DataViewSavedObjectConflictError } from '../../common/data_views'; + +describe('SavedObjectsClientPublicToCommon', () => { + const soClient = { resolve: jest.fn() } as unknown as SavedObjectsClientContract; + + test('get saved object - exactMatch', async () => { + const mockedSavedObject = { + version: 'abc', + }; + soClient.resolve = jest + .fn() + .mockResolvedValue({ outcome: 'exactMatch', saved_object: mockedSavedObject }); + const service = new SavedObjectsClientServerToCommon(soClient); + const result = await service.get('index-pattern', '1'); + expect(result).toStrictEqual(mockedSavedObject); + }); + + test('get saved object - aliasMatch', async () => { + const mockedSavedObject = { + version: 'def', + }; + soClient.resolve = jest + .fn() + .mockResolvedValue({ outcome: 'aliasMatch', saved_object: mockedSavedObject }); + const service = new SavedObjectsClientServerToCommon(soClient); + const result = await service.get('index-pattern', '1'); + expect(result).toStrictEqual(mockedSavedObject); + }); + + test('get saved object - conflict', async () => { + const mockedSavedObject = { + version: 'ghi', + }; + + soClient.resolve = jest + .fn() + .mockResolvedValue({ outcome: 'conflict', saved_object: mockedSavedObject }); + const service = new SavedObjectsClientServerToCommon(soClient); + + await expect(service.get('index-pattern', '1')).rejects.toThrow( + DataViewSavedObjectConflictError + ); + }); +}); diff --git a/src/plugins/data/server/data_views/saved_objects_client_wrapper.ts b/src/plugins/data/server/data_views/saved_objects_client_wrapper.ts index 034f59aa52568..22024cfad9057 100644 --- a/src/plugins/data/server/data_views/saved_objects_client_wrapper.ts +++ b/src/plugins/data/server/data_views/saved_objects_client_wrapper.ts @@ -10,6 +10,7 @@ import { SavedObjectsClientContract, SavedObject } from 'src/core/server'; import { SavedObjectsClientCommon, SavedObjectsClientCommonFindArgs, + DataViewSavedObjectConflictError, } from '../../common/data_views'; export class SavedObjectsClientServerToCommon implements SavedObjectsClientCommon { @@ -23,7 +24,11 @@ export class SavedObjectsClientServerToCommon implements SavedObjectsClientCommo } async get(type: string, id: string) { - return await this.savedObjectClient.get(type, id); + const response = await this.savedObjectClient.resolve(type, id); + if (response.outcome === 'conflict') { + throw new DataViewSavedObjectConflictError(id); + } + return response.saved_object; } async update( type: string, diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index 9d2e94bcf15c0..a17c66c694b2d 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -54,6 +54,7 @@ export { IndexPattern, IndexPatternsService, IndexPatternsService as IndexPatternsCommonService, + DataView, } from '../common'; /**