feat(templating): lots of progress on template variable context specific formats, #2918, all elasticsearch / lucene use cases seem to work now

This commit is contained in:
Torkel Ödegaard 2016-03-01 08:43:54 +01:00
parent cb8b038795
commit f3ad71d751
7 changed files with 75 additions and 35 deletions

View File

@ -4,7 +4,7 @@
"bitwise":false, "bitwise":false,
"curly": true, "curly": true,
"eqnull": true, "eqnull": true,
"globalstrict": true, "strict": true,
"devel": true, "devel": true,
"eqeqeq": true, "eqeqeq": true,
"forin": false, "forin": false,
@ -12,7 +12,7 @@
"supernew": true, "supernew": true,
"expr": true, "expr": true,
"indent": 2, "indent": 2,
"latedef": true, "latedef": false,
"newcap": true, "newcap": true,
"noarg": true, "noarg": true,
"noempty": true, "noempty": true,

View File

@ -24,7 +24,7 @@
"grunt-contrib-copy": "~0.8.2", "grunt-contrib-copy": "~0.8.2",
"grunt-contrib-cssmin": "~0.14.0", "grunt-contrib-cssmin": "~0.14.0",
"grunt-contrib-htmlmin": "~0.6.0", "grunt-contrib-htmlmin": "~0.6.0",
"grunt-contrib-jshint": "~0.11.3", "grunt-contrib-jshint": "~1.0.0",
"grunt-contrib-less": "~0.7.0", "grunt-contrib-less": "~0.7.0",
"grunt-contrib-uglify": "~0.11.0", "grunt-contrib-uglify": "~0.11.0",
"grunt-contrib-watch": "^0.6.1", "grunt-contrib-watch": "^0.6.1",
@ -39,7 +39,7 @@
"grunt-tslint": "^3.0.2", "grunt-tslint": "^3.0.2",
"grunt-typescript": "^0.8.0", "grunt-typescript": "^0.8.0",
"grunt-usemin": "3.0.0", "grunt-usemin": "3.0.0",
"jshint-stylish": "~0.1.5", "jshint-stylish": "~2.1.0",
"karma": "~0.13.15", "karma": "~0.13.15",
"karma-chrome-launcher": "~0.2.2", "karma-chrome-launcher": "~0.2.2",
"karma-coverage": "0.5.3", "karma-coverage": "0.5.3",

View File

@ -31,31 +31,37 @@ function (angular, _) {
}, this); }, this);
}; };
this.regexEscape = function(value) { function regexEscape(value) {
return value.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&'); return value.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
}; }
function luceneEscape(value) {
return value.replace(/([\!\*\+\-\=<>\s\&\|\(\)\[\]\{\}\^\~\?\:\\/"])/g, "\\$1");
}
this.formatValue = function(value, format) { this.formatValue = function(value, format) {
if (_.isString(value)) { switch(format) {
return value; case "regex": {
} else { var escapedValues = _.map(value, regexEscape);
switch(format) { return '(' + escapedValues.join('|') + ')';
case "regex": { }
var escapedValues = _.map(value, this.regexEscape); case "lucene": {
return '(' + escapedValues.join('|') + ')'; if (typeof value === 'string') {
return luceneEscape(value);
} }
case "lucene": { var quotedValues = _.map(value, function(val) {
var quotedValues = _.map(value, function(val) { return '\"' + luceneEscape(val) + '\"';
return '\\\"' + val + '\\\"'; });
}); return '(' + quotedValues.join(' OR ') + ')';
return '(' + quotedValues.join(' OR ') + ')'; }
} case "pipe": {
case "pipe": { return value.join('|');
return value.join('|'); }
} default: {
default: { if (typeof value === 'string') {
return '{' + value.join(',') + '}'; return value;
} }
return '{' + value.join(',') + '}';
} }
} }
}; };
@ -114,7 +120,9 @@ function (angular, _) {
return self.formatValue(systemValue); return self.formatValue(systemValue);
} }
return self.formatValue(value, format); var res = self.formatValue(value, format);
console.log('replace: ' + value, res);
return res;
}); });
}; };

View File

@ -47,15 +47,15 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
}; };
this._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) { results.data.$$config = results.config;
return results.data; return results.data;
}); });
}; };
this._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) { results.data.$$config = results.config;
return results.data; return results.data;
}); });
}; };
@ -170,7 +170,10 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
var queryObj = this.queryBuilder.build(target); var queryObj = this.queryBuilder.build(target);
var esQuery = angular.toJson(queryObj); var esQuery = angular.toJson(queryObj);
var luceneQuery = angular.toJson(target.query || '*'); var luceneQuery = target.query || '*';
luceneQuery = templateSrv.replace(luceneQuery, options.scopedVars, 'lucene');
luceneQuery = angular.toJson(luceneQuery);
// remove inner quotes // remove inner quotes
luceneQuery = luceneQuery.substr(1, luceneQuery.length - 2); luceneQuery = luceneQuery.substr(1, luceneQuery.length - 2);
esQuery = esQuery.replace("$lucene_query", luceneQuery); esQuery = esQuery.replace("$lucene_query", luceneQuery);
@ -190,7 +193,7 @@ function (angular, _, moment, kbn, ElasticQueryBuilder, IndexPattern, ElasticRes
payload = payload.replace(/\$interval/g, options.interval); payload = payload.replace(/\$interval/g, options.interval);
payload = payload.replace(/\$timeFrom/g, options.range.from.valueOf()); payload = payload.replace(/\$timeFrom/g, options.range.from.valueOf());
payload = payload.replace(/\$timeTo/g, options.range.to.valueOf()); payload = payload.replace(/\$timeTo/g, options.range.to.valueOf());
payload = templateSrv.replace(payload, options.scopedVars, 'lucene'); payload = templateSrv.replace(payload, options.scopedVars);
return this._post('_msearch', payload).then(function(res) { return this._post('_msearch', payload).then(function(res) {
return new ElasticResponse(sentTargets, res).getTimeSeries(); return new ElasticResponse(sentTargets, res).getTimeSeries();

View File

@ -284,13 +284,29 @@ function (_, queryDef) {
} }
}; };
ElasticResponse.prototype.getErrorFromElasticResponse = function(response, err) {
var result = {};
result.data = JSON.stringify(err, null, 4);
if (err.root_cause && err.root_cause.length > 0 && err.root_cause[0].reason) {
result.message = err.root_cause[0].reason;
} else {
result.message = err.reason || 'Unkown elatic error response';
}
if (response.$$config) {
result.config = response.$$config;
}
return result;
};
ElasticResponse.prototype.getTimeSeries = function() { ElasticResponse.prototype.getTimeSeries = function() {
var seriesList = []; var seriesList = [];
for (var i = 0; i < this.response.responses.length; i++) { for (var i = 0; i < this.response.responses.length; i++) {
var response = this.response.responses[i]; var response = this.response.responses[i];
if (response.error) { if (response.error) {
throw { message: response.error }; throw this.getErrorFromElasticResponse(this.response, response.error);
} }
if (response.hits && response.hits.hits.length > 0) { if (response.hits && response.hits.hits.length > 0) {

View File

@ -3,7 +3,7 @@
"bitwise":false, "bitwise":false,
"curly": true, "curly": true,
"eqnull": true, "eqnull": true,
"globalstrict": true, "strict": true,
"devel": true, "devel": true,
"eqeqeq": true, "eqeqeq": true,
"forin": false, "forin": false,
@ -11,7 +11,7 @@
"supernew": true, "supernew": true,
"expr": true, "expr": true,
"indent": 2, "indent": 2,
"latedef": true, "latedef": false,
"newcap": true, "newcap": true,
"noarg": true, "noarg": true,
"noempty": true, "noempty": true,

View File

@ -45,7 +45,7 @@ define([
}); });
}); });
describe.only('replace can pass multi / all format', function() { describe('replace can pass multi / all format', function() {
beforeEach(function() { beforeEach(function() {
_templateSrv.init([{name: 'test', current: {value: ['value1', 'value2'] }}]); _templateSrv.init([{name: 'test', current: {value: ['value1', 'value2'] }}]);
}); });
@ -59,6 +59,19 @@ define([
var target = _templateSrv.replace('this=$test', {}, 'pipe'); var target = _templateSrv.replace('this=$test', {}, 'pipe');
expect(target).to.be('this=value1|value2'); expect(target).to.be('this=value1|value2');
}); });
it('should replace $test with piped value', function() {
var target = _templateSrv.replace('this=$test', {}, 'pipe');
expect(target).to.be('this=value1|value2');
});
});
describe.only('lucene format', function() {
it('should properly escape $test with lucene escape sequences', function() {
_templateSrv.init([{name: 'test', current: {value: 'value/4' }}]);
var target = _templateSrv.replace('this:$test', {}, 'lucene');
expect(target).to.be("this:value\\\/4");
});
}); });
describe('render variable to string values', function() { describe('render variable to string values', function() {