AMBARI-22424. Quicklinks for OneFS (amagyar)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6fedb9f5 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6fedb9f5 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6fedb9f5 Branch: refs/heads/branch-feature-AMBARI-22008 Commit: 6fedb9f5ee4be16d2c856f944d8b7322d348ff33 Parents: 43840c5 Author: Attila Magyar <amag...@hortonworks.com> Authored: Mon Nov 13 16:00:50 2017 +0100 Committer: Attila Magyar <amag...@hortonworks.com> Committed: Wed Nov 22 10:55:11 2017 +0100 ---------------------------------------------------------------------- .../ambari/server/state/quicklinks/Host.java | 75 ++++++++++++++++++++ .../ambari/server/state/quicklinks/Link.java | 13 ++++ .../QuickLinksConfigurationModuleTest.java | 3 + .../resources/child_quicklinks_to_override.json | 4 ++ .../app/views/common/quick_view_link_view.js | 64 +++++++++++++---- .../test/views/common/quick_link_view_test.js | 15 +++- .../addon-services/ONEFS/1.0.0/metainfo.xml | 7 ++ .../ONEFS/1.0.0/quicklinks/quicklinks.json | 31 ++++++++ 8 files changed, 197 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/6fedb9f5/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinks/Host.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinks/Host.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinks/Host.java new file mode 100644 index 0000000..074d4e7 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinks/Host.java @@ -0,0 +1,75 @@ +/* + * 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. + */ + +package org.apache.ambari.server.state.quicklinks; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.map.annotate.JsonSerialize; + +/** + * Quick links may override host names of host components with host names that come from configuration. + */ +@JsonSerialize(include= JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Host { + /** + * The property name that has the host name if the protocol is http + */ + @JsonProperty("http_property") + private String httpProperty; + + /** + * The property name that has the host name if the protocol is https + */ + @JsonProperty("https_property") + private String httpsProperty; + + /** + * The config type where the overridden host name comes from + */ + @JsonProperty("site") + private String site; + + public String getHttpProperty() { + return httpProperty; + } + + public String getHttpsProperty() { + return httpsProperty; + } + + public String getSite() { + return site; + } + + public void mergeWithParent(Host parentHost) { + if(null == parentHost) { + return; + } + if(null == httpProperty && null != parentHost.getHttpProperty()) { + httpProperty = parentHost.getHttpProperty(); + } + if(null == httpsProperty && null != parentHost.getHttpsProperty()) { + httpsProperty = parentHost.getHttpsProperty(); + } + if(null == site && null != parentHost.getSite()) { + site = parentHost.getSite(); + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/6fedb9f5/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinks/Link.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinks/Link.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinks/Link.java index 1d2e712..4e8e8a3 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinks/Link.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinks/Link.java @@ -47,6 +47,9 @@ public class Link{ @JsonProperty("port") private Port port; + @JsonProperty("host") + private Host host; + @JsonProperty("protocol") private Protocol protocol; @@ -100,6 +103,10 @@ public class Link{ return port; } + public Host getHost() { + return host; + } + public void setPort(Port port) { this.port = port; } @@ -159,6 +166,12 @@ public class Link{ port.mergetWithParent(parentLink.getPort()); } + if(null == host){ + host = parentLink.getHost(); + } else { + host.mergeWithParent(parentLink.getHost()); + } + if (null == attributes && null != parentLink.attributes) { attributes = parentLink.attributes; } http://git-wip-us.apache.org/repos/asf/ambari/blob/6fedb9f5/ambari-server/src/test/java/org/apache/ambari/server/stack/QuickLinksConfigurationModuleTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/QuickLinksConfigurationModuleTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/QuickLinksConfigurationModuleTest.java index aac278d..040d630 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/stack/QuickLinksConfigurationModuleTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/QuickLinksConfigurationModuleTest.java @@ -33,6 +33,7 @@ import java.util.Set; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.state.quicklinks.Check; +import org.apache.ambari.server.state.quicklinks.Host; import org.apache.ambari.server.state.quicklinks.Link; import org.apache.ambari.server.state.quicklinks.Port; import org.apache.ambari.server.state.quicklinks.Protocol; @@ -127,6 +128,8 @@ public class QuickLinksConfigurationModuleTest { hasLink = true; Port port = link.getPort(); assertEquals("mapred-site", port.getSite()); + Host host = link.getHost(); + assertEquals("core-site", host.getSite()); } } assertTrue(hasLink); http://git-wip-us.apache.org/repos/asf/ambari/blob/6fedb9f5/ambari-server/src/test/resources/child_quicklinks_to_override.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/child_quicklinks_to_override.json b/ambari-server/src/test/resources/child_quicklinks_to_override.json index 4309532..0aaec1f 100644 --- a/ambari-server/src/test/resources/child_quicklinks_to_override.json +++ b/ambari-server/src/test/resources/child_quicklinks_to_override.json @@ -79,6 +79,10 @@ "https_default_port": "8090", "regex": "\\w*:(\\d+)", "site": "mapred-site" + }, + "host":{ + "http_property": "fs.defaultFS", + "site": "core-site" } } ] http://git-wip-us.apache.org/repos/asf/ambari/blob/6fedb9f5/ambari-web/app/views/common/quick_view_link_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/quick_view_link_view.js b/ambari-web/app/views/common/quick_view_link_view.js index 5888acb..3ccc973 100644 --- a/ambari-web/app/views/common/quick_view_link_view.js +++ b/ambari-web/app/views/common/quick_view_link_view.js @@ -206,11 +206,8 @@ App.QuickLinksView = Em.View.extend({ if (!Em.isEmpty(links)) { links.forEach(function (link) { if (!link.remove) { - var portConfig = Em.get(link, 'port'); - var portConfigSiteProp = Em.get(portConfig, 'site'); - if (!sites.contains(portConfigSiteProp)) { - sites.push(portConfigSiteProp); - } + this.addSite(link, 'host', sites); + this.addSite(link, 'port', sites); } }, this); this.set('requiredSiteNames', this.get('requiredSiteNames').pushObjects(sites).uniq()); @@ -222,6 +219,16 @@ App.QuickLinksView = Em.View.extend({ } }, + addSite: function(link, linkPropertyName, sites) { + var config = Em.get(link, linkPropertyName); + if (config) { + var siteName = Em.get(config, 'site'); + if (!sites.contains(siteName)) { + sites.push(siteName); + } + } + }, + /** * call for public host names * @@ -267,8 +274,8 @@ App.QuickLinksView = Em.View.extend({ }); // no need to set quicklinks if // 1)current service does not have quick links configured - // 2)No host component present for the configured quicklinks - if(hasQuickLinks && hasHosts) { + // 2)No host component present for the configured quicklinks and has no overridden hosts + if(hasQuickLinks && (hasHosts || this.hasOverriddenHost())) { this.set('showQuickLinks', true); } else { this.set('showNoLinks', true); @@ -276,15 +283,20 @@ App.QuickLinksView = Em.View.extend({ var isMultipleComponentsInLinks = componentNames.uniq().length > 1; - if (hosts.length === 0) { + if (hosts.length === 0 && !this.hasOverriddenHost()) { this.setEmptyLinks(); - } else if (hosts.length === 1 || isMultipleComponentsInLinks) { + } else if (hosts.length === 1 || isMultipleComponentsInLinks || this.hasOverriddenHost()) { this.setSingleHostLinks(hosts, response); } else { this.setMultipleHostLinks(hosts); } }, + hasOverriddenHost: function() { + var links = Em.get(this.getQuickLinksConfiguration(), 'links'); + return links && links.some(function (each) { return each.host; }); + }, + /** * Get public host name by its host name. * @@ -424,10 +436,8 @@ App.QuickLinksView = Em.View.extend({ var links = Em.get(quickLinksConfig, 'links'); links.forEach(function (link) { - var componentName = link.component_name; - var hostNameForComponent = hosts.findProperty('componentName',componentName); - if (hostNameForComponent) { - var publicHostName = hostNameForComponent.publicHostName; + var publicHostName = this.publicHostName(link, hosts, protocol); + if (publicHostName) { if (link.protocol) { protocol = this.setProtocol(configProperties, link.protocol); } @@ -446,6 +456,30 @@ App.QuickLinksView = Em.View.extend({ } }, + publicHostName: function(link, hosts, protocol) { + if (link.host) { // if quicklink overrides hostcomponent host name, get host from config + var configProperties = this.get('configProperties'); + var hostProperty = Em.get(link.host, protocol + '_property'); + var site = configProperties.findProperty('type', Em.get(link.host, 'site')); + return site && site.properties ? this.parseHostFromUri(site.properties[hostProperty]) : null; + } else { + var hostNameForComponent = hosts.findProperty('componentName', link.component_name); + return hostNameForComponent ? hostNameForComponent.publicHostName : null; + } + }, + + /** + * @param {string} uri + */ + parseHostFromUri: function(uri) { + if (uri) { + var match = uri.match(/:\/\/([^/:]+)/i); + return match != null && match.length == 2 ? match[1] : uri; + } else { + return null; + } + }, + /** * set links that contain multiple hosts * @@ -786,7 +820,9 @@ App.QuickLinksView = Em.View.extend({ * @method setPort */ setPort: function (portConfigs, protocol, configProperties) { - + if (!portConfigs) { + return ''; + } var defaultPort = Em.get(portConfigs, protocol + '_default_port'); var portProperty = Em.get(portConfigs, protocol + '_property'); var site = configProperties.findProperty('type', Em.get(portConfigs, 'site')); http://git-wip-us.apache.org/repos/asf/ambari/blob/6fedb9f5/ambari-web/test/views/common/quick_link_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/quick_link_view_test.js b/ambari-web/test/views/common/quick_link_view_test.js index 1998a9c..9adbbc8 100644 --- a/ambari-web/test/views/common/quick_link_view_test.js +++ b/ambari-web/test/views/common/quick_link_view_test.js @@ -195,6 +195,9 @@ describe('App.QuickViewLinks', function () { { port: { site: "yarn-site" + }, + host: { + site: "yarn-env" } } ] @@ -205,7 +208,7 @@ describe('App.QuickViewLinks', function () { quickViewLinks.set('content.serviceName', 'YARN'); mock.returns(quickLinksConfigYARN); quickViewLinks.loadQuickLinksConfigSuccessCallback({items: []}); - expect(quickViewLinks.get('requiredSiteNames')).to.be.eql(["core-site", "hdfs-site", "admin-properties", "hbase-site", "yarn-site"]); + expect(quickViewLinks.get('requiredSiteNames')).to.be.eql(["core-site", "hdfs-site", "admin-properties", "hbase-site", "yarn-site", "yarn-env"]); }); }); @@ -247,8 +250,11 @@ describe('App.QuickViewLinks', function () { }); describe("#setQuickLinksSuccessCallback()", function () { + var getQuickLinks; beforeEach(function () { this.mock = sinon.stub(quickViewLinks, 'getHosts'); + getQuickLinks = sinon.stub(quickViewLinks, 'getQuickLinksConfiguration'); + getQuickLinks.returns({}); sinon.stub(quickViewLinks, 'setEmptyLinks'); sinon.stub(quickViewLinks, 'setSingleHostLinks'); sinon.stub(quickViewLinks, 'setMultipleHostLinks'); @@ -256,6 +262,7 @@ describe('App.QuickViewLinks', function () { }); afterEach(function () { this.mock.restore(); + getQuickLinks.restore(); quickViewLinks.setEmptyLinks.restore(); quickViewLinks.setSingleHostLinks.restore(); quickViewLinks.setMultipleHostLinks.restore(); @@ -265,6 +272,12 @@ describe('App.QuickViewLinks', function () { quickViewLinks.setQuickLinksSuccessCallback(); expect(quickViewLinks.setEmptyLinks.calledOnce).to.be.true; }); + it("has overridden hosts", function () { + this.mock.returns([]); + getQuickLinks.returns({ links: [{ host: {site: "yarn-env"} }] }); + quickViewLinks.setQuickLinksSuccessCallback(); + expect(quickViewLinks.setEmptyLinks.calledOnce).to.be.false; + }); it("quickLinks is not configured", function () { this.mock.returns([{}]); quickViewLinks.setQuickLinksSuccessCallback(); http://git-wip-us.apache.org/repos/asf/ambari/blob/6fedb9f5/contrib/management-packs/isilon-onefs-mpack/src/main/resources/addon-services/ONEFS/1.0.0/metainfo.xml ---------------------------------------------------------------------- diff --git a/contrib/management-packs/isilon-onefs-mpack/src/main/resources/addon-services/ONEFS/1.0.0/metainfo.xml b/contrib/management-packs/isilon-onefs-mpack/src/main/resources/addon-services/ONEFS/1.0.0/metainfo.xml index 82e2022..5ba562e 100644 --- a/contrib/management-packs/isilon-onefs-mpack/src/main/resources/addon-services/ONEFS/1.0.0/metainfo.xml +++ b/contrib/management-packs/isilon-onefs-mpack/src/main/resources/addon-services/ONEFS/1.0.0/metainfo.xml @@ -86,6 +86,13 @@ <config-type>hadoop-env</config-type> </configuration-dependencies> <restartRequiredAfterRackChange>true</restartRequiredAfterRackChange> + + <quickLinksConfigurations> + <quickLinksConfiguration> + <fileName>quicklinks.json</fileName> + <default>true</default> + </quickLinksConfiguration> + </quickLinksConfigurations> </service> </services> </metainfo> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/6fedb9f5/contrib/management-packs/isilon-onefs-mpack/src/main/resources/addon-services/ONEFS/1.0.0/quicklinks/quicklinks.json ---------------------------------------------------------------------- diff --git a/contrib/management-packs/isilon-onefs-mpack/src/main/resources/addon-services/ONEFS/1.0.0/quicklinks/quicklinks.json b/contrib/management-packs/isilon-onefs-mpack/src/main/resources/addon-services/ONEFS/1.0.0/quicklinks/quicklinks.json new file mode 100644 index 0000000..0b9656f --- /dev/null +++ b/contrib/management-packs/isilon-onefs-mpack/src/main/resources/addon-services/ONEFS/1.0.0/quicklinks/quicklinks.json @@ -0,0 +1,31 @@ +{ + "name": "default", + "description": "default quick links configuration", + "configuration": { + "protocol": { + "type": "HTTP_ONLY" + }, + "links": [ + { + "component_name" : "ONEFS_CLIENT", + "name": "onefs_web_ui", + "label": "OneFS Web UI", + "url": "%@://%@", + "host": { + "http_property": "fs.defaultFS", + "site": "core-site" + } + }, + { + "component_name" : "ONEFS_CLIENT", + "name": "onefs_hdfs_web_ui", + "label": "OneFS HDFS Settings", + "url": "%@://%@/OneFS#HDFS/Settings", + "host": { + "http_property": "fs.defaultFS", + "site": "core-site" + } + } + ] + } +} \ No newline at end of file