You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by is...@apache.org on 2018/09/20 18:35:37 UTC

[ambari] branch branch-feature-AMBARI-23466 updated (4dc1c06 -> b04fa97)

This is an automated email from the ASF dual-hosted git repository.

ishanbha pushed a change to branch branch-feature-AMBARI-23466
in repository https://gitbox.apache.org/repos/asf/ambari.git.


    from 4dc1c06  [AMBARI-24665] Migrating grafana plugin for 5.x use.
     new c11e713  Revert "[AMBARI-24665] Migrating grafana plugin for 5.x use."
     new b04fa97  [AMBARI-24665] Migrating grafana plugin for 5.x use. (Prajwal Rao, Ishan Bhatt via Ishan Bhatt)

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../ambari-metrics-grafana/ambari-metrics/config_ctrl.ts    | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)
 copy ambari-logsearch/ambari-logsearch-web/src/app/classes/models/filter.ts => ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.ts (79%)


[ambari] 02/02: [AMBARI-24665] Migrating grafana plugin for 5.x use. (Prajwal Rao, Ishan Bhatt via Ishan Bhatt)

Posted by is...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ishanbha pushed a commit to branch branch-feature-AMBARI-23466
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit b04fa97eb230fe3d4e10485002273c0cd18f619f
Author: Ishan Bhatt <is...@gmail.com>
AuthorDate: Thu Sep 20 11:32:15 2018 -0700

    [AMBARI-24665] Migrating grafana plugin for 5.x use. (Prajwal Rao, Ishan Bhatt via Ishan Bhatt)
---
 .../ambari-metrics/config_ctrl.d.ts                |    5 +
 .../{directives.js => config_ctrl.js}              |   32 +-
 .../ambari-metrics/config_ctrl.js.map              |    1 +
 .../{directives.js => config_ctrl.ts}              |   24 +-
 .../{directives.js => datasource.d.ts}             |   20 +-
 .../ambari-metrics/datasource.js                   | 2066 +++++++++++---------
 .../ambari-metrics/directives.js                   |    1 +
 .../ambari-metrics/img/ams-screenshot.png          |  Bin 0 -> 157579 bytes
 .../ambari-metrics/img/apache-ambari-logo-sm.png   |  Bin 0 -> 11354 bytes
 .../ambari-metrics/img/apache-ambari-logo.png      |  Bin 0 -> 25912 bytes
 .../ambari-metrics/img/apache-ambari-project.png   |  Bin 0 -> 17174 bytes
 .../ambari-metrics/{directives.js => module.d.ts}  |   23 +-
 .../ambari-metrics/module.js                       |   21 +
 .../ambari-metrics/module.js.map                   |    1 +
 .../ambari-metrics/{directives.js => module.ts}    |   26 +-
 .../partials/annotations.editor.html               |    0
 .../ambari-metrics/partials/config.html            |    3 +-
 .../ambari-metrics/partials/query.editor.html      |  222 +--
 .../ambari-metrics/partials/query.options.html     |   42 -
 .../ambari-metrics/plugin.json                     |   31 +-
 .../ambari-metrics/queryCtrl.js                    |  160 --
 .../ambari-metrics/query_ctrl.d.ts                 |   21 +
 .../ambari-metrics/query_ctrl.js                   |  152 ++
 .../ambari-metrics/query_ctrl.js.map               |    1 +
 .../ambari-metrics/query_ctrl.ts                   |  169 ++
 25 files changed, 1602 insertions(+), 1419 deletions(-)

diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.d.ts b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.d.ts
new file mode 100644
index 0000000..33286c8
--- /dev/null
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.d.ts
@@ -0,0 +1,5 @@
+/// <reference path="../../../../../public/app/headers/common.d.ts" />
+export declare class AmbariMetricsConfigCtrl {
+    static templateUrl: string;
+    current: any;
+}
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js
similarity index 58%
copy from ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
copy to ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js
index aade7d7..84244ed 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js
@@ -1,3 +1,4 @@
+///<reference path="../../../headers/common.d.ts" />
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -15,22 +16,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- define([
-  'angular',
-],
-function (angular) {
-  'use strict';
-  var module = angular.module('grafana.directives');
-
-  module.directive('metricQueryEditorAmbarimetrics', function() {
+System.register([], function(exports_1) {
+    var AmbariMetricsConfigCtrl;
     return {
-      controller: 'AmbariMetricsQueryCtrl',
-      templateUrl: 'app/plugins/datasource/ambari-metrics/partials/query.editor.html',
-    };
-  });
-
-  module.directive('metricQueryOptionsAmbarimetrics', function() {
-    return {templateUrl: 'app/plugins/datasource/ambari-metrics/partials/query.options.html'};
-  });
-
+        setters:[],
+        execute: function() {
+            AmbariMetricsConfigCtrl = (function () {
+                function AmbariMetricsConfigCtrl() {
+                }
+                AmbariMetricsConfigCtrl.templateUrl = 'partials/config.html';
+                return AmbariMetricsConfigCtrl;
+            })();
+            exports_1("AmbariMetricsConfigCtrl", AmbariMetricsConfigCtrl);
+        }
+    }
 });
+//# sourceMappingURL=config_ctrl.js.map
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js.map b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js.map
new file mode 100644
index 0000000..8c46be5
--- /dev/null
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"config_ctrl.js","sourceRoot":"","sources":["../../../../../public/app/plugins/datasource/ambari-metrics/config_ctrl.ts"],"names":["AmbariMetricsConfigCtrl","AmbariMetricsConfigCtrl.constructor"],"mappings":"AAAA,oDAAoD;AACpD;;;;;;;;;;;;;;;;GAgBG;;;;;;YAKH;gBAAAA;gBAGAC,CAACA;gBAFUD,mCAAWA,GAAGA,sBAAsBA,CAACA;gBAEhDA,8BAACA;YAADA,CAACA,AAHD,IAGC;YAHD,6DAGC,CAAA"}
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.ts
similarity index 61%
copy from ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
copy to ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.ts
index aade7d7..f851f04 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.ts
@@ -1,3 +1,4 @@
+///<reference path="../../../headers/common.d.ts" />
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -15,22 +16,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- define([
-  'angular',
-],
-function (angular) {
-  'use strict';
-  var module = angular.module('grafana.directives');
 
-  module.directive('metricQueryEditorAmbarimetrics', function() {
-    return {
-      controller: 'AmbariMetricsQueryCtrl',
-      templateUrl: 'app/plugins/datasource/ambari-metrics/partials/query.editor.html',
-    };
-  });
+import angular from 'angular';
+import _ from 'lodash';
 
-  module.directive('metricQueryOptionsAmbarimetrics', function() {
-    return {templateUrl: 'app/plugins/datasource/ambari-metrics/partials/query.options.html'};
-  });
-
-});
+export class AmbariMetricsConfigCtrl {
+    static templateUrl = 'partials/config.html';
+    current: any;
+}
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.d.ts
similarity index 61%
copy from ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
copy to ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.d.ts
index aade7d7..8bab98c 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.d.ts
@@ -15,22 +15,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- define([
-  'angular',
-],
-function (angular) {
-  'use strict';
-  var module = angular.module('grafana.directives');
+declare var AmbariMetricsDatasource: any;
+export {AmbariMetricsDatasource};
 
-  module.directive('metricQueryEditorAmbarimetrics', function() {
-    return {
-      controller: 'AmbariMetricsQueryCtrl',
-      templateUrl: 'app/plugins/datasource/ambari-metrics/partials/query.editor.html',
-    };
-  });
-
-  module.directive('metricQueryOptionsAmbarimetrics', function() {
-    return {templateUrl: 'app/plugins/datasource/ambari-metrics/partials/query.options.html'};
-  });
-
-});
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js
index e7cd850..e34a1af 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js
@@ -16,1077 +16,1201 @@
  * limitations under the License.
  */
 define([
-      'angular',
-      'lodash',
-      'jquery',
-      './directives',
-      './queryCtrl'
-    ],
-    function (angular, _) {
-      'use strict';
+    'angular',
+    'lodash',
+    'jquery',
+    //'./directives',
+    './query_ctrl'
+  ],
+  function (angular, _) {
+    'use strict';
 
-      var module = angular.module('grafana.services');
 
-      module.factory('AmbariMetricsDatasource', function ($q, backendSrv, templateSrv) {
-        /**
-         * AMS Datasource Constructor
-         */
-        function AmbariMetricsDatasource(datasource) {
-          this.name = datasource.name;
-          this.url = datasource.url;
-          this.initMetricAppidMapping();
+    /**
+     * AMS Datasource Constructor
+     */
+    function AmbariMetricsDatasource(instanceSettings, $q, backendSrv, templateSrv) {
+      this.type = 'ambari-metrics';
+      this.name = instanceSettings.name;
+      this.url = instanceSettings.url;
+      this.withCredentials = instanceSettings.withCredentials;
+      this.basicAuth = instanceSettings.basicAuth;
+
+      var allMetrics = {};
+      var appIds = [];
+
+      /**
+       * AMS Datasource  Authentication
+       */
+      this.doAmbariRequest = function (options) {
+        if (this.basicAuth || this.withCredentials) {
+          options.withCredentials = true;
+        }
+        if (this.basicAuth) {
+          options.headers = options.headers || {};
+          options.headers.Authorization = this.basicAuth;
         }
-        var allMetrics = {};
-        var appIds = [];
 
-        //We get a list of components and their associated metrics.
-        AmbariMetricsDatasource.prototype.initMetricAppidMapping = function () {
-          return this.doAmbariRequest({ url: '/ws/v1/timeline/metrics/metadata' })
-            .then(function (items) {
-              items = items.data;
-              allMetrics = {};
-              appIds = [];
-              _.forEach(items, function (metric,app) {
-                metric.forEach(function (component) {
-                  if (!allMetrics[app]) {
-                    allMetrics[app] = [];
-                  }
-                  allMetrics[app].push(component.metricname);
-                });
+        options.url = this.url + options.url;
+        options.inspect = {type: 'ambarimetrics'};
+
+        return backendSrv.datasourceRequest(options);
+      };
+
+      //We get a list of components and their associated metrics.
+      this.initMetricAppidMapping = function () {
+        return this.doAmbariRequest({url: '/ws/v1/timeline/metrics/metadata'})
+          .then(function (items) {
+            items = items.data;
+            allMetrics = {};
+            appIds = [];
+            _.forEach(items, function (metric, app) {
+              metric.forEach(function (component) {
+                if (!allMetrics[app]) {
+                  allMetrics[app] = [];
+                }
+                allMetrics[app].push(component.metricname);
               });
-              //We remove a couple of components from the list that do not contain any
-              //pertinent metrics.
-              delete allMetrics["timeline_metric_store_watcher"];
-              delete allMetrics["amssmoketestfake"];
-              appIds = Object.keys(allMetrics);
             });
-        };
+            //We remove a couple of components from the list that do not contain any
+            //pertinent metrics.
+            delete allMetrics["timeline_metric_store_watcher"];
+            delete allMetrics["amssmoketestfake"];
+            appIds = Object.keys(allMetrics);
+          });
+      };
+      this.initMetricAppidMapping();
 
-        /**
-         * AMS Datasource  Authentication
-         */
-        AmbariMetricsDatasource.prototype.doAmbariRequest = function (options) {
-          if (this.basicAuth || this.withCredentials) {
-            options.withCredentials = true;
-          }
-          if (this.basicAuth) {
-            options.headers = options.headers || {};
-            options.headers.Authorization = this.basicAuth;
-          }
 
-          options.url = this.url + options.url;
-          options.inspect = {type: 'ambarimetrics'};
 
-          return backendSrv.datasourceRequest(options);
+      /**
+       * AMS Datasource  Query
+       */
+      this.query = function (options) {
+        var emptyData = function (metric) {
+          var legend = metric.alias ? metric.alias : metric.metric;
+          return {
+            data: {
+              target: legend,
+              datapoints: []
+            }
+          };
         };
-
-        /**
-         * AMS Datasource  Query
-         */
-        AmbariMetricsDatasource.prototype.query = function (options) {
-          var emptyData = function (metric) {
-            var legend = metric.alias ? metric.alias : metric.metric;
-            return {
-              data: {
-                target: legend,
-                datapoints: []
-              }
+        var self = this;
+        var getMetricsData = function (target) {
+          var alias = target.alias ? target.alias : target.metric;
+          if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "yarnqueues") {
+            alias = alias + ' on ' + target.qmetric;
+          }
+          if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "kafka-topics") {
+            alias = alias + ' on ' + target.kbTopic;
+          }
+          return function (res) {
+            res = res.data;
+            console.log('processing metric ' + target.metric);
+            if (!res.metrics[0] || target.hide) {
+              return $q.when(emptyData(target));
+            }
+            var series = [];
+            var metricData = res.metrics[0].metrics;
+            // Added hostname to legend for templated dashboards.
+            var hostLegend = res.metrics[0].hostname ? ' on ' + res.metrics[0].hostname : '';
+            var timeSeries = {};
+            timeSeries = {
+              target: alias + hostLegend,
+              datapoints: []
             };
-          };
-          var self = this;
-          var getMetricsData = function (target) {
-            var alias = target.alias ? target.alias : target.metric;
-            if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "yarnqueues") {
-              alias = alias + ' on ' + target.qmetric; }
-            if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "kafka-topics") {
-            alias = alias + ' on ' + target.kbTopic; }
-            return function (res) {
-              res = res.data;
-              console.log('processing metric ' + target.metric);
-              if (!res.metrics[0] || target.hide) {
-                return $q.when(emptyData(target));
-              }
-              var series = [];
-              var metricData = res.metrics[0].metrics;
-              // Added hostname to legend for templated dashboards.
-              var hostLegend = res.metrics[0].hostname ? ' on ' + res.metrics[0].hostname : '';
-              var timeSeries = {};
-              timeSeries = {
-                target: alias + hostLegend,
-                datapoints: []
-              };
-              for (var k in metricData){
-                if (metricData.hasOwnProperty(k)) {
-                  timeSeries.datapoints.push([metricData[k], (k - k % 1000)]);
-                }
+            for (var k in metricData) {
+              if (metricData.hasOwnProperty(k)) {
+                timeSeries.datapoints.push([metricData[k], (k - k % 1000)]);
               }
-              series.push(timeSeries);
-              return $q.when({data: series});
-            };
+            }
+            series.push(timeSeries);
+            return $q.when({data: series});
           };
-          // To speed up querying on templatized dashboards.
-          var allHostMetricsData = function (target) {
-            var alias = target.alias ? target.alias : target.metric;
-            if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "hbase-users") {
-            alias = alias + ' for ' + target.hbUser; }
-            // Aliases for Storm Topologies and components under a topology.
-            if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "topologies" &&
+        };
+        // To speed up querying on templatized dashboards.
+        var allHostMetricsData = function (target) {
+          var alias = target.alias ? target.alias : target.metric;
+          if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "hbase-users") {
+            alias = alias + ' for ' + target.hbUser;
+          }
+          // Aliases for Storm Topologies and components under a topology.
+          if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "topologies" &&
             !templateSrv.variables[1]) {
-              alias = alias + ' on ' + target.sTopology;
-            }
-            if(!_.isEmpty(templateSrv.variables[1]) && templateSrv.variables[1].name === "component") {
-              alias = alias + ' on ' + target.sTopology + ' for ' + target.sComponent;
-            }
+            alias = alias + ' on ' + target.sTopology;
+          }
+          if (!_.isEmpty(templateSrv.variables[1]) && templateSrv.variables[1].name === "component") {
+            alias = alias + ' on ' + target.sTopology + ' for ' + target.sComponent;
+          }
 
-            // Aliases for Druid Datasources.
-            if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "druidDataSources" &&
-                        !templateSrv.variables[1]) {
-              alias = alias.replace('$druidDataSource', target.sDataSource);
+          // Aliases for Druid Datasources.
+          if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "druidDataSources" &&
+            !templateSrv.variables[1]) {
+            alias = alias.replace('$druidDataSource', target.sDataSource);
+          }
+          return function (res) {
+            res = res.data;
+            console.log('processing metric ' + target.metric);
+            if (!res.metrics[0] || target.hide) {
+              return $q.when(emptyData(target));
             }
-            return function (res) {
-              res = res.data;
-              console.log('processing metric ' + target.metric);
-              if (!res.metrics[0] || target.hide) {
-                return $q.when(emptyData(target));
-              }
-              var series = [];
-              var timeSeries = {};
-              var metricData = res.metrics;
-              _.map(metricData, function (data) {
-                var totalCountFlag = false;
-                var aliasSuffix = data.hostname ? ' on ' + data.hostname : '';
-                var op = '';
-                var user = '';
-                if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "hbase-tables") {
-                  var tableName = "Tables.";
-                  var tableSuffix = data.metricname.substring(data.metricname.indexOf(tableName) + tableName.length,
+            var series = [];
+            var timeSeries = {};
+            var metricData = res.metrics;
+            _.map(metricData, function (data) {
+              var totalCountFlag = false;
+              var aliasSuffix = data.hostname ? ' on ' + data.hostname : '';
+              var op = '';
+              var user = '';
+              if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "hbase-tables") {
+                var tableName = "Tables.";
+                var tableSuffix = data.metricname.substring(data.metricname.indexOf(tableName) + tableName.length,
                   data.metricname.lastIndexOf("_metric"));
-                  aliasSuffix = ' on ' + tableSuffix;
-                }
-                if(templateSrv.variables[0].query === "callers") {
-                  alias = data.metricname.substring(data.metricname.indexOf('(')+1, data.metricname.indexOf(')'));
-                }
-                // Set legend and alias for HDFS - TopN dashboard
-                if(data.metricname.indexOf('dfs.NNTopUserOpCounts') === 0) {
-                  var metricname_arr = data.metricname.split(".");
-                  _.map(metricname_arr, function (segment) {
-                    if(segment.indexOf('op=') === 0) {
-                      var opKey = 'op=';
-                      op = segment.substring(segment.indexOf(opKey) + opKey.length);
-                    } else if(segment.indexOf('user=') === 0) {
-                      var userKey = 'user=';
-                      user = segment.substring(segment.indexOf(userKey) + userKey.length);
-                    }
-                  });
-                  // Check if metric is TotalCount
-                  if(data.metricname.indexOf('TotalCount') > 0) {
-                    totalCountFlag = true;
-                    if (op !== '*') {
-                      alias = op;
-                    } else {
-                      alias = 'Total Count';
-                    }
-                  } else if (op !== '*') {
-                    alias = op + ' by ' + user;
-                  } else {
-                    alias = user;
+                aliasSuffix = ' on ' + tableSuffix;
+              }
+              if (templateSrv.variables[0].query === "callers") {
+                alias = data.metricname.substring(data.metricname.indexOf('(') + 1, data.metricname.indexOf(')'));
+              }
+              // Set legend and alias for HDFS - TopN dashboard
+              if (data.metricname.indexOf('dfs.NNTopUserOpCounts') === 0) {
+                var metricname_arr = data.metricname.split(".");
+                _.map(metricname_arr, function (segment) {
+                  if (segment.indexOf('op=') === 0) {
+                    var opKey = 'op=';
+                    op = segment.substring(segment.indexOf(opKey) + opKey.length);
+                  } else if (segment.indexOf('user=') === 0) {
+                    var userKey = 'user=';
+                    user = segment.substring(segment.indexOf(userKey) + userKey.length);
                   }
-                  aliasSuffix = '';
-                }
-                if (data.appid.indexOf('ambari_server') === 0) {
-                  alias = data.metricname;
-                  aliasSuffix = '';
-                }
-                timeSeries = {
-                  target: alias + aliasSuffix,
-                  datapoints: []
-                };
-                for (var k in data.metrics){
-                  if (data.metrics.hasOwnProperty(k)) {
-                    timeSeries.datapoints.push([data.metrics[k], (k - k % 1000)]);
+                });
+                // Check if metric is TotalCount
+                if (data.metricname.indexOf('TotalCount') > 0) {
+                  totalCountFlag = true;
+                  if (op !== '*') {
+                    alias = op;
+                  } else {
+                    alias = 'Total Count';
                   }
+                } else if (op !== '*') {
+                  alias = op + ' by ' + user;
+                } else {
+                  alias = user;
                 }
-                if( (user !== '*') || (totalCountFlag) ) {
-                  series.push(timeSeries);
+                aliasSuffix = '';
+              }
+              if (data.appid.indexOf('ambari_server') === 0) {
+                alias = data.metricname;
+                aliasSuffix = '';
+              }
+              timeSeries = {
+                target: alias + aliasSuffix,
+                datapoints: []
+              };
+              for (var k in data.metrics) {
+                if (data.metrics.hasOwnProperty(k)) {
+                  timeSeries.datapoints.push([data.metrics[k], (k - k % 1000)]);
                 }
-              });
-              return $q.when({data: series});
-            };
+              }
+              if ((user !== '*') || (totalCountFlag)) {
+                series.push(timeSeries);
+              }
+            });
+            return $q.when({data: series});
           };
-          var getHostAppIdData = function(target) {
-            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision=' 
+        };
+        var getHostAppIdData = function (target) {
+          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
             + target.precision;
-            var instanceId = typeof target.cluster == 'undefined'  ? '' : '&instanceId=' + target.cluster;
-            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform +
+          var instanceId = typeof target.cluster == 'undefined' ? '' : '&instanceId=' + target.cluster;
+          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+          return self.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform +
             metricAggregator + "&hostname=" + target.hosts + '&appId=' + target.app + instanceId + '&startTime=' + from +
-            '&endTime=' + to + precision + seriesAggregator }).then(
-              getMetricsData(target)
-            );
-          };
-          //Check if it's a templated dashboard.
-          var templatedClusters = templateSrv.variables.filter(function(o) { return o.name === "cluster"});
-          var templatedCluster = (_.isEmpty(templatedClusters)) ? '' : templatedClusters[0].options.filter(function(cluster)
-            { return cluster.selected; }).map(function(clusterName) { return clusterName.value; });
+            '&endTime=' + to + precision + seriesAggregator
+          }).then(
+            getMetricsData(target)
+          );
+        };
+        //Check if it's a templated dashboard.
+        var templatedClusters = templateSrv.variables.filter(function (o) {
+          return o.name === "cluster"
+        });
+        var templatedCluster = (_.isEmpty(templatedClusters)) ? '' : templatedClusters[0].options.filter(function (cluster) {
+          return cluster.selected;
+        }).map(function (clusterName) {
+          return clusterName.value;
+        });
 
-          var templatedHosts = templateSrv.variables.filter(function(o) { return o.name === "hosts"});
-          var templatedHost = (_.isEmpty(templatedHosts)) ? '' : templatedHosts[0].options.filter(function(host)
-            { return host.selected; }).map(function(hostName) { return hostName.value; });
+        var templatedHosts = templateSrv.variables.filter(function (o) {
+          return o.name === "hosts"
+        });
+        var templatedHost = (_.isEmpty(templatedHosts)) ? '' : templatedHosts[0].options.filter(function (host) {
+          return host.selected;
+        }).map(function (hostName) {
+          return hostName.value;
+        });
 
-          var tComponents = _.isEmpty(templateSrv.variables) ? '' : templateSrv.variables.filter(function(variable)
-            { return variable.name === "components"});
-          var tComponent = _.isEmpty(tComponents) ? '' : tComponents[0].current.value;
+        var tComponents = _.isEmpty(templateSrv.variables) ? '' : templateSrv.variables.filter(function (variable) {
+          return variable.name === "components"
+        });
+        var tComponent = _.isEmpty(tComponents) ? '' : tComponents[0].current.value;
 
-          var getServiceAppIdData = function(target) {
-            var tCluster = (_.isEmpty(templateSrv.variables))? templatedCluster : '';
-            var instanceId = typeof tCluster == 'undefined'  ? '' : '&instanceId=' + tCluster;
-            var tHost = (_.isEmpty(templateSrv.variables)) ? templatedHost : target.templatedHost;
-            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
+        var getServiceAppIdData = function (target) {
+          var tCluster = (_.isEmpty(templateSrv.variables)) ? templatedCluster : '';
+          var instanceId = typeof tCluster == 'undefined' ? '' : '&instanceId=' + tCluster;
+          var tHost = (_.isEmpty(templateSrv.variables)) ? templatedHost : target.templatedHost;
+          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
             + target.precision;
-            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform
-              + metricAggregator + '&hostname=' + tHost + '&appId=' + target.app + instanceId + '&startTime=' + from +
-              '&endTime=' + to + precision + seriesAggregator }).then(
-              getMetricsData(target)
-            );
-          };
-          // To speed up querying on templatized dashboards.
-          var getAllHostData = function(target) {
-            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
-            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
+          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+          return self.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform
+            + metricAggregator + '&hostname=' + tHost + '&appId=' + target.app + instanceId + '&startTime=' + from +
+            '&endTime=' + to + precision + seriesAggregator
+          }).then(
+            getMetricsData(target)
+          );
+        };
+        // To speed up querying on templatized dashboards.
+        var getAllHostData = function (target) {
+          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
+          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
             + target.precision;
-            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-            var topN = ""; var isBottomN = "";
-            if (!_.isEmpty(templateSrv.variables.filter(function(o) { return o.name === "instances";}))) {
-              var metricTopN = _.filter(templateSrv.variables, function (o) { return o.name === "instances"; });
-              var metricTopAgg = _.filter(templateSrv.variables, function (o) { return o.name === "topagg"; });
-              isBottomN = templateSrv.variables.filter(function(o) { return o.name === "orientation";})[0].current.value
-              === "bottom" ? true : false;
-              topN = '&topN=' + metricTopN[0].current.value  +'&topNFunction=' + metricTopAgg[0].current.value  + '&isBottomN='+ isBottomN;
-            }
-            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-            var templatedComponent = (_.isEmpty(tComponent)) ? target.app : tComponent;
-            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform
-              + metricAggregator + '&hostname=' + target.templatedHost + '&appId=' + templatedComponent + instanceId
-              + '&startTime=' + from + '&endTime=' + to + precision + topN + seriesAggregator }).then(
-              allHostMetricsData(target)
-            );
-          };
-          var getYarnAppIdData = function(target) {
-            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
+          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+          var topN = "";
+          var isBottomN = "";
+          if (!_.isEmpty(templateSrv.variables.filter(function (o) {
+            return o.name === "instances";
+          }))) {
+            var metricTopN = _.filter(templateSrv.variables, function (o) {
+              return o.name === "instances";
+            });
+            var metricTopAgg = _.filter(templateSrv.variables, function (o) {
+              return o.name === "topagg";
+            });
+            isBottomN = templateSrv.variables.filter(function (o) {
+              return o.name === "orientation";
+            })[0].current.value
+            === "bottom" ? true : false;
+            topN = '&topN=' + metricTopN[0].current.value + '&topNFunction=' + metricTopAgg[0].current.value + '&isBottomN=' + isBottomN;
+          }
+          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+          var templatedComponent = (_.isEmpty(tComponent)) ? target.app : tComponent;
+          return self.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform
+            + metricAggregator + '&hostname=' + target.templatedHost + '&appId=' + templatedComponent + instanceId
+            + '&startTime=' + from + '&endTime=' + to + precision + topN + seriesAggregator
+          }).then(
+            allHostMetricsData(target)
+          );
+        };
+        var getYarnAppIdData = function (target) {
+          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
             + target.precision;
-            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
-            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + encodeURIComponent(target.queue) + metricTransform
-              + metricAggregator + '&appId=resourcemanager' + instanceId + '&startTime=' + from +
-              '&endTime=' + to + precision + seriesAggregator }).then(
-              getMetricsData(target)
-            );
-          };
-          var getHbaseAppIdData = function(target) {
-              var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
-              var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
+          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
+          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+          return self.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics?metricNames=' + encodeURIComponent(target.queue) + metricTransform
+            + metricAggregator + '&appId=resourcemanager' + instanceId + '&startTime=' + from +
+            '&endTime=' + to + precision + seriesAggregator
+          }).then(
+            getMetricsData(target)
+          );
+        };
+        var getHbaseAppIdData = function (target) {
+          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
+          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
             + target.precision;
-            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.hbMetric + instanceId + '&appId=hbase&startTime='
-            + from + '&endTime=' + to + precision + seriesAggregator }).then(
-              allHostMetricsData(target)
-            );
-          };
-          
-          var getKafkaAppIdData = function(target) {
-            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
+          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+          return self.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics?metricNames=' + target.hbMetric + instanceId + '&appId=hbase&startTime='
+            + from + '&endTime=' + to + precision + seriesAggregator
+          }).then(
+            allHostMetricsData(target)
+          );
+        };
+
+        var getKafkaAppIdData = function (target) {
+          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
             + target.precision;
-            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
-            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.kbMetric + metricTransform + instanceId
-              + metricAggregator + '&appId=kafka_broker&startTime=' + from +
-              '&endTime=' + to + precision + seriesAggregator }).then(
-              getMetricsData(target)
-            );
-          };
-          var getNnAppIdData = function(target) {
+          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
+          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+          return self.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics?metricNames=' + target.kbMetric + metricTransform + instanceId
+            + metricAggregator + '&appId=kafka_broker&startTime=' + from +
+            '&endTime=' + to + precision + seriesAggregator
+          }).then(
+            getMetricsData(target)
+          );
+        };
+        var getNnAppIdData = function (target) {
 
-            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
+          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
             + target.precision;
-            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
-            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.nnMetric + metricTransform + instanceId
-            + metricAggregator + '&appId=namenode&startTime=' + from + '&endTime=' + to + precision + seriesAggregator }).then(
-              allHostMetricsData(target)
-            );
-          };
+          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
+          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+          return self.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics?metricNames=' + target.nnMetric + metricTransform + instanceId
+            + metricAggregator + '&appId=namenode&startTime=' + from + '&endTime=' + to + precision + seriesAggregator
+          }).then(
+            allHostMetricsData(target)
+          );
+        };
 
-          // Storm Topology calls.
-          var getStormData = function(target) {
-            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
-            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
+        // Storm Topology calls.
+        var getStormData = function (target) {
+          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
+          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
             + target.precision;
-            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.sTopoMetric + metricTransform + instanceId
-                + metricAggregator + '&appId=nimbus&startTime=' + from + '&endTime=' + to + precision + seriesAggregator }).then(
-                allHostMetricsData(target)
-            );
-          };
+          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+          return self.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics?metricNames=' + target.sTopoMetric + metricTransform + instanceId
+            + metricAggregator + '&appId=nimbus&startTime=' + from + '&endTime=' + to + precision + seriesAggregator
+          }).then(
+            allHostMetricsData(target)
+          );
+        };
 
-            // Infra Solr Calls
-          var getSolrCoreData = function(target) {
-              var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
-              var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
-                  + target.precision;
-              var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-              var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-              var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-              return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.sCoreMetric + metricTransform + instanceId
-              + metricAggregator + '&appId=ambari-infra-solr&startTime=' + from + '&endTime=' + to + precision + seriesAggregator }).then(
-                  allHostMetricsData(target)
-              );
-          };
+        // Infra Solr Calls
+        var getSolrCoreData = function (target) {
+          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
+          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
+            + target.precision;
+          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+          return self.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics?metricNames=' + target.sCoreMetric + metricTransform + instanceId
+            + metricAggregator + '&appId=ambari-infra-solr&startTime=' + from + '&endTime=' + to + precision + seriesAggregator
+          }).then(
+            allHostMetricsData(target)
+          );
+        };
 
-          var getSolrCollectionData = function(target) {
-              var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
-              var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
-                  + target.precision;
-              var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-              var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-              var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-              return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.sCollectionMetric + metricTransform + instanceId
-              + metricAggregator + '&appId=ambari-infra-solr&startTime=' + from + '&endTime=' + to + precision + seriesAggregator }).then(
-                  allHostMetricsData(target)
-              );
-          };
+        var getSolrCollectionData = function (target) {
+          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
+          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
+            + target.precision;
+          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+          return self.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics?metricNames=' + target.sCollectionMetric + metricTransform + instanceId
+            + metricAggregator + '&appId=ambari-infra-solr&startTime=' + from + '&endTime=' + to + precision + seriesAggregator
+          }).then(
+            allHostMetricsData(target)
+          );
+        };
 
-          // Druid calls.
-          var getDruidData = function(target) {
-            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
-            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
+        // Druid calls.
+        var getDruidData = function (target) {
+          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
+          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
             + target.precision;
-            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.sDataSourceMetric + metricTransform + instanceId
-                          + metricAggregator + '&appId=druid&startTime=' + from + '&endTime=' + to + precision + seriesAggregator }).then(
-                          allHostMetricsData(target)
-            );
-          };
+          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+          return self.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics?metricNames=' + target.sDataSourceMetric + metricTransform + instanceId
+            + metricAggregator + '&appId=druid&startTime=' + from + '&endTime=' + to + precision + seriesAggregator
+          }).then(
+            allHostMetricsData(target)
+          );
+        };
 
-          // Time Ranges
-          var from = Math.floor(options.range.from.valueOf() / 1000);
-          var to = Math.floor(options.range.to.valueOf() / 1000);
+        // Time Ranges
+        var from = Math.floor(options.range.from.valueOf() / 1000);
+        var to = Math.floor(options.range.to.valueOf() / 1000);
 
-          var metricsPromises = [];
-          if (!_.isEmpty(templateSrv.variables)) {
-            // YARN Queues Dashboard
-            if (templateSrv.variables[0].query === "yarnqueues") {
-              var allQueues = templateSrv.variables.filter(function(variable) { return variable.query === "yarnqueues";});
-              var selectedQs = (_.isEmpty(allQueues)) ? "" : allQueues[0].options.filter(function(q)
-              { return q.selected; }).map(function(qName) { return qName.value; });
-              // All Queues
-              if (!_.isEmpty(_.find(selectedQs, function (wildcard) { return wildcard === "*"; })))  {
-                var allQueue = allQueues[0].options.filter(function(q) {
-                  return q.text !== "All"; }).map(function(queue) { return queue.value; });
-                _.forEach(allQueue, function(processQueue) {
-                  metricsPromises.push(_.map(options.targets, function(target) {
-                    target.qmetric = processQueue;
-                    target.queue = target.metric.replace('root', target.qmetric);
-                    return getYarnAppIdData(target);
-                  }));
-                });
-              } else {
-                // All selected queues.
-                _.forEach(selectedQs, function(processQueue) {
-                  metricsPromises.push(_.map(options.targets, function(target) {
-                    target.qmetric = processQueue;
-                    target.queue = target.metric.replace('root', target.qmetric);
-                    return getYarnAppIdData(target);
-                  }));
-                });
-              }
-            }
-            // Templatized Dashboard for per-user metrics in HBase.
-            if (templateSrv.variables[0].query === "hbase-users") {
-              var allUsers = templateSrv.variables.filter(function(variable) { return variable.query === "hbase-users";});
-              var selectedUsers = (_.isEmpty(allUsers)) ? "" : allUsers[0].options.filter(function(user)
-              { return user.selected; }).map(function(uName) { return uName.value; });
-              selectedUsers = templateSrv._values.Users.lastIndexOf('}') > 0 ? templateSrv._values.Users.slice(1,-1) :
-                templateSrv._values.Users;
-              var selectedUser = selectedUsers.split(',');
-              _.forEach(selectedUser, function(processUser) {
-                  metricsPromises.push(_.map(options.targets, function(target) {
-                    target.hbUser = processUser;
-                    var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-                    target.hbMetric = target.metric.replace('*', target.hbUser) + metricTransform +'._' +  target.aggregator;
-                    return getHbaseAppIdData(target);
-                  }));
-                });
-            }
-            // Templatized Dashboard for per-table metrics in HBase.
-            if (templateSrv.variables[0].query === "hbase-tables") {
-              var splitTables = [];
-              var allTables = templateSrv._values.Tables.lastIndexOf('}') > 0 ? templateSrv._values.Tables.slice(1,-1) :
-                templateSrv._values.Tables;
-              var allTable = allTables.split(',');
-              while (allTable.length > 0) {
-                splitTables.push(allTable.splice(0,20));
-              }
-              _.forEach(splitTables, function(table) {
-                metricsPromises.push(_.map(options.targets, function(target) {
-                  var hbMetric = [];
-                  _.map(table, function(tableMetric) { hbMetric.push(target.metric.replace('*', tableMetric)); });
-                  var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform; 
-                  hbMetric = _.map(hbMetric, function(tbl) { return tbl + metricTransform +'._' +  target.aggregator; });
-                  target.hbMetric = _.flatten(hbMetric).join(',');
-                  return getHbaseAppIdData(target);
+        var metricsPromises = [];
+        if (!_.isEmpty(templateSrv.variables)) {
+          // YARN Queues Dashboard
+          if (templateSrv.variables[0].query === "yarnqueues") {
+            var allQueues = templateSrv.variables.filter(function (variable) {
+              return variable.query === "yarnqueues";
+            });
+            var selectedQs = (_.isEmpty(allQueues)) ? "" : allQueues[0].options.filter(function (q) {
+              return q.selected;
+            }).map(function (qName) {
+              return qName.value;
+            });
+            // All Queues
+            if (!_.isEmpty(_.find(selectedQs, function (wildcard) {
+              return wildcard === "*";
+            }))) {
+              var allQueue = allQueues[0].options.filter(function (q) {
+                return q.text !== "All";
+              }).map(function (queue) {
+                return queue.value;
+              });
+              _.forEach(allQueue, function (processQueue) {
+                metricsPromises.push(_.map(options.targets, function (target) {
+                  target.qmetric = processQueue;
+                  target.queue = target.metric.replace('root', target.qmetric);
+                  return getYarnAppIdData(target);
                 }));
               });
-            }
-            // Templatized Dashboard for per-topic metrics in Kafka.
-            if (templateSrv.variables[0].query === "kafka-topics") {
-              var allTopics = templateSrv.variables.filter(function(variable) { return variable.query === "kafka-topics";});
-              var selectedTopics = (_.isEmpty(allTopics)) ? "" : allTopics[0].options.filter(function(topic)
-              { return topic.selected; }).map(function(topicName) { return topicName.value; });
-              selectedTopics = templateSrv._values.Topics.lastIndexOf('}') > 0 ? templateSrv._values.Topics.slice(1,-1) :
-                templateSrv._values.Topics;
-              var selectedTopic = selectedTopics.split(',');  
-              _.forEach(selectedTopic, function(processTopic) {
-                metricsPromises.push(_.map(options.targets, function(target) {
-                  target.kbTopic = processTopic;
-                  target.kbMetric = target.metric.replace('*', target.kbTopic);
-                  return getKafkaAppIdData(target);
+            } else {
+              // All selected queues.
+              _.forEach(selectedQs, function (processQueue) {
+                metricsPromises.push(_.map(options.targets, function (target) {
+                  target.qmetric = processQueue;
+                  target.queue = target.metric.replace('root', target.qmetric);
+                  return getYarnAppIdData(target);
                 }));
               });
             }
-            //Templatized Dashboard for Call Queues
-            if (templateSrv.variables[0].query === "callers") {
-              var allCallers = templateSrv.variables.filter(function(variable) { return variable.query === "callers";});
-              var selectedCallers = (_.isEmpty(allCallers)) ? "" : allCallers[0].options.filter(function(user)
-              { return user.selected; }).map(function(callerName) { return callerName.value; });
-              selectedCallers = templateSrv._values.Callers.lastIndexOf('}') > 0 ? templateSrv._values.Callers.slice(1,-1) :
-                templateSrv._values.Callers;
-              var selectedCaller = selectedCallers.split(',');
-              _.forEach(selectedCaller, function(processCaller) {
-                  metricsPromises.push(_.map(options.targets, function(target) {
-                    target.nnCaller = processCaller;
-                    target.nnMetric = target.metric.replace('*', target.nnCaller);
-                    return getNnAppIdData(target);
-                  }));
-              });
+          }
+          // Templatized Dashboard for per-user metrics in HBase.
+          if (templateSrv.variables[0].query === "hbase-users") {
+            var allUsers = templateSrv.variables.filter(function (variable) {
+              return variable.query === "hbase-users";
+            });
+            var selectedUsers = (_.isEmpty(allUsers)) ? "" : allUsers[0].options.filter(function (user) {
+              return user.selected;
+            }).map(function (uName) {
+              return uName.value;
+            });
+            selectedUsers = templateSrv._values.Users.lastIndexOf('}') > 0 ? templateSrv._values.Users.slice(1, -1) :
+              templateSrv._values.Users;
+            var selectedUser = selectedUsers.split(',');
+            _.forEach(selectedUser, function (processUser) {
+              metricsPromises.push(_.map(options.targets, function (target) {
+                target.hbUser = processUser;
+                var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+                target.hbMetric = target.metric.replace('*', target.hbUser) + metricTransform + '._' + target.aggregator;
+                return getHbaseAppIdData(target);
+              }));
+            });
+          }
+          // Templatized Dashboard for per-table metrics in HBase.
+          if (templateSrv.variables[0].query === "hbase-tables") {
+            var splitTables = [];
+            var allTables = templateSrv._values.Tables.lastIndexOf('}') > 0 ? templateSrv._values.Tables.slice(1, -1) :
+              templateSrv._values.Tables;
+            var allTable = allTables.split(',');
+            while (allTable.length > 0) {
+              splitTables.push(allTable.splice(0, 20));
             }
-
-            //Templatized Dashboard for Infra Solr Cores
-            if (templateSrv.variables[0].query === "infra_solr_core") {
-                var allCores = templateSrv.variables.filter(function(variable) { return variable.query === "infra_solr_core";});
-                var selectedCores = (_.isEmpty(allCores)) ? "" : allCores[0].options.filter(function(core)
-                { return core.selected; }).map(function(coreName) { return coreName.value; });
-                selectedCores = templateSrv._values.Cores.lastIndexOf('}') > 0 ? templateSrv._values.Cores.slice(1,-1) :
-                    templateSrv._values.Cores;
-                var selectedCore= selectedCores.split(',');
-                _.forEach(selectedCore, function(processCore) {
-                    metricsPromises.push(_.map(options.targets, function(target) {
-                        target.sCore = processCore;
-                        target.sCoreMetric = target.metric.replace('*', target.sCore);
-                        return getSolrCoreData(target);
-                    }));
+            _.forEach(splitTables, function (table) {
+              metricsPromises.push(_.map(options.targets, function (target) {
+                var hbMetric = [];
+                _.map(table, function (tableMetric) {
+                  hbMetric.push(target.metric.replace('*', tableMetric));
                 });
-            }
-
-            //Templatized Dashboard for Infra Solr Collections
-            if (templateSrv.variables[0].query === "infra_solr_collection") {
-                var allCollections = templateSrv.variables.filter(function(variable) { return variable.query === "infra_solr_collection";});
-                var selectedCollections = (_.isEmpty(allCollections)) ? "" : allCollections[0].options.filter(function(collection)
-                { return collection.selected; }).map(function(collectionsName) { return collectionsName.value; });
-                selectedCollections = templateSrv._values.Collections.lastIndexOf('}') > 0 ? templateSrv._values.Collections.slice(1,-1) :
-                    templateSrv._values.Collections;
-                var selectedCollection= selectedCollections.split(',');
-                _.forEach(selectedCollection, function(processCollection) {
-                    metricsPromises.push(_.map(options.targets, function(target) {
-                        target.sCollection = processCollection;
-                        target.sCollectionMetric = target.metric.replace('*', target.sCollection);
-                        return getSolrCollectionData(target);
-                    }));
+                var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+                hbMetric = _.map(hbMetric, function (tbl) {
+                  return tbl + metricTransform + '._' + target.aggregator;
                 });
-            }
+                target.hbMetric = _.flatten(hbMetric).join(',');
+                return getHbaseAppIdData(target);
+              }));
+            });
+          }
+          // Templatized Dashboard for per-topic metrics in Kafka.
+          if (templateSrv.variables[0].query === "kafka-topics") {
+            var allTopics = templateSrv.variables.filter(function (variable) {
+              return variable.query === "kafka-topics";
+            });
+            var selectedTopics = (_.isEmpty(allTopics)) ? "" : allTopics[0].options.filter(function (topic) {
+              return topic.selected;
+            }).map(function (topicName) {
+              return topicName.value;
+            });
+            selectedTopics = templateSrv._values.Topics.lastIndexOf('}') > 0 ? templateSrv._values.Topics.slice(1, -1) :
+              templateSrv._values.Topics;
+            var selectedTopic = selectedTopics.split(',');
+            _.forEach(selectedTopic, function (processTopic) {
+              metricsPromises.push(_.map(options.targets, function (target) {
+                target.kbTopic = processTopic;
+                target.kbMetric = target.metric.replace('*', target.kbTopic);
+                return getKafkaAppIdData(target);
+              }));
+            });
+          }
+          //Templatized Dashboard for Call Queues
+          if (templateSrv.variables[0].query === "callers") {
+            var allCallers = templateSrv.variables.filter(function (variable) {
+              return variable.query === "callers";
+            });
+            var selectedCallers = (_.isEmpty(allCallers)) ? "" : allCallers[0].options.filter(function (user) {
+              return user.selected;
+            }).map(function (callerName) {
+              return callerName.value;
+            });
+            selectedCallers = templateSrv._values.Callers.lastIndexOf('}') > 0 ? templateSrv._values.Callers.slice(1, -1) :
+              templateSrv._values.Callers;
+            var selectedCaller = selectedCallers.split(',');
+            _.forEach(selectedCaller, function (processCaller) {
+              metricsPromises.push(_.map(options.targets, function (target) {
+                target.nnCaller = processCaller;
+                target.nnMetric = target.metric.replace('*', target.nnCaller);
+                return getNnAppIdData(target);
+              }));
+            });
+          }
 
-            //Templatized Dashboard for Storm Topologies
-            if (templateSrv.variables[0].query === "topologies" && !templateSrv.variables[1]) {
-              var allTopologies = templateSrv.variables.filter(function(variable) { return variable.query === "topologies";});
-              var selectedTopologies = (_.isEmpty(allTopologies)) ? "" : allTopologies[0].options.filter(function(topo)
-              { return topo.selected; }).map(function(topoName) { return topoName.value; });
-              selectedTopologies = templateSrv._values.topologies.lastIndexOf('}') > 0 ? templateSrv._values.topologies.slice(1,-1) :
-                  templateSrv._values.topologies;
-              var selectedTopology= selectedTopologies.split(',');
-              _.forEach(selectedTopology, function(processTopology) {
-                metricsPromises.push(_.map(options.targets, function(target) {
-                  target.sTopology = processTopology;
-                  target.sTopoMetric = target.metric.replace('*', target.sTopology);
-                  return getStormData(target);
-                }));
-              });
-            }
+          //Templatized Dashboard for Infra Solr Cores
+          if (templateSrv.variables[0].query === "infra_solr_core") {
+            var allCores = templateSrv.variables.filter(function (variable) {
+              return variable.query === "infra_solr_core";
+            });
+            var selectedCores = (_.isEmpty(allCores)) ? "" : allCores[0].options.filter(function (core) {
+              return core.selected;
+            }).map(function (coreName) {
+              return coreName.value;
+            });
+            selectedCores = templateSrv._values.Cores.lastIndexOf('}') > 0 ? templateSrv._values.Cores.slice(1, -1) :
+              templateSrv._values.Cores;
+            var selectedCore = selectedCores.split(',');
+            _.forEach(selectedCore, function (processCore) {
+              metricsPromises.push(_.map(options.targets, function (target) {
+                target.sCore = processCore;
+                target.sCoreMetric = target.metric.replace('*', target.sCore);
+                return getSolrCoreData(target);
+              }));
+            });
+          }
 
-            //Templatized Dashboards for Storm Components
-            if (templateSrv.variables[0].query === "topologies" && templateSrv.variables[1] &&
-                templateSrv.variables[1].name === "component") {
-              var selectedTopology = templateSrv._values.topologies;
-              var selectedComponent = templateSrv._values.component;
-              metricsPromises.push(_.map(options.targets, function(target) {
-                target.sTopology = selectedTopology;
-                target.sComponent = selectedComponent;
-                target.sTopoMetric = target.metric.replace('*', target.sTopology).replace('*', target.sComponent);
-                  return getStormData(target);
+          //Templatized Dashboard for Infra Solr Collections
+          if (templateSrv.variables[0].query === "infra_solr_collection") {
+            var allCollections = templateSrv.variables.filter(function (variable) {
+              return variable.query === "infra_solr_collection";
+            });
+            var selectedCollections = (_.isEmpty(allCollections)) ? "" : allCollections[0].options.filter(function (collection) {
+              return collection.selected;
+            }).map(function (collectionsName) {
+              return collectionsName.value;
+            });
+            selectedCollections = templateSrv._values.Collections.lastIndexOf('}') > 0 ? templateSrv._values.Collections.slice(1, -1) :
+              templateSrv._values.Collections;
+            var selectedCollection = selectedCollections.split(',');
+            _.forEach(selectedCollection, function (processCollection) {
+              metricsPromises.push(_.map(options.targets, function (target) {
+                target.sCollection = processCollection;
+                target.sCollectionMetric = target.metric.replace('*', target.sCollection);
+                return getSolrCollectionData(target);
               }));
-            }
+            });
+          }
 
-            //Templatized Dashboard for Storm Kafka Offset
-            if (templateSrv.variables[0].query === "topologies" && templateSrv.variables[1] &&
-                templateSrv.variables[1].name === "topic") {
-              var selectedTopology = templateSrv._values.topologies;
-              var selectedTopic = templateSrv._values.topic;
-              metricsPromises.push(_.map(options.targets, function(target) {
-                target.sTopology = selectedTopology;
-                target.sTopic = selectedTopic;
-                target.sPartition = options.scopedVars.partition.value;
-                target.sTopoMetric = target.metric.replace('*', target.sTopology).replace('*', target.sTopic)
-                    .replace('*', target.sPartition);
+          //Templatized Dashboard for Storm Topologies
+          if (templateSrv.variables[0].query === "topologies" && !templateSrv.variables[1]) {
+            var allTopologies = templateSrv.variables.filter(function (variable) {
+              return variable.query === "topologies";
+            });
+            var selectedTopologies = (_.isEmpty(allTopologies)) ? "" : allTopologies[0].options.filter(function (topo) {
+              return topo.selected;
+            }).map(function (topoName) {
+              return topoName.value;
+            });
+            selectedTopologies = templateSrv._values.topologies.lastIndexOf('}') > 0 ? templateSrv._values.topologies.slice(1, -1) :
+              templateSrv._values.topologies;
+            var selectedTopology = selectedTopologies.split(',');
+            _.forEach(selectedTopology, function (processTopology) {
+              metricsPromises.push(_.map(options.targets, function (target) {
+                target.sTopology = processTopology;
+                target.sTopoMetric = target.metric.replace('*', target.sTopology);
                 return getStormData(target);
               }));
-            }
+            });
+          }
 
-            //Templatized Dashboards for Druid
-            if (templateSrv.variables[0].query === "druidDataSources" && !templateSrv.variables[1]) {
-              var allDataSources = templateSrv.variables.filter(function(variable) { return variable.query === "druidDataSources";});
-              var selectedDataSources = (_.isEmpty(allDataSources)) ? "" : allDataSources[0].options.filter(function(dataSource)
-                            { return dataSource.selected; }).map(function(dataSourceName) { return dataSourceName.value; });
-               selectedDataSources = templateSrv._values.druidDataSources.lastIndexOf('}') > 0 ? templateSrv._values.druidDataSources.slice(1,-1) :
-                                              templateSrv._values.druidDataSources;
-              var selectedDataSource = selectedDataSources.split(',');
-              _.forEach(selectedDataSource, function(processDataSource) {
-                metricsPromises.push(_.map(options.targets, function(target) {
-                  target.sDataSource = processDataSource;
-                  target.sDataSourceMetric = target.metric.replace('*', target.sDataSource);
-                  return getDruidData(target);
-                }));
-              });
-            }
-            // To speed up querying on templatized dashboards.
-              var indexOfHosts = -1;
-              for (var i = 0; i < templateSrv.variables.length; i++) {
-                  if (templateSrv.variables[i].name == 'hosts') {
-                      indexOfHosts = i;
-                  }
-              }
-              if (indexOfHosts >= 0) {
-              var allHosts = templateSrv._values.hosts.lastIndexOf('}') > 0 ? templateSrv._values.hosts.slice(1,-1) :
-              templateSrv._values.hosts;
-              allHosts = templateSrv._texts.hosts === "All" ? '%' : allHosts;
-              metricsPromises.push(_.map(options.targets, function(target) {
-                  target.templatedHost = allHosts? allHosts : '';
-                  target.templatedCluster = templatedCluster;
-                  return getAllHostData(target);
+          //Templatized Dashboards for Storm Components
+          if (templateSrv.variables[0].query === "topologies" && templateSrv.variables[1] &&
+            templateSrv.variables[1].name === "component") {
+            var selectedTopology = templateSrv._values.topologies;
+            var selectedComponent = templateSrv._values.component;
+            metricsPromises.push(_.map(options.targets, function (target) {
+              target.sTopology = selectedTopology;
+              target.sComponent = selectedComponent;
+              target.sTopoMetric = target.metric.replace('*', target.sTopology).replace('*', target.sComponent);
+              return getStormData(target);
+            }));
+          }
+
+          //Templatized Dashboard for Storm Kafka Offset
+          if (templateSrv.variables[0].query === "topologies" && templateSrv.variables[1] &&
+            templateSrv.variables[1].name === "topic") {
+            var selectedTopology = templateSrv._values.topologies;
+            var selectedTopic = templateSrv._values.topic;
+            metricsPromises.push(_.map(options.targets, function (target) {
+              target.sTopology = selectedTopology;
+              target.sTopic = selectedTopic;
+              target.sPartition = options.scopedVars.partition.value;
+              target.sTopoMetric = target.metric.replace('*', target.sTopology).replace('*', target.sTopic)
+                .replace('*', target.sPartition);
+              return getStormData(target);
+            }));
+          }
+
+          //Templatized Dashboards for Druid
+          if (templateSrv.variables[0].query === "druidDataSources" && !templateSrv.variables[1]) {
+            var allDataSources = templateSrv.variables.filter(function (variable) {
+              return variable.query === "druidDataSources";
+            });
+            var selectedDataSources = (_.isEmpty(allDataSources)) ? "" : allDataSources[0].options.filter(function (dataSource) {
+              return dataSource.selected;
+            }).map(function (dataSourceName) {
+              return dataSourceName.value;
+            });
+            selectedDataSources = templateSrv._values.druidDataSources.lastIndexOf('}') > 0 ? templateSrv._values.druidDataSources.slice(1, -1) :
+              templateSrv._values.druidDataSources;
+            var selectedDataSource = selectedDataSources.split(',');
+            _.forEach(selectedDataSource, function (processDataSource) {
+              metricsPromises.push(_.map(options.targets, function (target) {
+                target.sDataSource = processDataSource;
+                target.sDataSourceMetric = target.metric.replace('*', target.sDataSource);
+                return getDruidData(target);
               }));
-            }
-            metricsPromises = _.flatten(metricsPromises);
-          } else {
-            // Non Templatized Dashboards
-            metricsPromises = _.map(options.targets, function(target) {
-              console.debug('target app=' + target.app + ',' +
-                'target metric=' + target.metric + ' on host=' + target.tempHost);
-              if (!!target.hosts) {
-                return getHostAppIdData(target);
-              } else {
-                return getServiceAppIdData(target);
-              }
             });
           }
+          // To speed up querying on templatized dashboards.
+          var indexOfHosts = -1;
+          for (var i = 0; i < templateSrv.variables.length; i++) {
+            if (templateSrv.variables[i].name == 'hosts') {
+              indexOfHosts = i;
+            }
+          }
+          if (indexOfHosts >= 0) {
+            var allHosts = templateSrv._values.hosts.lastIndexOf('}') > 0 ? templateSrv._values.hosts.slice(1, -1) :
+              templateSrv._values.hosts;
+            allHosts = templateSrv._texts.hosts === "All" ? '%' : allHosts;
+            metricsPromises.push(_.map(options.targets, function (target) {
+              target.templatedHost = allHosts ? allHosts : '';
+              target.templatedCluster = templatedCluster;
+              return getAllHostData(target);
+            }));
+          }
+          metricsPromises = _.flatten(metricsPromises);
+        } else {
+          // Non Templatized Dashboards
+          metricsPromises = _.map(options.targets, function (target) {
+            console.debug('target app=' + target.app + ',' +
+              'target metric=' + target.metric + ' on host=' + target.tempHost);
+            if (!!target.hosts) {
+              return getHostAppIdData(target);
+            } else {
+              return getServiceAppIdData(target);
+            }
+          });
+        }
 
-          return $q.all(metricsPromises).then(function(metricsDataArray) {
-            var data = _.map(metricsDataArray, function(metricsData) {
-              return metricsData.data;
-            });
-            var metricsDataResult = {data: _.flatten(data)};
-            return $q.when(metricsDataResult);
+        return $q.all(metricsPromises).then(function (metricsDataArray) {
+          var data = _.map(metricsDataArray, function (metricsData) {
+            return metricsData.data;
           });
-        };
+          var metricsDataResult = {data: _.flatten(data)};
+          return $q.when(metricsDataResult);
+        });
+      };
 
-        /**
-         * AMS Datasource  List Series.
-         */
-        AmbariMetricsDatasource.prototype.listSeries = function (query) {
-          // wrap in regex
-          if (query && query.length > 0 && query[0] !== '/') {
-            query = '/' + query + '/';
-          }
-          return $q.when([]);
-        };
+      /**
+       * AMS Datasource  List Series.
+       */
+      this.listSeries = function (query) {
+        // wrap in regex
+        if (query && query.length > 0 && query[0] !== '/') {
+          query = '/' + query + '/';
+        }
+        return $q.when([]);
+      };
 
-        /**
-         * AMS Datasource Templating Variables.
-         */
-        AmbariMetricsDatasource.prototype.metricFindQuery = function (query) {
-          var interpolated;
-          try {
-            interpolated = query.split('.')[0];
-          } catch (err) {
-            return $q.reject(err);
-          }
-          var templatedClusters = templateSrv.variables.filter(function(o) { return o.name === "cluster"});
-          var templatedCluster = (_.isEmpty(templatedClusters)) ? '' : templatedClusters[0].options.filter(function(cluster)
-          { return cluster.selected; }).map(function(clusterName) { return clusterName.value; });
+      /**
+       * AMS Datasource Templating Variables.
+       */
+      this.metricFindQuery = function (query) {
+        var interpolated;
+        try {
+          interpolated = query.split('.')[0];
+        } catch (err) {
+          return $q.reject(err);
+        }
+        var templatedClusters = templateSrv.variables.filter(function (o) {
+          return o.name === "cluster"
+        });
+        var templatedCluster = (_.isEmpty(templatedClusters)) ? '' : templatedClusters[0].options.filter(function (cluster) {
+          return cluster.selected;
+        }).map(function (clusterName) {
+          return clusterName.value;
+        });
 
-          var tComponents = _.isEmpty(templateSrv.variables) ? '' : templateSrv.variables.filter(function(variable) 
-            { return variable.name === "components"});
-          var tComponent = _.isEmpty(tComponents) ? '' : tComponents[0].current.value;
+        var tComponents = _.isEmpty(templateSrv.variables) ? '' : templateSrv.variables.filter(function (variable) {
+          return variable.name === "components"
+        });
+        var tComponent = _.isEmpty(tComponents) ? '' : tComponents[0].current.value;
 
 
-          // Templated Variable for HBase Users
-          // It will search the cluster and populate the HBase Users.
-          if(interpolated === "hbase-users") {
-            return this.initMetricAppidMapping()
-              .then(function () {
-                var hbaseUsers = allMetrics["hbase"];
-                var extractUsers = hbaseUsers.filter(/./.test.bind(new RegExp("regionserver.Users.", 'g')));
-                var removeUser = "regionserver.Users.numUsers";
-                var i = extractUsers.indexOf(removeUser);
-                if(i !== -1) { extractUsers.splice(i, 1);}
-                var userPrefix = "regionserver.Users.";
-                var users = _.map(extractUsers, function(user) {
-                  return user.substring(userPrefix.length);
-                });
-                users = _.map(users, function(userName) {
-                  return userName.substring(0,userName.lastIndexOf("_metric"));
-                });
-                users = _.sortBy(_.uniq(users));
-                return _.map(users, function (users) {
-                  return {
-                    text: users
-                  };
-                });
+        // Templated Variable for HBase Users
+        // It will search the cluster and populate the HBase Users.
+        if (interpolated === "hbase-users") {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var hbaseUsers = allMetrics["hbase"];
+              var extractUsers = hbaseUsers.filter(/./.test.bind(new RegExp("regionserver.Users.", 'g')));
+              var removeUser = "regionserver.Users.numUsers";
+              var i = extractUsers.indexOf(removeUser);
+              if (i !== -1) {
+                extractUsers.splice(i, 1);
+              }
+              var userPrefix = "regionserver.Users.";
+              var users = _.map(extractUsers, function (user) {
+                return user.substring(userPrefix.length);
               });
-          }
-          // Templated Variable for HBase Tables.
-          // It will search the cluster and populate the hbase-tables.
-          if(interpolated === "hbase-tables") {
-            return this.initMetricAppidMapping()
-              .then(function () {
-                var hbaseTables = allMetrics["hbase"];
-                var extractTables = hbaseTables.filter(/./.test.bind(new RegExp("regionserver.Tables.", 'g')));
-                var removeTable = "regionserver.Tables.numTables";
-                var i = extractTables.indexOf(removeTable);
-                if(i != -1) { extractTables.splice(i, 1);}
-                var tablePrefix = "regionserver.Tables.";
-                var tables = _.map(extractTables, function(user) {
-                  return user.substring(tablePrefix.length);
-                });
-                tables = _.map(tables, function(userName) {
-                  return userName.substring(0,userName.lastIndexOf("_metric"));
-                });
-                tables = _.sortBy(_.uniq(tables));
-                return _.map(tables, function (tables) {
-                  return {
-                    text: tables
-                  };
-                });
+              users = _.map(users, function (userName) {
+                return userName.substring(0, userName.lastIndexOf("_metric"));
               });
-          }
-          // Templated Variable for Kafka Topics.
-          // It will search the cluster and populate the topics.
-          if(interpolated === "kafka-topics") {
-            return this.initMetricAppidMapping()
-              .then(function () {
-                var kafkaTopics = allMetrics["kafka_broker"];
-                var extractTopics = kafkaTopics.filter(/./.test.bind(new RegExp("\\b.log.Log.\\b", 'g')));
-                var topics =_.map(extractTopics, function (topic) {
-                  var topicPrefix = "topic.";
-                  return topic.substring(topic.lastIndexOf(topicPrefix)+topicPrefix.length, topic.length);
-                });
-                topics = _.sortBy(_.uniq(topics));
-                var i = topics.indexOf("ambari_kafka_service_check");
-                if(i != -1) { topics.splice(i, 1);}
-                return _.map(topics, function (topics) {
-                  return {
-                    text: topics
-                  };
-                });
+              users = _.sortBy(_.uniq(users));
+              return _.map(users, function (users) {
+                return {
+                  text: users
+                };
               });
-          }
+            });
+        }
+        // Templated Variable for HBase Tables.
+        // It will search the cluster and populate the hbase-tables.
+        if (interpolated === "hbase-tables") {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var hbaseTables = allMetrics["hbase"];
+              var extractTables = hbaseTables.filter(/./.test.bind(new RegExp("regionserver.Tables.", 'g')));
+              var removeTable = "regionserver.Tables.numTables";
+              var i = extractTables.indexOf(removeTable);
+              if (i != -1) {
+                extractTables.splice(i, 1);
+              }
+              var tablePrefix = "regionserver.Tables.";
+              var tables = _.map(extractTables, function (user) {
+                return user.substring(tablePrefix.length);
+              });
+              tables = _.map(tables, function (userName) {
+                return userName.substring(0, userName.lastIndexOf("_metric"));
+              });
+              tables = _.sortBy(_.uniq(tables));
+              return _.map(tables, function (tables) {
+                return {
+                  text: tables
+                };
+              });
+            });
+        }
+        // Templated Variable for Kafka Topics.
+        // It will search the cluster and populate the topics.
+        if (interpolated === "kafka-topics") {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var kafkaTopics = allMetrics["kafka_broker"];
+              var extractTopics = kafkaTopics.filter(/./.test.bind(new RegExp("\\b.log.Log.\\b", 'g')));
+              var topics = _.map(extractTopics, function (topic) {
+                var topicPrefix = "topic.";
+                return topic.substring(topic.lastIndexOf(topicPrefix) + topicPrefix.length, topic.length);
+              });
+              topics = _.sortBy(_.uniq(topics));
+              var i = topics.indexOf("ambari_kafka_service_check");
+              if (i != -1) {
+                topics.splice(i, 1);
+              }
+              return _.map(topics, function (topics) {
+                return {
+                  text: topics
+                };
+              });
+            });
+        }
 
-          //Templated Variables for Call Queue Metrics
-          if(interpolated === "callers") {
-            return this.initMetricAppidMapping()
-              .then(function () {
-                var nnCallers = allMetrics["namenode"];
-                var extractCallers = nnCallers.filter(/./.test.bind(new 
-                  RegExp("ipc.client.org.apache.hadoop.ipc.DecayRpcScheduler.Caller", 'g')));
-                var callers = _.sortBy(_.uniq(_.map(extractCallers, function(caller) { 
-                  return caller.substring(caller.indexOf('(')+1, caller.indexOf(')')) })));
-                return _.map(callers, function (callers) {
-                  return {
-                    text: callers
-                  };
-                });
+        //Templated Variables for Call Queue Metrics
+        if (interpolated === "callers") {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var nnCallers = allMetrics["namenode"];
+              var extractCallers = nnCallers.filter(/./.test.bind(new
+              RegExp("ipc.client.org.apache.hadoop.ipc.DecayRpcScheduler.Caller", 'g')));
+              var callers = _.sortBy(_.uniq(_.map(extractCallers, function (caller) {
+                return caller.substring(caller.indexOf('(') + 1, caller.indexOf(')'))
+              })));
+              return _.map(callers, function (callers) {
+                return {
+                  text: callers
+                };
               });
-          }
+            });
+        }
 
-          var cores = [];
-          //Templated Variables for Infra Solr Cores
-          if (interpolated === "infra_solr_core") {
-              return this.initMetricAppidMapping()
-                  .then(function () {
-                      var solrMetrics = allMetrics["ambari-infra-solr"];
-                      var extractCores = solrMetrics.filter(/./.test.bind(new
-                      RegExp("^infra.solr.core.", 'g')));
-                      _.map(extractCores, function (core) {
-                          // Core naming convention is infra.solr.core.<collection_name>.<shard>.<replica>.<metric_name>
-                          // coreName should be <collection_name>.<shard>.<replica>
-                          core = core.split('.');
-                          var coreName = core.slice(3,6).join(".");
-                          if (cores.indexOf(coreName) < 0) {
-                              cores.push(coreName);
-                          }
-                      });
-                      return _.map(cores, function (cores) {
-                              return {
-                                  text: cores
-                              };
-                          });
-                      });
-          }
+        var cores = [];
+        //Templated Variables for Infra Solr Cores
+        if (interpolated === "infra_solr_core") {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var solrMetrics = allMetrics["ambari-infra-solr"];
+              var extractCores = solrMetrics.filter(/./.test.bind(new
+              RegExp("^infra.solr.core.", 'g')));
+              _.map(extractCores, function (core) {
+                // Core naming convention is infra.solr.core.<collection_name>.<shard>.<replica>.<metric_name>
+                // coreName should be <collection_name>.<shard>.<replica>
+                core = core.split('.');
+                var coreName = core.slice(3, 6).join(".");
+                if (cores.indexOf(coreName) < 0) {
+                  cores.push(coreName);
+                }
+              });
+              return _.map(cores, function (cores) {
+                return {
+                  text: cores
+                };
+              });
+            });
+        }
 
-          var collections = [];
-          //Templated Variables for Infra Solr Collections
-          if (interpolated === "infra_solr_collection") {
-              return this.initMetricAppidMapping()
-                  .then(function () {
-                      var solrMetrics = allMetrics["ambari-infra-solr"];
-                      var extractCollections = solrMetrics.filter(/./.test.bind(new
-                      RegExp("^infra.solr.core.", 'g')));
-                      _.map(extractCollections, function (core) {
-                          // Core naming convention is infra.solr.core.<collection_name>.<shard>.<replica>.<metric_name>
-                          core = core.split('.');
-                          var collection = core[3];
-                          if (collections.indexOf(collection) < 0) {
-                              collections.push(collection);
-                          }
-                      });
-                      return _.map(collections, function (collections) {
-                              return {
-                                  text: collections
-                              };
-                          });
-                      });
-          }
+        var collections = [];
+        //Templated Variables for Infra Solr Collections
+        if (interpolated === "infra_solr_collection") {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var solrMetrics = allMetrics["ambari-infra-solr"];
+              var extractCollections = solrMetrics.filter(/./.test.bind(new
+              RegExp("^infra.solr.core.", 'g')));
+              _.map(extractCollections, function (core) {
+                // Core naming convention is infra.solr.core.<collection_name>.<shard>.<replica>.<metric_name>
+                core = core.split('.');
+                var collection = core[3];
+                if (collections.indexOf(collection) < 0) {
+                  collections.push(collection);
+                }
+              });
+              return _.map(collections, function (collections) {
+                return {
+                  text: collections
+                };
+              });
+            });
+        }
 
-          var topologies = {};
-          //Templated Variables for Storm Topologies
-          if(interpolated === "topologies") {
-            return this.initMetricAppidMapping()
-                .then(function () {
-                  var storm = allMetrics["nimbus"];
-                  var extractTopologies = storm.filter(/./.test.bind(new
-                      RegExp("^topology.", 'g')));
-                  _.map(extractTopologies, function(topology){
-                    // Topology naming convention is topology.<topology-name>.component.
-                    topology = topology.split('.').slice(0,3);
-                    if (topologies[topology[1]]){
-                      topologies[topology[1]].push(topology[2]);
-                    } else {
-                      topologies[topology[1]] = [topology[2]];
-                    }
-                  });
-                  return _.map(Object.keys(topologies), function(topologyNames){
-                    return {
-                      text: topologyNames
-                    };
-                  });
-                });
-          }
-          //Templated Variables for Storm Components per Topology
-          if (interpolated.indexOf("stormComponent") >= 0) {
-            var componentName = interpolated.substring(0,interpolated.indexOf('.'));
-            return this.initMetricAppidMapping()
-                .then(function () {
-                  var storm = allMetrics["nimbus"];
-                  var extractTopologies = storm.filter(/./.test.bind(new
-                      RegExp("^topology.", 'g')));
-                  _.map(extractTopologies, function(topology){
-                    topology = topology.split('.').slice(0,3);
-                    if (topologies[topology[1]]){
-                      topologies[topology[1]].push(topology[2]);
-                    } else {
-                      topologies[topology[1]] = [topology[2]];
-                    }
-                  });
-                  // Retrieve unique component names from the list.
-                  var compName = _.uniq(topologies[componentName]);
-                  // Remove "kafka-topic" from the list of components.
-                  var remove = compName.indexOf('kafka-topic');
-                  if (remove > -1) { compName.splice(remove, 1);}
-                  return _.map(compName, function(components){
-                    return {
-                      text: components
-                    };
-                  });
-                });
-          }
-          var stormEntities = {};
-          AmbariMetricsDatasource.prototype.getStormEntities = function () {
-            return this.initMetricAppidMapping()
-                .then(function () {
-                  var storm = allMetrics["nimbus"];
-                  var extractTopologies = storm.filter(/./.test.bind(new
-                      RegExp("partition", 'g')));
-                  _.map(extractTopologies, function(topology){
-                    topology = topology.split('.').slice(0,5);
-                    var topologyName = topologyN = topology[1]; // Topology
-                    var topologyTopicName = topicN = topology[3]; // Topic
-                    var topologyTopicPartitionName = topology[4]; // Partition
-                    if (stormEntities[topologyName]) {
-                      if (stormEntities[topologyName][topologyTopicName]) {
-                        stormEntities[topologyName][topologyTopicName].push(topologyTopicPartitionName);
-                      } else {
-                        stormEntities[topologyName][topologyTopicName] = [topologyTopicPartitionName];
-                      }
-                    } else {
-                      stormEntities[topologyName] = {};
-                      stormEntities[topologyName][topologyTopicName] = [topologyTopicPartitionName];
-                    }
-                  });
-                });
-          };
-          //Templated Variables for Storm Topics per Topology
-          if (interpolated.indexOf("stormTopic") >= 0) {
-            var topicName = interpolated.substring(0,interpolated.indexOf('.'));
-            return this.getStormEntities().then(function () {
-              var topicNames = Object.keys(stormEntities[topicName]);
-              return _.map(topicNames, function(names){
+        var topologies = {};
+        //Templated Variables for Storm Topologies
+        if (interpolated === "topologies") {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var storm = allMetrics["nimbus"];
+              var extractTopologies = storm.filter(/./.test.bind(new
+              RegExp("^topology.", 'g')));
+              _.map(extractTopologies, function (topology) {
+                // Topology naming convention is topology.<topology-name>.component.
+                topology = topology.split('.').slice(0, 3);
+                if (topologies[topology[1]]) {
+                  topologies[topology[1]].push(topology[2]);
+                } else {
+                  topologies[topology[1]] = [topology[2]];
+                }
+              });
+              return _.map(Object.keys(topologies), function (topologyNames) {
                 return {
-                  text: names
+                  text: topologyNames
                 };
               });
             });
-          }
-          //Templated Variables for Storm Partitions per Topic
-          if (interpolated.indexOf("stormPartition") >= 0) {
-            var topicN, topologyN;
-            return this.getStormEntities().then(function () {
-              var partitionNames = _.uniq(stormEntities[topologyN][topicN]);
-              return _.map(partitionNames, function(names){
+        }
+        //Templated Variables for Storm Components per Topology
+        if (interpolated.indexOf("stormComponent") >= 0) {
+          var componentName = interpolated.substring(0, interpolated.indexOf('.'));
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var storm = allMetrics["nimbus"];
+              var extractTopologies = storm.filter(/./.test.bind(new
+              RegExp("^topology.", 'g')));
+              _.map(extractTopologies, function (topology) {
+                topology = topology.split('.').slice(0, 3);
+                if (topologies[topology[1]]) {
+                  topologies[topology[1]].push(topology[2]);
+                } else {
+                  topologies[topology[1]] = [topology[2]];
+                }
+              });
+              // Retrieve unique component names from the list.
+              var compName = _.uniq(topologies[componentName]);
+              // Remove "kafka-topic" from the list of components.
+              var remove = compName.indexOf('kafka-topic');
+              if (remove > -1) {
+                compName.splice(remove, 1);
+              }
+              return _.map(compName, function (components) {
                 return {
-                  text: names
+                  text: components
                 };
               });
             });
-          }
-          // Templated Variable for YARN Queues.
-          // It will search the cluster and populate the queues.
-          if(interpolated === "yarnqueues") {
-            return this.initMetricAppidMapping()
-              .then(function () {
-                var yarnqueues = allMetrics["resourcemanager"];
-                var extractQueues = yarnqueues.filter(/./.test.bind(new RegExp(".=root", 'g')));
-                var queues = _.map(extractQueues, function(metric) {
-                  return metric.substring("yarn.QueueMetrics.Queue=".length);
-                });
-                queues = _.map(queues, function(metricName) {
-                  return metricName.substring(metricName.lastIndexOf("."), 0);
-                });
-                queues = _.sortBy(_.uniq(queues));
-                return _.map(queues, function (queues) {
-                  return {
-                    text: queues
-                  };
-                });
+        }
+        var stormEntities = {};
+        this.getStormEntities = function () {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var storm = allMetrics["nimbus"];
+              var extractTopologies = storm.filter(/./.test.bind(new
+              RegExp("partition", 'g')));
+              _.map(extractTopologies, function (topology) {
+                topology = topology.split('.').slice(0, 5);
+                var topologyName = topologyN = topology[1]; // Topology
+                var topologyTopicName = topicN = topology[3]; // Topic
+                var topologyTopicPartitionName = topology[4]; // Partition
+                if (stormEntities[topologyName]) {
+                  if (stormEntities[topologyName][topologyTopicName]) {
+                    stormEntities[topologyName][topologyTopicName].push(topologyTopicPartitionName);
+                  } else {
+                    stormEntities[topologyName][topologyTopicName] = [topologyTopicPartitionName];
+                  }
+                } else {
+                  stormEntities[topologyName] = {};
+                  stormEntities[topologyName][topologyTopicName] = [topologyTopicPartitionName];
+                }
               });
-          }
+            });
+        };
+        //Templated Variables for Storm Topics per Topology
+        if (interpolated.indexOf("stormTopic") >= 0) {
+          var topicName = interpolated.substring(0, interpolated.indexOf('.'));
+          return this.getStormEntities().then(function () {
+            var topicNames = Object.keys(stormEntities[topicName]);
+            return _.map(topicNames, function (names) {
+              return {
+                text: names
+              };
+            });
+          });
+        }
+        //Templated Variables for Storm Partitions per Topic
+        if (interpolated.indexOf("stormPartition") >= 0) {
+          var topicN, topologyN;
+          return this.getStormEntities().then(function () {
+            var partitionNames = _.uniq(stormEntities[topologyN][topicN]);
+            return _.map(partitionNames, function (names) {
+              return {
+                text: names
+              };
+            });
+          });
+        }
+        // Templated Variable for YARN Queues.
+        // It will search the cluster and populate the queues.
+        if (interpolated === "yarnqueues") {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var yarnqueues = allMetrics["resourcemanager"];
+              var extractQueues = yarnqueues.filter(/./.test.bind(new RegExp(".=root", 'g')));
+              var queues = _.map(extractQueues, function (metric) {
+                return metric.substring("yarn.QueueMetrics.Queue=".length);
+              });
+              queues = _.map(queues, function (metricName) {
+                return metricName.substring(metricName.lastIndexOf("."), 0);
+              });
+              queues = _.sortBy(_.uniq(queues));
+              return _.map(queues, function (queues) {
+                return {
+                  text: queues
+                };
+              });
+            });
+        }
 
-          // Templated Variable for DruidServices.
-          // It will search the cluster and populate the druid service names.
-          if(interpolated === "druidServices") {
-            return this.initMetricAppidMapping()
-              .then(function () {
-                var druidMetrics = allMetrics["druid"];
-                // Assumption: each node always emits jvm metrics
-                var extractNodeTypes = druidMetrics.filter(/./.test.bind(new RegExp("jvm/gc/time", 'g')));
-                var nodeTypes = _.map(extractNodeTypes, function(metricName) {
-                  return metricName.substring(0, metricName.indexOf("."));
-                });
-                nodeTypes = _.sortBy(_.uniq(nodeTypes));
-                return _.map(nodeTypes, function (nodeType) {
-                  return {
-                    text: nodeType
-                  };
-                });
+        // Templated Variable for DruidServices.
+        // It will search the cluster and populate the druid service names.
+        if (interpolated === "druidServices") {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var druidMetrics = allMetrics["druid"];
+              // Assumption: each node always emits jvm metrics
+              var extractNodeTypes = druidMetrics.filter(/./.test.bind(new RegExp("jvm/gc/time", 'g')));
+              var nodeTypes = _.map(extractNodeTypes, function (metricName) {
+                return metricName.substring(0, metricName.indexOf("."));
               });
-          }
+              nodeTypes = _.sortBy(_.uniq(nodeTypes));
+              return _.map(nodeTypes, function (nodeType) {
+                return {
+                  text: nodeType
+                };
+              });
+            });
+        }
 
-          // Templated Variable for Druid datasources.
-          // It will search the cluster and populate the druid datasources.
-          if(interpolated === "druidDataSources") {
-            return this.initMetricAppidMapping()
-              .then(function () {
-                var druidMetrics = allMetrics["druid"];
-                // Assumption: query/time is emitted for each datasource
-                var extractDataSources = druidMetrics.filter(/./.test.bind(new RegExp("query/time", 'g')));
-                var dataSources = _.map(extractDataSources, function(metricName) {
-                  return metricName.split('.')[1]
-                });
-                dataSources = _.sortBy(_.uniq(dataSources));
-                return _.map(dataSources, function (dataSource) {
-                  return {
-                    text: dataSource
-                  };
-                });
+        // Templated Variable for Druid datasources.
+        // It will search the cluster and populate the druid datasources.
+        if (interpolated === "druidDataSources") {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var druidMetrics = allMetrics["druid"];
+              // Assumption: query/time is emitted for each datasource
+              var extractDataSources = druidMetrics.filter(/./.test.bind(new RegExp("query/time", 'g')));
+              var dataSources = _.map(extractDataSources, function (metricName) {
+                return metricName.split('.')[1]
               });
-          }
+              dataSources = _.sortBy(_.uniq(dataSources));
+              return _.map(dataSources, function (dataSource) {
+                return {
+                  text: dataSource
+                };
+              });
+            });
+        }
 
-          // Templated Variable for Druid query type.
-          // It will search the cluster and populate the druid query types.
-          if(interpolated === "druidQueryTypes") {
-            return this.initMetricAppidMapping()
-              .then(function () {
-                var druidMetrics = allMetrics["druid"];
-                // Assumption: query/time is emitted for each query type.
-                var extractQueryTypes = druidMetrics.filter(/./.test.bind(new RegExp("query/time", 'g')));
-                var queryTypes = _.map(extractQueryTypes, function(metricName) {
-                  return metricName.split('.')[2]
-                });
-                queryTypes = _.sortBy(_.uniq(queryTypes));
-                return _.map(queryTypes, function (queryType) {
-                  return {
-                    text: queryType
-                  };
-                });
+        // Templated Variable for Druid query type.
+        // It will search the cluster and populate the druid query types.
+        if (interpolated === "druidQueryTypes") {
+          return this.initMetricAppidMapping()
+            .then(function () {
+              var druidMetrics = allMetrics["druid"];
+              // Assumption: query/time is emitted for each query type.
+              var extractQueryTypes = druidMetrics.filter(/./.test.bind(new RegExp("query/time", 'g')));
+              var queryTypes = _.map(extractQueryTypes, function (metricName) {
+                return metricName.split('.')[2]
               });
-          }
+              queryTypes = _.sortBy(_.uniq(queryTypes));
+              return _.map(queryTypes, function (queryType) {
+                return {
+                  text: queryType
+                };
+              });
+            });
+        }
+
+        if (interpolated == 'hosts') {
+          return this.suggestHosts(tComponent, templatedCluster);
+        } else if (interpolated == 'cluster') {
+          return this.suggestClusters(tComponent)
+        }
+      };
 
-          if (interpolated == 'hosts') {
-            return this.suggestHosts(tComponent, templatedCluster);
-          } else if (interpolated == 'cluster') {
-            return this.suggestClusters(tComponent)
+      /**
+       * AMS Datasource  - Test Data Source Connection.
+       *
+       * Added Check to see if Datasource is working. Throws up an error in the
+       * Datasources page if incorrect info is passed on.
+       */
+      this.testDatasource = function () {
+        return this.doAmbariRequest({
+          url: '/ws/v1/timeline/metrics/metadata',
+          method: 'GET'
+        }).then(function (response) {
+          console.log(response);
+          if (response.status === 200) {
+            return {status: "success", message: "Data source is working", title: "Success"};
           }
-        };
+        });
+      };
 
-        /**
-         * AMS Datasource  - Test Data Source Connection.
-         *
-         * Added Check to see if Datasource is working. Throws up an error in the
-         * Datasources page if incorrect info is passed on.
-         */
-        AmbariMetricsDatasource.prototype.testDatasource = function () {
-          return this.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics/metadata',
-            method: 'GET'
-          }).then(function(response) {
-            console.log(response);
-            if (response.status === 200) {
-              return { status: "success", message: "Data source is working", title: "Success" };
-            }
-          });
-        };
+      /**
+       * AMS Datasource - Suggest AppId.
+       *
+       * Read AppIds from cache.
+       */
+      this.suggestApps = function (query) {
+        console.log(query);
 
-        /**
-         * AMS Datasource - Suggest AppId.
-         *
-         * Read AppIds from cache.
-         */
-        AmbariMetricsDatasource.prototype.suggestApps = function (query) {
-          console.log(query);
+        appIds = appIds.sort();
+        var appId = _.map(appIds, function (k) {
+          return {text: k};
+        });
+        return $q.when(appId);
+      };
 
-          appIds = appIds.sort();
-          var appId = _.map(appIds, function (k) {
-            return {text: k};
-          });
-          return $q.when(appId);
-        };
+      /**
+       * AMS Datasource - Suggest Metrics.
+       *
+       * Read Metrics based on AppId chosen.
+       */
+      this.suggestMetrics = function (query, app) {
+        if (!app) {
+          return $q.when([]);
+        }
+        var keys = [];
+        keys = _.map(allMetrics[app], function (m) {
+          return {text: m};
+        });
+        keys = _.sortBy(keys, function (i) {
+          return i.text.toLowerCase();
+        });
+        return $q.when(keys);
+      };
 
-        /**
-         * AMS Datasource - Suggest Metrics.
-         *
-         * Read Metrics based on AppId chosen.
-         */
-        AmbariMetricsDatasource.prototype.suggestMetrics = function (query, app) {
-          if (!app) {
-            return $q.when([]);
+      this.suggestClusters = function (app) {
+        if (!app) {
+          app = '';
+        }
+        return this.doAmbariRequest({
+          method: 'GET',
+          url: '/ws/v1/timeline/metrics/instances?' + 'appId=' + app
+        }).then(function (response) {
+          var clusters = [];
+          var data = response.data;
+          for (var cluster in data) {
+            if (data[cluster].hasOwnProperty(app)) {
+              clusters.push({text: cluster});
+            }
           }
-          var keys = [];
-          keys = _.map(allMetrics[app],function(m) {
-            return {text: m};
-          });
-          keys = _.sortBy(keys, function (i) { return i.text.toLowerCase(); });
-          return $q.when(keys);
-        };
-
-        AmbariMetricsDatasource.prototype.suggestClusters = function(app) {
-          if (!app) { app = ''; }
-          return this.doAmbariRequest({
-            method: 'GET',
-            url: '/ws/v1/timeline/metrics/instances?' + 'appId=' + app
-          }).then(function(response) {
-              var clusters = [];
-              var data = response.data;
-              for (var cluster in data) {
-                if (data[cluster].hasOwnProperty(app)) {
-                  clusters.push({text: cluster});
-                }
-              }
-              return $q.when(clusters);
-          });
-        };
+          return $q.when(clusters);
+        });
+      };
 
-        /**
-         * AMS Datasource - Suggest Hosts.
-         *
-         * Query Hosts on the cluster.
-         */
-        AmbariMetricsDatasource.prototype.suggestHosts = function (app, cluster) {
-          if (!app) { app = ''; }
-          if (!cluster) { cluster = ''; }
-          return this.doAmbariRequest({
-            method: 'GET',
-            url: '/ws/v1/timeline/metrics/instances?' + 'appId=' + app + '&instanceId=' + cluster
-          }).then(function (response) {
-            var hosts = [];
-            var data = response.data;
-            for (var cluster in data) {
-              var appHosts = data[cluster][app];
-              if (appHosts) {
-                for (var index in appHosts) {
-                  hosts.push({text: appHosts[index]});
-                }
+      /**
+       * AMS Datasource - Suggest Hosts.
+       *
+       * Query Hosts on the cluster.
+       */
+      this.suggestHosts = function (app, cluster) {
+        if (!app) {
+          app = '';
+        }
+        if (!cluster) {
+          cluster = '';
+        }
+        return this.doAmbariRequest({
+          method: 'GET',
+          url: '/ws/v1/timeline/metrics/instances?' + 'appId=' + app + '&instanceId=' + cluster
+        }).then(function (response) {
+          var hosts = [];
+          var data = response.data;
+          for (var cluster in data) {
+            var appHosts = data[cluster][app];
+            if (appHosts) {
+              for (var index in appHosts) {
+                hosts.push({text: appHosts[index]});
               }
             }
-            return $q.when(hosts);
-          });
-        };
-
-        /**
-         * AMS Datasource Aggregators.
-         */
-        var aggregatorsPromise = null;
-        AmbariMetricsDatasource.prototype.getAggregators = function () {
-          if (aggregatorsPromise) {
-            return aggregatorsPromise;
           }
-          aggregatorsPromise = $q.when([
-            'none','avg', 'sum', 'min', 'max'
-          ]);
+          return $q.when(hosts);
+        });
+      };
+
+      /**
+       * AMS Datasource Aggregators.
+       */
+      var aggregatorsPromise = null;
+      this.getAggregators = function () {
+        if (aggregatorsPromise) {
           return aggregatorsPromise;
-        };
+        }
+        aggregatorsPromise = $q.when([
+          'none', 'avg', 'sum', 'min', 'max'
+        ]);
+        return aggregatorsPromise;
+      };
+    };
+
+    return {
+      AmbariMetricsDatasource: AmbariMetricsDatasource
+    };
+
+
+  });
 
-        return AmbariMetricsDatasource;
-      });
-    }
-);
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
index aade7d7..087533c 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
@@ -34,3 +34,4 @@ function (angular) {
   });
 
 });
+
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/ams-screenshot.png b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/ams-screenshot.png
new file mode 100644
index 0000000..358e42e
Binary files /dev/null and b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/ams-screenshot.png differ
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo-sm.png b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo-sm.png
new file mode 100644
index 0000000..0f90391
Binary files /dev/null and b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo-sm.png differ
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo.png b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo.png
new file mode 100644
index 0000000..07412bd
Binary files /dev/null and b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo.png differ
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-project.png b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-project.png
new file mode 100644
index 0000000..7ce8965
Binary files /dev/null and b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-project.png differ
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.d.ts
similarity index 61%
copy from ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
copy to ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.d.ts
index aade7d7..3e12e14 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.d.ts
@@ -15,22 +15,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- define([
-  'angular',
-],
-function (angular) {
-  'use strict';
-  var module = angular.module('grafana.directives');
-
-  module.directive('metricQueryEditorAmbarimetrics', function() {
-    return {
-      controller: 'AmbariMetricsQueryCtrl',
-      templateUrl: 'app/plugins/datasource/ambari-metrics/partials/query.editor.html',
-    };
-  });
-
-  module.directive('metricQueryOptionsAmbarimetrics', function() {
-    return {templateUrl: 'app/plugins/datasource/ambari-metrics/partials/query.options.html'};
-  });
-
-});
+import { AmbariMetricsDatasource } from './datasource';
+import { AmbariMetricsQueryCtrl } from './query_ctrl';
+import { AmbariMetricsConfigCtrl } from './config_ctrl';
+export { AmbariMetricsDatasource as Datasource, AmbariMetricsQueryCtrl as QueryCtrl, AmbariMetricsConfigCtrl as ConfigCtrl };
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js
new file mode 100644
index 0000000..ebc4f8a
--- /dev/null
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js
@@ -0,0 +1,21 @@
+System.register(['./datasource', './query_ctrl', './config_ctrl'], function(exports_1) {
+    var datasource_1, query_ctrl_1, config_ctrl_1;
+    return {
+        setters:[
+            function (datasource_1_1) {
+                datasource_1 = datasource_1_1;
+            },
+            function (query_ctrl_1_1) {
+                query_ctrl_1 = query_ctrl_1_1;
+            },
+            function (config_ctrl_1_1) {
+                config_ctrl_1 = config_ctrl_1_1;
+            }],
+        execute: function() {
+            exports_1("Datasource", datasource_1.AmbariMetricsDatasource);
+            exports_1("QueryCtrl", query_ctrl_1.AmbariMetricsQueryCtrl);
+            exports_1("ConfigCtrl", config_ctrl_1.AmbariMetricsConfigCtrl);
+        }
+    }
+});
+//# sourceMappingURL=module.js.map
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js.map b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js.map
new file mode 100644
index 0000000..5bdb60e
--- /dev/null
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"module.js","sourceRoot":"","sources":["../../../../../public/app/plugins/datasource/ambari-metrics/module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;YAsB+B,6DAAU;YACX,2DAAS;YACR,8DAAU"}
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.ts
similarity index 61%
copy from ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
copy to ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.ts
index aade7d7..137e7c7 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.ts
@@ -15,22 +15,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- define([
-  'angular',
-],
-function (angular) {
-  'use strict';
-  var module = angular.module('grafana.directives');
+import {AmbariMetricsDatasource} from './datasource';
+import {AmbariMetricsQueryCtrl} from './query_ctrl';
+import {AmbariMetricsConfigCtrl} from './config_ctrl';
 
-  module.directive('metricQueryEditorAmbarimetrics', function() {
-    return {
-      controller: 'AmbariMetricsQueryCtrl',
-      templateUrl: 'app/plugins/datasource/ambari-metrics/partials/query.editor.html',
-    };
-  });
-
-  module.directive('metricQueryOptionsAmbarimetrics', function() {
-    return {templateUrl: 'app/plugins/datasource/ambari-metrics/partials/query.options.html'};
-  });
-
-});
+export {
+    AmbariMetricsDatasource as Datasource,
+    AmbariMetricsQueryCtrl as QueryCtrl,
+    AmbariMetricsConfigCtrl as ConfigCtrl
+};
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/annotations.editor.html b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/annotations.editor.html
new file mode 100644
index 0000000..e69de29
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/config.html b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/config.html
index 360c15c..d4ad4b3 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/config.html
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/config.html
@@ -15,5 +15,4 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<div ng-include="httpConfigPartialSrc"></div>
-<br>
+<datasource-http-settings current="ctrl.current"></datasource-http-settings>
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html
index 7e78cc0..e0f1461 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html
@@ -15,162 +15,98 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<div class="tight-form">
-    <ul class="tight-form-list pull-right">
-        <li class="tight-form-item small" ng-show="target.datasource">
-            <em>{{target.datasource}}</em>
-        </li>
-        <li class="tight-form-item">
-            <div class="dropdown">
-                <a class="pointer dropdown-toggle" data-toggle="dropdown" tabindex="1">
-                    <i class="fa fa-bars"></i>
-                </a>
-                <ul class="dropdown-menu pull-right" role="menu">
-                    <li role="menuitem"><a tabindex="1" ng-click="toggleQueryMode()">Switch editor mode</a></li>
-                    <li role="menuitem"><a tabindex="1" ng-click="duplicateDataQuery(target)">Duplicate</a></li>
-                    <li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index-1)">Move up</a></li>
-                    <li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index+1)">Move down</a></li>
-                </ul>
-            </div>
-        </li>
-        <li class="tight-form-item last">
-            <a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
-                <i class="fa fa-remove"></i>
-            </a>
-        </li>
-    </ul>
+<query-editor-row query-ctrl="ctrl" can-collapse="true">
+	<div class="gf-form-inline">
+		<div class="gf-form max-width-25">
+    		<label class="gf-form-label query-keyword width-8">
+        		Component
+    		</label>
+        	<input type="text" class="gf-form-input" ng-model="ctrl.target.app"
+               spellcheck='false' bs-typeahead="ctrl.suggestApps" placeholder="Component Name" data-min-length=0 data-items=100
+               ng-blur="ctrl.targetBlur()">
+        	</input>
+    </div>
 
-    <ul class="tight-form-list">
-        <li class="tight-form-item" style="min-width: 15px; text-align: center">
-            {{target.refId}}
-        </li>
-        <li>
-            <a  class="tight-form-item"
-                ng-click="target.hide = !target.hide; get_data();"
-                role="menuitem">
-                <i class="fa fa-eye"></i>
-            </a>
-        </li>
-    </ul>
+    <div class="gf-form">
+    	<label class="gf-form-label query-keyword width-8">
+        	Metric
+    	</label>
+        <input type="text" class="input-large gf-form-input" ng-model="ctrl.target.metric"
+               spellcheck='false' bs-typeahead="ctrl.suggestMetrics" placeholder="metric name" data-min-length=0 data-items=100
+               ng-blur="ctrl.targetBlur()">
+        </input>
+        <a bs-tooltip="ctrl.target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="ctrl.target.errors.metric">
+            <i class="fa fa-warning"></i>
+        </a>
+    </div>
 
-    <ul class="tight-form-list" role="menu">
 
-        <li class="tight-form-item" style="width: 86px">
-        Component
-    </li>
-        <li>
-            <input type="text" class="input-large tight-form-input" ng-model="target.app"
-                   spellcheck='false' bs-typeahead="suggestApps" placeholder="Component Name" data-min-length=0 data-items=100
-                   ng-blur="targetBlur()">
-            </input>
-            <a bs-tooltip="target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="target.errors.metric">
-                <i class="fa fa-warning"></i>
-            </a>
-        </li>
+    <div class="gf-form">
+    	<label class="gf-form-label query-keyword width-8">
+        Hosts
+    	</label>
+    
+        <input type="text" class="input-large gf-form-input" ng-model="ctrl.target.hosts"
+               spellcheck='false' bs-typeahead="ctrl.suggestHosts" placeholder="host name" data-min-length=0 data-items=100
+               ng-blur="ctrl.targetBlur()">
+        </input>
+        <a bs-tooltip="ctrl.target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="ctrl.target.errors.metric">
+            <i class="fa fa-warning"></i>
+        </a>
+    </div>
 
-        <li class="tight-form-item" style="width: 86px">
-            Metric
-        </li>
-        <li>
-            <input type="text" class="input-large tight-form-input" ng-model="target.metric"
-                   spellcheck='false' bs-typeahead="suggestMetrics" placeholder="metric name" data-min-length=0 data-items=100
-                   ng-blur="targetBlur()">
-            </input>
-            <a bs-tooltip="target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="target.errors.metric">
-                <i class="fa fa-warning"></i>
-            </a>
-        </li>
+    <div class="gf-form">
+    	<label class="gf-form-label query-keyword width-8">
+        Aggregator
+    	</label>
+        <select ng-model="ctrl.target.aggregator" class="gf-form-input input-small"
+                ng-options="agg for agg in ctrl.aggregators"
+                ng-change="ctrl.targetBlur()">
+        </select>
+        <a bs-tooltip="ctrl.target.errors.aggregator" style="color: rgb(229, 189, 28)" ng-show="ctrl.target.errors.aggregator">
+            <i class="fa fa-warning"></i>
+        </a>
+    </div>
 
-        <li class="tight-form-item" style="width: 86px" ng-hide="dashboard.templating.list.length > 0">
-            Cluster
-        </li>
-        <li ng-hide="dashboard.templating.list.length > 0">
-            <input type="text" class="input-large tight-form-input" ng-model="target.cluster"
-                   spellcheck='false' bs-typeahead="suggestClusters" placeholder="cluster name" data-min-length=0 data-items=100
-                   ng-blur="targetBlur()">
-            </input>
-            <a bs-tooltip="target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="target.errors.metric">
-                <i class="fa fa-warning"></i>
-            </a>
-        </li>
-
-        <li class="tight-form-item" style="width: 86px" ng-hide="dashboard.templating.list.length > 0">
-            Hosts
-        </li>
-        <li ng-hide="dashboard.templating.list.length > 0">
-            <input type="text" class="input-large tight-form-input" ng-model="target.hosts"
-                   spellcheck='false' bs-typeahead="suggestHosts" placeholder="host name" data-min-length=0 data-items=100
-                   ng-blur="targetBlur()">
-            </input>
-            <a bs-tooltip="target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="target.errors.metric">
-                <i class="fa fa-warning"></i>
-            </a>
-        </li>
+	</div>
+	<div class="gf-form-inline">
 
-        <li class="tight-form-item">
-            Aggregator
-        </li>
-        <li>
-            <select ng-model="target.aggregator" class="tight-form-input input-small"
-                    ng-options="agg for agg in aggregators"
-                    ng-change="targetBlur()">
-            </select>
-            <a bs-tooltip="target.errors.aggregator" style="color: rgb(229, 189, 28)" ng-show="target.errors.aggregator">
-                <i class="fa fa-warning"></i>
-            </a>
-        </li>
-
-    </ul>
-
-    <div class="clearfix"></div>
-</div>
-
-<div class="tight-form">
-    <ul class="tight-form-list" role="menu">
-        <li class="tight-form-item tight-form-align" style="width: 86px">
+    <div class="gf-form">
+    	<label class="gf-form-label query-keyword width-8">
             Alias
-        </li>
-        <li>
-            <input type="text" class="tight-form-input input-large"
-                   ng-model="target.alias"
+        </label>
+            <input type="text" class="gf-form-input input-large"
+                   ng-model="ctrl.target.alias"
                    spellcheck='false'
                    placeholder="series alias"
                    data-min-length=0 data-items=100
-                   ng-blur="targetBlur()"></input>
-            <a bs-tooltip="target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="target.errors.metric">
+                   ng-blur="ctrl.targetBlur()"></input>
+            <a bs-tooltip="ctrl.target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="ctrl.target.errors.metric">
                 <i class="fa fa-warning"></i>
             </a>
-        </li>
-        <li class="tight-form-item tight-form-align">
-           Transform
-        </li>
-        <li>
-            <select ng-model="target.transform" class="tight-form-input input-small"
-                    ng-options="transform for transform in transforms"
-                    ng-init="transform()"
-                    ng-change="targetBlur()"></select>
-        </li>
+    </div>
+    
+    <div class="gf-form">
+    	<label class="gf-form-label query-keyword width-8">
+            Transform
+        </label>
+            <select ng-model="ctrl.target.transform" class="gf-form-input input-small"
+                    ng-options="transform for transform in ctrl.transforms"
+                    ng-init="ctrl.transform()"
+                    ng-change="ctrl.targetBlur()"></select>
+    </div>
 
-        <li class="tight-form-item tight-form-align">
-            Precision
-        </li>
-        <li>
-            <select ng-model="target.precision" class="tight-form-input input-small"
-                    ng-options="precision for precision in precisions"
-                    ng-init="precisionInit()"
-                    ng-change="targetBlur()">
-            </select>
-        </li>
 
-        <li class="tight-form-item">
-            Series Aggregator
-        </li>
-        <li>
-            <select ng-model="target.seriesAggregator" class="tight-form-input input-small"
-                    ng-options="seriesAggregator for seriesAggregator in seriesAggregators"
-                    ng-init="seriesAggregator()"
-                    ng-change="targetBlur()">
+    <div class="gf-form">
+    	<label class="gf-form-label query-keyword width-8">
+            Precision
+        </label>
+            <select ng-model="ctrl.target.precision" class="gf-form-input input-small"
+                    ng-options="precision for precision in ctrl.precisions"
+                    ng-init="ctrl.precisionInit()"
+                    ng-change="ctrl.targetBlur()">
             </select>
-        </li>
-    <div class="clearfix"></div>
+    </div>
+        <div class="clearfix"></div>
 </div>
+</query-editor-row>
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.options.html b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.options.html
deleted file mode 100644
index e58ca64..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.options.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one
-  ~ or more contributor license agreements.  See the NOTICE file
-  ~ distributed with this work for additional information
-  ~ regarding copyright ownership.  The ASF licenses this file
-  ~ to you under the Apache License, Version 2.0 (the
-  ~ "License"); you may not use this file except in compliance
-  ~ with the License.  You may obtain a copy of the License at
-  ~
-  ~     http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<section class="grafana-metric-options">
-	<div class="tight-form last">
-		<ul class="tight-form-list">
-			<li class="tight-form-item tight-form-item-icon">
-				<i class="fa fa-info-circle"></i>
-			</li>
-			<li class="tight-form-item">
-				<a ng-click="toggleEditorHelp(1);" bs-tooltip="'click to show helpful info'" data-placement="bottom">
-					Single Stats
-				</a>
-			</li>
-		</ul>
-		<div class="clearfix"></div>
-	</div>
-</section>
-
-<div class="editor-row">
-	<div class="pull-left" style="margin-top: 30px;">
-		<div class="grafana-info-box span6" ng-if="editorHelpIndex === 1">
-			<h5>Single Stats</h5>
-			<blockquote>To get the current value of the metric selected, Click on the <strong>Options</strong> tab above
-				and set the <strong>Big Value's</strong> value to <strong>"current"</strong>.</blockquote>
-		</div>
-	</div>
-</div>
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/plugin.json b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/plugin.json
index 5226ae7..643da57 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/plugin.json
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/plugin.json
@@ -1,14 +1,21 @@
 {
-  "pluginType": "datasource",
-  "name": "AmbariMetrics",
-
-  "type": "ambarimetrics",
-  "serviceName": "AmbariMetricsDatasource",
-
-  "module": "app/plugins/datasource/ambari-metrics/datasource",
-    "partials": {
-    "config": "app/plugins/datasource/ambari-metrics/partials/config.html"
+  "type": "datasource",
+  "name": "Ambari Metrics",
+  "id": "praj-ams-datasource",
+  "metrics": true,
+  "staticRoot": ".",
+  "defaultMatchFormat": "glob",
+  "info": {
+    "author": {
+      "name": "",
+      "url": ""
+    },
+    "links": [
+    ],
+    "logos": {
+      "small": "img/apache-ambari-logo-sm.png",
+      "large": "img/apache-ambari-logo.png"
+    },
+    "version": "1.0.1",
   },
-
-  "metrics": true
-}
\ No newline at end of file
+}
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/queryCtrl.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/queryCtrl.js
deleted file mode 100644
index 02b5813..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/queryCtrl.js
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-define([
-      'angular',
-      'lodash'
-    ],
-    function (angular, _) {
-      'use strict';
-
-      var module = angular.module('grafana.controllers');
-
-      module.controller('AmbariMetricsQueryCtrl', function($scope) {
-
-        $scope.init = function() {
-          $scope.target.errors = validateTarget($scope.target);
-          $scope.aggregators = ['none','avg', 'sum', 'min', 'max'];
-          $scope.precisions = ['default','seconds', 'minutes', 'hours', 'days'];
-          $scope.transforms = ['none','diff','rate'];
-          $scope.seriesAggregators = ['none', 'avg', 'sum', 'min', 'max'];
-
-          if (!$scope.target.aggregator) {
-            $scope.target.aggregator = 'avg';
-          }
-          $scope.precisionInit = function () {
-           if (typeof $scope.target.precision == 'undefined') {
-                $scope.target.precision = "default";
-           }
-          };
-          $scope.transform = function () {
-           if (typeof $scope.target.transform == 'undefined') {
-                $scope.target.transform = "none";
-           }
-          };
-          $scope.seriesAggregator = function () {
-           if (typeof $scope.target.seriesAggregator == 'undefined') {
-                $scope.target.seriesAggregator = "none";
-           }
-          };
-          $scope.$watch('target.app', function (newValue) {
-            if (newValue === '') {
-              $scope.target.metric = '';
-              $scope.target.hosts = '';
-              $scope.target.cluster = '';
-            }
-          });
-          if (!$scope.target.downsampleAggregator) {
-            $scope.target.downsampleAggregator = 'avg';
-          }
-
-          $scope.datasource.getAggregators().then(function(aggs) {
-            $scope.aggregators = aggs;
-          });
-        };
-
-        $scope.targetBlur = function() {
-          $scope.target.errors = validateTarget($scope.target);
-
-          // this does not work so good
-          if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
-            $scope.oldTarget = angular.copy($scope.target);
-            $scope.get_data();
-          }
-        };
-
-        $scope.getTextValues = function(metricFindResult) {
-          return _.map(metricFindResult, function(value) { return value.text; });
-        };
-
-        $scope.suggestApps = function(query, callback) {
-          $scope.datasource.suggestApps(query)
-            .then($scope.getTextValues)
-            .then(callback);
-        };
-
-        $scope.suggestClusters = function(query, callback) {
-          $scope.datasource.suggestClusters($scope.target.app)
-            .then($scope.getTextValues)
-            .then(callback);
-        };
-
-        $scope.suggestHosts = function(query, callback) {
-          $scope.datasource.suggestHosts($scope.target.app, $scope.target.cluster)
-            .then($scope.getTextValues)
-            .then(callback);
-        };
-
-        $scope.suggestMetrics = function(query, callback) {
-          $scope.datasource.suggestMetrics(query, $scope.target.app)
-            .then($scope.getTextValues)
-            .then(callback);
-        };
-
-        $scope.suggestTagKeys = function(query, callback) {
-          $scope.datasource.metricFindQuery('tag_names(' + $scope.target.metric + ')')
-              .then($scope.getTextValues)
-              .then(callback);
-        };
-
-        $scope.suggestTagValues = function(query, callback) {
-          $scope.datasource.metricFindQuery('tag_values(' + $scope.target.metric + ',' + $scope.target.currentTagKey + ')')
-              .then($scope.getTextValues)
-              .then(callback);
-        };
-
-        $scope.addTag = function() {
-          if (!$scope.addTagMode) {
-            $scope.addTagMode = true;
-            return;
-          }
-
-          if (!$scope.target.tags) {
-            $scope.target.tags = {};
-          }
-
-          $scope.target.errors = validateTarget($scope.target);
-
-          if (!$scope.target.errors.tags) {
-            $scope.target.tags[$scope.target.currentTagKey] = $scope.target.currentTagValue;
-            $scope.target.currentTagKey = '';
-            $scope.target.currentTagValue = '';
-            $scope.targetBlur();
-          }
-
-          $scope.addTagMode = false;
-        };
-
-        $scope.removeTag = function(key) {
-          delete $scope.target.tags[key];
-          $scope.targetBlur();
-        };
-
-        function validateTarget(target) {
-          var errs = {};
-
-          if (target.tags && _.has(target.tags, target.currentTagKey)) {
-            errs.tags = "Duplicate tag key '" + target.currentTagKey + "'.";
-          }
-
-          return errs;
-        }
-
-        $scope.init();
-      });
-
-    });
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.d.ts b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.d.ts
new file mode 100644
index 0000000..83363f7
--- /dev/null
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.d.ts
@@ -0,0 +1,21 @@
+/// <reference path="../../../../../public/app/headers/common.d.ts" />
+import { QueryCtrl } from 'app/plugins/sdk';
+export declare class AmbariMetricsQueryCtrl extends QueryCtrl {
+    static templateUrl: string;
+    aggregators: any;
+    aggregator: any;
+    errors: any;
+    precisions: any;
+    transforms: any;
+    transform: any;
+    precisionInit: any;
+    suggestMetrics: any;
+    suggestApps: any;
+    suggestHosts: any;
+    /** @ngInject **/
+    constructor($scope: any, $injector: any);
+    targetBlur(): void;
+    getTextValues(metricFindResult: any): any;
+    getCollapsedText(): string;
+    validateTarget(): any;
+}
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js
new file mode 100644
index 0000000..5b5c4a9
--- /dev/null
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js
@@ -0,0 +1,152 @@
+"use strict";
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = function (d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    }
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+exports.__esModule = true;
+///<reference path="../../../headers/common.d.ts" />
+var angular_1 = require("angular");
+var lodash_1 = require("lodash");
+var sdk_1 = require("app/plugins/sdk");
+var AmbariMetricsQueryCtrl = /** @class */ (function (_super) {
+    __extends(AmbariMetricsQueryCtrl, _super);
+    /** @ngInject **/
+    function AmbariMetricsQueryCtrl($scope, $injector) {
+        var _this = _super.call(this, $scope, $injector) || this;
+        _this.targetBlur = function () {
+            this.target.errors = this.validateTarget(this.target);
+            // this does not work so good
+            if (!lodash_1["default"].isEqual(this.oldTarget, this.target) && lodash_1["default"].isEmpty(this.target.errors)) {
+                this.oldTarget = angular_1["default"].copy(this.target);
+                this.get_data();
+            }
+        };
+        _this.getTextValues = function (metricFindResult) {
+            return lodash_1["default"].map(metricFindResult, function (value) { return value.text; });
+        };
+        _this.suggestApps = function (query, callback) {
+            this.datasource.suggestApps(query)
+                .then(this.getTextValues)
+                .then(callback);
+        };
+        _this.suggestClusters = function (query, callback) {
+            this.datasource.suggestClusters(this.target.app)
+                .then(this.getTextValues)
+                .then(callback);
+        };
+        _this.suggestHosts = function (query, callback) {
+            this.datasource.suggestHosts(this.target.app, this.target.cluster)
+                .then(this.getTextValues)
+                .then(callback);
+        };
+        _this.suggestMetrics = function (query, callback) {
+            this.datasource.suggestMetrics(query, this.target.app)
+                .then(this.getTextValues)
+                .then(callback);
+        };
+        _this.suggestTagKeys = function (query, callback) {
+            this.datasource.metricFindQuery('tag_names(' + this.target.metric + ')')
+                .then(this.getTextValues)
+                .then(callback);
+        };
+        _this.suggestTagValues = function (query, callback) {
+            this.datasource.metricFindQuery('tag_values(' + this.target.metric + ',' + this.target.currentTagKey + ')')
+                .then(this.getTextValues)
+                .then(callback);
+        };
+        _this.addTag = function () {
+            if (!this.addTagMode) {
+                this.addTagMode = true;
+                return;
+            }
+            if (!this.target.tags) {
+                this.target.tags = {};
+            }
+            this.target.errors = this.validateTarget(this.target);
+            if (!this.target.errors.tags) {
+                this.target.tags[this.target.currentTagKey] = this.target.currentTagValue;
+                this.target.currentTagKey = '';
+                this.target.currentTagValue = '';
+                this.targetBlur();
+            }
+            this.addTagMode = false;
+        };
+        _this.removeTag = function (key) {
+            delete this.target.tags[key];
+            this.targetBlur();
+        };
+        _this.validateTarget = function (target) {
+            var errs = {};
+            if (target.tags && lodash_1["default"].has(target.tags, target.currentTagKey)) {
+                errs.tags = "Duplicate tag key '" + target.currentTagKey + "'.";
+            }
+            return errs;
+        };
+        _this.errors = _this.validateTarget(_this.target);
+        _this.aggregators = ['none', 'avg', 'sum', 'min', 'max'];
+        _this.precisions = ['default', 'seconds', 'minutes', 'hours', 'days'];
+        _this.transforms = ['none', 'diff', 'rate'];
+        _this.seriesAggregators = ['none', 'avg', 'sum', 'min', 'max'];
+        if (!_this.target.aggregator) {
+            _this.target.aggregator = 'avg';
+        }
+        _this.precisionInit = function () {
+            if (typeof this.target.precision == 'undefined') {
+                this.target.precision = "default";
+            }
+        };
+        _this.transform = function () {
+            if (typeof this.target.transform == 'undefined') {
+                this.target.transform = "none";
+            }
+        };
+        _this.seriesAggregator = function () {
+            if (typeof $scope.target.seriesAggregator == 'undefined') {
+                this.target.seriesAggregator = "none";
+            }
+        };
+        _this.$watch('target.app', function (newValue) {
+            if (newValue === '') {
+                this.target.metric = '';
+                this.target.hosts = '';
+                this.target.cluster = '';
+            }
+        });
+        if (!_this.target.downsampleAggregator) {
+            _this.target.downsampleAggregator = 'avg';
+        }
+        _this.datasource.getAggregators().then(function (aggs) {
+            this.aggregators = aggs;
+        });
+        return _this;
+    }
+    AmbariMetricsQueryCtrl.templateUrl = 'partials/query.editor.html';
+    return AmbariMetricsQueryCtrl;
+}(sdk_1.QueryCtrl));
+exports.AmbariMetricsQueryCtrl = AmbariMetricsQueryCtrl;
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js.map b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js.map
new file mode 100644
index 0000000..2f80a63
--- /dev/null
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"query_ctrl.js","sourceRoot":"","sources":["../../../../../public/app/plugins/datasource/ambari-metrics/query_ctrl.ts"],"names":["AmbariMetricsQueryCtrl","AmbariMetricsQueryCtrl.constructor","AmbariMetricsQueryCtrl.targetBlur","AmbariMetricsQueryCtrl.getTextValues","AmbariMetricsQueryCtrl.getCollapsedText","AmbariMetricsQueryCtrl.validateTarget"],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,oDAAoD;;;;;;;;;;;;;;;;;;YAMpD;gBAA4CA,0CAASA;gBAajDA,iBAAiBA;gBACjBA,gCAAYA,MAAM [...]
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.ts b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.ts
new file mode 100644
index 0000000..70087b6
--- /dev/null
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.ts
@@ -0,0 +1,169 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+///<reference path="../../../headers/common.d.ts" />
+
+import angular from 'angular';
+import _ from 'lodash';
+import {QueryCtrl} from "app/plugins/sdk";
+
+export class AmbariMetricsQueryCtrl extends QueryCtrl {
+
+    static templateUrl = 'partials/query.editor.html';
+    aggregators: any;
+    aggregator: any;
+    errors: any;
+    precisions: any;
+    transforms: any;
+    transform: any;
+    precisionInit: any;
+    suggestMetrics: any;
+    suggestApps: any;
+    suggestHosts: any;
+    seriesAggregators: any;
+
+    /** @ngInject **/
+    constructor($scope, $injector) {
+        super($scope, $injector);
+        this.errors = this.validateTarget(this.target);
+        this.aggregators = ['none','avg', 'sum', 'min', 'max'];
+        this.precisions = ['default','seconds', 'minutes', 'hours', 'days'];
+        this.transforms = ['none','diff','rate'];
+        this.seriesAggregators = ['none', 'avg', 'sum', 'min', 'max'];
+
+        if (!this.target.aggregator) {
+            this.target.aggregator = 'avg';
+        }
+        this.precisionInit = function () {
+            if (typeof this.target.precision == 'undefined') {
+                this.target.precision = "default";
+            }
+        };
+        this.transform = function () {
+            if (typeof this.target.transform == 'undefined') {
+                this.target.transform = "none";
+            }
+        };
+        this.seriesAggregator = function () {
+            if (typeof $scope.target.seriesAggregator == 'undefined') {
+                this.target.seriesAggregator = "none";
+            }
+        };
+        this.$watch('target.app', function (newValue) {
+            if (newValue === '') {
+                this.target.metric = '';
+                this.target.hosts = '';
+                this.target.cluster = '';
+            }
+        });
+        if (!this.target.downsampleAggregator) {
+            this.target.downsampleAggregator = 'avg';
+        }
+
+        this.datasource.getAggregators().then(function(aggs) {
+            this.aggregators = aggs;
+        });
+    }
+
+    targetBlur = function() {
+        this.target.errors = this.validateTarget(this.target);
+
+        // this does not work so good
+        if (!_.isEqual(this.oldTarget, this.target) && _.isEmpty(this.target.errors)) {
+            this.oldTarget = angular.copy(this.target);
+            this.get_data();
+        }
+    };
+
+    getTextValues = function(metricFindResult) {
+        return _.map(metricFindResult, function(value) { return value.text; });
+    };
+
+    suggestApps = function(query, callback) {
+        this.datasource.suggestApps(query)
+            .then(this.getTextValues)
+            .then(callback);
+    };
+
+    suggestClusters = function(query, callback) {
+        this.datasource.suggestClusters(this.target.app)
+            .then(this.getTextValues)
+            .then(callback);
+    };
+
+    suggestHosts = function(query, callback) {
+        this.datasource.suggestHosts(this.target.app, this.target.cluster)
+            .then(this.getTextValues)
+            .then(callback);
+    };
+
+    suggestMetrics = function(query, callback) {
+        this.datasource.suggestMetrics(query, this.target.app)
+            .then(this.getTextValues)
+            .then(callback);
+    };
+
+    suggestTagKeys = function(query, callback) {
+        this.datasource.metricFindQuery('tag_names(' + this.target.metric + ')')
+            .then(this.getTextValues)
+            .then(callback);
+    };
+
+    suggestTagValues = function(query, callback) {
+        this.datasource.metricFindQuery('tag_values(' + this.target.metric + ',' + this.target.currentTagKey + ')')
+            .then(this.getTextValues)
+            .then(callback);
+    };
+
+    addTag = function() {
+        if (!this.addTagMode) {
+            this.addTagMode = true;
+            return;
+        }
+
+        if (!this.target.tags) {
+            this.target.tags = {};
+        }
+
+        this.target.errors = this.validateTarget(this.target);
+
+        if (!this.target.errors.tags) {
+            this.target.tags[this.target.currentTagKey] = this.target.currentTagValue;
+            this.target.currentTagKey = '';
+            this.target.currentTagValue = '';
+            this.targetBlur();
+        }
+
+        this.addTagMode = false;
+    };
+
+    removeTag = function(key) {
+        delete this.target.tags[key];
+        this.targetBlur();
+    };
+
+    validateTarget = function(target) {
+        var errs = {};
+
+        if (target.tags && _.has(target.tags, target.currentTagKey)) {
+            errs.tags = "Duplicate tag key '" + target.currentTagKey + "'.";
+        }
+
+        return errs;
+    }
+}


[ambari] 01/02: Revert "[AMBARI-24665] Migrating grafana plugin for 5.x use."

Posted by is...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ishanbha pushed a commit to branch branch-feature-AMBARI-23466
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit c11e713081a31a21dcb6d339b3e979f65da1ee38
Author: Ishan Bhatt <is...@gmail.com>
AuthorDate: Thu Sep 20 11:27:20 2018 -0700

    Revert "[AMBARI-24665] Migrating grafana plugin for 5.x use."
    
    This reverts commit 4dc1c063bd9e1429b53a2d4265745b87b46787d2.
---
 .../ambari-metrics/config_ctrl.d.ts                |    5 -
 .../ambari-metrics/config_ctrl.js                  |   34 -
 .../ambari-metrics/config_ctrl.js.map              |    1 -
 .../ambari-metrics/datasource.d.ts                 |   20 -
 .../ambari-metrics/datasource.js                   | 2066 +++++++++-----------
 .../ambari-metrics/directives.js                   |    1 -
 .../ambari-metrics/img/ams-screenshot.png          |  Bin 157579 -> 0 bytes
 .../ambari-metrics/img/apache-ambari-logo-sm.png   |  Bin 11354 -> 0 bytes
 .../ambari-metrics/img/apache-ambari-logo.png      |  Bin 25912 -> 0 bytes
 .../ambari-metrics/img/apache-ambari-project.png   |  Bin 17174 -> 0 bytes
 .../ambari-metrics/module.d.ts                     |   21 -
 .../ambari-metrics/module.js                       |   21 -
 .../ambari-metrics/module.js.map                   |    1 -
 .../ambari-metrics/module.ts                       |   26 -
 .../partials/annotations.editor.html               |    0
 .../ambari-metrics/partials/config.html            |    3 +-
 .../ambari-metrics/partials/query.editor.html      |  222 ++-
 .../ambari-metrics/partials/query.options.html     |   42 +
 .../ambari-metrics/plugin.json                     |   31 +-
 .../ambari-metrics/queryCtrl.js                    |  160 ++
 .../ambari-metrics/query_ctrl.d.ts                 |   21 -
 .../ambari-metrics/query_ctrl.js                   |  152 --
 .../ambari-metrics/query_ctrl.js.map               |    1 -
 .../ambari-metrics/query_ctrl.ts                   |  169 --
 24 files changed, 1330 insertions(+), 1667 deletions(-)

diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.d.ts b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.d.ts
deleted file mode 100644
index 33286c8..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.d.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-/// <reference path="../../../../../public/app/headers/common.d.ts" />
-export declare class AmbariMetricsConfigCtrl {
-    static templateUrl: string;
-    current: any;
-}
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js
deleted file mode 100644
index 84244ed..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js
+++ /dev/null
@@ -1,34 +0,0 @@
-///<reference path="../../../headers/common.d.ts" />
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-System.register([], function(exports_1) {
-    var AmbariMetricsConfigCtrl;
-    return {
-        setters:[],
-        execute: function() {
-            AmbariMetricsConfigCtrl = (function () {
-                function AmbariMetricsConfigCtrl() {
-                }
-                AmbariMetricsConfigCtrl.templateUrl = 'partials/config.html';
-                return AmbariMetricsConfigCtrl;
-            })();
-            exports_1("AmbariMetricsConfigCtrl", AmbariMetricsConfigCtrl);
-        }
-    }
-});
-//# sourceMappingURL=config_ctrl.js.map
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js.map b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js.map
deleted file mode 100644
index 8c46be5..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/config_ctrl.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"config_ctrl.js","sourceRoot":"","sources":["../../../../../public/app/plugins/datasource/ambari-metrics/config_ctrl.ts"],"names":["AmbariMetricsConfigCtrl","AmbariMetricsConfigCtrl.constructor"],"mappings":"AAAA,oDAAoD;AACpD;;;;;;;;;;;;;;;;GAgBG;;;;;;YAKH;gBAAAA;gBAGAC,CAACA;gBAFUD,mCAAWA,GAAGA,sBAAsBA,CAACA;gBAEhDA,8BAACA;YAADA,CAACA,AAHD,IAGC;YAHD,6DAGC,CAAA"}
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.d.ts b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.d.ts
deleted file mode 100644
index 8bab98c..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.d.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-declare var AmbariMetricsDatasource: any;
-export {AmbariMetricsDatasource};
-
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js
index e34a1af..e7cd850 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/datasource.js
@@ -16,1201 +16,1077 @@
  * limitations under the License.
  */
 define([
-    'angular',
-    'lodash',
-    'jquery',
-    //'./directives',
-    './query_ctrl'
-  ],
-  function (angular, _) {
-    'use strict';
+      'angular',
+      'lodash',
+      'jquery',
+      './directives',
+      './queryCtrl'
+    ],
+    function (angular, _) {
+      'use strict';
 
+      var module = angular.module('grafana.services');
 
-    /**
-     * AMS Datasource Constructor
-     */
-    function AmbariMetricsDatasource(instanceSettings, $q, backendSrv, templateSrv) {
-      this.type = 'ambari-metrics';
-      this.name = instanceSettings.name;
-      this.url = instanceSettings.url;
-      this.withCredentials = instanceSettings.withCredentials;
-      this.basicAuth = instanceSettings.basicAuth;
-
-      var allMetrics = {};
-      var appIds = [];
-
-      /**
-       * AMS Datasource  Authentication
-       */
-      this.doAmbariRequest = function (options) {
-        if (this.basicAuth || this.withCredentials) {
-          options.withCredentials = true;
-        }
-        if (this.basicAuth) {
-          options.headers = options.headers || {};
-          options.headers.Authorization = this.basicAuth;
+      module.factory('AmbariMetricsDatasource', function ($q, backendSrv, templateSrv) {
+        /**
+         * AMS Datasource Constructor
+         */
+        function AmbariMetricsDatasource(datasource) {
+          this.name = datasource.name;
+          this.url = datasource.url;
+          this.initMetricAppidMapping();
         }
+        var allMetrics = {};
+        var appIds = [];
 
-        options.url = this.url + options.url;
-        options.inspect = {type: 'ambarimetrics'};
-
-        return backendSrv.datasourceRequest(options);
-      };
-
-      //We get a list of components and their associated metrics.
-      this.initMetricAppidMapping = function () {
-        return this.doAmbariRequest({url: '/ws/v1/timeline/metrics/metadata'})
-          .then(function (items) {
-            items = items.data;
-            allMetrics = {};
-            appIds = [];
-            _.forEach(items, function (metric, app) {
-              metric.forEach(function (component) {
-                if (!allMetrics[app]) {
-                  allMetrics[app] = [];
-                }
-                allMetrics[app].push(component.metricname);
+        //We get a list of components and their associated metrics.
+        AmbariMetricsDatasource.prototype.initMetricAppidMapping = function () {
+          return this.doAmbariRequest({ url: '/ws/v1/timeline/metrics/metadata' })
+            .then(function (items) {
+              items = items.data;
+              allMetrics = {};
+              appIds = [];
+              _.forEach(items, function (metric,app) {
+                metric.forEach(function (component) {
+                  if (!allMetrics[app]) {
+                    allMetrics[app] = [];
+                  }
+                  allMetrics[app].push(component.metricname);
+                });
               });
+              //We remove a couple of components from the list that do not contain any
+              //pertinent metrics.
+              delete allMetrics["timeline_metric_store_watcher"];
+              delete allMetrics["amssmoketestfake"];
+              appIds = Object.keys(allMetrics);
             });
-            //We remove a couple of components from the list that do not contain any
-            //pertinent metrics.
-            delete allMetrics["timeline_metric_store_watcher"];
-            delete allMetrics["amssmoketestfake"];
-            appIds = Object.keys(allMetrics);
-          });
-      };
-      this.initMetricAppidMapping();
+        };
 
+        /**
+         * AMS Datasource  Authentication
+         */
+        AmbariMetricsDatasource.prototype.doAmbariRequest = function (options) {
+          if (this.basicAuth || this.withCredentials) {
+            options.withCredentials = true;
+          }
+          if (this.basicAuth) {
+            options.headers = options.headers || {};
+            options.headers.Authorization = this.basicAuth;
+          }
 
+          options.url = this.url + options.url;
+          options.inspect = {type: 'ambarimetrics'};
 
-      /**
-       * AMS Datasource  Query
-       */
-      this.query = function (options) {
-        var emptyData = function (metric) {
-          var legend = metric.alias ? metric.alias : metric.metric;
-          return {
-            data: {
-              target: legend,
-              datapoints: []
-            }
-          };
+          return backendSrv.datasourceRequest(options);
         };
-        var self = this;
-        var getMetricsData = function (target) {
-          var alias = target.alias ? target.alias : target.metric;
-          if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "yarnqueues") {
-            alias = alias + ' on ' + target.qmetric;
-          }
-          if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "kafka-topics") {
-            alias = alias + ' on ' + target.kbTopic;
-          }
-          return function (res) {
-            res = res.data;
-            console.log('processing metric ' + target.metric);
-            if (!res.metrics[0] || target.hide) {
-              return $q.when(emptyData(target));
-            }
-            var series = [];
-            var metricData = res.metrics[0].metrics;
-            // Added hostname to legend for templated dashboards.
-            var hostLegend = res.metrics[0].hostname ? ' on ' + res.metrics[0].hostname : '';
-            var timeSeries = {};
-            timeSeries = {
-              target: alias + hostLegend,
-              datapoints: []
+
+        /**
+         * AMS Datasource  Query
+         */
+        AmbariMetricsDatasource.prototype.query = function (options) {
+          var emptyData = function (metric) {
+            var legend = metric.alias ? metric.alias : metric.metric;
+            return {
+              data: {
+                target: legend,
+                datapoints: []
+              }
             };
-            for (var k in metricData) {
-              if (metricData.hasOwnProperty(k)) {
-                timeSeries.datapoints.push([metricData[k], (k - k % 1000)]);
+          };
+          var self = this;
+          var getMetricsData = function (target) {
+            var alias = target.alias ? target.alias : target.metric;
+            if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "yarnqueues") {
+              alias = alias + ' on ' + target.qmetric; }
+            if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "kafka-topics") {
+            alias = alias + ' on ' + target.kbTopic; }
+            return function (res) {
+              res = res.data;
+              console.log('processing metric ' + target.metric);
+              if (!res.metrics[0] || target.hide) {
+                return $q.when(emptyData(target));
               }
-            }
-            series.push(timeSeries);
-            return $q.when({data: series});
+              var series = [];
+              var metricData = res.metrics[0].metrics;
+              // Added hostname to legend for templated dashboards.
+              var hostLegend = res.metrics[0].hostname ? ' on ' + res.metrics[0].hostname : '';
+              var timeSeries = {};
+              timeSeries = {
+                target: alias + hostLegend,
+                datapoints: []
+              };
+              for (var k in metricData){
+                if (metricData.hasOwnProperty(k)) {
+                  timeSeries.datapoints.push([metricData[k], (k - k % 1000)]);
+                }
+              }
+              series.push(timeSeries);
+              return $q.when({data: series});
+            };
           };
-        };
-        // To speed up querying on templatized dashboards.
-        var allHostMetricsData = function (target) {
-          var alias = target.alias ? target.alias : target.metric;
-          if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "hbase-users") {
-            alias = alias + ' for ' + target.hbUser;
-          }
-          // Aliases for Storm Topologies and components under a topology.
-          if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "topologies" &&
+          // To speed up querying on templatized dashboards.
+          var allHostMetricsData = function (target) {
+            var alias = target.alias ? target.alias : target.metric;
+            if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "hbase-users") {
+            alias = alias + ' for ' + target.hbUser; }
+            // Aliases for Storm Topologies and components under a topology.
+            if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "topologies" &&
             !templateSrv.variables[1]) {
-            alias = alias + ' on ' + target.sTopology;
-          }
-          if (!_.isEmpty(templateSrv.variables[1]) && templateSrv.variables[1].name === "component") {
-            alias = alias + ' on ' + target.sTopology + ' for ' + target.sComponent;
-          }
+              alias = alias + ' on ' + target.sTopology;
+            }
+            if(!_.isEmpty(templateSrv.variables[1]) && templateSrv.variables[1].name === "component") {
+              alias = alias + ' on ' + target.sTopology + ' for ' + target.sComponent;
+            }
 
-          // Aliases for Druid Datasources.
-          if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "druidDataSources" &&
-            !templateSrv.variables[1]) {
-            alias = alias.replace('$druidDataSource', target.sDataSource);
-          }
-          return function (res) {
-            res = res.data;
-            console.log('processing metric ' + target.metric);
-            if (!res.metrics[0] || target.hide) {
-              return $q.when(emptyData(target));
+            // Aliases for Druid Datasources.
+            if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "druidDataSources" &&
+                        !templateSrv.variables[1]) {
+              alias = alias.replace('$druidDataSource', target.sDataSource);
             }
-            var series = [];
-            var timeSeries = {};
-            var metricData = res.metrics;
-            _.map(metricData, function (data) {
-              var totalCountFlag = false;
-              var aliasSuffix = data.hostname ? ' on ' + data.hostname : '';
-              var op = '';
-              var user = '';
-              if (!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "hbase-tables") {
-                var tableName = "Tables.";
-                var tableSuffix = data.metricname.substring(data.metricname.indexOf(tableName) + tableName.length,
-                  data.metricname.lastIndexOf("_metric"));
-                aliasSuffix = ' on ' + tableSuffix;
+            return function (res) {
+              res = res.data;
+              console.log('processing metric ' + target.metric);
+              if (!res.metrics[0] || target.hide) {
+                return $q.when(emptyData(target));
               }
-              if (templateSrv.variables[0].query === "callers") {
-                alias = data.metricname.substring(data.metricname.indexOf('(') + 1, data.metricname.indexOf(')'));
-              }
-              // Set legend and alias for HDFS - TopN dashboard
-              if (data.metricname.indexOf('dfs.NNTopUserOpCounts') === 0) {
-                var metricname_arr = data.metricname.split(".");
-                _.map(metricname_arr, function (segment) {
-                  if (segment.indexOf('op=') === 0) {
-                    var opKey = 'op=';
-                    op = segment.substring(segment.indexOf(opKey) + opKey.length);
-                  } else if (segment.indexOf('user=') === 0) {
-                    var userKey = 'user=';
-                    user = segment.substring(segment.indexOf(userKey) + userKey.length);
-                  }
-                });
-                // Check if metric is TotalCount
-                if (data.metricname.indexOf('TotalCount') > 0) {
-                  totalCountFlag = true;
-                  if (op !== '*') {
-                    alias = op;
+              var series = [];
+              var timeSeries = {};
+              var metricData = res.metrics;
+              _.map(metricData, function (data) {
+                var totalCountFlag = false;
+                var aliasSuffix = data.hostname ? ' on ' + data.hostname : '';
+                var op = '';
+                var user = '';
+                if(!_.isEmpty(templateSrv.variables) && templateSrv.variables[0].query === "hbase-tables") {
+                  var tableName = "Tables.";
+                  var tableSuffix = data.metricname.substring(data.metricname.indexOf(tableName) + tableName.length,
+                  data.metricname.lastIndexOf("_metric"));
+                  aliasSuffix = ' on ' + tableSuffix;
+                }
+                if(templateSrv.variables[0].query === "callers") {
+                  alias = data.metricname.substring(data.metricname.indexOf('(')+1, data.metricname.indexOf(')'));
+                }
+                // Set legend and alias for HDFS - TopN dashboard
+                if(data.metricname.indexOf('dfs.NNTopUserOpCounts') === 0) {
+                  var metricname_arr = data.metricname.split(".");
+                  _.map(metricname_arr, function (segment) {
+                    if(segment.indexOf('op=') === 0) {
+                      var opKey = 'op=';
+                      op = segment.substring(segment.indexOf(opKey) + opKey.length);
+                    } else if(segment.indexOf('user=') === 0) {
+                      var userKey = 'user=';
+                      user = segment.substring(segment.indexOf(userKey) + userKey.length);
+                    }
+                  });
+                  // Check if metric is TotalCount
+                  if(data.metricname.indexOf('TotalCount') > 0) {
+                    totalCountFlag = true;
+                    if (op !== '*') {
+                      alias = op;
+                    } else {
+                      alias = 'Total Count';
+                    }
+                  } else if (op !== '*') {
+                    alias = op + ' by ' + user;
                   } else {
-                    alias = 'Total Count';
+                    alias = user;
                   }
-                } else if (op !== '*') {
-                  alias = op + ' by ' + user;
-                } else {
-                  alias = user;
+                  aliasSuffix = '';
                 }
-                aliasSuffix = '';
-              }
-              if (data.appid.indexOf('ambari_server') === 0) {
-                alias = data.metricname;
-                aliasSuffix = '';
-              }
-              timeSeries = {
-                target: alias + aliasSuffix,
-                datapoints: []
-              };
-              for (var k in data.metrics) {
-                if (data.metrics.hasOwnProperty(k)) {
-                  timeSeries.datapoints.push([data.metrics[k], (k - k % 1000)]);
+                if (data.appid.indexOf('ambari_server') === 0) {
+                  alias = data.metricname;
+                  aliasSuffix = '';
                 }
-              }
-              if ((user !== '*') || (totalCountFlag)) {
-                series.push(timeSeries);
-              }
-            });
-            return $q.when({data: series});
+                timeSeries = {
+                  target: alias + aliasSuffix,
+                  datapoints: []
+                };
+                for (var k in data.metrics){
+                  if (data.metrics.hasOwnProperty(k)) {
+                    timeSeries.datapoints.push([data.metrics[k], (k - k % 1000)]);
+                  }
+                }
+                if( (user !== '*') || (totalCountFlag) ) {
+                  series.push(timeSeries);
+                }
+              });
+              return $q.when({data: series});
+            };
           };
-        };
-        var getHostAppIdData = function (target) {
-          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
+          var getHostAppIdData = function(target) {
+            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision=' 
             + target.precision;
-          var instanceId = typeof target.cluster == 'undefined' ? '' : '&instanceId=' + target.cluster;
-          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-          return self.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform +
+            var instanceId = typeof target.cluster == 'undefined'  ? '' : '&instanceId=' + target.cluster;
+            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform +
             metricAggregator + "&hostname=" + target.hosts + '&appId=' + target.app + instanceId + '&startTime=' + from +
-            '&endTime=' + to + precision + seriesAggregator
-          }).then(
-            getMetricsData(target)
-          );
-        };
-        //Check if it's a templated dashboard.
-        var templatedClusters = templateSrv.variables.filter(function (o) {
-          return o.name === "cluster"
-        });
-        var templatedCluster = (_.isEmpty(templatedClusters)) ? '' : templatedClusters[0].options.filter(function (cluster) {
-          return cluster.selected;
-        }).map(function (clusterName) {
-          return clusterName.value;
-        });
+            '&endTime=' + to + precision + seriesAggregator }).then(
+              getMetricsData(target)
+            );
+          };
+          //Check if it's a templated dashboard.
+          var templatedClusters = templateSrv.variables.filter(function(o) { return o.name === "cluster"});
+          var templatedCluster = (_.isEmpty(templatedClusters)) ? '' : templatedClusters[0].options.filter(function(cluster)
+            { return cluster.selected; }).map(function(clusterName) { return clusterName.value; });
 
-        var templatedHosts = templateSrv.variables.filter(function (o) {
-          return o.name === "hosts"
-        });
-        var templatedHost = (_.isEmpty(templatedHosts)) ? '' : templatedHosts[0].options.filter(function (host) {
-          return host.selected;
-        }).map(function (hostName) {
-          return hostName.value;
-        });
+          var templatedHosts = templateSrv.variables.filter(function(o) { return o.name === "hosts"});
+          var templatedHost = (_.isEmpty(templatedHosts)) ? '' : templatedHosts[0].options.filter(function(host)
+            { return host.selected; }).map(function(hostName) { return hostName.value; });
 
-        var tComponents = _.isEmpty(templateSrv.variables) ? '' : templateSrv.variables.filter(function (variable) {
-          return variable.name === "components"
-        });
-        var tComponent = _.isEmpty(tComponents) ? '' : tComponents[0].current.value;
+          var tComponents = _.isEmpty(templateSrv.variables) ? '' : templateSrv.variables.filter(function(variable)
+            { return variable.name === "components"});
+          var tComponent = _.isEmpty(tComponents) ? '' : tComponents[0].current.value;
 
-        var getServiceAppIdData = function (target) {
-          var tCluster = (_.isEmpty(templateSrv.variables)) ? templatedCluster : '';
-          var instanceId = typeof tCluster == 'undefined' ? '' : '&instanceId=' + tCluster;
-          var tHost = (_.isEmpty(templateSrv.variables)) ? templatedHost : target.templatedHost;
-          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
+          var getServiceAppIdData = function(target) {
+            var tCluster = (_.isEmpty(templateSrv.variables))? templatedCluster : '';
+            var instanceId = typeof tCluster == 'undefined'  ? '' : '&instanceId=' + tCluster;
+            var tHost = (_.isEmpty(templateSrv.variables)) ? templatedHost : target.templatedHost;
+            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
             + target.precision;
-          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-          return self.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform
-            + metricAggregator + '&hostname=' + tHost + '&appId=' + target.app + instanceId + '&startTime=' + from +
-            '&endTime=' + to + precision + seriesAggregator
-          }).then(
-            getMetricsData(target)
-          );
-        };
-        // To speed up querying on templatized dashboards.
-        var getAllHostData = function (target) {
-          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
-          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
+            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform
+              + metricAggregator + '&hostname=' + tHost + '&appId=' + target.app + instanceId + '&startTime=' + from +
+              '&endTime=' + to + precision + seriesAggregator }).then(
+              getMetricsData(target)
+            );
+          };
+          // To speed up querying on templatized dashboards.
+          var getAllHostData = function(target) {
+            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
+            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
             + target.precision;
-          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-          var topN = "";
-          var isBottomN = "";
-          if (!_.isEmpty(templateSrv.variables.filter(function (o) {
-            return o.name === "instances";
-          }))) {
-            var metricTopN = _.filter(templateSrv.variables, function (o) {
-              return o.name === "instances";
-            });
-            var metricTopAgg = _.filter(templateSrv.variables, function (o) {
-              return o.name === "topagg";
-            });
-            isBottomN = templateSrv.variables.filter(function (o) {
-              return o.name === "orientation";
-            })[0].current.value
-            === "bottom" ? true : false;
-            topN = '&topN=' + metricTopN[0].current.value + '&topNFunction=' + metricTopAgg[0].current.value + '&isBottomN=' + isBottomN;
-          }
-          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-          var templatedComponent = (_.isEmpty(tComponent)) ? target.app : tComponent;
-          return self.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform
-            + metricAggregator + '&hostname=' + target.templatedHost + '&appId=' + templatedComponent + instanceId
-            + '&startTime=' + from + '&endTime=' + to + precision + topN + seriesAggregator
-          }).then(
-            allHostMetricsData(target)
-          );
-        };
-        var getYarnAppIdData = function (target) {
-          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
+            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+            var topN = ""; var isBottomN = "";
+            if (!_.isEmpty(templateSrv.variables.filter(function(o) { return o.name === "instances";}))) {
+              var metricTopN = _.filter(templateSrv.variables, function (o) { return o.name === "instances"; });
+              var metricTopAgg = _.filter(templateSrv.variables, function (o) { return o.name === "topagg"; });
+              isBottomN = templateSrv.variables.filter(function(o) { return o.name === "orientation";})[0].current.value
+              === "bottom" ? true : false;
+              topN = '&topN=' + metricTopN[0].current.value  +'&topNFunction=' + metricTopAgg[0].current.value  + '&isBottomN='+ isBottomN;
+            }
+            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+            var templatedComponent = (_.isEmpty(tComponent)) ? target.app : tComponent;
+            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.metric + metricTransform
+              + metricAggregator + '&hostname=' + target.templatedHost + '&appId=' + templatedComponent + instanceId
+              + '&startTime=' + from + '&endTime=' + to + precision + topN + seriesAggregator }).then(
+              allHostMetricsData(target)
+            );
+          };
+          var getYarnAppIdData = function(target) {
+            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
             + target.precision;
-          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
-          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-          return self.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics?metricNames=' + encodeURIComponent(target.queue) + metricTransform
-            + metricAggregator + '&appId=resourcemanager' + instanceId + '&startTime=' + from +
-            '&endTime=' + to + precision + seriesAggregator
-          }).then(
-            getMetricsData(target)
-          );
-        };
-        var getHbaseAppIdData = function (target) {
-          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
-          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
+            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
+            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + encodeURIComponent(target.queue) + metricTransform
+              + metricAggregator + '&appId=resourcemanager' + instanceId + '&startTime=' + from +
+              '&endTime=' + to + precision + seriesAggregator }).then(
+              getMetricsData(target)
+            );
+          };
+          var getHbaseAppIdData = function(target) {
+              var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
+              var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
             + target.precision;
-          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-          return self.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics?metricNames=' + target.hbMetric + instanceId + '&appId=hbase&startTime='
-            + from + '&endTime=' + to + precision + seriesAggregator
-          }).then(
-            allHostMetricsData(target)
-          );
-        };
-
-        var getKafkaAppIdData = function (target) {
-          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
+            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.hbMetric + instanceId + '&appId=hbase&startTime='
+            + from + '&endTime=' + to + precision + seriesAggregator }).then(
+              allHostMetricsData(target)
+            );
+          };
+          
+          var getKafkaAppIdData = function(target) {
+            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
             + target.precision;
-          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
-          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-          return self.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics?metricNames=' + target.kbMetric + metricTransform + instanceId
-            + metricAggregator + '&appId=kafka_broker&startTime=' + from +
-            '&endTime=' + to + precision + seriesAggregator
-          }).then(
-            getMetricsData(target)
-          );
-        };
-        var getNnAppIdData = function (target) {
+            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
+            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.kbMetric + metricTransform + instanceId
+              + metricAggregator + '&appId=kafka_broker&startTime=' + from +
+              '&endTime=' + to + precision + seriesAggregator }).then(
+              getMetricsData(target)
+            );
+          };
+          var getNnAppIdData = function(target) {
 
-          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
+            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
             + target.precision;
-          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
-          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-          return self.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics?metricNames=' + target.nnMetric + metricTransform + instanceId
-            + metricAggregator + '&appId=namenode&startTime=' + from + '&endTime=' + to + precision + seriesAggregator
-          }).then(
-            allHostMetricsData(target)
-          );
-        };
+            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
+            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.nnMetric + metricTransform + instanceId
+            + metricAggregator + '&appId=namenode&startTime=' + from + '&endTime=' + to + precision + seriesAggregator }).then(
+              allHostMetricsData(target)
+            );
+          };
 
-        // Storm Topology calls.
-        var getStormData = function (target) {
-          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
-          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
+          // Storm Topology calls.
+          var getStormData = function(target) {
+            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
+            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
             + target.precision;
-          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-          return self.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics?metricNames=' + target.sTopoMetric + metricTransform + instanceId
-            + metricAggregator + '&appId=nimbus&startTime=' + from + '&endTime=' + to + precision + seriesAggregator
-          }).then(
-            allHostMetricsData(target)
-          );
-        };
+            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.sTopoMetric + metricTransform + instanceId
+                + metricAggregator + '&appId=nimbus&startTime=' + from + '&endTime=' + to + precision + seriesAggregator }).then(
+                allHostMetricsData(target)
+            );
+          };
 
-        // Infra Solr Calls
-        var getSolrCoreData = function (target) {
-          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
-          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
-            + target.precision;
-          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-          return self.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics?metricNames=' + target.sCoreMetric + metricTransform + instanceId
-            + metricAggregator + '&appId=ambari-infra-solr&startTime=' + from + '&endTime=' + to + precision + seriesAggregator
-          }).then(
-            allHostMetricsData(target)
-          );
-        };
+            // Infra Solr Calls
+          var getSolrCoreData = function(target) {
+              var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
+              var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
+                  + target.precision;
+              var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+              var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+              var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+              return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.sCoreMetric + metricTransform + instanceId
+              + metricAggregator + '&appId=ambari-infra-solr&startTime=' + from + '&endTime=' + to + precision + seriesAggregator }).then(
+                  allHostMetricsData(target)
+              );
+          };
 
-        var getSolrCollectionData = function (target) {
-          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
-          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
-            + target.precision;
-          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-          return self.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics?metricNames=' + target.sCollectionMetric + metricTransform + instanceId
-            + metricAggregator + '&appId=ambari-infra-solr&startTime=' + from + '&endTime=' + to + precision + seriesAggregator
-          }).then(
-            allHostMetricsData(target)
-          );
-        };
+          var getSolrCollectionData = function(target) {
+              var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
+              var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
+                  + target.precision;
+              var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+              var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+              var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+              return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.sCollectionMetric + metricTransform + instanceId
+              + metricAggregator + '&appId=ambari-infra-solr&startTime=' + from + '&endTime=' + to + precision + seriesAggregator }).then(
+                  allHostMetricsData(target)
+              );
+          };
 
-        // Druid calls.
-        var getDruidData = function (target) {
-          var instanceId = typeof target.templatedCluster == 'undefined' ? '' : '&instanceId=' + target.templatedCluster;
-          var precision = target.precision === 'default' || typeof target.precision == 'undefined' ? '' : '&precision='
+          // Druid calls.
+          var getDruidData = function(target) {
+            var instanceId = typeof target.templatedCluster == 'undefined'  ? '' : '&instanceId=' + target.templatedCluster;
+            var precision = target.precision === 'default' || typeof target.precision == 'undefined'  ? '' : '&precision='
             + target.precision;
-          var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
-          var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-          var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
-          return self.doAmbariRequest({
-            url: '/ws/v1/timeline/metrics?metricNames=' + target.sDataSourceMetric + metricTransform + instanceId
-            + metricAggregator + '&appId=druid&startTime=' + from + '&endTime=' + to + precision + seriesAggregator
-          }).then(
-            allHostMetricsData(target)
-          );
-        };
+            var metricAggregator = target.aggregator === "none" ? '' : '._' + target.aggregator;
+            var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+            var seriesAggregator = !target.seriesAggregator || target.seriesAggregator === "none" ? '' : '&seriesAggregateFunction=' + target.seriesAggregator;
+            return self.doAmbariRequest({ url: '/ws/v1/timeline/metrics?metricNames=' + target.sDataSourceMetric + metricTransform + instanceId
+                          + metricAggregator + '&appId=druid&startTime=' + from + '&endTime=' + to + precision + seriesAggregator }).then(
+                          allHostMetricsData(target)
+            );
+          };
 
-        // Time Ranges
-        var from = Math.floor(options.range.from.valueOf() / 1000);
-        var to = Math.floor(options.range.to.valueOf() / 1000);
+          // Time Ranges
+          var from = Math.floor(options.range.from.valueOf() / 1000);
+          var to = Math.floor(options.range.to.valueOf() / 1000);
 
-        var metricsPromises = [];
-        if (!_.isEmpty(templateSrv.variables)) {
-          // YARN Queues Dashboard
-          if (templateSrv.variables[0].query === "yarnqueues") {
-            var allQueues = templateSrv.variables.filter(function (variable) {
-              return variable.query === "yarnqueues";
-            });
-            var selectedQs = (_.isEmpty(allQueues)) ? "" : allQueues[0].options.filter(function (q) {
-              return q.selected;
-            }).map(function (qName) {
-              return qName.value;
-            });
-            // All Queues
-            if (!_.isEmpty(_.find(selectedQs, function (wildcard) {
-              return wildcard === "*";
-            }))) {
-              var allQueue = allQueues[0].options.filter(function (q) {
-                return q.text !== "All";
-              }).map(function (queue) {
-                return queue.value;
-              });
-              _.forEach(allQueue, function (processQueue) {
-                metricsPromises.push(_.map(options.targets, function (target) {
-                  target.qmetric = processQueue;
-                  target.queue = target.metric.replace('root', target.qmetric);
-                  return getYarnAppIdData(target);
+          var metricsPromises = [];
+          if (!_.isEmpty(templateSrv.variables)) {
+            // YARN Queues Dashboard
+            if (templateSrv.variables[0].query === "yarnqueues") {
+              var allQueues = templateSrv.variables.filter(function(variable) { return variable.query === "yarnqueues";});
+              var selectedQs = (_.isEmpty(allQueues)) ? "" : allQueues[0].options.filter(function(q)
+              { return q.selected; }).map(function(qName) { return qName.value; });
+              // All Queues
+              if (!_.isEmpty(_.find(selectedQs, function (wildcard) { return wildcard === "*"; })))  {
+                var allQueue = allQueues[0].options.filter(function(q) {
+                  return q.text !== "All"; }).map(function(queue) { return queue.value; });
+                _.forEach(allQueue, function(processQueue) {
+                  metricsPromises.push(_.map(options.targets, function(target) {
+                    target.qmetric = processQueue;
+                    target.queue = target.metric.replace('root', target.qmetric);
+                    return getYarnAppIdData(target);
+                  }));
+                });
+              } else {
+                // All selected queues.
+                _.forEach(selectedQs, function(processQueue) {
+                  metricsPromises.push(_.map(options.targets, function(target) {
+                    target.qmetric = processQueue;
+                    target.queue = target.metric.replace('root', target.qmetric);
+                    return getYarnAppIdData(target);
+                  }));
+                });
+              }
+            }
+            // Templatized Dashboard for per-user metrics in HBase.
+            if (templateSrv.variables[0].query === "hbase-users") {
+              var allUsers = templateSrv.variables.filter(function(variable) { return variable.query === "hbase-users";});
+              var selectedUsers = (_.isEmpty(allUsers)) ? "" : allUsers[0].options.filter(function(user)
+              { return user.selected; }).map(function(uName) { return uName.value; });
+              selectedUsers = templateSrv._values.Users.lastIndexOf('}') > 0 ? templateSrv._values.Users.slice(1,-1) :
+                templateSrv._values.Users;
+              var selectedUser = selectedUsers.split(',');
+              _.forEach(selectedUser, function(processUser) {
+                  metricsPromises.push(_.map(options.targets, function(target) {
+                    target.hbUser = processUser;
+                    var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
+                    target.hbMetric = target.metric.replace('*', target.hbUser) + metricTransform +'._' +  target.aggregator;
+                    return getHbaseAppIdData(target);
+                  }));
+                });
+            }
+            // Templatized Dashboard for per-table metrics in HBase.
+            if (templateSrv.variables[0].query === "hbase-tables") {
+              var splitTables = [];
+              var allTables = templateSrv._values.Tables.lastIndexOf('}') > 0 ? templateSrv._values.Tables.slice(1,-1) :
+                templateSrv._values.Tables;
+              var allTable = allTables.split(',');
+              while (allTable.length > 0) {
+                splitTables.push(allTable.splice(0,20));
+              }
+              _.forEach(splitTables, function(table) {
+                metricsPromises.push(_.map(options.targets, function(target) {
+                  var hbMetric = [];
+                  _.map(table, function(tableMetric) { hbMetric.push(target.metric.replace('*', tableMetric)); });
+                  var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform; 
+                  hbMetric = _.map(hbMetric, function(tbl) { return tbl + metricTransform +'._' +  target.aggregator; });
+                  target.hbMetric = _.flatten(hbMetric).join(',');
+                  return getHbaseAppIdData(target);
                 }));
               });
-            } else {
-              // All selected queues.
-              _.forEach(selectedQs, function (processQueue) {
-                metricsPromises.push(_.map(options.targets, function (target) {
-                  target.qmetric = processQueue;
-                  target.queue = target.metric.replace('root', target.qmetric);
-                  return getYarnAppIdData(target);
+            }
+            // Templatized Dashboard for per-topic metrics in Kafka.
+            if (templateSrv.variables[0].query === "kafka-topics") {
+              var allTopics = templateSrv.variables.filter(function(variable) { return variable.query === "kafka-topics";});
+              var selectedTopics = (_.isEmpty(allTopics)) ? "" : allTopics[0].options.filter(function(topic)
+              { return topic.selected; }).map(function(topicName) { return topicName.value; });
+              selectedTopics = templateSrv._values.Topics.lastIndexOf('}') > 0 ? templateSrv._values.Topics.slice(1,-1) :
+                templateSrv._values.Topics;
+              var selectedTopic = selectedTopics.split(',');  
+              _.forEach(selectedTopic, function(processTopic) {
+                metricsPromises.push(_.map(options.targets, function(target) {
+                  target.kbTopic = processTopic;
+                  target.kbMetric = target.metric.replace('*', target.kbTopic);
+                  return getKafkaAppIdData(target);
                 }));
               });
             }
-          }
-          // Templatized Dashboard for per-user metrics in HBase.
-          if (templateSrv.variables[0].query === "hbase-users") {
-            var allUsers = templateSrv.variables.filter(function (variable) {
-              return variable.query === "hbase-users";
-            });
-            var selectedUsers = (_.isEmpty(allUsers)) ? "" : allUsers[0].options.filter(function (user) {
-              return user.selected;
-            }).map(function (uName) {
-              return uName.value;
-            });
-            selectedUsers = templateSrv._values.Users.lastIndexOf('}') > 0 ? templateSrv._values.Users.slice(1, -1) :
-              templateSrv._values.Users;
-            var selectedUser = selectedUsers.split(',');
-            _.forEach(selectedUser, function (processUser) {
-              metricsPromises.push(_.map(options.targets, function (target) {
-                target.hbUser = processUser;
-                var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-                target.hbMetric = target.metric.replace('*', target.hbUser) + metricTransform + '._' + target.aggregator;
-                return getHbaseAppIdData(target);
-              }));
-            });
-          }
-          // Templatized Dashboard for per-table metrics in HBase.
-          if (templateSrv.variables[0].query === "hbase-tables") {
-            var splitTables = [];
-            var allTables = templateSrv._values.Tables.lastIndexOf('}') > 0 ? templateSrv._values.Tables.slice(1, -1) :
-              templateSrv._values.Tables;
-            var allTable = allTables.split(',');
-            while (allTable.length > 0) {
-              splitTables.push(allTable.splice(0, 20));
+            //Templatized Dashboard for Call Queues
+            if (templateSrv.variables[0].query === "callers") {
+              var allCallers = templateSrv.variables.filter(function(variable) { return variable.query === "callers";});
+              var selectedCallers = (_.isEmpty(allCallers)) ? "" : allCallers[0].options.filter(function(user)
+              { return user.selected; }).map(function(callerName) { return callerName.value; });
+              selectedCallers = templateSrv._values.Callers.lastIndexOf('}') > 0 ? templateSrv._values.Callers.slice(1,-1) :
+                templateSrv._values.Callers;
+              var selectedCaller = selectedCallers.split(',');
+              _.forEach(selectedCaller, function(processCaller) {
+                  metricsPromises.push(_.map(options.targets, function(target) {
+                    target.nnCaller = processCaller;
+                    target.nnMetric = target.metric.replace('*', target.nnCaller);
+                    return getNnAppIdData(target);
+                  }));
+              });
             }
-            _.forEach(splitTables, function (table) {
-              metricsPromises.push(_.map(options.targets, function (target) {
-                var hbMetric = [];
-                _.map(table, function (tableMetric) {
-                  hbMetric.push(target.metric.replace('*', tableMetric));
+
+            //Templatized Dashboard for Infra Solr Cores
+            if (templateSrv.variables[0].query === "infra_solr_core") {
+                var allCores = templateSrv.variables.filter(function(variable) { return variable.query === "infra_solr_core";});
+                var selectedCores = (_.isEmpty(allCores)) ? "" : allCores[0].options.filter(function(core)
+                { return core.selected; }).map(function(coreName) { return coreName.value; });
+                selectedCores = templateSrv._values.Cores.lastIndexOf('}') > 0 ? templateSrv._values.Cores.slice(1,-1) :
+                    templateSrv._values.Cores;
+                var selectedCore= selectedCores.split(',');
+                _.forEach(selectedCore, function(processCore) {
+                    metricsPromises.push(_.map(options.targets, function(target) {
+                        target.sCore = processCore;
+                        target.sCoreMetric = target.metric.replace('*', target.sCore);
+                        return getSolrCoreData(target);
+                    }));
                 });
-                var metricTransform = !target.transform || target.transform === "none" ? '' : '._' + target.transform;
-                hbMetric = _.map(hbMetric, function (tbl) {
-                  return tbl + metricTransform + '._' + target.aggregator;
+            }
+
+            //Templatized Dashboard for Infra Solr Collections
+            if (templateSrv.variables[0].query === "infra_solr_collection") {
+                var allCollections = templateSrv.variables.filter(function(variable) { return variable.query === "infra_solr_collection";});
+                var selectedCollections = (_.isEmpty(allCollections)) ? "" : allCollections[0].options.filter(function(collection)
+                { return collection.selected; }).map(function(collectionsName) { return collectionsName.value; });
+                selectedCollections = templateSrv._values.Collections.lastIndexOf('}') > 0 ? templateSrv._values.Collections.slice(1,-1) :
+                    templateSrv._values.Collections;
+                var selectedCollection= selectedCollections.split(',');
+                _.forEach(selectedCollection, function(processCollection) {
+                    metricsPromises.push(_.map(options.targets, function(target) {
+                        target.sCollection = processCollection;
+                        target.sCollectionMetric = target.metric.replace('*', target.sCollection);
+                        return getSolrCollectionData(target);
+                    }));
                 });
-                target.hbMetric = _.flatten(hbMetric).join(',');
-                return getHbaseAppIdData(target);
-              }));
-            });
-          }
-          // Templatized Dashboard for per-topic metrics in Kafka.
-          if (templateSrv.variables[0].query === "kafka-topics") {
-            var allTopics = templateSrv.variables.filter(function (variable) {
-              return variable.query === "kafka-topics";
-            });
-            var selectedTopics = (_.isEmpty(allTopics)) ? "" : allTopics[0].options.filter(function (topic) {
-              return topic.selected;
-            }).map(function (topicName) {
-              return topicName.value;
-            });
-            selectedTopics = templateSrv._values.Topics.lastIndexOf('}') > 0 ? templateSrv._values.Topics.slice(1, -1) :
-              templateSrv._values.Topics;
-            var selectedTopic = selectedTopics.split(',');
-            _.forEach(selectedTopic, function (processTopic) {
-              metricsPromises.push(_.map(options.targets, function (target) {
-                target.kbTopic = processTopic;
-                target.kbMetric = target.metric.replace('*', target.kbTopic);
-                return getKafkaAppIdData(target);
-              }));
-            });
-          }
-          //Templatized Dashboard for Call Queues
-          if (templateSrv.variables[0].query === "callers") {
-            var allCallers = templateSrv.variables.filter(function (variable) {
-              return variable.query === "callers";
-            });
-            var selectedCallers = (_.isEmpty(allCallers)) ? "" : allCallers[0].options.filter(function (user) {
-              return user.selected;
-            }).map(function (callerName) {
-              return callerName.value;
-            });
-            selectedCallers = templateSrv._values.Callers.lastIndexOf('}') > 0 ? templateSrv._values.Callers.slice(1, -1) :
-              templateSrv._values.Callers;
-            var selectedCaller = selectedCallers.split(',');
-            _.forEach(selectedCaller, function (processCaller) {
-              metricsPromises.push(_.map(options.targets, function (target) {
-                target.nnCaller = processCaller;
-                target.nnMetric = target.metric.replace('*', target.nnCaller);
-                return getNnAppIdData(target);
-              }));
-            });
-          }
+            }
 
-          //Templatized Dashboard for Infra Solr Cores
-          if (templateSrv.variables[0].query === "infra_solr_core") {
-            var allCores = templateSrv.variables.filter(function (variable) {
-              return variable.query === "infra_solr_core";
-            });
-            var selectedCores = (_.isEmpty(allCores)) ? "" : allCores[0].options.filter(function (core) {
-              return core.selected;
-            }).map(function (coreName) {
-              return coreName.value;
-            });
-            selectedCores = templateSrv._values.Cores.lastIndexOf('}') > 0 ? templateSrv._values.Cores.slice(1, -1) :
-              templateSrv._values.Cores;
-            var selectedCore = selectedCores.split(',');
-            _.forEach(selectedCore, function (processCore) {
-              metricsPromises.push(_.map(options.targets, function (target) {
-                target.sCore = processCore;
-                target.sCoreMetric = target.metric.replace('*', target.sCore);
-                return getSolrCoreData(target);
-              }));
-            });
-          }
+            //Templatized Dashboard for Storm Topologies
+            if (templateSrv.variables[0].query === "topologies" && !templateSrv.variables[1]) {
+              var allTopologies = templateSrv.variables.filter(function(variable) { return variable.query === "topologies";});
+              var selectedTopologies = (_.isEmpty(allTopologies)) ? "" : allTopologies[0].options.filter(function(topo)
+              { return topo.selected; }).map(function(topoName) { return topoName.value; });
+              selectedTopologies = templateSrv._values.topologies.lastIndexOf('}') > 0 ? templateSrv._values.topologies.slice(1,-1) :
+                  templateSrv._values.topologies;
+              var selectedTopology= selectedTopologies.split(',');
+              _.forEach(selectedTopology, function(processTopology) {
+                metricsPromises.push(_.map(options.targets, function(target) {
+                  target.sTopology = processTopology;
+                  target.sTopoMetric = target.metric.replace('*', target.sTopology);
+                  return getStormData(target);
+                }));
+              });
+            }
 
-          //Templatized Dashboard for Infra Solr Collections
-          if (templateSrv.variables[0].query === "infra_solr_collection") {
-            var allCollections = templateSrv.variables.filter(function (variable) {
-              return variable.query === "infra_solr_collection";
-            });
-            var selectedCollections = (_.isEmpty(allCollections)) ? "" : allCollections[0].options.filter(function (collection) {
-              return collection.selected;
-            }).map(function (collectionsName) {
-              return collectionsName.value;
-            });
-            selectedCollections = templateSrv._values.Collections.lastIndexOf('}') > 0 ? templateSrv._values.Collections.slice(1, -1) :
-              templateSrv._values.Collections;
-            var selectedCollection = selectedCollections.split(',');
-            _.forEach(selectedCollection, function (processCollection) {
-              metricsPromises.push(_.map(options.targets, function (target) {
-                target.sCollection = processCollection;
-                target.sCollectionMetric = target.metric.replace('*', target.sCollection);
-                return getSolrCollectionData(target);
+            //Templatized Dashboards for Storm Components
+            if (templateSrv.variables[0].query === "topologies" && templateSrv.variables[1] &&
+                templateSrv.variables[1].name === "component") {
+              var selectedTopology = templateSrv._values.topologies;
+              var selectedComponent = templateSrv._values.component;
+              metricsPromises.push(_.map(options.targets, function(target) {
+                target.sTopology = selectedTopology;
+                target.sComponent = selectedComponent;
+                target.sTopoMetric = target.metric.replace('*', target.sTopology).replace('*', target.sComponent);
+                  return getStormData(target);
               }));
-            });
-          }
+            }
 
-          //Templatized Dashboard for Storm Topologies
-          if (templateSrv.variables[0].query === "topologies" && !templateSrv.variables[1]) {
-            var allTopologies = templateSrv.variables.filter(function (variable) {
-              return variable.query === "topologies";
-            });
-            var selectedTopologies = (_.isEmpty(allTopologies)) ? "" : allTopologies[0].options.filter(function (topo) {
-              return topo.selected;
-            }).map(function (topoName) {
-              return topoName.value;
-            });
-            selectedTopologies = templateSrv._values.topologies.lastIndexOf('}') > 0 ? templateSrv._values.topologies.slice(1, -1) :
-              templateSrv._values.topologies;
-            var selectedTopology = selectedTopologies.split(',');
-            _.forEach(selectedTopology, function (processTopology) {
-              metricsPromises.push(_.map(options.targets, function (target) {
-                target.sTopology = processTopology;
-                target.sTopoMetric = target.metric.replace('*', target.sTopology);
+            //Templatized Dashboard for Storm Kafka Offset
+            if (templateSrv.variables[0].query === "topologies" && templateSrv.variables[1] &&
+                templateSrv.variables[1].name === "topic") {
+              var selectedTopology = templateSrv._values.topologies;
+              var selectedTopic = templateSrv._values.topic;
+              metricsPromises.push(_.map(options.targets, function(target) {
+                target.sTopology = selectedTopology;
+                target.sTopic = selectedTopic;
+                target.sPartition = options.scopedVars.partition.value;
+                target.sTopoMetric = target.metric.replace('*', target.sTopology).replace('*', target.sTopic)
+                    .replace('*', target.sPartition);
                 return getStormData(target);
               }));
-            });
-          }
-
-          //Templatized Dashboards for Storm Components
-          if (templateSrv.variables[0].query === "topologies" && templateSrv.variables[1] &&
-            templateSrv.variables[1].name === "component") {
-            var selectedTopology = templateSrv._values.topologies;
-            var selectedComponent = templateSrv._values.component;
-            metricsPromises.push(_.map(options.targets, function (target) {
-              target.sTopology = selectedTopology;
-              target.sComponent = selectedComponent;
-              target.sTopoMetric = target.metric.replace('*', target.sTopology).replace('*', target.sComponent);
-              return getStormData(target);
-            }));
-          }
-
-          //Templatized Dashboard for Storm Kafka Offset
-          if (templateSrv.variables[0].query === "topologies" && templateSrv.variables[1] &&
-            templateSrv.variables[1].name === "topic") {
-            var selectedTopology = templateSrv._values.topologies;
-            var selectedTopic = templateSrv._values.topic;
-            metricsPromises.push(_.map(options.targets, function (target) {
-              target.sTopology = selectedTopology;
-              target.sTopic = selectedTopic;
-              target.sPartition = options.scopedVars.partition.value;
-              target.sTopoMetric = target.metric.replace('*', target.sTopology).replace('*', target.sTopic)
-                .replace('*', target.sPartition);
-              return getStormData(target);
-            }));
-          }
+            }
 
-          //Templatized Dashboards for Druid
-          if (templateSrv.variables[0].query === "druidDataSources" && !templateSrv.variables[1]) {
-            var allDataSources = templateSrv.variables.filter(function (variable) {
-              return variable.query === "druidDataSources";
-            });
-            var selectedDataSources = (_.isEmpty(allDataSources)) ? "" : allDataSources[0].options.filter(function (dataSource) {
-              return dataSource.selected;
-            }).map(function (dataSourceName) {
-              return dataSourceName.value;
-            });
-            selectedDataSources = templateSrv._values.druidDataSources.lastIndexOf('}') > 0 ? templateSrv._values.druidDataSources.slice(1, -1) :
-              templateSrv._values.druidDataSources;
-            var selectedDataSource = selectedDataSources.split(',');
-            _.forEach(selectedDataSource, function (processDataSource) {
-              metricsPromises.push(_.map(options.targets, function (target) {
-                target.sDataSource = processDataSource;
-                target.sDataSourceMetric = target.metric.replace('*', target.sDataSource);
-                return getDruidData(target);
-              }));
-            });
-          }
-          // To speed up querying on templatized dashboards.
-          var indexOfHosts = -1;
-          for (var i = 0; i < templateSrv.variables.length; i++) {
-            if (templateSrv.variables[i].name == 'hosts') {
-              indexOfHosts = i;
+            //Templatized Dashboards for Druid
+            if (templateSrv.variables[0].query === "druidDataSources" && !templateSrv.variables[1]) {
+              var allDataSources = templateSrv.variables.filter(function(variable) { return variable.query === "druidDataSources";});
+              var selectedDataSources = (_.isEmpty(allDataSources)) ? "" : allDataSources[0].options.filter(function(dataSource)
+                            { return dataSource.selected; }).map(function(dataSourceName) { return dataSourceName.value; });
+               selectedDataSources = templateSrv._values.druidDataSources.lastIndexOf('}') > 0 ? templateSrv._values.druidDataSources.slice(1,-1) :
+                                              templateSrv._values.druidDataSources;
+              var selectedDataSource = selectedDataSources.split(',');
+              _.forEach(selectedDataSource, function(processDataSource) {
+                metricsPromises.push(_.map(options.targets, function(target) {
+                  target.sDataSource = processDataSource;
+                  target.sDataSourceMetric = target.metric.replace('*', target.sDataSource);
+                  return getDruidData(target);
+                }));
+              });
             }
-          }
-          if (indexOfHosts >= 0) {
-            var allHosts = templateSrv._values.hosts.lastIndexOf('}') > 0 ? templateSrv._values.hosts.slice(1, -1) :
+            // To speed up querying on templatized dashboards.
+              var indexOfHosts = -1;
+              for (var i = 0; i < templateSrv.variables.length; i++) {
+                  if (templateSrv.variables[i].name == 'hosts') {
+                      indexOfHosts = i;
+                  }
+              }
+              if (indexOfHosts >= 0) {
+              var allHosts = templateSrv._values.hosts.lastIndexOf('}') > 0 ? templateSrv._values.hosts.slice(1,-1) :
               templateSrv._values.hosts;
-            allHosts = templateSrv._texts.hosts === "All" ? '%' : allHosts;
-            metricsPromises.push(_.map(options.targets, function (target) {
-              target.templatedHost = allHosts ? allHosts : '';
-              target.templatedCluster = templatedCluster;
-              return getAllHostData(target);
-            }));
-          }
-          metricsPromises = _.flatten(metricsPromises);
-        } else {
-          // Non Templatized Dashboards
-          metricsPromises = _.map(options.targets, function (target) {
-            console.debug('target app=' + target.app + ',' +
-              'target metric=' + target.metric + ' on host=' + target.tempHost);
-            if (!!target.hosts) {
-              return getHostAppIdData(target);
-            } else {
-              return getServiceAppIdData(target);
+              allHosts = templateSrv._texts.hosts === "All" ? '%' : allHosts;
+              metricsPromises.push(_.map(options.targets, function(target) {
+                  target.templatedHost = allHosts? allHosts : '';
+                  target.templatedCluster = templatedCluster;
+                  return getAllHostData(target);
+              }));
             }
-          });
-        }
+            metricsPromises = _.flatten(metricsPromises);
+          } else {
+            // Non Templatized Dashboards
+            metricsPromises = _.map(options.targets, function(target) {
+              console.debug('target app=' + target.app + ',' +
+                'target metric=' + target.metric + ' on host=' + target.tempHost);
+              if (!!target.hosts) {
+                return getHostAppIdData(target);
+              } else {
+                return getServiceAppIdData(target);
+              }
+            });
+          }
 
-        return $q.all(metricsPromises).then(function (metricsDataArray) {
-          var data = _.map(metricsDataArray, function (metricsData) {
-            return metricsData.data;
+          return $q.all(metricsPromises).then(function(metricsDataArray) {
+            var data = _.map(metricsDataArray, function(metricsData) {
+              return metricsData.data;
+            });
+            var metricsDataResult = {data: _.flatten(data)};
+            return $q.when(metricsDataResult);
           });
-          var metricsDataResult = {data: _.flatten(data)};
-          return $q.when(metricsDataResult);
-        });
-      };
+        };
 
-      /**
-       * AMS Datasource  List Series.
-       */
-      this.listSeries = function (query) {
-        // wrap in regex
-        if (query && query.length > 0 && query[0] !== '/') {
-          query = '/' + query + '/';
-        }
-        return $q.when([]);
-      };
+        /**
+         * AMS Datasource  List Series.
+         */
+        AmbariMetricsDatasource.prototype.listSeries = function (query) {
+          // wrap in regex
+          if (query && query.length > 0 && query[0] !== '/') {
+            query = '/' + query + '/';
+          }
+          return $q.when([]);
+        };
 
-      /**
-       * AMS Datasource Templating Variables.
-       */
-      this.metricFindQuery = function (query) {
-        var interpolated;
-        try {
-          interpolated = query.split('.')[0];
-        } catch (err) {
-          return $q.reject(err);
-        }
-        var templatedClusters = templateSrv.variables.filter(function (o) {
-          return o.name === "cluster"
-        });
-        var templatedCluster = (_.isEmpty(templatedClusters)) ? '' : templatedClusters[0].options.filter(function (cluster) {
-          return cluster.selected;
-        }).map(function (clusterName) {
-          return clusterName.value;
-        });
+        /**
+         * AMS Datasource Templating Variables.
+         */
+        AmbariMetricsDatasource.prototype.metricFindQuery = function (query) {
+          var interpolated;
+          try {
+            interpolated = query.split('.')[0];
+          } catch (err) {
+            return $q.reject(err);
+          }
+          var templatedClusters = templateSrv.variables.filter(function(o) { return o.name === "cluster"});
+          var templatedCluster = (_.isEmpty(templatedClusters)) ? '' : templatedClusters[0].options.filter(function(cluster)
+          { return cluster.selected; }).map(function(clusterName) { return clusterName.value; });
 
-        var tComponents = _.isEmpty(templateSrv.variables) ? '' : templateSrv.variables.filter(function (variable) {
-          return variable.name === "components"
-        });
-        var tComponent = _.isEmpty(tComponents) ? '' : tComponents[0].current.value;
+          var tComponents = _.isEmpty(templateSrv.variables) ? '' : templateSrv.variables.filter(function(variable) 
+            { return variable.name === "components"});
+          var tComponent = _.isEmpty(tComponents) ? '' : tComponents[0].current.value;
 
 
-        // Templated Variable for HBase Users
-        // It will search the cluster and populate the HBase Users.
-        if (interpolated === "hbase-users") {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var hbaseUsers = allMetrics["hbase"];
-              var extractUsers = hbaseUsers.filter(/./.test.bind(new RegExp("regionserver.Users.", 'g')));
-              var removeUser = "regionserver.Users.numUsers";
-              var i = extractUsers.indexOf(removeUser);
-              if (i !== -1) {
-                extractUsers.splice(i, 1);
-              }
-              var userPrefix = "regionserver.Users.";
-              var users = _.map(extractUsers, function (user) {
-                return user.substring(userPrefix.length);
-              });
-              users = _.map(users, function (userName) {
-                return userName.substring(0, userName.lastIndexOf("_metric"));
-              });
-              users = _.sortBy(_.uniq(users));
-              return _.map(users, function (users) {
-                return {
-                  text: users
-                };
-              });
-            });
-        }
-        // Templated Variable for HBase Tables.
-        // It will search the cluster and populate the hbase-tables.
-        if (interpolated === "hbase-tables") {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var hbaseTables = allMetrics["hbase"];
-              var extractTables = hbaseTables.filter(/./.test.bind(new RegExp("regionserver.Tables.", 'g')));
-              var removeTable = "regionserver.Tables.numTables";
-              var i = extractTables.indexOf(removeTable);
-              if (i != -1) {
-                extractTables.splice(i, 1);
-              }
-              var tablePrefix = "regionserver.Tables.";
-              var tables = _.map(extractTables, function (user) {
-                return user.substring(tablePrefix.length);
-              });
-              tables = _.map(tables, function (userName) {
-                return userName.substring(0, userName.lastIndexOf("_metric"));
-              });
-              tables = _.sortBy(_.uniq(tables));
-              return _.map(tables, function (tables) {
-                return {
-                  text: tables
-                };
+          // Templated Variable for HBase Users
+          // It will search the cluster and populate the HBase Users.
+          if(interpolated === "hbase-users") {
+            return this.initMetricAppidMapping()
+              .then(function () {
+                var hbaseUsers = allMetrics["hbase"];
+                var extractUsers = hbaseUsers.filter(/./.test.bind(new RegExp("regionserver.Users.", 'g')));
+                var removeUser = "regionserver.Users.numUsers";
+                var i = extractUsers.indexOf(removeUser);
+                if(i !== -1) { extractUsers.splice(i, 1);}
+                var userPrefix = "regionserver.Users.";
+                var users = _.map(extractUsers, function(user) {
+                  return user.substring(userPrefix.length);
+                });
+                users = _.map(users, function(userName) {
+                  return userName.substring(0,userName.lastIndexOf("_metric"));
+                });
+                users = _.sortBy(_.uniq(users));
+                return _.map(users, function (users) {
+                  return {
+                    text: users
+                  };
+                });
               });
-            });
-        }
-        // Templated Variable for Kafka Topics.
-        // It will search the cluster and populate the topics.
-        if (interpolated === "kafka-topics") {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var kafkaTopics = allMetrics["kafka_broker"];
-              var extractTopics = kafkaTopics.filter(/./.test.bind(new RegExp("\\b.log.Log.\\b", 'g')));
-              var topics = _.map(extractTopics, function (topic) {
-                var topicPrefix = "topic.";
-                return topic.substring(topic.lastIndexOf(topicPrefix) + topicPrefix.length, topic.length);
+          }
+          // Templated Variable for HBase Tables.
+          // It will search the cluster and populate the hbase-tables.
+          if(interpolated === "hbase-tables") {
+            return this.initMetricAppidMapping()
+              .then(function () {
+                var hbaseTables = allMetrics["hbase"];
+                var extractTables = hbaseTables.filter(/./.test.bind(new RegExp("regionserver.Tables.", 'g')));
+                var removeTable = "regionserver.Tables.numTables";
+                var i = extractTables.indexOf(removeTable);
+                if(i != -1) { extractTables.splice(i, 1);}
+                var tablePrefix = "regionserver.Tables.";
+                var tables = _.map(extractTables, function(user) {
+                  return user.substring(tablePrefix.length);
+                });
+                tables = _.map(tables, function(userName) {
+                  return userName.substring(0,userName.lastIndexOf("_metric"));
+                });
+                tables = _.sortBy(_.uniq(tables));
+                return _.map(tables, function (tables) {
+                  return {
+                    text: tables
+                  };
+                });
               });
-              topics = _.sortBy(_.uniq(topics));
-              var i = topics.indexOf("ambari_kafka_service_check");
-              if (i != -1) {
-                topics.splice(i, 1);
-              }
-              return _.map(topics, function (topics) {
-                return {
-                  text: topics
-                };
+          }
+          // Templated Variable for Kafka Topics.
+          // It will search the cluster and populate the topics.
+          if(interpolated === "kafka-topics") {
+            return this.initMetricAppidMapping()
+              .then(function () {
+                var kafkaTopics = allMetrics["kafka_broker"];
+                var extractTopics = kafkaTopics.filter(/./.test.bind(new RegExp("\\b.log.Log.\\b", 'g')));
+                var topics =_.map(extractTopics, function (topic) {
+                  var topicPrefix = "topic.";
+                  return topic.substring(topic.lastIndexOf(topicPrefix)+topicPrefix.length, topic.length);
+                });
+                topics = _.sortBy(_.uniq(topics));
+                var i = topics.indexOf("ambari_kafka_service_check");
+                if(i != -1) { topics.splice(i, 1);}
+                return _.map(topics, function (topics) {
+                  return {
+                    text: topics
+                  };
+                });
               });
-            });
-        }
+          }
 
-        //Templated Variables for Call Queue Metrics
-        if (interpolated === "callers") {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var nnCallers = allMetrics["namenode"];
-              var extractCallers = nnCallers.filter(/./.test.bind(new
-              RegExp("ipc.client.org.apache.hadoop.ipc.DecayRpcScheduler.Caller", 'g')));
-              var callers = _.sortBy(_.uniq(_.map(extractCallers, function (caller) {
-                return caller.substring(caller.indexOf('(') + 1, caller.indexOf(')'))
-              })));
-              return _.map(callers, function (callers) {
-                return {
-                  text: callers
-                };
+          //Templated Variables for Call Queue Metrics
+          if(interpolated === "callers") {
+            return this.initMetricAppidMapping()
+              .then(function () {
+                var nnCallers = allMetrics["namenode"];
+                var extractCallers = nnCallers.filter(/./.test.bind(new 
+                  RegExp("ipc.client.org.apache.hadoop.ipc.DecayRpcScheduler.Caller", 'g')));
+                var callers = _.sortBy(_.uniq(_.map(extractCallers, function(caller) { 
+                  return caller.substring(caller.indexOf('(')+1, caller.indexOf(')')) })));
+                return _.map(callers, function (callers) {
+                  return {
+                    text: callers
+                  };
+                });
               });
-            });
-        }
+          }
 
-        var cores = [];
-        //Templated Variables for Infra Solr Cores
-        if (interpolated === "infra_solr_core") {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var solrMetrics = allMetrics["ambari-infra-solr"];
-              var extractCores = solrMetrics.filter(/./.test.bind(new
-              RegExp("^infra.solr.core.", 'g')));
-              _.map(extractCores, function (core) {
-                // Core naming convention is infra.solr.core.<collection_name>.<shard>.<replica>.<metric_name>
-                // coreName should be <collection_name>.<shard>.<replica>
-                core = core.split('.');
-                var coreName = core.slice(3, 6).join(".");
-                if (cores.indexOf(coreName) < 0) {
-                  cores.push(coreName);
-                }
-              });
-              return _.map(cores, function (cores) {
-                return {
-                  text: cores
-                };
-              });
-            });
-        }
+          var cores = [];
+          //Templated Variables for Infra Solr Cores
+          if (interpolated === "infra_solr_core") {
+              return this.initMetricAppidMapping()
+                  .then(function () {
+                      var solrMetrics = allMetrics["ambari-infra-solr"];
+                      var extractCores = solrMetrics.filter(/./.test.bind(new
+                      RegExp("^infra.solr.core.", 'g')));
+                      _.map(extractCores, function (core) {
+                          // Core naming convention is infra.solr.core.<collection_name>.<shard>.<replica>.<metric_name>
+                          // coreName should be <collection_name>.<shard>.<replica>
+                          core = core.split('.');
+                          var coreName = core.slice(3,6).join(".");
+                          if (cores.indexOf(coreName) < 0) {
+                              cores.push(coreName);
+                          }
+                      });
+                      return _.map(cores, function (cores) {
+                              return {
+                                  text: cores
+                              };
+                          });
+                      });
+          }
 
-        var collections = [];
-        //Templated Variables for Infra Solr Collections
-        if (interpolated === "infra_solr_collection") {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var solrMetrics = allMetrics["ambari-infra-solr"];
-              var extractCollections = solrMetrics.filter(/./.test.bind(new
-              RegExp("^infra.solr.core.", 'g')));
-              _.map(extractCollections, function (core) {
-                // Core naming convention is infra.solr.core.<collection_name>.<shard>.<replica>.<metric_name>
-                core = core.split('.');
-                var collection = core[3];
-                if (collections.indexOf(collection) < 0) {
-                  collections.push(collection);
-                }
-              });
-              return _.map(collections, function (collections) {
-                return {
-                  text: collections
-                };
-              });
-            });
-        }
+          var collections = [];
+          //Templated Variables for Infra Solr Collections
+          if (interpolated === "infra_solr_collection") {
+              return this.initMetricAppidMapping()
+                  .then(function () {
+                      var solrMetrics = allMetrics["ambari-infra-solr"];
+                      var extractCollections = solrMetrics.filter(/./.test.bind(new
+                      RegExp("^infra.solr.core.", 'g')));
+                      _.map(extractCollections, function (core) {
+                          // Core naming convention is infra.solr.core.<collection_name>.<shard>.<replica>.<metric_name>
+                          core = core.split('.');
+                          var collection = core[3];
+                          if (collections.indexOf(collection) < 0) {
+                              collections.push(collection);
+                          }
+                      });
+                      return _.map(collections, function (collections) {
+                              return {
+                                  text: collections
+                              };
+                          });
+                      });
+          }
 
-        var topologies = {};
-        //Templated Variables for Storm Topologies
-        if (interpolated === "topologies") {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var storm = allMetrics["nimbus"];
-              var extractTopologies = storm.filter(/./.test.bind(new
-              RegExp("^topology.", 'g')));
-              _.map(extractTopologies, function (topology) {
-                // Topology naming convention is topology.<topology-name>.component.
-                topology = topology.split('.').slice(0, 3);
-                if (topologies[topology[1]]) {
-                  topologies[topology[1]].push(topology[2]);
-                } else {
-                  topologies[topology[1]] = [topology[2]];
-                }
-              });
-              return _.map(Object.keys(topologies), function (topologyNames) {
+          var topologies = {};
+          //Templated Variables for Storm Topologies
+          if(interpolated === "topologies") {
+            return this.initMetricAppidMapping()
+                .then(function () {
+                  var storm = allMetrics["nimbus"];
+                  var extractTopologies = storm.filter(/./.test.bind(new
+                      RegExp("^topology.", 'g')));
+                  _.map(extractTopologies, function(topology){
+                    // Topology naming convention is topology.<topology-name>.component.
+                    topology = topology.split('.').slice(0,3);
+                    if (topologies[topology[1]]){
+                      topologies[topology[1]].push(topology[2]);
+                    } else {
+                      topologies[topology[1]] = [topology[2]];
+                    }
+                  });
+                  return _.map(Object.keys(topologies), function(topologyNames){
+                    return {
+                      text: topologyNames
+                    };
+                  });
+                });
+          }
+          //Templated Variables for Storm Components per Topology
+          if (interpolated.indexOf("stormComponent") >= 0) {
+            var componentName = interpolated.substring(0,interpolated.indexOf('.'));
+            return this.initMetricAppidMapping()
+                .then(function () {
+                  var storm = allMetrics["nimbus"];
+                  var extractTopologies = storm.filter(/./.test.bind(new
+                      RegExp("^topology.", 'g')));
+                  _.map(extractTopologies, function(topology){
+                    topology = topology.split('.').slice(0,3);
+                    if (topologies[topology[1]]){
+                      topologies[topology[1]].push(topology[2]);
+                    } else {
+                      topologies[topology[1]] = [topology[2]];
+                    }
+                  });
+                  // Retrieve unique component names from the list.
+                  var compName = _.uniq(topologies[componentName]);
+                  // Remove "kafka-topic" from the list of components.
+                  var remove = compName.indexOf('kafka-topic');
+                  if (remove > -1) { compName.splice(remove, 1);}
+                  return _.map(compName, function(components){
+                    return {
+                      text: components
+                    };
+                  });
+                });
+          }
+          var stormEntities = {};
+          AmbariMetricsDatasource.prototype.getStormEntities = function () {
+            return this.initMetricAppidMapping()
+                .then(function () {
+                  var storm = allMetrics["nimbus"];
+                  var extractTopologies = storm.filter(/./.test.bind(new
+                      RegExp("partition", 'g')));
+                  _.map(extractTopologies, function(topology){
+                    topology = topology.split('.').slice(0,5);
+                    var topologyName = topologyN = topology[1]; // Topology
+                    var topologyTopicName = topicN = topology[3]; // Topic
+                    var topologyTopicPartitionName = topology[4]; // Partition
+                    if (stormEntities[topologyName]) {
+                      if (stormEntities[topologyName][topologyTopicName]) {
+                        stormEntities[topologyName][topologyTopicName].push(topologyTopicPartitionName);
+                      } else {
+                        stormEntities[topologyName][topologyTopicName] = [topologyTopicPartitionName];
+                      }
+                    } else {
+                      stormEntities[topologyName] = {};
+                      stormEntities[topologyName][topologyTopicName] = [topologyTopicPartitionName];
+                    }
+                  });
+                });
+          };
+          //Templated Variables for Storm Topics per Topology
+          if (interpolated.indexOf("stormTopic") >= 0) {
+            var topicName = interpolated.substring(0,interpolated.indexOf('.'));
+            return this.getStormEntities().then(function () {
+              var topicNames = Object.keys(stormEntities[topicName]);
+              return _.map(topicNames, function(names){
                 return {
-                  text: topologyNames
+                  text: names
                 };
               });
             });
-        }
-        //Templated Variables for Storm Components per Topology
-        if (interpolated.indexOf("stormComponent") >= 0) {
-          var componentName = interpolated.substring(0, interpolated.indexOf('.'));
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var storm = allMetrics["nimbus"];
-              var extractTopologies = storm.filter(/./.test.bind(new
-              RegExp("^topology.", 'g')));
-              _.map(extractTopologies, function (topology) {
-                topology = topology.split('.').slice(0, 3);
-                if (topologies[topology[1]]) {
-                  topologies[topology[1]].push(topology[2]);
-                } else {
-                  topologies[topology[1]] = [topology[2]];
-                }
-              });
-              // Retrieve unique component names from the list.
-              var compName = _.uniq(topologies[componentName]);
-              // Remove "kafka-topic" from the list of components.
-              var remove = compName.indexOf('kafka-topic');
-              if (remove > -1) {
-                compName.splice(remove, 1);
-              }
-              return _.map(compName, function (components) {
+          }
+          //Templated Variables for Storm Partitions per Topic
+          if (interpolated.indexOf("stormPartition") >= 0) {
+            var topicN, topologyN;
+            return this.getStormEntities().then(function () {
+              var partitionNames = _.uniq(stormEntities[topologyN][topicN]);
+              return _.map(partitionNames, function(names){
                 return {
-                  text: components
+                  text: names
                 };
               });
             });
-        }
-        var stormEntities = {};
-        this.getStormEntities = function () {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var storm = allMetrics["nimbus"];
-              var extractTopologies = storm.filter(/./.test.bind(new
-              RegExp("partition", 'g')));
-              _.map(extractTopologies, function (topology) {
-                topology = topology.split('.').slice(0, 5);
-                var topologyName = topologyN = topology[1]; // Topology
-                var topologyTopicName = topicN = topology[3]; // Topic
-                var topologyTopicPartitionName = topology[4]; // Partition
-                if (stormEntities[topologyName]) {
-                  if (stormEntities[topologyName][topologyTopicName]) {
-                    stormEntities[topologyName][topologyTopicName].push(topologyTopicPartitionName);
-                  } else {
-                    stormEntities[topologyName][topologyTopicName] = [topologyTopicPartitionName];
-                  }
-                } else {
-                  stormEntities[topologyName] = {};
-                  stormEntities[topologyName][topologyTopicName] = [topologyTopicPartitionName];
-                }
-              });
-            });
-        };
-        //Templated Variables for Storm Topics per Topology
-        if (interpolated.indexOf("stormTopic") >= 0) {
-          var topicName = interpolated.substring(0, interpolated.indexOf('.'));
-          return this.getStormEntities().then(function () {
-            var topicNames = Object.keys(stormEntities[topicName]);
-            return _.map(topicNames, function (names) {
-              return {
-                text: names
-              };
-            });
-          });
-        }
-        //Templated Variables for Storm Partitions per Topic
-        if (interpolated.indexOf("stormPartition") >= 0) {
-          var topicN, topologyN;
-          return this.getStormEntities().then(function () {
-            var partitionNames = _.uniq(stormEntities[topologyN][topicN]);
-            return _.map(partitionNames, function (names) {
-              return {
-                text: names
-              };
-            });
-          });
-        }
-        // Templated Variable for YARN Queues.
-        // It will search the cluster and populate the queues.
-        if (interpolated === "yarnqueues") {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var yarnqueues = allMetrics["resourcemanager"];
-              var extractQueues = yarnqueues.filter(/./.test.bind(new RegExp(".=root", 'g')));
-              var queues = _.map(extractQueues, function (metric) {
-                return metric.substring("yarn.QueueMetrics.Queue=".length);
-              });
-              queues = _.map(queues, function (metricName) {
-                return metricName.substring(metricName.lastIndexOf("."), 0);
-              });
-              queues = _.sortBy(_.uniq(queues));
-              return _.map(queues, function (queues) {
-                return {
-                  text: queues
-                };
+          }
+          // Templated Variable for YARN Queues.
+          // It will search the cluster and populate the queues.
+          if(interpolated === "yarnqueues") {
+            return this.initMetricAppidMapping()
+              .then(function () {
+                var yarnqueues = allMetrics["resourcemanager"];
+                var extractQueues = yarnqueues.filter(/./.test.bind(new RegExp(".=root", 'g')));
+                var queues = _.map(extractQueues, function(metric) {
+                  return metric.substring("yarn.QueueMetrics.Queue=".length);
+                });
+                queues = _.map(queues, function(metricName) {
+                  return metricName.substring(metricName.lastIndexOf("."), 0);
+                });
+                queues = _.sortBy(_.uniq(queues));
+                return _.map(queues, function (queues) {
+                  return {
+                    text: queues
+                  };
+                });
               });
-            });
-        }
+          }
 
-        // Templated Variable for DruidServices.
-        // It will search the cluster and populate the druid service names.
-        if (interpolated === "druidServices") {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var druidMetrics = allMetrics["druid"];
-              // Assumption: each node always emits jvm metrics
-              var extractNodeTypes = druidMetrics.filter(/./.test.bind(new RegExp("jvm/gc/time", 'g')));
-              var nodeTypes = _.map(extractNodeTypes, function (metricName) {
-                return metricName.substring(0, metricName.indexOf("."));
-              });
-              nodeTypes = _.sortBy(_.uniq(nodeTypes));
-              return _.map(nodeTypes, function (nodeType) {
-                return {
-                  text: nodeType
-                };
+          // Templated Variable for DruidServices.
+          // It will search the cluster and populate the druid service names.
+          if(interpolated === "druidServices") {
+            return this.initMetricAppidMapping()
+              .then(function () {
+                var druidMetrics = allMetrics["druid"];
+                // Assumption: each node always emits jvm metrics
+                var extractNodeTypes = druidMetrics.filter(/./.test.bind(new RegExp("jvm/gc/time", 'g')));
+                var nodeTypes = _.map(extractNodeTypes, function(metricName) {
+                  return metricName.substring(0, metricName.indexOf("."));
+                });
+                nodeTypes = _.sortBy(_.uniq(nodeTypes));
+                return _.map(nodeTypes, function (nodeType) {
+                  return {
+                    text: nodeType
+                  };
+                });
               });
-            });
-        }
+          }
 
-        // Templated Variable for Druid datasources.
-        // It will search the cluster and populate the druid datasources.
-        if (interpolated === "druidDataSources") {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var druidMetrics = allMetrics["druid"];
-              // Assumption: query/time is emitted for each datasource
-              var extractDataSources = druidMetrics.filter(/./.test.bind(new RegExp("query/time", 'g')));
-              var dataSources = _.map(extractDataSources, function (metricName) {
-                return metricName.split('.')[1]
-              });
-              dataSources = _.sortBy(_.uniq(dataSources));
-              return _.map(dataSources, function (dataSource) {
-                return {
-                  text: dataSource
-                };
+          // Templated Variable for Druid datasources.
+          // It will search the cluster and populate the druid datasources.
+          if(interpolated === "druidDataSources") {
+            return this.initMetricAppidMapping()
+              .then(function () {
+                var druidMetrics = allMetrics["druid"];
+                // Assumption: query/time is emitted for each datasource
+                var extractDataSources = druidMetrics.filter(/./.test.bind(new RegExp("query/time", 'g')));
+                var dataSources = _.map(extractDataSources, function(metricName) {
+                  return metricName.split('.')[1]
+                });
+                dataSources = _.sortBy(_.uniq(dataSources));
+                return _.map(dataSources, function (dataSource) {
+                  return {
+                    text: dataSource
+                  };
+                });
               });
-            });
-        }
+          }
 
-        // Templated Variable for Druid query type.
-        // It will search the cluster and populate the druid query types.
-        if (interpolated === "druidQueryTypes") {
-          return this.initMetricAppidMapping()
-            .then(function () {
-              var druidMetrics = allMetrics["druid"];
-              // Assumption: query/time is emitted for each query type.
-              var extractQueryTypes = druidMetrics.filter(/./.test.bind(new RegExp("query/time", 'g')));
-              var queryTypes = _.map(extractQueryTypes, function (metricName) {
-                return metricName.split('.')[2]
-              });
-              queryTypes = _.sortBy(_.uniq(queryTypes));
-              return _.map(queryTypes, function (queryType) {
-                return {
-                  text: queryType
-                };
+          // Templated Variable for Druid query type.
+          // It will search the cluster and populate the druid query types.
+          if(interpolated === "druidQueryTypes") {
+            return this.initMetricAppidMapping()
+              .then(function () {
+                var druidMetrics = allMetrics["druid"];
+                // Assumption: query/time is emitted for each query type.
+                var extractQueryTypes = druidMetrics.filter(/./.test.bind(new RegExp("query/time", 'g')));
+                var queryTypes = _.map(extractQueryTypes, function(metricName) {
+                  return metricName.split('.')[2]
+                });
+                queryTypes = _.sortBy(_.uniq(queryTypes));
+                return _.map(queryTypes, function (queryType) {
+                  return {
+                    text: queryType
+                  };
+                });
               });
-            });
-        }
-
-        if (interpolated == 'hosts') {
-          return this.suggestHosts(tComponent, templatedCluster);
-        } else if (interpolated == 'cluster') {
-          return this.suggestClusters(tComponent)
-        }
-      };
+          }
 
-      /**
-       * AMS Datasource  - Test Data Source Connection.
-       *
-       * Added Check to see if Datasource is working. Throws up an error in the
-       * Datasources page if incorrect info is passed on.
-       */
-      this.testDatasource = function () {
-        return this.doAmbariRequest({
-          url: '/ws/v1/timeline/metrics/metadata',
-          method: 'GET'
-        }).then(function (response) {
-          console.log(response);
-          if (response.status === 200) {
-            return {status: "success", message: "Data source is working", title: "Success"};
+          if (interpolated == 'hosts') {
+            return this.suggestHosts(tComponent, templatedCluster);
+          } else if (interpolated == 'cluster') {
+            return this.suggestClusters(tComponent)
           }
-        });
-      };
+        };
 
-      /**
-       * AMS Datasource - Suggest AppId.
-       *
-       * Read AppIds from cache.
-       */
-      this.suggestApps = function (query) {
-        console.log(query);
+        /**
+         * AMS Datasource  - Test Data Source Connection.
+         *
+         * Added Check to see if Datasource is working. Throws up an error in the
+         * Datasources page if incorrect info is passed on.
+         */
+        AmbariMetricsDatasource.prototype.testDatasource = function () {
+          return this.doAmbariRequest({
+            url: '/ws/v1/timeline/metrics/metadata',
+            method: 'GET'
+          }).then(function(response) {
+            console.log(response);
+            if (response.status === 200) {
+              return { status: "success", message: "Data source is working", title: "Success" };
+            }
+          });
+        };
 
-        appIds = appIds.sort();
-        var appId = _.map(appIds, function (k) {
-          return {text: k};
-        });
-        return $q.when(appId);
-      };
+        /**
+         * AMS Datasource - Suggest AppId.
+         *
+         * Read AppIds from cache.
+         */
+        AmbariMetricsDatasource.prototype.suggestApps = function (query) {
+          console.log(query);
 
-      /**
-       * AMS Datasource - Suggest Metrics.
-       *
-       * Read Metrics based on AppId chosen.
-       */
-      this.suggestMetrics = function (query, app) {
-        if (!app) {
-          return $q.when([]);
-        }
-        var keys = [];
-        keys = _.map(allMetrics[app], function (m) {
-          return {text: m};
-        });
-        keys = _.sortBy(keys, function (i) {
-          return i.text.toLowerCase();
-        });
-        return $q.when(keys);
-      };
+          appIds = appIds.sort();
+          var appId = _.map(appIds, function (k) {
+            return {text: k};
+          });
+          return $q.when(appId);
+        };
 
-      this.suggestClusters = function (app) {
-        if (!app) {
-          app = '';
-        }
-        return this.doAmbariRequest({
-          method: 'GET',
-          url: '/ws/v1/timeline/metrics/instances?' + 'appId=' + app
-        }).then(function (response) {
-          var clusters = [];
-          var data = response.data;
-          for (var cluster in data) {
-            if (data[cluster].hasOwnProperty(app)) {
-              clusters.push({text: cluster});
-            }
+        /**
+         * AMS Datasource - Suggest Metrics.
+         *
+         * Read Metrics based on AppId chosen.
+         */
+        AmbariMetricsDatasource.prototype.suggestMetrics = function (query, app) {
+          if (!app) {
+            return $q.when([]);
           }
-          return $q.when(clusters);
-        });
-      };
+          var keys = [];
+          keys = _.map(allMetrics[app],function(m) {
+            return {text: m};
+          });
+          keys = _.sortBy(keys, function (i) { return i.text.toLowerCase(); });
+          return $q.when(keys);
+        };
 
-      /**
-       * AMS Datasource - Suggest Hosts.
-       *
-       * Query Hosts on the cluster.
-       */
-      this.suggestHosts = function (app, cluster) {
-        if (!app) {
-          app = '';
-        }
-        if (!cluster) {
-          cluster = '';
-        }
-        return this.doAmbariRequest({
-          method: 'GET',
-          url: '/ws/v1/timeline/metrics/instances?' + 'appId=' + app + '&instanceId=' + cluster
-        }).then(function (response) {
-          var hosts = [];
-          var data = response.data;
-          for (var cluster in data) {
-            var appHosts = data[cluster][app];
-            if (appHosts) {
-              for (var index in appHosts) {
-                hosts.push({text: appHosts[index]});
+        AmbariMetricsDatasource.prototype.suggestClusters = function(app) {
+          if (!app) { app = ''; }
+          return this.doAmbariRequest({
+            method: 'GET',
+            url: '/ws/v1/timeline/metrics/instances?' + 'appId=' + app
+          }).then(function(response) {
+              var clusters = [];
+              var data = response.data;
+              for (var cluster in data) {
+                if (data[cluster].hasOwnProperty(app)) {
+                  clusters.push({text: cluster});
+                }
+              }
+              return $q.when(clusters);
+          });
+        };
+
+        /**
+         * AMS Datasource - Suggest Hosts.
+         *
+         * Query Hosts on the cluster.
+         */
+        AmbariMetricsDatasource.prototype.suggestHosts = function (app, cluster) {
+          if (!app) { app = ''; }
+          if (!cluster) { cluster = ''; }
+          return this.doAmbariRequest({
+            method: 'GET',
+            url: '/ws/v1/timeline/metrics/instances?' + 'appId=' + app + '&instanceId=' + cluster
+          }).then(function (response) {
+            var hosts = [];
+            var data = response.data;
+            for (var cluster in data) {
+              var appHosts = data[cluster][app];
+              if (appHosts) {
+                for (var index in appHosts) {
+                  hosts.push({text: appHosts[index]});
+                }
               }
             }
-          }
-          return $q.when(hosts);
-        });
-      };
+            return $q.when(hosts);
+          });
+        };
 
-      /**
-       * AMS Datasource Aggregators.
-       */
-      var aggregatorsPromise = null;
-      this.getAggregators = function () {
-        if (aggregatorsPromise) {
+        /**
+         * AMS Datasource Aggregators.
+         */
+        var aggregatorsPromise = null;
+        AmbariMetricsDatasource.prototype.getAggregators = function () {
+          if (aggregatorsPromise) {
+            return aggregatorsPromise;
+          }
+          aggregatorsPromise = $q.when([
+            'none','avg', 'sum', 'min', 'max'
+          ]);
           return aggregatorsPromise;
-        }
-        aggregatorsPromise = $q.when([
-          'none', 'avg', 'sum', 'min', 'max'
-        ]);
-        return aggregatorsPromise;
-      };
-    };
-
-    return {
-      AmbariMetricsDatasource: AmbariMetricsDatasource
-    };
-
-
-  });
+        };
 
+        return AmbariMetricsDatasource;
+      });
+    }
+);
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
index 087533c..aade7d7 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/directives.js
@@ -34,4 +34,3 @@ function (angular) {
   });
 
 });
-
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/ams-screenshot.png b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/ams-screenshot.png
deleted file mode 100644
index 358e42e..0000000
Binary files a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/ams-screenshot.png and /dev/null differ
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo-sm.png b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo-sm.png
deleted file mode 100644
index 0f90391..0000000
Binary files a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo-sm.png and /dev/null differ
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo.png b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo.png
deleted file mode 100644
index 07412bd..0000000
Binary files a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-logo.png and /dev/null differ
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-project.png b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-project.png
deleted file mode 100644
index 7ce8965..0000000
Binary files a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/img/apache-ambari-project.png and /dev/null differ
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.d.ts b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.d.ts
deleted file mode 100644
index 3e12e14..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.d.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { AmbariMetricsDatasource } from './datasource';
-import { AmbariMetricsQueryCtrl } from './query_ctrl';
-import { AmbariMetricsConfigCtrl } from './config_ctrl';
-export { AmbariMetricsDatasource as Datasource, AmbariMetricsQueryCtrl as QueryCtrl, AmbariMetricsConfigCtrl as ConfigCtrl };
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js
deleted file mode 100644
index ebc4f8a..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js
+++ /dev/null
@@ -1,21 +0,0 @@
-System.register(['./datasource', './query_ctrl', './config_ctrl'], function(exports_1) {
-    var datasource_1, query_ctrl_1, config_ctrl_1;
-    return {
-        setters:[
-            function (datasource_1_1) {
-                datasource_1 = datasource_1_1;
-            },
-            function (query_ctrl_1_1) {
-                query_ctrl_1 = query_ctrl_1_1;
-            },
-            function (config_ctrl_1_1) {
-                config_ctrl_1 = config_ctrl_1_1;
-            }],
-        execute: function() {
-            exports_1("Datasource", datasource_1.AmbariMetricsDatasource);
-            exports_1("QueryCtrl", query_ctrl_1.AmbariMetricsQueryCtrl);
-            exports_1("ConfigCtrl", config_ctrl_1.AmbariMetricsConfigCtrl);
-        }
-    }
-});
-//# sourceMappingURL=module.js.map
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js.map b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js.map
deleted file mode 100644
index 5bdb60e..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"module.js","sourceRoot":"","sources":["../../../../../public/app/plugins/datasource/ambari-metrics/module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;YAsB+B,6DAAU;YACX,2DAAS;YACR,8DAAU"}
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.ts b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.ts
deleted file mode 100644
index 137e7c7..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/module.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {AmbariMetricsDatasource} from './datasource';
-import {AmbariMetricsQueryCtrl} from './query_ctrl';
-import {AmbariMetricsConfigCtrl} from './config_ctrl';
-
-export {
-    AmbariMetricsDatasource as Datasource,
-    AmbariMetricsQueryCtrl as QueryCtrl,
-    AmbariMetricsConfigCtrl as ConfigCtrl
-};
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/annotations.editor.html b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/annotations.editor.html
deleted file mode 100644
index e69de29..0000000
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/config.html b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/config.html
index d4ad4b3..360c15c 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/config.html
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/config.html
@@ -15,4 +15,5 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<datasource-http-settings current="ctrl.current"></datasource-http-settings>
\ No newline at end of file
+<div ng-include="httpConfigPartialSrc"></div>
+<br>
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html
index e0f1461..7e78cc0 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.editor.html
@@ -15,98 +15,162 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<query-editor-row query-ctrl="ctrl" can-collapse="true">
-	<div class="gf-form-inline">
-		<div class="gf-form max-width-25">
-    		<label class="gf-form-label query-keyword width-8">
-        		Component
-    		</label>
-        	<input type="text" class="gf-form-input" ng-model="ctrl.target.app"
-               spellcheck='false' bs-typeahead="ctrl.suggestApps" placeholder="Component Name" data-min-length=0 data-items=100
-               ng-blur="ctrl.targetBlur()">
-        	</input>
-    </div>
+<div class="tight-form">
+    <ul class="tight-form-list pull-right">
+        <li class="tight-form-item small" ng-show="target.datasource">
+            <em>{{target.datasource}}</em>
+        </li>
+        <li class="tight-form-item">
+            <div class="dropdown">
+                <a class="pointer dropdown-toggle" data-toggle="dropdown" tabindex="1">
+                    <i class="fa fa-bars"></i>
+                </a>
+                <ul class="dropdown-menu pull-right" role="menu">
+                    <li role="menuitem"><a tabindex="1" ng-click="toggleQueryMode()">Switch editor mode</a></li>
+                    <li role="menuitem"><a tabindex="1" ng-click="duplicateDataQuery(target)">Duplicate</a></li>
+                    <li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index-1)">Move up</a></li>
+                    <li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index+1)">Move down</a></li>
+                </ul>
+            </div>
+        </li>
+        <li class="tight-form-item last">
+            <a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
+                <i class="fa fa-remove"></i>
+            </a>
+        </li>
+    </ul>
 
-    <div class="gf-form">
-    	<label class="gf-form-label query-keyword width-8">
-        	Metric
-    	</label>
-        <input type="text" class="input-large gf-form-input" ng-model="ctrl.target.metric"
-               spellcheck='false' bs-typeahead="ctrl.suggestMetrics" placeholder="metric name" data-min-length=0 data-items=100
-               ng-blur="ctrl.targetBlur()">
-        </input>
-        <a bs-tooltip="ctrl.target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="ctrl.target.errors.metric">
-            <i class="fa fa-warning"></i>
-        </a>
-    </div>
+    <ul class="tight-form-list">
+        <li class="tight-form-item" style="min-width: 15px; text-align: center">
+            {{target.refId}}
+        </li>
+        <li>
+            <a  class="tight-form-item"
+                ng-click="target.hide = !target.hide; get_data();"
+                role="menuitem">
+                <i class="fa fa-eye"></i>
+            </a>
+        </li>
+    </ul>
 
+    <ul class="tight-form-list" role="menu">
 
-    <div class="gf-form">
-    	<label class="gf-form-label query-keyword width-8">
-        Hosts
-    	</label>
-    
-        <input type="text" class="input-large gf-form-input" ng-model="ctrl.target.hosts"
-               spellcheck='false' bs-typeahead="ctrl.suggestHosts" placeholder="host name" data-min-length=0 data-items=100
-               ng-blur="ctrl.targetBlur()">
-        </input>
-        <a bs-tooltip="ctrl.target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="ctrl.target.errors.metric">
-            <i class="fa fa-warning"></i>
-        </a>
-    </div>
+        <li class="tight-form-item" style="width: 86px">
+        Component
+    </li>
+        <li>
+            <input type="text" class="input-large tight-form-input" ng-model="target.app"
+                   spellcheck='false' bs-typeahead="suggestApps" placeholder="Component Name" data-min-length=0 data-items=100
+                   ng-blur="targetBlur()">
+            </input>
+            <a bs-tooltip="target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="target.errors.metric">
+                <i class="fa fa-warning"></i>
+            </a>
+        </li>
 
-    <div class="gf-form">
-    	<label class="gf-form-label query-keyword width-8">
-        Aggregator
-    	</label>
-        <select ng-model="ctrl.target.aggregator" class="gf-form-input input-small"
-                ng-options="agg for agg in ctrl.aggregators"
-                ng-change="ctrl.targetBlur()">
-        </select>
-        <a bs-tooltip="ctrl.target.errors.aggregator" style="color: rgb(229, 189, 28)" ng-show="ctrl.target.errors.aggregator">
-            <i class="fa fa-warning"></i>
-        </a>
-    </div>
+        <li class="tight-form-item" style="width: 86px">
+            Metric
+        </li>
+        <li>
+            <input type="text" class="input-large tight-form-input" ng-model="target.metric"
+                   spellcheck='false' bs-typeahead="suggestMetrics" placeholder="metric name" data-min-length=0 data-items=100
+                   ng-blur="targetBlur()">
+            </input>
+            <a bs-tooltip="target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="target.errors.metric">
+                <i class="fa fa-warning"></i>
+            </a>
+        </li>
 
-	</div>
-	<div class="gf-form-inline">
+        <li class="tight-form-item" style="width: 86px" ng-hide="dashboard.templating.list.length > 0">
+            Cluster
+        </li>
+        <li ng-hide="dashboard.templating.list.length > 0">
+            <input type="text" class="input-large tight-form-input" ng-model="target.cluster"
+                   spellcheck='false' bs-typeahead="suggestClusters" placeholder="cluster name" data-min-length=0 data-items=100
+                   ng-blur="targetBlur()">
+            </input>
+            <a bs-tooltip="target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="target.errors.metric">
+                <i class="fa fa-warning"></i>
+            </a>
+        </li>
+
+        <li class="tight-form-item" style="width: 86px" ng-hide="dashboard.templating.list.length > 0">
+            Hosts
+        </li>
+        <li ng-hide="dashboard.templating.list.length > 0">
+            <input type="text" class="input-large tight-form-input" ng-model="target.hosts"
+                   spellcheck='false' bs-typeahead="suggestHosts" placeholder="host name" data-min-length=0 data-items=100
+                   ng-blur="targetBlur()">
+            </input>
+            <a bs-tooltip="target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="target.errors.metric">
+                <i class="fa fa-warning"></i>
+            </a>
+        </li>
 
-    <div class="gf-form">
-    	<label class="gf-form-label query-keyword width-8">
+        <li class="tight-form-item">
+            Aggregator
+        </li>
+        <li>
+            <select ng-model="target.aggregator" class="tight-form-input input-small"
+                    ng-options="agg for agg in aggregators"
+                    ng-change="targetBlur()">
+            </select>
+            <a bs-tooltip="target.errors.aggregator" style="color: rgb(229, 189, 28)" ng-show="target.errors.aggregator">
+                <i class="fa fa-warning"></i>
+            </a>
+        </li>
+
+    </ul>
+
+    <div class="clearfix"></div>
+</div>
+
+<div class="tight-form">
+    <ul class="tight-form-list" role="menu">
+        <li class="tight-form-item tight-form-align" style="width: 86px">
             Alias
-        </label>
-            <input type="text" class="gf-form-input input-large"
-                   ng-model="ctrl.target.alias"
+        </li>
+        <li>
+            <input type="text" class="tight-form-input input-large"
+                   ng-model="target.alias"
                    spellcheck='false'
                    placeholder="series alias"
                    data-min-length=0 data-items=100
-                   ng-blur="ctrl.targetBlur()"></input>
-            <a bs-tooltip="ctrl.target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="ctrl.target.errors.metric">
+                   ng-blur="targetBlur()"></input>
+            <a bs-tooltip="target.errors.metric" style="color: rgb(229, 189, 28)" ng-show="target.errors.metric">
                 <i class="fa fa-warning"></i>
             </a>
-    </div>
-    
-    <div class="gf-form">
-    	<label class="gf-form-label query-keyword width-8">
-            Transform
-        </label>
-            <select ng-model="ctrl.target.transform" class="gf-form-input input-small"
-                    ng-options="transform for transform in ctrl.transforms"
-                    ng-init="ctrl.transform()"
-                    ng-change="ctrl.targetBlur()"></select>
-    </div>
-
+        </li>
+        <li class="tight-form-item tight-form-align">
+           Transform
+        </li>
+        <li>
+            <select ng-model="target.transform" class="tight-form-input input-small"
+                    ng-options="transform for transform in transforms"
+                    ng-init="transform()"
+                    ng-change="targetBlur()"></select>
+        </li>
 
-    <div class="gf-form">
-    	<label class="gf-form-label query-keyword width-8">
+        <li class="tight-form-item tight-form-align">
             Precision
-        </label>
-            <select ng-model="ctrl.target.precision" class="gf-form-input input-small"
-                    ng-options="precision for precision in ctrl.precisions"
-                    ng-init="ctrl.precisionInit()"
-                    ng-change="ctrl.targetBlur()">
+        </li>
+        <li>
+            <select ng-model="target.precision" class="tight-form-input input-small"
+                    ng-options="precision for precision in precisions"
+                    ng-init="precisionInit()"
+                    ng-change="targetBlur()">
+            </select>
+        </li>
+
+        <li class="tight-form-item">
+            Series Aggregator
+        </li>
+        <li>
+            <select ng-model="target.seriesAggregator" class="tight-form-input input-small"
+                    ng-options="seriesAggregator for seriesAggregator in seriesAggregators"
+                    ng-init="seriesAggregator()"
+                    ng-change="targetBlur()">
             </select>
-    </div>
-        <div class="clearfix"></div>
+        </li>
+    <div class="clearfix"></div>
 </div>
-</query-editor-row>
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.options.html b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.options.html
new file mode 100644
index 0000000..e58ca64
--- /dev/null
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/partials/query.options.html
@@ -0,0 +1,42 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<section class="grafana-metric-options">
+	<div class="tight-form last">
+		<ul class="tight-form-list">
+			<li class="tight-form-item tight-form-item-icon">
+				<i class="fa fa-info-circle"></i>
+			</li>
+			<li class="tight-form-item">
+				<a ng-click="toggleEditorHelp(1);" bs-tooltip="'click to show helpful info'" data-placement="bottom">
+					Single Stats
+				</a>
+			</li>
+		</ul>
+		<div class="clearfix"></div>
+	</div>
+</section>
+
+<div class="editor-row">
+	<div class="pull-left" style="margin-top: 30px;">
+		<div class="grafana-info-box span6" ng-if="editorHelpIndex === 1">
+			<h5>Single Stats</h5>
+			<blockquote>To get the current value of the metric selected, Click on the <strong>Options</strong> tab above
+				and set the <strong>Big Value's</strong> value to <strong>"current"</strong>.</blockquote>
+		</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/plugin.json b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/plugin.json
index 643da57..5226ae7 100644
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/plugin.json
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/plugin.json
@@ -1,21 +1,14 @@
 {
-  "type": "datasource",
-  "name": "Ambari Metrics",
-  "id": "praj-ams-datasource",
-  "metrics": true,
-  "staticRoot": ".",
-  "defaultMatchFormat": "glob",
-  "info": {
-    "author": {
-      "name": "",
-      "url": ""
-    },
-    "links": [
-    ],
-    "logos": {
-      "small": "img/apache-ambari-logo-sm.png",
-      "large": "img/apache-ambari-logo.png"
-    },
-    "version": "1.0.1",
+  "pluginType": "datasource",
+  "name": "AmbariMetrics",
+
+  "type": "ambarimetrics",
+  "serviceName": "AmbariMetricsDatasource",
+
+  "module": "app/plugins/datasource/ambari-metrics/datasource",
+    "partials": {
+    "config": "app/plugins/datasource/ambari-metrics/partials/config.html"
   },
-}
+
+  "metrics": true
+}
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/queryCtrl.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/queryCtrl.js
new file mode 100644
index 0000000..02b5813
--- /dev/null
+++ b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/queryCtrl.js
@@ -0,0 +1,160 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+define([
+      'angular',
+      'lodash'
+    ],
+    function (angular, _) {
+      'use strict';
+
+      var module = angular.module('grafana.controllers');
+
+      module.controller('AmbariMetricsQueryCtrl', function($scope) {
+
+        $scope.init = function() {
+          $scope.target.errors = validateTarget($scope.target);
+          $scope.aggregators = ['none','avg', 'sum', 'min', 'max'];
+          $scope.precisions = ['default','seconds', 'minutes', 'hours', 'days'];
+          $scope.transforms = ['none','diff','rate'];
+          $scope.seriesAggregators = ['none', 'avg', 'sum', 'min', 'max'];
+
+          if (!$scope.target.aggregator) {
+            $scope.target.aggregator = 'avg';
+          }
+          $scope.precisionInit = function () {
+           if (typeof $scope.target.precision == 'undefined') {
+                $scope.target.precision = "default";
+           }
+          };
+          $scope.transform = function () {
+           if (typeof $scope.target.transform == 'undefined') {
+                $scope.target.transform = "none";
+           }
+          };
+          $scope.seriesAggregator = function () {
+           if (typeof $scope.target.seriesAggregator == 'undefined') {
+                $scope.target.seriesAggregator = "none";
+           }
+          };
+          $scope.$watch('target.app', function (newValue) {
+            if (newValue === '') {
+              $scope.target.metric = '';
+              $scope.target.hosts = '';
+              $scope.target.cluster = '';
+            }
+          });
+          if (!$scope.target.downsampleAggregator) {
+            $scope.target.downsampleAggregator = 'avg';
+          }
+
+          $scope.datasource.getAggregators().then(function(aggs) {
+            $scope.aggregators = aggs;
+          });
+        };
+
+        $scope.targetBlur = function() {
+          $scope.target.errors = validateTarget($scope.target);
+
+          // this does not work so good
+          if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
+            $scope.oldTarget = angular.copy($scope.target);
+            $scope.get_data();
+          }
+        };
+
+        $scope.getTextValues = function(metricFindResult) {
+          return _.map(metricFindResult, function(value) { return value.text; });
+        };
+
+        $scope.suggestApps = function(query, callback) {
+          $scope.datasource.suggestApps(query)
+            .then($scope.getTextValues)
+            .then(callback);
+        };
+
+        $scope.suggestClusters = function(query, callback) {
+          $scope.datasource.suggestClusters($scope.target.app)
+            .then($scope.getTextValues)
+            .then(callback);
+        };
+
+        $scope.suggestHosts = function(query, callback) {
+          $scope.datasource.suggestHosts($scope.target.app, $scope.target.cluster)
+            .then($scope.getTextValues)
+            .then(callback);
+        };
+
+        $scope.suggestMetrics = function(query, callback) {
+          $scope.datasource.suggestMetrics(query, $scope.target.app)
+            .then($scope.getTextValues)
+            .then(callback);
+        };
+
+        $scope.suggestTagKeys = function(query, callback) {
+          $scope.datasource.metricFindQuery('tag_names(' + $scope.target.metric + ')')
+              .then($scope.getTextValues)
+              .then(callback);
+        };
+
+        $scope.suggestTagValues = function(query, callback) {
+          $scope.datasource.metricFindQuery('tag_values(' + $scope.target.metric + ',' + $scope.target.currentTagKey + ')')
+              .then($scope.getTextValues)
+              .then(callback);
+        };
+
+        $scope.addTag = function() {
+          if (!$scope.addTagMode) {
+            $scope.addTagMode = true;
+            return;
+          }
+
+          if (!$scope.target.tags) {
+            $scope.target.tags = {};
+          }
+
+          $scope.target.errors = validateTarget($scope.target);
+
+          if (!$scope.target.errors.tags) {
+            $scope.target.tags[$scope.target.currentTagKey] = $scope.target.currentTagValue;
+            $scope.target.currentTagKey = '';
+            $scope.target.currentTagValue = '';
+            $scope.targetBlur();
+          }
+
+          $scope.addTagMode = false;
+        };
+
+        $scope.removeTag = function(key) {
+          delete $scope.target.tags[key];
+          $scope.targetBlur();
+        };
+
+        function validateTarget(target) {
+          var errs = {};
+
+          if (target.tags && _.has(target.tags, target.currentTagKey)) {
+            errs.tags = "Duplicate tag key '" + target.currentTagKey + "'.";
+          }
+
+          return errs;
+        }
+
+        $scope.init();
+      });
+
+    });
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.d.ts b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.d.ts
deleted file mode 100644
index 83363f7..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.d.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/// <reference path="../../../../../public/app/headers/common.d.ts" />
-import { QueryCtrl } from 'app/plugins/sdk';
-export declare class AmbariMetricsQueryCtrl extends QueryCtrl {
-    static templateUrl: string;
-    aggregators: any;
-    aggregator: any;
-    errors: any;
-    precisions: any;
-    transforms: any;
-    transform: any;
-    precisionInit: any;
-    suggestMetrics: any;
-    suggestApps: any;
-    suggestHosts: any;
-    /** @ngInject **/
-    constructor($scope: any, $injector: any);
-    targetBlur(): void;
-    getTextValues(metricFindResult: any): any;
-    getCollapsedText(): string;
-    validateTarget(): any;
-}
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js
deleted file mode 100644
index 5b5c4a9..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js
+++ /dev/null
@@ -1,152 +0,0 @@
-"use strict";
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-var __extends = (this && this.__extends) || (function () {
-    var extendStatics = function (d, b) {
-        extendStatics = Object.setPrototypeOf ||
-            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-        return extendStatics(d, b);
-    }
-    return function (d, b) {
-        extendStatics(d, b);
-        function __() { this.constructor = d; }
-        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-    };
-})();
-exports.__esModule = true;
-///<reference path="../../../headers/common.d.ts" />
-var angular_1 = require("angular");
-var lodash_1 = require("lodash");
-var sdk_1 = require("app/plugins/sdk");
-var AmbariMetricsQueryCtrl = /** @class */ (function (_super) {
-    __extends(AmbariMetricsQueryCtrl, _super);
-    /** @ngInject **/
-    function AmbariMetricsQueryCtrl($scope, $injector) {
-        var _this = _super.call(this, $scope, $injector) || this;
-        _this.targetBlur = function () {
-            this.target.errors = this.validateTarget(this.target);
-            // this does not work so good
-            if (!lodash_1["default"].isEqual(this.oldTarget, this.target) && lodash_1["default"].isEmpty(this.target.errors)) {
-                this.oldTarget = angular_1["default"].copy(this.target);
-                this.get_data();
-            }
-        };
-        _this.getTextValues = function (metricFindResult) {
-            return lodash_1["default"].map(metricFindResult, function (value) { return value.text; });
-        };
-        _this.suggestApps = function (query, callback) {
-            this.datasource.suggestApps(query)
-                .then(this.getTextValues)
-                .then(callback);
-        };
-        _this.suggestClusters = function (query, callback) {
-            this.datasource.suggestClusters(this.target.app)
-                .then(this.getTextValues)
-                .then(callback);
-        };
-        _this.suggestHosts = function (query, callback) {
-            this.datasource.suggestHosts(this.target.app, this.target.cluster)
-                .then(this.getTextValues)
-                .then(callback);
-        };
-        _this.suggestMetrics = function (query, callback) {
-            this.datasource.suggestMetrics(query, this.target.app)
-                .then(this.getTextValues)
-                .then(callback);
-        };
-        _this.suggestTagKeys = function (query, callback) {
-            this.datasource.metricFindQuery('tag_names(' + this.target.metric + ')')
-                .then(this.getTextValues)
-                .then(callback);
-        };
-        _this.suggestTagValues = function (query, callback) {
-            this.datasource.metricFindQuery('tag_values(' + this.target.metric + ',' + this.target.currentTagKey + ')')
-                .then(this.getTextValues)
-                .then(callback);
-        };
-        _this.addTag = function () {
-            if (!this.addTagMode) {
-                this.addTagMode = true;
-                return;
-            }
-            if (!this.target.tags) {
-                this.target.tags = {};
-            }
-            this.target.errors = this.validateTarget(this.target);
-            if (!this.target.errors.tags) {
-                this.target.tags[this.target.currentTagKey] = this.target.currentTagValue;
-                this.target.currentTagKey = '';
-                this.target.currentTagValue = '';
-                this.targetBlur();
-            }
-            this.addTagMode = false;
-        };
-        _this.removeTag = function (key) {
-            delete this.target.tags[key];
-            this.targetBlur();
-        };
-        _this.validateTarget = function (target) {
-            var errs = {};
-            if (target.tags && lodash_1["default"].has(target.tags, target.currentTagKey)) {
-                errs.tags = "Duplicate tag key '" + target.currentTagKey + "'.";
-            }
-            return errs;
-        };
-        _this.errors = _this.validateTarget(_this.target);
-        _this.aggregators = ['none', 'avg', 'sum', 'min', 'max'];
-        _this.precisions = ['default', 'seconds', 'minutes', 'hours', 'days'];
-        _this.transforms = ['none', 'diff', 'rate'];
-        _this.seriesAggregators = ['none', 'avg', 'sum', 'min', 'max'];
-        if (!_this.target.aggregator) {
-            _this.target.aggregator = 'avg';
-        }
-        _this.precisionInit = function () {
-            if (typeof this.target.precision == 'undefined') {
-                this.target.precision = "default";
-            }
-        };
-        _this.transform = function () {
-            if (typeof this.target.transform == 'undefined') {
-                this.target.transform = "none";
-            }
-        };
-        _this.seriesAggregator = function () {
-            if (typeof $scope.target.seriesAggregator == 'undefined') {
-                this.target.seriesAggregator = "none";
-            }
-        };
-        _this.$watch('target.app', function (newValue) {
-            if (newValue === '') {
-                this.target.metric = '';
-                this.target.hosts = '';
-                this.target.cluster = '';
-            }
-        });
-        if (!_this.target.downsampleAggregator) {
-            _this.target.downsampleAggregator = 'avg';
-        }
-        _this.datasource.getAggregators().then(function (aggs) {
-            this.aggregators = aggs;
-        });
-        return _this;
-    }
-    AmbariMetricsQueryCtrl.templateUrl = 'partials/query.editor.html';
-    return AmbariMetricsQueryCtrl;
-}(sdk_1.QueryCtrl));
-exports.AmbariMetricsQueryCtrl = AmbariMetricsQueryCtrl;
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js.map b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js.map
deleted file mode 100644
index 2f80a63..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"query_ctrl.js","sourceRoot":"","sources":["../../../../../public/app/plugins/datasource/ambari-metrics/query_ctrl.ts"],"names":["AmbariMetricsQueryCtrl","AmbariMetricsQueryCtrl.constructor","AmbariMetricsQueryCtrl.targetBlur","AmbariMetricsQueryCtrl.getTextValues","AmbariMetricsQueryCtrl.getCollapsedText","AmbariMetricsQueryCtrl.validateTarget"],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,oDAAoD;;;;;;;;;;;;;;;;;;YAMpD;gBAA4CA,0CAASA;gBAajDA,iBAAiBA;gBACjBA,gCAAYA,MAAM [...]
\ No newline at end of file
diff --git a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.ts b/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.ts
deleted file mode 100644
index 70087b6..0000000
--- a/ambari-metrics/ambari-metrics-grafana/ambari-metrics/query_ctrl.ts
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-///<reference path="../../../headers/common.d.ts" />
-
-import angular from 'angular';
-import _ from 'lodash';
-import {QueryCtrl} from "app/plugins/sdk";
-
-export class AmbariMetricsQueryCtrl extends QueryCtrl {
-
-    static templateUrl = 'partials/query.editor.html';
-    aggregators: any;
-    aggregator: any;
-    errors: any;
-    precisions: any;
-    transforms: any;
-    transform: any;
-    precisionInit: any;
-    suggestMetrics: any;
-    suggestApps: any;
-    suggestHosts: any;
-    seriesAggregators: any;
-
-    /** @ngInject **/
-    constructor($scope, $injector) {
-        super($scope, $injector);
-        this.errors = this.validateTarget(this.target);
-        this.aggregators = ['none','avg', 'sum', 'min', 'max'];
-        this.precisions = ['default','seconds', 'minutes', 'hours', 'days'];
-        this.transforms = ['none','diff','rate'];
-        this.seriesAggregators = ['none', 'avg', 'sum', 'min', 'max'];
-
-        if (!this.target.aggregator) {
-            this.target.aggregator = 'avg';
-        }
-        this.precisionInit = function () {
-            if (typeof this.target.precision == 'undefined') {
-                this.target.precision = "default";
-            }
-        };
-        this.transform = function () {
-            if (typeof this.target.transform == 'undefined') {
-                this.target.transform = "none";
-            }
-        };
-        this.seriesAggregator = function () {
-            if (typeof $scope.target.seriesAggregator == 'undefined') {
-                this.target.seriesAggregator = "none";
-            }
-        };
-        this.$watch('target.app', function (newValue) {
-            if (newValue === '') {
-                this.target.metric = '';
-                this.target.hosts = '';
-                this.target.cluster = '';
-            }
-        });
-        if (!this.target.downsampleAggregator) {
-            this.target.downsampleAggregator = 'avg';
-        }
-
-        this.datasource.getAggregators().then(function(aggs) {
-            this.aggregators = aggs;
-        });
-    }
-
-    targetBlur = function() {
-        this.target.errors = this.validateTarget(this.target);
-
-        // this does not work so good
-        if (!_.isEqual(this.oldTarget, this.target) && _.isEmpty(this.target.errors)) {
-            this.oldTarget = angular.copy(this.target);
-            this.get_data();
-        }
-    };
-
-    getTextValues = function(metricFindResult) {
-        return _.map(metricFindResult, function(value) { return value.text; });
-    };
-
-    suggestApps = function(query, callback) {
-        this.datasource.suggestApps(query)
-            .then(this.getTextValues)
-            .then(callback);
-    };
-
-    suggestClusters = function(query, callback) {
-        this.datasource.suggestClusters(this.target.app)
-            .then(this.getTextValues)
-            .then(callback);
-    };
-
-    suggestHosts = function(query, callback) {
-        this.datasource.suggestHosts(this.target.app, this.target.cluster)
-            .then(this.getTextValues)
-            .then(callback);
-    };
-
-    suggestMetrics = function(query, callback) {
-        this.datasource.suggestMetrics(query, this.target.app)
-            .then(this.getTextValues)
-            .then(callback);
-    };
-
-    suggestTagKeys = function(query, callback) {
-        this.datasource.metricFindQuery('tag_names(' + this.target.metric + ')')
-            .then(this.getTextValues)
-            .then(callback);
-    };
-
-    suggestTagValues = function(query, callback) {
-        this.datasource.metricFindQuery('tag_values(' + this.target.metric + ',' + this.target.currentTagKey + ')')
-            .then(this.getTextValues)
-            .then(callback);
-    };
-
-    addTag = function() {
-        if (!this.addTagMode) {
-            this.addTagMode = true;
-            return;
-        }
-
-        if (!this.target.tags) {
-            this.target.tags = {};
-        }
-
-        this.target.errors = this.validateTarget(this.target);
-
-        if (!this.target.errors.tags) {
-            this.target.tags[this.target.currentTagKey] = this.target.currentTagValue;
-            this.target.currentTagKey = '';
-            this.target.currentTagValue = '';
-            this.targetBlur();
-        }
-
-        this.addTagMode = false;
-    };
-
-    removeTag = function(key) {
-        delete this.target.tags[key];
-        this.targetBlur();
-    };
-
-    validateTarget = function(target) {
-        var errs = {};
-
-        if (target.tags && _.has(target.tags, target.currentTagKey)) {
-            errs.tags = "Duplicate tag key '" + target.currentTagKey + "'.";
-        }
-
-        return errs;
-    }
-}