From c5635f9c89d3505b5836626bc002427e37169e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 9 Jan 2016 13:21:16 +0100 Subject: [PATCH] feat(plugins): changed what datasources should return, they should now return the datasource constructor --- pkg/plugins/models.go | 1 + public/app/core/controllers/all.js | 6 -- public/app/core/services/datasource_srv.js | 17 ++++- .../datasource/elasticsearch/datasource.d.ts | 3 + .../datasource/elasticsearch/datasource.js | 76 +++++++++---------- .../elasticsearch/specs/datasource_specs.ts | 32 ++++---- .../plugins/datasource/graphite/datasource.js | 3 + .../plugins/datasource/mixed/datasource.js | 35 --------- .../plugins/datasource/mixed/datasource.ts | 37 +++++++++ public/test/lib/common.ts | 3 + 10 files changed, 112 insertions(+), 101 deletions(-) create mode 100644 public/app/plugins/datasource/elasticsearch/datasource.d.ts delete mode 100644 public/app/plugins/datasource/mixed/datasource.js create mode 100644 public/app/plugins/datasource/mixed/datasource.ts diff --git a/pkg/plugins/models.go b/pkg/plugins/models.go index e60ff558df2..4516bbd5491 100644 --- a/pkg/plugins/models.go +++ b/pkg/plugins/models.go @@ -38,6 +38,7 @@ type DataSourcePlugin struct { Annotations bool `json:"annotations"` Metrics bool `json:"metrics"` BuiltIn bool `json:"builtIn"` + Mixed bool `json:"mixed"` App string `json:"app"` } diff --git a/public/app/core/controllers/all.js b/public/app/core/controllers/all.js index 0d39cf57d69..d22010cffdc 100644 --- a/public/app/core/controllers/all.js +++ b/public/app/core/controllers/all.js @@ -1,9 +1,3 @@ -// import grafanaCtrl from './grafana_ctrl'; -// -// import * as asd from './sidemenu_ctrl'; -// -// export {grafanaCtrl}; - define([ './grafana_ctrl', './search_ctrl', diff --git a/public/app/core/services/datasource_srv.js b/public/app/core/services/datasource_srv.js index 3811daad168..054504ec602 100644 --- a/public/app/core/services/datasource_srv.js +++ b/public/app/core/services/datasource_srv.js @@ -58,12 +58,21 @@ function (angular, _, coreModule, config) { } var deferred = $q.defer(); - var pluginDef = dsConfig.meta; - System.import(pluginDef.module).then(function() { - var AngularService = $injector.get(pluginDef.serviceName); - var instance = new AngularService(dsConfig, pluginDef); + System.import(pluginDef.module).then(function(plugin) { + // check if its in cache now + if (self.datasources[name]) { + deferred.resolve(self.datasources[name]); + return; + } + + // plugin module needs to export a constructor function named Datasource + if (!plugin.Datasource) { + return; + } + + var instance = $injector.instantiate(plugin.Datasource, {instanceSettings: dsConfig}); instance.meta = pluginDef; instance.name = name; self.datasources[name] = instance; diff --git a/public/app/plugins/datasource/elasticsearch/datasource.d.ts b/public/app/plugins/datasource/elasticsearch/datasource.d.ts new file mode 100644 index 00000000000..4de8bcda15d --- /dev/null +++ b/public/app/plugins/datasource/elasticsearch/datasource.d.ts @@ -0,0 +1,3 @@ +declare var Datasource: any; +export {Datasource}; + diff --git a/public/app/plugins/datasource/elasticsearch/datasource.js b/public/app/plugins/datasource/elasticsearch/datasource.js index 72eaa4fcfd6..2a43e45aba8 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.js +++ b/public/app/plugins/datasource/elasticsearch/datasource.js @@ -12,28 +12,22 @@ define([ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticResponse) { 'use strict'; - var module = angular.module('grafana.services'); + function ElasticDatasource(instanceSettings, $q, backendSrv, templateSrv, timeSrv) { + this.basicAuth = instanceSettings.basicAuth; + this.withCredentials = instanceSettings.withCredentials; + this.url = instanceSettings.url; + this.name = instanceSettings.name; + this.index = instanceSettings.index; + this.timeField = instanceSettings.jsonData.timeField; + this.esVersion = instanceSettings.jsonData.esVersion; + this.indexPattern = new IndexPattern(instanceSettings.index, instanceSettings.jsonData.interval); + this.interval = instanceSettings.jsonData.timeInterval; + this.queryBuilder = new ElasticQueryBuilder({ + timeField: this.timeField, + esVersion: this.esVersion, + }); - module.factory('ElasticDatasource', function($q, backendSrv, templateSrv, timeSrv) { - - function ElasticDatasource(datasource) { - this.type = 'elasticsearch'; - this.basicAuth = datasource.basicAuth; - this.withCredentials = datasource.withCredentials; - this.url = datasource.url; - this.name = datasource.name; - this.index = datasource.index; - this.timeField = datasource.jsonData.timeField; - this.esVersion = datasource.jsonData.esVersion; - this.indexPattern = new IndexPattern(datasource.index, datasource.jsonData.interval); - this.interval = datasource.jsonData.timeInterval; - this.queryBuilder = new ElasticQueryBuilder({ - timeField: this.timeField, - esVersion: this.esVersion, - }); - } - - ElasticDatasource.prototype._request = function(method, url, data) { + this._request = function(method, url, data) { var options = { url: this.url + "/" + url, method: method, @@ -52,21 +46,21 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes return backendSrv.datasourceRequest(options); }; - ElasticDatasource.prototype._get = function(url) { + this._get = function(url) { return this._request('GET', this.indexPattern.getIndexForToday() + url) - .then(function(results) { - return results.data; - }); + .then(function(results) { + return results.data; + }); }; - ElasticDatasource.prototype._post = function(url, data) { + this._post = function(url, data) { return this._request('POST', url, data) - .then(function(results) { - return results.data; - }); + .then(function(results) { + return results.data; + }); }; - ElasticDatasource.prototype.annotationQuery = function(options) { + this.annotationQuery = function(options) { var annotation = options.annotation; var timeField = annotation.timeField || '@timestamp'; var queryString = annotation.query || '*'; @@ -147,7 +141,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes }); }; - ElasticDatasource.prototype.testDatasource = function() { + this.testDatasource = function() { return this._get('/_stats').then(function() { return { status: "success", message: "Data source is working", title: "Success" }; }, function(err) { @@ -159,13 +153,13 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes }); }; - ElasticDatasource.prototype.getQueryHeader = function(searchType, timeFrom, timeTo) { + this.getQueryHeader = function(searchType, timeFrom, timeTo) { var header = {search_type: searchType, "ignore_unavailable": true}; header.index = this.indexPattern.getIndexList(timeFrom, timeTo); return angular.toJson(header); }; - ElasticDatasource.prototype.query = function(options) { + this.query = function(options) { var payload = ""; var target; var sentTargets = []; @@ -203,7 +197,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes }); }; - ElasticDatasource.prototype.getFields = function(query) { + this.getFields = function(query) { return this._get('/_mapping').then(function(res) { var fields = {}; var typeMap = { @@ -240,7 +234,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes }); }; - ElasticDatasource.prototype.getTerms = function(queryDef) { + this.getTerms = function(queryDef) { var range = timeSrv.timeRange(); var header = this.getQueryHeader('count', range.from, range.to); var esQuery = angular.toJson(this.queryBuilder.getTermsQuery(queryDef)); @@ -258,7 +252,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes }); }; - ElasticDatasource.prototype.metricFindQuery = function(query) { + this.metricFindQuery = function(query) { query = templateSrv.replace(query); query = angular.fromJson(query); if (!query) { @@ -273,14 +267,14 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes } }; - ElasticDatasource.prototype.getDashboard = function(id) { + this.getDashboard = function(id) { return this._get('/dashboard/' + id) .then(function(result) { return angular.fromJson(result._source.dashboard); }); }; - ElasticDatasource.prototype.searchDashboards = function() { + this.searchDashboards = function() { var query = { query: { query_string: { query: '*' } }, size: 10000, @@ -308,7 +302,9 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes return displayHits; }); }; + } - return ElasticDatasource; - }); + return { + Datasource: ElasticDatasource, + }; }); diff --git a/public/app/plugins/datasource/elasticsearch/specs/datasource_specs.ts b/public/app/plugins/datasource/elasticsearch/specs/datasource_specs.ts index f34d52b42df..88700838cc0 100644 --- a/public/app/plugins/datasource/elasticsearch/specs/datasource_specs.ts +++ b/public/app/plugins/datasource/elasticsearch/specs/datasource_specs.ts @@ -1,28 +1,32 @@ -import "../datasource"; import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common'; import moment from 'moment'; import angular from 'angular'; import helpers from 'test/specs/helpers'; +import {Datasource} from "../datasource"; describe('ElasticDatasource', function() { var ctx = new helpers.ServiceTestContext(); + var instanceSettings: any = {jsonData: {}}; beforeEach(angularMocks.module('grafana.core')); beforeEach(angularMocks.module('grafana.services')); beforeEach(ctx.providePhase(['templateSrv', 'backendSrv'])); - beforeEach(ctx.createService('ElasticDatasource')); - beforeEach(function() { - ctx.ds = new ctx.service({jsonData: {}}); - }); + beforeEach(angularMocks.inject(function($q, $rootScope, $httpBackend, $injector) { + ctx.$q = $q; + ctx.$httpBackend = $httpBackend; + ctx.$rootScope = $rootScope; + ctx.$injector = $injector; + })); + + function createDatasource(instanceSettings) { + instanceSettings.jsonData = instanceSettings.jsonData || {}; + ctx.ds = ctx.$injector.instantiate(Datasource, {instanceSettings: instanceSettings}); + } describe('When testing datasource with index pattern', function() { beforeEach(function() { - ctx.ds = new ctx.service({ - url: 'http://es.com', - index: '[asd-]YYYY.MM.DD', - jsonData: { interval: 'Daily' } - }); + createDatasource({url: 'http://es.com', index: '[asd-]YYYY.MM.DD', jsonData: {interval: 'Daily'}}); }); it('should translate index pattern to current day', function() { @@ -44,11 +48,7 @@ describe('ElasticDatasource', function() { var requestOptions, parts, header; beforeEach(function() { - ctx.ds = new ctx.service({ - url: 'http://es.com', - index: '[asd-]YYYY.MM.DD', - jsonData: { interval: 'Daily' } - }); + createDatasource({url: 'http://es.com', index: '[asd-]YYYY.MM.DD', jsonData: {interval: 'Daily'}}); ctx.backendSrv.datasourceRequest = function(options) { requestOptions = options; @@ -83,7 +83,7 @@ describe('ElasticDatasource', function() { var requestOptions, parts, header; beforeEach(function() { - ctx.ds = new ctx.service({url: 'http://es.com', index: 'test', jsonData: {}}); + createDatasource({url: 'http://es.com', index: 'test'}); ctx.backendSrv.datasourceRequest = function(options) { requestOptions = options; diff --git a/public/app/plugins/datasource/graphite/datasource.js b/public/app/plugins/datasource/graphite/datasource.js index 49aa589db45..3548fcb9571 100644 --- a/public/app/plugins/datasource/graphite/datasource.js +++ b/public/app/plugins/datasource/graphite/datasource.js @@ -301,4 +301,7 @@ function (angular, _, $, config, dateMath) { }); + return { + serviceName: "GraphiteDatasource" + }; }); diff --git a/public/app/plugins/datasource/mixed/datasource.js b/public/app/plugins/datasource/mixed/datasource.js deleted file mode 100644 index a74e872276b..00000000000 --- a/public/app/plugins/datasource/mixed/datasource.js +++ /dev/null @@ -1,35 +0,0 @@ -define([ - 'angular', - 'lodash', -], -function (angular, _) { - 'use strict'; - - var module = angular.module('grafana.services'); - - module.factory('MixedDatasource', function($q, backendSrv, datasourceSrv) { - - function MixedDatasource() { - } - - MixedDatasource.prototype.query = function(options) { - var sets = _.groupBy(options.targets, 'datasource'); - var promises = _.map(sets, function(targets) { - return datasourceSrv.get(targets[0].datasource).then(function(ds) { - var opt = angular.copy(options); - opt.targets = targets; - return ds.query(opt); - }); - }); - - return $q.all(promises).then(function(results) { - return { data: _.flatten(_.pluck(results, 'data')) }; - }); - - }; - - return MixedDatasource; - - }); - -}); diff --git a/public/app/plugins/datasource/mixed/datasource.ts b/public/app/plugins/datasource/mixed/datasource.ts new file mode 100644 index 00000000000..874773e7f45 --- /dev/null +++ b/public/app/plugins/datasource/mixed/datasource.ts @@ -0,0 +1,37 @@ +/// + +import angular from 'angular'; +import _ from 'lodash'; + +class MixedDatasource { + + constructor(private $q, private datasourceSrv) { + } + + query(options) { + var sets = _.groupBy(options.targets, 'datasource'); + var promises = _.map(sets, targets => { + var dsName = targets[0].datasource; + if (dsName === '-- Mixed --') { + return this.$q([]); + } + + return this.datasourceSrv.get(dsName).then(function(ds) { + var opt = angular.copy(options); + opt.targets = targets; + return ds.query(opt); + }); + }); + + return this.$q.all(promises).then(function(results) { + return { data: _.flatten(_.pluck(results, 'data')) }; + }); + } +} + +export {MixedDatasource, MixedDatasource as Datasource} + +// var module = angular.module('grafana.services'); +// module.factory('MixedDatasource', MixedDatasource); +// + diff --git a/public/test/lib/common.ts b/public/test/lib/common.ts index 523a97c2c03..c7e8147c9c9 100644 --- a/public/test/lib/common.ts +++ b/public/test/lib/common.ts @@ -2,6 +2,7 @@ var _global = (window); var beforeEach = _global.beforeEach; +var before = _global.before; var describe = _global.describe; var it = _global.it; var sinon = _global.sinon; @@ -9,10 +10,12 @@ var expect = _global.expect; var angularMocks = { module: _global.module, + inject: _global.inject, }; export { beforeEach, + before, describe, it, sinon,