Commit c5635f9c by Torkel Ödegaard

feat(plugins): changed what datasources should return, they should now return…

feat(plugins): changed what datasources should return, they should now return the datasource constructor
parent d932653c
...@@ -38,6 +38,7 @@ type DataSourcePlugin struct { ...@@ -38,6 +38,7 @@ type DataSourcePlugin struct {
Annotations bool `json:"annotations"` Annotations bool `json:"annotations"`
Metrics bool `json:"metrics"` Metrics bool `json:"metrics"`
BuiltIn bool `json:"builtIn"` BuiltIn bool `json:"builtIn"`
Mixed bool `json:"mixed"`
App string `json:"app"` App string `json:"app"`
} }
......
// import grafanaCtrl from './grafana_ctrl';
//
// import * as asd from './sidemenu_ctrl';
//
// export {grafanaCtrl};
define([ define([
'./grafana_ctrl', './grafana_ctrl',
'./search_ctrl', './search_ctrl',
......
...@@ -58,12 +58,21 @@ function (angular, _, coreModule, config) { ...@@ -58,12 +58,21 @@ function (angular, _, coreModule, config) {
} }
var deferred = $q.defer(); var deferred = $q.defer();
var pluginDef = dsConfig.meta; var pluginDef = dsConfig.meta;
System.import(pluginDef.module).then(function() { System.import(pluginDef.module).then(function(plugin) {
var AngularService = $injector.get(pluginDef.serviceName); // check if its in cache now
var instance = new AngularService(dsConfig, pluginDef); 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.meta = pluginDef;
instance.name = name; instance.name = name;
self.datasources[name] = instance; self.datasources[name] = instance;
......
declare var Datasource: any;
export {Datasource};
...@@ -12,28 +12,22 @@ define([ ...@@ -12,28 +12,22 @@ define([
function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticResponse) { function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticResponse) {
'use strict'; 'use strict';
var module = angular.module('grafana.services'); function ElasticDatasource(instanceSettings, $q, backendSrv, templateSrv, timeSrv) {
this.basicAuth = instanceSettings.basicAuth;
module.factory('ElasticDatasource', function($q, backendSrv, templateSrv, timeSrv) { this.withCredentials = instanceSettings.withCredentials;
this.url = instanceSettings.url;
function ElasticDatasource(datasource) { this.name = instanceSettings.name;
this.type = 'elasticsearch'; this.index = instanceSettings.index;
this.basicAuth = datasource.basicAuth; this.timeField = instanceSettings.jsonData.timeField;
this.withCredentials = datasource.withCredentials; this.esVersion = instanceSettings.jsonData.esVersion;
this.url = datasource.url; this.indexPattern = new IndexPattern(instanceSettings.index, instanceSettings.jsonData.interval);
this.name = datasource.name; this.interval = instanceSettings.jsonData.timeInterval;
this.index = datasource.index; this.queryBuilder = new ElasticQueryBuilder({
this.timeField = datasource.jsonData.timeField; timeField: this.timeField,
this.esVersion = datasource.jsonData.esVersion; esVersion: this.esVersion,
this.indexPattern = new IndexPattern(datasource.index, datasource.jsonData.interval); });
this.interval = datasource.jsonData.timeInterval;
this.queryBuilder = new ElasticQueryBuilder({ this._request = function(method, url, data) {
timeField: this.timeField,
esVersion: this.esVersion,
});
}
ElasticDatasource.prototype._request = function(method, url, data) {
var options = { var options = {
url: this.url + "/" + url, url: this.url + "/" + url,
method: method, method: method,
...@@ -52,21 +46,21 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes ...@@ -52,21 +46,21 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
return backendSrv.datasourceRequest(options); return backendSrv.datasourceRequest(options);
}; };
ElasticDatasource.prototype._get = function(url) { this._get = function(url) {
return this._request('GET', this.indexPattern.getIndexForToday() + url) return this._request('GET', this.indexPattern.getIndexForToday() + url)
.then(function(results) { .then(function(results) {
return results.data; return results.data;
}); });
}; };
ElasticDatasource.prototype._post = function(url, data) { this._post = function(url, data) {
return this._request('POST', url, data) return this._request('POST', url, data)
.then(function(results) { .then(function(results) {
return results.data; return results.data;
}); });
}; };
ElasticDatasource.prototype.annotationQuery = function(options) { this.annotationQuery = function(options) {
var annotation = options.annotation; var annotation = options.annotation;
var timeField = annotation.timeField || '@timestamp'; var timeField = annotation.timeField || '@timestamp';
var queryString = annotation.query || '*'; var queryString = annotation.query || '*';
...@@ -147,7 +141,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes ...@@ -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 this._get('/_stats').then(function() {
return { status: "success", message: "Data source is working", title: "Success" }; return { status: "success", message: "Data source is working", title: "Success" };
}, function(err) { }, function(err) {
...@@ -159,13 +153,13 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes ...@@ -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}; var header = {search_type: searchType, "ignore_unavailable": true};
header.index = this.indexPattern.getIndexList(timeFrom, timeTo); header.index = this.indexPattern.getIndexList(timeFrom, timeTo);
return angular.toJson(header); return angular.toJson(header);
}; };
ElasticDatasource.prototype.query = function(options) { this.query = function(options) {
var payload = ""; var payload = "";
var target; var target;
var sentTargets = []; var sentTargets = [];
...@@ -203,7 +197,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes ...@@ -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) { return this._get('/_mapping').then(function(res) {
var fields = {}; var fields = {};
var typeMap = { var typeMap = {
...@@ -240,7 +234,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes ...@@ -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 range = timeSrv.timeRange();
var header = this.getQueryHeader('count', range.from, range.to); var header = this.getQueryHeader('count', range.from, range.to);
var esQuery = angular.toJson(this.queryBuilder.getTermsQuery(queryDef)); var esQuery = angular.toJson(this.queryBuilder.getTermsQuery(queryDef));
...@@ -258,7 +252,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes ...@@ -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 = templateSrv.replace(query);
query = angular.fromJson(query); query = angular.fromJson(query);
if (!query) { if (!query) {
...@@ -273,14 +267,14 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes ...@@ -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) return this._get('/dashboard/' + id)
.then(function(result) { .then(function(result) {
return angular.fromJson(result._source.dashboard); return angular.fromJson(result._source.dashboard);
}); });
}; };
ElasticDatasource.prototype.searchDashboards = function() { this.searchDashboards = function() {
var query = { var query = {
query: { query_string: { query: '*' } }, query: { query_string: { query: '*' } },
size: 10000, size: 10000,
...@@ -308,7 +302,9 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes ...@@ -308,7 +302,9 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
return displayHits; return displayHits;
}); });
}; };
}
return ElasticDatasource; return {
}); Datasource: ElasticDatasource,
};
}); });
import "../datasource";
import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common'; import {describe, beforeEach, it, sinon, expect, angularMocks} from 'test/lib/common';
import moment from 'moment'; import moment from 'moment';
import angular from 'angular'; import angular from 'angular';
import helpers from 'test/specs/helpers'; import helpers from 'test/specs/helpers';
import {Datasource} from "../datasource";
describe('ElasticDatasource', function() { describe('ElasticDatasource', function() {
var ctx = new helpers.ServiceTestContext(); var ctx = new helpers.ServiceTestContext();
var instanceSettings: any = {jsonData: {}};
beforeEach(angularMocks.module('grafana.core')); beforeEach(angularMocks.module('grafana.core'));
beforeEach(angularMocks.module('grafana.services')); beforeEach(angularMocks.module('grafana.services'));
beforeEach(ctx.providePhase(['templateSrv', 'backendSrv'])); beforeEach(ctx.providePhase(['templateSrv', 'backendSrv']));
beforeEach(ctx.createService('ElasticDatasource')); beforeEach(angularMocks.inject(function($q, $rootScope, $httpBackend, $injector) {
beforeEach(function() { ctx.$q = $q;
ctx.ds = new ctx.service({jsonData: {}}); 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() { describe('When testing datasource with index pattern', function() {
beforeEach(function() { beforeEach(function() {
ctx.ds = new ctx.service({ createDatasource({url: 'http://es.com', index: '[asd-]YYYY.MM.DD', jsonData: {interval: 'Daily'}});
url: 'http://es.com',
index: '[asd-]YYYY.MM.DD',
jsonData: { interval: 'Daily' }
});
}); });
it('should translate index pattern to current day', function() { it('should translate index pattern to current day', function() {
...@@ -44,11 +48,7 @@ describe('ElasticDatasource', function() { ...@@ -44,11 +48,7 @@ describe('ElasticDatasource', function() {
var requestOptions, parts, header; var requestOptions, parts, header;
beforeEach(function() { beforeEach(function() {
ctx.ds = new ctx.service({ createDatasource({url: 'http://es.com', index: '[asd-]YYYY.MM.DD', jsonData: {interval: 'Daily'}});
url: 'http://es.com',
index: '[asd-]YYYY.MM.DD',
jsonData: { interval: 'Daily' }
});
ctx.backendSrv.datasourceRequest = function(options) { ctx.backendSrv.datasourceRequest = function(options) {
requestOptions = options; requestOptions = options;
...@@ -83,7 +83,7 @@ describe('ElasticDatasource', function() { ...@@ -83,7 +83,7 @@ describe('ElasticDatasource', function() {
var requestOptions, parts, header; var requestOptions, parts, header;
beforeEach(function() { 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) { ctx.backendSrv.datasourceRequest = function(options) {
requestOptions = options; requestOptions = options;
......
...@@ -301,4 +301,7 @@ function (angular, _, $, config, dateMath) { ...@@ -301,4 +301,7 @@ function (angular, _, $, config, dateMath) {
}); });
return {
serviceName: "GraphiteDatasource"
};
}); });
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;
});
});
///<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);
//
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
var _global = <any>(window); var _global = <any>(window);
var beforeEach = _global.beforeEach; var beforeEach = _global.beforeEach;
var before = _global.before;
var describe = _global.describe; var describe = _global.describe;
var it = _global.it; var it = _global.it;
var sinon = _global.sinon; var sinon = _global.sinon;
...@@ -9,10 +10,12 @@ var expect = _global.expect; ...@@ -9,10 +10,12 @@ var expect = _global.expect;
var angularMocks = { var angularMocks = {
module: _global.module, module: _global.module,
inject: _global.inject,
}; };
export { export {
beforeEach, beforeEach,
before,
describe, describe,
it, it,
sinon, sinon,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment