Переглянути джерело

feat(plugins): changed what datasources should return, they should now return the datasource constructor

Torkel Ödegaard 10 роки тому
батько
коміт
c5635f9c89

+ 1 - 0
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"`
 }
 

+ 0 - 6
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',

+ 13 - 4
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;

+ 3 - 0
public/app/plugins/datasource/elasticsearch/datasource.d.ts

@@ -0,0 +1,3 @@
+declare var Datasource: any;
+export {Datasource};
+

+ 37 - 41
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');
-
-  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) {
+  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,
+    });
+
+    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,
+  };
 });

+ 16 - 16
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;

+ 3 - 0
public/app/plugins/datasource/graphite/datasource.js

@@ -301,4 +301,7 @@ function (angular, _, $, config, dateMath) {
 
   });
 
+  return {
+    serviceName: "GraphiteDatasource"
+  };
 });

+ 0 - 35
public/app/plugins/datasource/mixed/datasource.js

@@ -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;
-
-  });
-
-});

+ 37 - 0
public/app/plugins/datasource/mixed/datasource.ts

@@ -0,0 +1,37 @@
+///<reference path="../../../headers/common.d.ts" />
+
+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);
+//
+

+ 3 - 0
public/test/lib/common.ts

@@ -2,6 +2,7 @@
 
 var _global = <any>(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,