From 3d735c48090cb1e4fe837d5eeb4f0500fa2300b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 11 Nov 2021 19:45:07 +0100 Subject: [PATCH] DataSources: Patch legacy instances so they have the required properties and functions (#41594) * DataSources: Patch legacy instances so they have the required properties and functions * Missed setting components --- packages/grafana-data/src/types/datasource.ts | 5 +--- public/app/features/plugins/datasource_srv.ts | 24 +++++++++++++------ .../plugins/specs/datasource_srv.test.ts | 13 ++++++++-- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/packages/grafana-data/src/types/datasource.ts b/packages/grafana-data/src/types/datasource.ts index 05304075dfa..ec5597e4401 100644 --- a/packages/grafana-data/src/types/datasource.ts +++ b/packages/grafana-data/src/types/datasource.ts @@ -205,11 +205,8 @@ abstract class DataSourceApi< this.name = instanceSettings.name; this.id = instanceSettings.id; this.type = instanceSettings.type; - this.meta = {} as DataSourcePluginMeta; + this.meta = instanceSettings.meta; this.uid = instanceSettings.uid; - if (!this.uid) { - this.uid = this.name; // Internal datasources do not have a UID (-- Grafana --) - } } /** diff --git a/public/app/features/plugins/datasource_srv.ts b/public/app/features/plugins/datasource_srv.ts index 9798eab9b59..ac70b5fb410 100644 --- a/public/app/features/plugins/datasource_srv.ts +++ b/public/app/features/plugins/datasource_srv.ts @@ -144,13 +144,13 @@ export class DatasourceSrv implements DataSourceService { } // find the metadata - const dsConfig = this.settingsMapByUid[key] ?? this.settingsMapByName[key] ?? this.settingsMapById[key]; - if (!dsConfig) { + const instanceSettings = this.settingsMapByUid[key] ?? this.settingsMapByName[key] ?? this.settingsMapById[key]; + if (!instanceSettings) { return Promise.reject({ message: `Datasource ${key} was not found` }); } try { - const dsPlugin = await importDataSourcePlugin(dsConfig.meta); + const dsPlugin = await importDataSourcePlugin(instanceSettings.meta); // check if its in cache now if (this.datasources[key]) { return this.datasources[key]; @@ -162,21 +162,31 @@ export class DatasourceSrv implements DataSourceService { if (useAngular) { instance = getLegacyAngularInjector().instantiate(dsPlugin.DataSourceClass, { - instanceSettings: dsConfig, + instanceSettings, }); } else { - instance = new dsPlugin.DataSourceClass(dsConfig); + instance = new dsPlugin.DataSourceClass(instanceSettings); } instance.components = dsPlugin.components; - instance.meta = dsConfig.meta; + + // Some old plugins does not extend DataSourceApi so we need to manually patch them + if (!(instance instanceof DataSourceApi)) { + const anyInstance = instance as any; + anyInstance.name = instanceSettings.name; + anyInstance.id = instanceSettings.id; + anyInstance.type = instanceSettings.type; + anyInstance.meta = instanceSettings.meta; + anyInstance.uid = instanceSettings.uid; + (instance as any).getRef = DataSourceApi.prototype.getRef; + } // store in instance cache this.datasources[key] = instance; this.datasources[instance.uid] = instance; return instance; } catch (err) { - appEvents.emit(AppEvents.alertError, [dsConfig.name + ' plugin failed', err.toString()]); + appEvents.emit(AppEvents.alertError, [instanceSettings.name + ' plugin failed', err.toString()]); return Promise.reject({ message: `Datasource: ${key} was not found` }); } } diff --git a/public/app/features/plugins/specs/datasource_srv.test.ts b/public/app/features/plugins/specs/datasource_srv.test.ts index f13d2dcf01e..9579f6d106c 100644 --- a/public/app/features/plugins/specs/datasource_srv.test.ts +++ b/public/app/features/plugins/specs/datasource_srv.test.ts @@ -1,5 +1,5 @@ import { DatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { DataSourceInstanceSettings, DataSourcePlugin } from '@grafana/data'; +import { DataSourceApi, DataSourceInstanceSettings, DataSourcePlugin, DataSourcePluginMeta } from '@grafana/data'; // Datasource variable $datasource with current value 'BBB' const templateSrv: any = { @@ -31,7 +31,7 @@ class TestDataSource { } jest.mock('../plugin_loader', () => ({ - importDataSourcePlugin: () => { + importDataSourcePlugin: (meta: DataSourcePluginMeta) => { return Promise.resolve(new DataSourcePlugin(TestDataSource as any)); }, })); @@ -115,6 +115,15 @@ describe('datasource_srv', () => { expect(dsByUid.meta).toBe(dsByName.meta); expect(dsByUid).toBe(dsByName); }); + + it('should patch legacy datasources', async () => { + expect(TestDataSource instanceof DataSourceApi).toBe(false); + const instance = await dataSourceSrv.get('mmm'); + expect(instance.name).toBe('mmm'); + expect(instance.type).toBe('test-db'); + expect(instance.uid).toBe('uid-code-mmm'); + expect(instance.getRef()).toEqual({ type: 'test-db', uid: 'uid-code-mmm' }); + }); }); describe('when getting instance settings', () => {