浏览代码

AMBARI-16244. Show the connect string with the HiveServer instance. (Jaimin)

Jaimin Jetly 9 年之前
父节点
当前提交
111cc827d0

+ 30 - 0
LICENSE.txt

@@ -738,6 +738,35 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 
 
+For clipboard.js 1.5.10 (ambari/ambari-web/vendor/scripts/clipboard.min.js):
+
+clipboard.js v1.5.10
+https://clipboardjs.com/
+Copyright 2016 Zeno Rocha <hi@zenorocha.com>
+Clipboard may be freely distributed under the MIT license.
+
+MIT license selected:
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
 For MockJax 1.6.0 (contrib/views/slider/src/main/resources/ui/app/assets/javascripts/jquery.mockjax.js,
 For MockJax 1.6.0 (contrib/views/slider/src/main/resources/ui/app/assets/javascripts/jquery.mockjax.js,
 /contrib/views/files/src/main/resources/ui/app/assets/javascripts/jquery.mockjax.js,
 /contrib/views/files/src/main/resources/ui/app/assets/javascripts/jquery.mockjax.js,
 /contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/javascripts/jquery.mockjax.js):
 /contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/javascripts/jquery.mockjax.js):
@@ -892,4 +921,5 @@ This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
 
 
 This product uses software based on SIL Open Font License (OFL)
 This product uses software based on SIL Open Font License (OFL)
 * Font-Awesome (SIL OFL 1.1) [http://fortawesome.github.io/Font-Awesome/]
 * Font-Awesome (SIL OFL 1.1) [http://fortawesome.github.io/Font-Awesome/]
+* Image clippy.svg from Octicon project (SIL OFL 1.1)  [https://octicons.github.com/]
 
 

+ 3 - 0
ambari-web/app/assets/img/clippy.svg

@@ -0,0 +1,3 @@
+<svg height="16" width="14" xmlns="http://www.w3.org/2000/svg">
+  <path d="M2 12h4v1H2v-1z m5-6H2v1h5v-1z m2 3V7L6 10l3 3V11h5V9H9z m-4.5-1H2v1h2.5v-1zM2 11h2.5v-1H2v1z m9 1h1v2c-0.02 0.28-0.11 0.52-0.3 0.7s-0.42 0.28-0.7 0.3H1c-0.55 0-1-0.45-1-1V3c0-0.55 0.45-1 1-1h3C4 0.89 4.89 0 6 0s2 0.89 2 2h3c0.55 0 1 0.45 1 1v5h-1V5H1v9h10V12zM2 4h8c0-0.55-0.45-1-1-1h-1c-0.55 0-1-0.45-1-1s-0.45-1-1-1-1 0.45-1 1-0.45 1-1 1h-1c-0.55 0-1 0.45-1 1z" />
+</svg>

+ 1 - 1
ambari-web/app/controllers/global/configuration_controller.js

@@ -56,7 +56,7 @@ App.ConfigurationController = Em.Controller.extend({
     var i = 0;
     var i = 0;
     while (i < tags.length && !isDifferent) {
     while (i < tags.length && !isDifferent) {
       var storedTag = storedTags.findProperty('siteName', tags[i].siteName);
       var storedTag = storedTags.findProperty('siteName', tags[i].siteName);
-      isDifferent = (!storedTag || storedTag.tagName !== tags[i].tagName);
+      isDifferent = (!storedTag || !tags[i].tagName || storedTag.tagName !== tags[i].tagName);
       i++;
       i++;
     }
     }
     return isDifferent;
     return isDifferent;

+ 65 - 0
ambari-web/app/controllers/main/service/info/summary.js

@@ -44,6 +44,12 @@ App.MainServiceInfoSummaryController = Em.Controller.extend(App.WidgetSectionMix
 
 
   sectionNameSuffix: "_SUMMARY",
   sectionNameSuffix: "_SUMMARY",
 
 
+  /**
+   * HiveServer2 JDBC connection endpoint data
+   * @type {array}
+   */
+  hiveServerEndPoints: [],
+
   /**
   /**
    * Ranger plugins data
    * Ranger plugins data
    * @type {array}
    * @type {array}
@@ -222,6 +228,65 @@ App.MainServiceInfoSummaryController = Em.Controller.extend(App.WidgetSectionMix
     this.set('isPreviousRangerConfigsCallFailed', true);
     this.set('isPreviousRangerConfigsCallFailed', true);
   },
   },
 
 
+  /**
+   * This method is invoked when hive view is rendered to fetch and display
+   * information for JDBC connect string for HiveServer2 instances
+   * @method  setHiveEndPointsValue
+   * @public
+   */
+  setHiveEndPointsValue: function() {
+    var self = this;
+    var tags = [
+      {
+        siteName: 'hive-site'
+      },
+      {
+        siteName: 'hive-interactive-site'
+      }
+    ];
+
+    var siteToComponentMap = {
+      'hive-site': 'HIVE_SERVER',
+      'hive-interactive-site': 'HIVE_SERVER_INTERACTIVE'
+    };
+
+    App.router.get('configurationController').getConfigsByTags(tags).done(function (configs) {
+
+      var hiveSiteIndex =  configs.map(function(item){
+        return item.type;
+      }).indexOf('hive-site');
+
+      // if hive-site is not first item then rotate the array to make it first
+      if (!!hiveSiteIndex) {
+        configs.push(configs.shift());
+      }
+
+      var hiveSiteDynamicDiscovery = configs[0].properties['hive.server2.support.dynamic.service.discovery'];
+      var hiveSiteZkNameSpace =  configs[0].properties['hive.server2.zookeeper.namespace'];
+      var hiveSiteZkQuorom =  configs[0].properties['hive.zookeeper.quorum'];
+
+
+      configs.forEach(function(_config) {
+        var masterComponent = App.MasterComponent.find().findProperty('componentName', siteToComponentMap[_config.type]);
+        if (_config.type === 'hive-interactive-site') {
+          hiveSiteDynamicDiscovery =  _config.properties['hive.server2.support.dynamic.service.discovery'] || hiveSiteDynamicDiscovery;
+          hiveSiteZkQuorom =  _config.properties['hive.zookeeper.quorum'] || hiveSiteZkQuorom;
+          hiveSiteZkNameSpace =  _config.properties['hive.server2.zookeeper.namespace'] || hiveSiteZkNameSpace;
+        }
+        if (masterComponent && !!masterComponent.get('totalCount')) {
+          var hiveEndPoint = {
+            isVisible: hiveSiteDynamicDiscovery,
+            componentName: masterComponent.get('componentName'),
+            label: masterComponent.get('displayName') + ' Endpoint',
+            value: Em.I18n.t('services.service.summary.hiveserver2.endpoint.value').format(hiveSiteZkQuorom, hiveSiteZkNameSpace),
+            tooltipText: Em.I18n.t('services.service.summary.hiveserver2.endpoint.tooltip.text').format(masterComponent.get('displayName'))
+          };
+          self.get('hiveServerEndPoints').pushObject(Em.Object.create(hiveEndPoint));
+        }
+      });
+    });
+  },
+
   /**
   /**
    * Send start command for selected Flume Agent
    * Send start command for selected Flume Agent
    * @method startFlumeAgent
    * @method startFlumeAgent

+ 2 - 0
ambari-web/app/messages.js

@@ -1756,6 +1756,8 @@ Em.I18n.translations = {
   'services.service.summary.moreStats':'more stats here',
   'services.service.summary.moreStats':'more stats here',
   'services.service.summary.clientCount': '{0} Client Hosts',
   'services.service.summary.clientCount': '{0} Client Hosts',
   'services.service.summary.historyServer': 'History Server Web UI',
   'services.service.summary.historyServer': 'History Server Web UI',
+  'services.service.summary.hiveserver2.endpoint.tooltip.text':'JDBC connection string for {0}',
+  'services.service.summary.hiveserver2.endpoint.value':'jdbc:hive2://{0}/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace={1}',
   'services.service.actions.downloadClientConfigs':'Download Client Configs',
   'services.service.actions.downloadClientConfigs':'Download Client Configs',
   'services.service.actions.downloadClientConfigs.fail.noConfigFile':'No configuration files defined for the component',
   'services.service.actions.downloadClientConfigs.fail.noConfigFile':'No configuration files defined for the component',
   'services.service.actions.downloadClientConfigs.fail.popup.header':'{0} Configs',
   'services.service.actions.downloadClientConfigs.fail.popup.header':'{0} Configs',

+ 19 - 18
ambari-web/app/templates/main/service/services/hive.hbs

@@ -16,22 +16,23 @@
 * limitations under the License.
 * limitations under the License.
 }}
 }}
 
 
-<div class="clearfix">
-  <div class="name span2">
-    <i class="pull-left icon-empty"></i>
-    {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
-    <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
-    {{#if view.alertsCount}}
-      <a href="#" class="label label-important" {{action "showAlertsPopup" view.service target="view.parentView"}}>
-        {{view.alertsCount}}
-      </a>
-    {{/if}}
-  </div>
-  <div class="summary span">
-    {{#each component in view.titleMasters}}
-      <a href="#" {{action showDetails component.host}}>{{component.displayName}}</a>,
-    {{/each}}
+{{view App.SummaryMasterComponentsView mastersCompBinding="view.parentView.mastersObj"}}
+{{view App.SummaryClientComponentsView clientsObjBinding="view.parentView.clientObj"}}
 
 
-    <a href="#" {{action filterHosts view.clients.component}}>{{view.clients.title}}</a>
-  </div>
-</div>
+<tr class="hidden"><td></td></tr>
+
+{{#each endpoint in hiveServerEndPoints}}
+  {{#if endpoint.isVisible}}
+   <tr {{bindAttr class=":component endpoint.componentName"}}>
+     <td class="summary-label">{{endpoint.label}}</td>
+     <td class="summary-value" >
+       {{#view view.summaryValueView titleBinding="endpoint.tooltipText" data-toggle="tooltip"}}
+         {{endpoint.value}}
+       {{/view}}
+       {{#view view.clipBoardView data-clipboard-action= "copy" data-clipboard-textBinding="endpoint.value"}}
+         <img src="/img/clippy.svg" alt="Copy" rel="clipboard-tooltip" data-toggle="tooltip" data-placement="bottom" title="Copied!"/>
+       {{/view}}
+     </td>
+   </tr>
+  {{/if}}
+{{/each}}

+ 2 - 1
ambari-web/app/views/main/service/info/summary.js

@@ -72,7 +72,8 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin
       STORM: App.MainDashboardServiceStormView,
       STORM: App.MainDashboardServiceStormView,
       YARN: App.MainDashboardServiceYARNView,
       YARN: App.MainDashboardServiceYARNView,
       RANGER: App.MainDashboardServiceRangerView,
       RANGER: App.MainDashboardServiceRangerView,
-      FLUME: App.MainDashboardServiceFlumeView
+      FLUME: App.MainDashboardServiceFlumeView,
+      HIVE:  App.MainDashboardServiceHiveView
     }
     }
   }.property('serviceName'),
   }.property('serviceName'),
   /** @property collapsedMetrics {object[]} - metrics list for collapsed section
   /** @property collapsedMetrics {object[]} - metrics list for collapsed section

+ 75 - 5
ambari-web/app/views/main/service/services/hive.js

@@ -20,10 +20,80 @@ var App = require('app');
 
 
 App.MainDashboardServiceHiveView = App.MainDashboardServiceView.extend({
 App.MainDashboardServiceHiveView = App.MainDashboardServiceView.extend({
   templateName: require('templates/main/service/services/hive'),
   templateName: require('templates/main/service/services/hive'),
-  serviceName: 'hive',
+  serviceName: 'HIVE',
+  
+  didInsertElement: function () {
+    var controller = this.get('controller');
+    this._super();
+    App.router.get('mainController').isLoading.call(App.router.get('clusterController'), 'isComponentsStateLoaded').done(function () {
+      controller.setHiveEndPointsValue();
+    });
+  },
 
 
-  titleMasters: function () {
-    var masters = this.get('masters');
-    return [masters.findProperty('componentName', 'HIVE_SERVER'), masters.findProperty('componentName', 'HIVE_METASTORE')];
-  }.property('masters')
+  willDestroyElement: function () {
+    this.get('controller.hiveServerEndPoints').clear();
+  },
+
+  /**
+   * view for JDBC connection String
+   */
+  summaryValueView: Em.View.extend({
+    tagName: 'span',
+    attributeBindings: ['title'],
+
+    didInsertElement: function() {
+      this.setEllipsis();
+      this.setTooltip();
+    },
+
+    /**
+     * sets the Hive JDBC connection text with ellipsis
+     */
+    setEllipsis: function() {
+      var $ = this.$();
+      var text =  $.text();
+      var MAX_LENGTH = 32;
+      var ellipsis = '...';
+      var length = MAX_LENGTH > text.length ? text.length : MAX_LENGTH;
+      var start = Math.max(length - ellipsis.length, ellipsis.length);
+      text = text.slice(0, start);
+      text += ellipsis;
+      $.text(text);
+    },
+
+    /**
+     * sets the tooltip for Hive JDBC connection string
+     */
+    setTooltip: function() {
+      var $ = this.$();
+      Em.run.next(function () {
+        $.tooltip();
+      });
+    }
+  }),
+
+  /**
+   * View for clipboard image that copies JDBC connection string
+   */
+  clipBoardView: Em.View.extend({
+    tagName: 'a',
+    href: "javascript:void(null)",
+    attributeBindings: ['data-clipboard-text', 'data-clipboard-action', "href"],
+    didInsertElement: function() {
+      var $this =  this.$();
+      var id = "#" + $this.attr('id');
+      var clipboard = new Clipboard(id);
+      var options = {
+        trigger: "click"
+      };
+      Em.run.next(function () {
+        $("[rel=clipboard-tooltip]").tooltip(options);
+      });
+    },
+    mouseLeave: function() {
+      Em.run.next(function () {
+        $("[rel=clipboard-tooltip]").tooltip("hide");
+      });
+    }
+  })
 });
 });

+ 0 - 16
ambari-web/test/views/main/service/services/hive_test.js

@@ -25,20 +25,4 @@ describe('App.MainDashboardServiceHiveView', function () {
   beforeEach(function() {
   beforeEach(function() {
     view = App.MainDashboardServiceHiveView.create();
     view = App.MainDashboardServiceHiveView.create();
   });
   });
-
-  describe("#titleMasters", function () {
-
-    it("should pass components", function () {
-      view.set('masters', [
-        Em.Object.create({
-          componentName: 'HIVE_SERVER'
-        }),
-        Em.Object.create({
-          componentName: 'HIVE_METASTORE'
-        })
-      ]);
-      view.propertyDidChange('titleMasters');
-      expect(view.get('titleMasters')).to.be.eql([view.get('masters')[0], view.get('masters')[1]]);
-    });
-  });
 });
 });

文件差异内容过多而无法显示
+ 6 - 0
ambari-web/vendor/scripts/clipboard.min.js


部分文件因为文件数量过多而无法显示