Refactor: queryProcessor.service.

This commit is contained in:
Alexander Zobnin
2016-11-12 18:04:29 +03:00
parent 4a73957c16
commit 2e57b9b166
4 changed files with 166 additions and 267 deletions

View File

@@ -146,12 +146,10 @@ class ZabbixAPIDatasource {
} }
queryNumericData(target, timeFrom, timeTo, useTrends) { queryNumericData(target, timeFrom, timeTo, useTrends) {
// Build query in asynchronous manner let options = {
return this.queryProcessor.build(target.group.filter, itemtype: 'num'
target.host.filter, };
target.application.filter, return this.queryProcessor.build(target, options)
target.item.filter,
'num')
.then(items => { .then(items => {
// Add hostname for items from multiple hosts // Add hostname for items from multiple hosts
var addHostName = utils.isRegex(target.host.filter); var addHostName = utils.isRegex(target.host.filter);
@@ -227,11 +225,10 @@ class ZabbixAPIDatasource {
} }
queryTextData(target, timeFrom, timeTo) { queryTextData(target, timeFrom, timeTo) {
return this.queryProcessor.build(target.group.filter, let options = {
target.host.filter, itemtype: 'text'
target.application.filter, };
target.item.filter, return this.queryProcessor.build(target, options)
'text')
.then(items => { .then(items => {
if (items.length) { if (items.length) {
return this.zabbixAPI.getHistory(items, timeFrom, timeTo) return this.zabbixAPI.getHistory(items, timeFrom, timeTo)

View File

@@ -20,6 +20,7 @@ export class ZabbixQueryController extends QueryCtrl {
this.zabbix = this.datasource.zabbixAPI; this.zabbix = this.datasource.zabbixAPI;
this.cache = this.datasource.zabbixCache; this.cache = this.datasource.zabbixCache;
this.queryProcessor = this.datasource.queryProcessor;
this.$q = $q; this.$q = $q;
// Use custom format for template variables // Use custom format for template variables
@@ -115,76 +116,47 @@ export class ZabbixQueryController extends QueryCtrl {
} }
suggestGroups() { suggestGroups() {
var self = this; return this.queryProcessor.getAllGroups()
return this.cache.getGroups().then(groups => { .then(groups => {
self.metric.groupList = groups; this.metric.groupList = groups;
return groups; return groups;
}); });
} }
suggestHosts() { suggestHosts() {
var self = this; let groupFilter = this.replaceTemplateVars(this.target.group.filter);
var groupFilter = this.replaceTemplateVars(this.target.group.filter); return this.queryProcessor.getAllHosts(groupFilter)
return this.datasource.queryProcessor
.filterGroups(self.metric.groupList, groupFilter)
.then(groups => {
var groupids = _.map(groups, 'groupid');
return self.zabbix
.getHosts(groupids)
.then(hosts => { .then(hosts => {
self.metric.hostList = hosts; this.metric.hostList = hosts;
return hosts; return hosts;
}); });
});
} }
suggestApps() { suggestApps() {
var self = this; let groupFilter = this.replaceTemplateVars(this.target.group.filter);
var hostFilter = this.replaceTemplateVars(this.target.host.filter); let hostFilter = this.replaceTemplateVars(this.target.host.filter);
return this.datasource.queryProcessor return this.queryProcessor.getAllApps(groupFilter, hostFilter)
.filterHosts(self.metric.hostList, hostFilter)
.then(hosts => {
var hostids = _.map(hosts, 'hostid');
return self.zabbix
.getApps(hostids)
.then(apps => { .then(apps => {
return self.metric.appList = apps; this.metric.appList = apps;
}); return apps;
}); });
} }
suggestItems(itemtype = 'num') { suggestItems(itemtype = 'num') {
var self = this; let groupFilter = this.replaceTemplateVars(this.target.group.filter);
var appFilter = this.replaceTemplateVars(this.target.application.filter); let hostFilter = this.replaceTemplateVars(this.target.host.filter);
if (appFilter) { let appFilter = this.replaceTemplateVars(this.target.application.filter);
// Filter by applications let options = {
return this.datasource.queryProcessor itemtype: itemtype,
.filterApps(self.metric.appList, appFilter) showDisabledItems: this.target.options.showDisabledItems
.then(apps => { };
var appids = _.map(apps, 'applicationid');
return self.zabbix return this.queryProcessor
.getItems(undefined, appids, itemtype) .getAllItems(groupFilter, hostFilter, appFilter, options)
.then(items => { .then(items => {
if (!self.target.options.showDisabledItems) { this.metric.itemList = items;
items = _.filter(items, {'status': '0'});
}
self.metric.itemList = items;
return items; return items;
}); });
});
} else {
// Return all items belonged to selected hosts
var hostids = _.map(self.metric.hostList, 'hostid');
return self.zabbix
.getItems(hostids, undefined, itemtype)
.then(items => {
if (!self.target.options.showDisabledItems) {
items = _.filter(items, {'status': '0'});
}
self.metric.itemList = items;
return items;
});
}
} }
isRegex(str) { isRegex(str) {

View File

@@ -2,197 +2,137 @@ import angular from 'angular';
import _ from 'lodash'; import _ from 'lodash';
import * as utils from './utils'; import * as utils from './utils';
/** @ngInject */ function QueryProcessorFactory() {
angular.module('grafana.services').factory('QueryProcessor', function($q) {
class QueryProcessor { class QueryProcessor {
constructor(zabbixCacheInstance) { constructor(zabbixCacheInstance) {
this.cache = zabbixCacheInstance; this.cache = zabbixCacheInstance;
this.$q = $q; }
initializeCache() {
if (this.cache._initialized) {
return Promise.resolve();
} else {
return this.cache.refresh();
}
} }
/** /**
* Build query in asynchronous manner * Build query - convert target filters to array of Zabbix items
*/ */
build(groupFilter, hostFilter, appFilter, itemFilter, itemtype) { build(target, options) {
var self = this; function getFiltersFromTarget(target) {
if (this.cache._initialized) { let parts = ['group', 'host', 'application', 'item'];
return this.$q.when(self.buildFromCache(groupFilter, hostFilter, appFilter, itemFilter, itemtype)); return _.map(parts, p => target[p].filter);
} else {
return this.cache.refresh().then(function() {
return self.buildFromCache(groupFilter, hostFilter, appFilter, itemFilter, itemtype);
});
} }
return this.initializeCache()
.then(() => {
return this.getItems(...getFiltersFromTarget(target), options);
});
} }
/** /**
* Build trigger query in asynchronous manner * Build trigger query in asynchronous manner
*/ */
buildTriggerQuery(groupFilter, hostFilter, appFilter) { buildTriggerQuery(groupFilter, hostFilter, appFilter) {
var self = this; return this.initializeCache()
if (this.cache._initialized) { .then(() => {
return this.$q.when(self.buildTriggerQueryFromCache(groupFilter, hostFilter, appFilter)); return this.buildTriggerQueryFromCache(groupFilter, hostFilter, appFilter);
} else {
return this.cache.refresh().then(function() {
return self.buildTriggerQueryFromCache(groupFilter, hostFilter, appFilter);
});
}
}
filterGroups(groups, groupFilter) {
return this.$q.when(
findByFilter(groups, groupFilter)
);
}
/**
* Get list of host belonging to given groups.
* @return list of hosts
*/
filterHosts(hosts, hostFilter) {
return this.$q.when(
findByFilter(hosts, hostFilter)
);
}
filterApps(apps, appFilter) {
return this.$q.when(
findByFilter(apps, appFilter)
);
}
/**
* Build query - convert target filters to array of Zabbix items
*/
buildFromCache(groupFilter, hostFilter, appFilter, itemFilter, itemtype, showDisabledItems) {
return this.getItems(groupFilter, hostFilter, appFilter, itemtype, showDisabledItems)
.then(items => {
return getByFilter(items, itemFilter);
}); });
} }
getGroups() { getAllGroups() {
return this.cache.getGroups(); return this.cache.getGroups();
} }
getGroups(groupFilter) {
return this.getAllGroups()
.then(groups => findByFilter(groups, groupFilter));
}
/** /**
* Get list of host belonging to given groups. * Get list of host belonging to given groups.
* @return list of hosts
*/ */
getHosts(groupFilter) { getAllHosts(groupFilter) {
var self = this; return this.getGroups(groupFilter)
return this.cache
.getGroups()
.then(groups => { .then(groups => {
return findByFilter(groups, groupFilter); let groupids = _.map(groups, 'groupid');
}) return this.cache.getHosts(groupids);
.then(groups => {
var groupids = _.map(groups, 'groupid');
return self.cache.getHosts(groupids);
}); });
} }
getHosts(groupFilter, hostFilter) {
return this.getAllHosts(groupFilter)
.then(hosts => findByFilter(hosts, hostFilter));
}
/** /**
* Get list of applications belonging to given groups and hosts. * Get list of applications belonging to given groups and hosts.
* @return list of applications belonging to given hosts
*/ */
getApps(groupFilter, hostFilter) { getAllApps(groupFilter, hostFilter) {
var self = this; return this.getHosts(groupFilter, hostFilter)
return this.getHosts(groupFilter)
.then(hosts => { .then(hosts => {
return findByFilter(hosts, hostFilter); let hostids = _.map(hosts, 'hostid');
}) return this.cache.getApps(hostids);
.then(hosts => {
var hostids = _.map(hosts, 'hostid');
return self.cache.getApps(hostids);
}); });
} }
getItems(groupFilter, hostFilter, appFilter, itemtype, showDisabledItems) { getApps(groupFilter, hostFilter, appFilter) {
var self = this; return this.getHosts(groupFilter, hostFilter)
return this.getHosts(groupFilter)
.then(hosts => { .then(hosts => {
return findByFilter(hosts, hostFilter); let hostids = _.map(hosts, 'hostid');
})
.then(hosts => {
var hostids = _.map(hosts, 'hostid');
if (appFilter) { if (appFilter) {
return self.cache return this.cache.getApps(hostids)
.getApps(hostids) .then(apps => filterByQuery(apps, appFilter));
.then(apps => {
// Use getByFilter for proper item filtering
return getByFilter(apps, appFilter);
});
} else { } else {
return { return {
appFilterEmpty: true, appFilterEmpty: true,
hostids: hostids hostids: hostids
}; };
} }
}) });
}
getAllItems(groupFilter, hostFilter, appFilter, options = {}) {
return this.getApps(groupFilter, hostFilter, appFilter)
.then(apps => { .then(apps => {
if (apps.appFilterEmpty) { if (apps.appFilterEmpty) {
return self.cache return this.cache.getItems(apps.hostids, undefined, options.itemtype);
.getItems(apps.hostids, undefined, itemtype)
.then(items => {
if (showDisabledItems) {
items = _.filter(items, {'status': '0'});
}
return items;
});
} else { } else {
var appids = _.map(apps, 'applicationid'); let appids = _.map(apps, 'applicationid');
return self.cache return this.cache.getItems(undefined, appids, options.itemtype);
.getItems(undefined, appids, itemtype) }
})
.then(items => { .then(items => {
if (showDisabledItems) { if (!options.showDisabledItems) {
items = _.filter(items, {'status': '0'}); items = _.filter(items, {'status': '0'});
} }
return items; return items;
}); });
} }
});
getItems(groupFilter, hostFilter, appFilter, itemFilter, options = {}) {
return this.getAllItems(groupFilter, hostFilter, appFilter, options)
.then(items => filterByQuery(items, itemFilter));
} }
/** /**
* Build query - convert target filters to array of Zabbix items * Build query - convert target filters to array of Zabbix items
*/ */
buildTriggerQueryFromCache(groupFilter, hostFilter, appFilter) { buildTriggerQueryFromCache(groupFilter, hostFilter, appFilter) {
var promises = [ let promises = [
this.cache.getGroups().then(function(groups) { this.getGroups(groupFilter),
return _.filter(groups, function(group) { this.getHosts(groupFilter, hostFilter),
if (utils.isRegex(groupFilter)) { this.getApps(groupFilter, hostFilter, appFilter)
return utils.buildRegex(groupFilter).test(group.name);
} else {
return group.name === groupFilter;
}
});
}),
this.getHosts(groupFilter).then(function(hosts) {
return _.filter(hosts, function(host) {
if (utils.isRegex(hostFilter)) {
return utils.buildRegex(hostFilter).test(host.name);
} else {
return host.name === hostFilter;
}
});
}),
this.getApps(groupFilter, hostFilter).then(function(apps) {
return _.filter(apps, function(app) {
if (utils.isRegex(appFilter)) {
return utils.buildRegex(appFilter).test(app.name);
} else {
return app.name === appFilter;
}
});
})
]; ];
return this.$q.all(promises).then(function(results) { return Promise.all(promises)
var filteredGroups = results[0]; .then(results => {
var filteredHosts = results[1]; let filteredGroups = results[0];
var filteredApps = results[2]; let filteredHosts = results[1];
var query = {}; let filteredApps = results[2];
let query = {};
if (appFilter) { if (appFilter) {
query.applicationids = _.flatten(_.map(filteredApps, 'applicationid')); query.applicationids = _.flatten(_.map(filteredApps, 'applicationid'));
@@ -278,7 +218,11 @@ angular.module('grafana.services').factory('QueryProcessor', function($q) {
} }
return QueryProcessor; return QueryProcessor;
}); }
angular
.module('grafana.services')
.factory('QueryProcessor', QueryProcessorFactory);
/** /**
* Find group, host, app or item by given name. * Find group, host, app or item by given name.
@@ -312,7 +256,7 @@ function filterByName(list, name) {
} }
} }
function findByRegex(list, regex) { function filterByRegex(list, regex) {
var filterPattern = utils.buildRegex(regex); var filterPattern = utils.buildRegex(regex);
return _.filter(list, function (zbx_obj) { return _.filter(list, function (zbx_obj) {
return filterPattern.test(zbx_obj.name); return filterPattern.test(zbx_obj.name);
@@ -321,15 +265,15 @@ function findByRegex(list, regex) {
function findByFilter(list, filter) { function findByFilter(list, filter) {
if (utils.isRegex(filter)) { if (utils.isRegex(filter)) {
return findByRegex(list, filter); return filterByRegex(list, filter);
} else { } else {
return findByName(list, filter); return findByName(list, filter);
} }
} }
function getByFilter(list, filter) { function filterByQuery(list, filter) {
if (utils.isRegex(filter)) { if (utils.isRegex(filter)) {
return findByRegex(list, filter); return filterByRegex(list, filter);
} else { } else {
return filterByName(list, filter); return filterByName(list, filter);
} }

View File

@@ -62,8 +62,6 @@ class TriggerPanelEditorCtrl {
}; };
_.defaults(this, scopeDefaults); _.defaults(this, scopeDefaults);
var self = this;
// Get zabbix data sources // Get zabbix data sources
var datasources = _.filter(this.datasourceSrv.getMetricSources(), datasource => { var datasources = _.filter(this.datasourceSrv.getMetricSources(), datasource => {
return datasource.meta.id === 'alexanderzobnin-zabbix-datasource'; return datasource.meta.id === 'alexanderzobnin-zabbix-datasource';
@@ -75,10 +73,12 @@ class TriggerPanelEditorCtrl {
this.panel.datasource = this.datasources[0]; this.panel.datasource = this.datasources[0];
} }
// Load datasource // Load datasource
this.datasourceSrv.get(this.panel.datasource).then(function (datasource) { this.datasourceSrv.get(this.panel.datasource)
self.datasource = datasource; .then(datasource => {
self.initFilters(); this.datasource = datasource;
self.panelCtrl.refresh(); this.queryProcessor = datasource.queryProcessor;
this.initFilters();
this.panelCtrl.refresh();
}); });
} }
@@ -91,43 +91,29 @@ class TriggerPanelEditorCtrl {
} }
suggestGroups() { suggestGroups() {
var self = this; return this.queryProcessor.getAllGroups()
return this.datasource.zabbixCache
.getGroups()
.then(groups => { .then(groups => {
self.metric.groupList = groups; this.metric.groupList = groups;
return groups; return groups;
}); });
} }
suggestHosts() { suggestHosts() {
var self = this; let groupFilter = this.datasource.replaceTemplateVars(this.panel.triggers.group.filter);
var groupFilter = this.datasource.replaceTemplateVars(this.panel.triggers.group.filter); return this.queryProcessor.getAllHosts(groupFilter)
return this.datasource.queryProcessor
.filterGroups(self.metric.groupList, groupFilter)
.then(groups => {
var groupids = _.map(groups, 'groupid');
return self.datasource.zabbixAPI
.getHosts(groupids)
.then(hosts => { .then(hosts => {
self.metric.hostList = hosts; this.metric.hostList = hosts;
return hosts; return hosts;
}); });
});
} }
suggestApps() { suggestApps() {
var self = this; let groupFilter = this.datasource.replaceTemplateVars(this.panel.triggers.group.filter);
var hostFilter = this.datasource.replaceTemplateVars(this.panel.triggers.host.filter); let hostFilter = this.datasource.replaceTemplateVars(this.panel.triggers.host.filter);
return this.datasource.queryProcessor return this.queryProcessor.getAllApps(groupFilter, hostFilter)
.filterHosts(self.metric.hostList, hostFilter)
.then(hosts => {
var hostids = _.map(hosts, 'hostid');
return self.datasource.zabbixAPI
.getApps(hostids)
.then(apps => { .then(apps => {
return self.metric.appList = apps; this.metric.appList = apps;
}); return apps;
}); });
} }