From 462e0d0c6f39ec7884b399551a0ef79d417feea2 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 26 Mar 2019 16:15:23 +0100 Subject: [PATCH] Fix: Elasticsearch fix template variables in the alias field (#16629) Fixes #16040 Fix so that a template variable in the alias field is not interpolated on blur and only the value sent in the query is interpolated. Does a deep clone of the options.targets to avoid changing the original alias field. --- .../datasource/elasticsearch/datasource.ts | 9 ++-- .../elasticsearch/specs/datasource.test.ts | 42 ++++++++++++++----- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/public/app/plugins/datasource/elasticsearch/datasource.ts b/public/app/plugins/datasource/elasticsearch/datasource.ts index 3781a9048a6..0e510470db9 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.ts @@ -1,9 +1,9 @@ import angular from 'angular'; import _ from 'lodash'; import moment from 'moment'; -import { ElasticQueryBuilder } from './query_builder'; -import { IndexPattern } from './index_pattern'; import { ElasticResponse } from './elastic_response'; +import { IndexPattern } from './index_pattern'; +import { ElasticQueryBuilder } from './query_builder'; export class ElasticDatasource { basicAuth: string; @@ -242,14 +242,13 @@ export class ElasticDatasource { query(options) { let payload = ''; - let target; + const targets = _.cloneDeep(options.targets); const sentTargets = []; // add global adhoc filters to timeFilter const adhocFilters = this.templateSrv.getAdhocFilters(this.name); - for (let i = 0; i < options.targets.length; i++) { - target = options.targets[i]; + for (const target of targets) { if (target.hide) { continue; } diff --git a/public/app/plugins/datasource/elasticsearch/specs/datasource.test.ts b/public/app/plugins/datasource/elasticsearch/specs/datasource.test.ts index 71b4a55b35b..f98e09862f4 100644 --- a/public/app/plugins/datasource/elasticsearch/specs/datasource.test.ts +++ b/public/app/plugins/datasource/elasticsearch/specs/datasource.test.ts @@ -1,10 +1,9 @@ +import angular from 'angular'; +import * as dateMath from 'app/core/utils/datemath'; import _ from 'lodash'; import moment from 'moment'; -import angular from 'angular'; import { ElasticDatasource } from '../datasource'; -import * as dateMath from 'app/core/utils/datemath'; - describe('ElasticDatasource', function(this: any) { const backendSrv = { datasourceRequest: jest.fn(), @@ -73,9 +72,9 @@ describe('ElasticDatasource', function(this: any) { }); describe('When issuing metric query with interval pattern', () => { - let requestOptions, parts, header, query; + let requestOptions, parts, header, query, result; - beforeEach(() => { + beforeEach(async () => { createDatasource({ url: 'http://es.com', index: '[asd-]YYYY.MM.DD', @@ -84,7 +83,24 @@ describe('ElasticDatasource', function(this: any) { ctx.backendSrv.datasourceRequest = jest.fn(options => { requestOptions = options; - return Promise.resolve({ data: { responses: [] } }); + return Promise.resolve({ + data: { + responses: [ + { + aggregations: { + '1': { + buckets: [ + { + doc_count: 10, + key: 1000, + }, + ], + }, + }, + }, + ], + }, + }); }); query = { @@ -95,14 +111,14 @@ describe('ElasticDatasource', function(this: any) { targets: [ { alias: '$varAlias', - bucketAggs: [], - metrics: [{ type: 'raw_document' }], + bucketAggs: [{ type: 'date_histogram', field: '@timestamp', id: '1' }], + metrics: [{ type: 'count', id: '1' }], query: 'escape\\:test', }, ], }; - ctx.ds.query(query); + result = await ctx.ds.query(query); parts = requestOptions.data.split('\n'); header = angular.fromJson(parts[0]); @@ -112,8 +128,12 @@ describe('ElasticDatasource', function(this: any) { expect(header.index).toEqual(['asd-2015.05.30', 'asd-2015.05.31', 'asd-2015.06.01']); }); - it('should resolve the alias variable', () => { - expect(query.targets[0].alias).toEqual('resolvedVariable'); + it('should not resolve the variable in the original alias field in the query', () => { + expect(query.targets[0].alias).toEqual('$varAlias'); + }); + + it('should resolve the alias variable for the alias/target in the result', () => { + expect(result.data[0].target).toEqual('resolvedVariable'); }); it('should json escape lucene query', () => {