Repository: ambari Updated Branches: refs/heads/trunk 564b8f775 -> 83f3b6fb0
AMBARI-19244. Create profile evaluator. (Balazs Bence Sari via stoader) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/83f3b6fb Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/83f3b6fb Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/83f3b6fb Branch: refs/heads/trunk Commit: 83f3b6fb0fb98bc99e74b0d1f2c55e5229c697ac Parents: 564b8f7 Author: Balazs Bence Sari <ba...@hortonworks.com> Authored: Fri Dec 23 13:27:56 2016 +0100 Committer: Toader, Sebastian <stoa...@hortonworks.com> Committed: Fri Dec 23 13:27:56 2016 +0100 ---------------------------------------------------------------------- .../ambari/server/state/quicklinks/Link.java | 16 +- .../quicklinksprofile/AcceptAllFilter.java | 2 +- .../state/quicklinksprofile/Component.java | 7 + .../server/state/quicklinksprofile/Filter.java | 10 +- .../quicklinksprofile/LinkAttributeFilter.java | 61 ++++++ .../state/quicklinksprofile/PropertyFilter.java | 60 ------ .../quicklinksprofile/QuickLinksProfile.java | 7 + .../QuickLinksProfileEvaluator.java | 202 ++++++++++++++++++ .../QuickLinksProfileEvaluatorException.java | 27 +++ .../QuickLinksProfileParser.java | 10 +- .../server/state/quicklinksprofile/Service.java | 8 + .../QuickLinksConfigurationModuleTest.java | 10 +- .../state/quicklinksprofile/EvaluatorTest.java | 204 +++++++++++++++++++ .../QuickLinksProfileEvaluatorTest.java | 167 +++++++++++++++ .../QuickLinksProfileParserTest.java | 4 +- .../HIVE/0.11.0.2.0.5.0/package/.hash | 1 - .../dummy_stack/HIVE/package/.hash | 1 - .../child_quicklinks_with_attributes.json | 64 ++++++ .../child_quicklinks_with_properties.json | 64 ------ .../resources/example_quicklinks_profile.json | 4 +- .../inconsistent_quicklinks_profile.json | 2 +- .../parent_quicklinks_with_attributes.json | 65 ++++++ .../parent_quicklinks_with_properties.json | 65 ------ 23 files changed, 841 insertions(+), 220 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/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 72ad764..f589f5d 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 @@ -50,8 +50,8 @@ public class Link{ @JsonProperty("protocol") private Protocol protocol; - @JsonProperty("properties") - private List<String> properties; + @JsonProperty("attributes") + private List<String> attributes; public String getName() { return name; @@ -110,12 +110,12 @@ public class Link{ } @Nullable - public List<String> getProperties() { - return properties; + public List<String> getAttributes() { + return attributes; } - public void setProperties(List<String> properties) { - this.properties = properties; + public void setAttributes(List<String> attributes) { + this.attributes = attributes; } public boolean isRemoved(){ @@ -148,8 +148,8 @@ public class Link{ port.mergetWithParent(parentLink.getPort()); } - if (null == properties && null != parentLink.properties) { - properties = parentLink.properties; + if (null == attributes && null != parentLink.attributes) { + attributes = parentLink.attributes; } } http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/AcceptAllFilter.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/AcceptAllFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/AcceptAllFilter.java index 5124241..d784a22 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/AcceptAllFilter.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/AcceptAllFilter.java @@ -22,7 +22,7 @@ import org.apache.ambari.server.state.quicklinks.Link; /** * A filter that accepts all links. It is useful to specify a general rule while the more specific - * ({@link LinkNameFilter} and {@link PropertyFilter}) filters handle more special cases. + * ({@link LinkNameFilter} and {@link LinkAttributeFilter}) filters handle more special cases. */ public class AcceptAllFilter extends Filter { http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Component.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Component.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Component.java index 7ef0259..a1267df 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Component.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Component.java @@ -36,6 +36,13 @@ public class Component { @JsonProperty("filters") private List<Filter> filters; + static Component create(String name, List<Filter> filters) { + Component component = new Component(); + component.setName(name); + component.setFilters(filters); + return component; + } + public String getName() { return name; } http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Filter.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Filter.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Filter.java index 1711628..c551830 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Filter.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Filter.java @@ -69,10 +69,10 @@ public abstract class Filter { return linkNameFilter; } - static PropertyFilter propertyFilter(String propertyName, boolean visible) { - PropertyFilter propertyFilter = new PropertyFilter(); - propertyFilter.setPropertyName(propertyName); - propertyFilter.setVisible(visible); - return propertyFilter; + static LinkAttributeFilter linkAttributeFilter(String linkAttribute, boolean visible) { + LinkAttributeFilter linkAttributeFilter = new LinkAttributeFilter(); + linkAttributeFilter.setLinkAttribute(linkAttribute); + linkAttributeFilter.setVisible(visible); + return linkAttributeFilter; } } http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/LinkAttributeFilter.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/LinkAttributeFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/LinkAttributeFilter.java new file mode 100644 index 0000000..b10111d --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/LinkAttributeFilter.java @@ -0,0 +1,61 @@ +/* + * 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.quicklinksprofile; + +import java.util.Objects; + +import org.apache.ambari.server.state.quicklinks.Link; +import org.codehaus.jackson.annotate.JsonProperty; + +/** + * A quicklink filter based on link attribute match (the filter's link_attribute is contained by the links set of + * attributes) + */ +public class LinkAttributeFilter extends Filter { + static final String LINK_ATTRIBUTE = "link_attribute"; + + @JsonProperty(LINK_ATTRIBUTE) + private String linkAttribute; + + public String getLinkAttribute() { + return linkAttribute; + } + + public void setLinkAttribute(String linkAttribute) { + this.linkAttribute = linkAttribute; + } + + @Override + public boolean accept(Link link) { + return link.getAttributes().contains(linkAttribute); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + LinkAttributeFilter that = (LinkAttributeFilter) o; + return isVisible() == that.isVisible() && Objects.equals(linkAttribute, that.linkAttribute); + } + + @Override + public int hashCode() { + return Objects.hash(isVisible(), linkAttribute); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/PropertyFilter.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/PropertyFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/PropertyFilter.java deleted file mode 100644 index 7b5eba0..0000000 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/PropertyFilter.java +++ /dev/null @@ -1,60 +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. - */ - -package org.apache.ambari.server.state.quicklinksprofile; - -import java.util.Objects; - -import org.apache.ambari.server.state.quicklinks.Link; -import org.codehaus.jackson.annotate.JsonProperty; - -/** - * A quicklink filter based on property-match (the filter's property is contained by the links set of properties) - */ -public class PropertyFilter extends Filter { - static final String PROPERTY_NAME = "property_name"; - - @JsonProperty(PROPERTY_NAME) - private String propertyName; - - public String getPropertyName() { - return propertyName; - } - - public void setPropertyName(String propertyName) { - this.propertyName = propertyName; - } - - @Override - public boolean accept(Link link) { - return link.getProperties().contains(propertyName); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PropertyFilter that = (PropertyFilter) o; - return isVisible() == that.isVisible() && Objects.equals(propertyName, that.propertyName); - } - - @Override - public int hashCode() { - return Objects.hash(isVisible(), propertyName); - } -} http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfile.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfile.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfile.java index 1a1488b..e86af38 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfile.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfile.java @@ -45,6 +45,13 @@ public class QuickLinksProfile { @JsonProperty("services") private List<Service> services; + static QuickLinksProfile create(List<Filter> globalFilters, List<Service> services) { + QuickLinksProfile profile = new QuickLinksProfile(); + profile.setFilters(globalFilters); + profile.setServices(services); + return profile; + } + /** * @return service-specific quicklink filter definitions */ http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluator.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluator.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluator.java new file mode 100644 index 0000000..31335b6 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluator.java @@ -0,0 +1,202 @@ +/* + * 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.quicklinksprofile; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import org.apache.ambari.server.state.quicklinks.Link; + +import com.google.common.base.Optional; + +/** + * This class can evaluate whether a quicklink has to be shown or hidden based on the received {@link QuickLinksProfile}. + */ +public class QuickLinksProfileEvaluator { + private final Evaluator globalRules; + private final Map<String, Evaluator> serviceRules = new HashMap<>(); + private final Map<ServiceComponent, Evaluator> componentRules = new HashMap<>(); + + public QuickLinksProfileEvaluator(QuickLinksProfile profile) throws QuickLinksProfileEvaluatorException { + globalRules = new Evaluator(profile.getFilters()); + for (Service service: nullToEmptyList(profile.getServices())) { + serviceRules.put(service.getName(), new Evaluator(service.getFilters())); + for (Component component: nullToEmptyList(service.getComponents())) { + componentRules.put(ServiceComponent.of(service.getName(), component.getName()), + new Evaluator(component.getFilters())); + } + } + } + + /** + * @param service the name of the service + * @param quickLink the quicklink + * @return a boolean indicating whether the link in the parameter should be visible + */ + public boolean isVisible(@Nonnull String service, @Nonnull Link quickLink) { + // First, component rules are evaluated if exist and applicable + Optional<Boolean> componentResult = evaluateComponentRules(service, quickLink); + if (componentResult.isPresent()) { + return componentResult.get(); + } + + // Secondly, service level rules are applied + Optional<Boolean> serviceResult = evaluateServiceRules(service, quickLink); + if (serviceResult.isPresent()) { + return serviceResult.get(); + } + + // Global rules are evaluated lastly. If no rules apply to the link, it will be hidden. + return globalRules.isVisible(quickLink).or(false); + } + + private Optional<Boolean> evaluateComponentRules(@Nonnull String service, @Nonnull Link quickLink) { + if (null == quickLink.getComponentName()) { + return Optional.absent(); + } + else { + Evaluator componentEvaluator = componentRules.get(ServiceComponent.of(service, quickLink.getComponentName())); + return componentEvaluator != null ? componentEvaluator.isVisible(quickLink) : Optional.<Boolean>absent(); + } + } + + private Optional<Boolean> evaluateServiceRules(@Nonnull String service, @Nonnull Link quickLink) { + return serviceRules.containsKey(service) ? + serviceRules.get(service).isVisible(quickLink) : Optional.<Boolean>absent(); + } + + static <T> List<T> nullToEmptyList(@Nullable List<T> items) { + return items != null ? items : Collections.<T>emptyList(); + } +} + +/** + * Groups quicklink filters that are on the same level (e.g. a global evaluator or an evaluator for the "HDFS" service, + * etc.). The evaluator pick the most applicable filter for a given quick link. If no applicable filter is found, it + * returns {@link Optional#absent()}. + * <p> + * Filter evaluation order is the following: + * <ol> + * <li>First, link name filters are evaluated. These match links by name.</li> + * <li>If there is no matching link name filter, link attribute filters are evaluated next. "Hide" type filters + * take precedence to "show" type filters.</li> + * <li>Finally, the match-all filter is evaluated, provided it exists.</li> + * </ol> + * </p> + */ +class Evaluator { + private final Map<String, Boolean> linkNameFilters = new HashMap<>(); + private final Set<String> showAttributes = new HashSet<>(); + private final Set<String> hideAttributes = new HashSet<>(); + private Optional<Boolean> acceptAllFilter = Optional.absent(); + + Evaluator(List<Filter> filters) throws QuickLinksProfileEvaluatorException { + for (Filter filter: QuickLinksProfileEvaluator.nullToEmptyList(filters)) { + if (filter instanceof LinkNameFilter) { + String linkName = ((LinkNameFilter)filter).getLinkName(); + if (linkNameFilters.containsKey(linkName) && linkNameFilters.get(linkName) != filter.isVisible()) { + throw new QuickLinksProfileEvaluatorException("Contradicting filters for link name [" + linkName + "]"); + } + linkNameFilters.put(linkName, filter.isVisible()); + } + else if (filter instanceof LinkAttributeFilter) { + String linkAttribute = ((LinkAttributeFilter)filter).getLinkAttribute(); + if (filter.isVisible()) { + showAttributes.add(linkAttribute); + } + else { + hideAttributes.add(linkAttribute); + } + if (showAttributes.contains(linkAttribute) && hideAttributes.contains(linkAttribute)) { + throw new QuickLinksProfileEvaluatorException("Contradicting filters for link attribute [" + linkAttribute + "]"); + } + } + // If none of the above, it is an accept-all filter. We expect only one for an Evaluator + else { + if (acceptAllFilter.isPresent() && !acceptAllFilter.get().equals(filter.isVisible())) { + throw new QuickLinksProfileEvaluatorException("Contradicting accept-all filters."); + } + acceptAllFilter = Optional.of(filter.isVisible()); + } + } + } + + /** + * @param quickLink the link to evaluate + * @return Three way evaluation result, which can be one of these: + * show: Optional.of(true), hide: Optional.of(false), don't know: absent optional + */ + Optional<Boolean> isVisible(Link quickLink) { + // process first priority filters based on link name + if (linkNameFilters.containsKey(quickLink.getName())) { + return Optional.of(linkNameFilters.get(quickLink.getName())); + } + + // process second priority filters based on link attributes + // 'hide' rules take precedence over 'show' rules + for (String attribute: QuickLinksProfileEvaluator.nullToEmptyList(quickLink.getAttributes())) { + if (hideAttributes.contains(attribute)) return Optional.of(false); + } + for (String attribute: QuickLinksProfileEvaluator.nullToEmptyList(quickLink.getAttributes())) { + if (showAttributes.contains(attribute)) return Optional.of(true); + } + + // accept all filter (if exists) is the last priority + return acceptAllFilter; + } +} + +/** + * Simple value class encapsulating a link name an component name. + */ +class ServiceComponent { + private final String service; + private final String component; + + ServiceComponent(String service, String component) { + this.service = service; + this.component = component; + } + + static ServiceComponent of(String service, String component) { + return new ServiceComponent(service, component); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ServiceComponent that = (ServiceComponent) o; + return Objects.equals(service, that.service) && + Objects.equals(component, that.component); + } + + @Override + public int hashCode() { + return Objects.hash(service, component); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluatorException.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluatorException.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluatorException.java new file mode 100644 index 0000000..c24281a --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluatorException.java @@ -0,0 +1,27 @@ +/* + * 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.quicklinksprofile; + +public class QuickLinksProfileEvaluatorException extends Exception { + + public QuickLinksProfileEvaluatorException(String message) { + super(message); + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParser.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParser.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParser.java index c1f3c86..a3ae677 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParser.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParser.java @@ -62,7 +62,7 @@ public class QuickLinksProfileParser { */ class QuickLinksFilterDeserializer extends StdDeserializer<Filter> { private static final String PARSE_ERROR_MESSAGE = - "A filter is not allowed to declare both property_name and link_name at the same time."; + "A filter is not allowed to declare both link_name and link_attribute at the same time."; QuickLinksFilterDeserializer() { super(Filter.class); @@ -71,9 +71,9 @@ class QuickLinksFilterDeserializer extends StdDeserializer<Filter> { /** * Filter polymorphism is handled here. If a filter object in the JSON document has: * <ul> - * <li>a {@code property_name} field, it will parsed as {@link PropertyFilter}</li> + * <li>a {@code link_attribute} field, it will parsed as {@link LinkAttributeFilter}</li> * <li>a {@code link_name} field, it will be parsed as {@link LinkNameFilter}</li> - * <li>both {@code property_name} and {@code link_name}, it will throw a {@link JsonParseException}</li> + * <li>both {@code link_attribute} and {@code link_name}, it will throw a {@link JsonParseException}</li> * <li>neither of the above fields, it will be parsed as {@link AcceptAllFilter}</li> * </ul> * @@ -86,11 +86,11 @@ class QuickLinksFilterDeserializer extends StdDeserializer<Filter> { Class<? extends Filter> filterClass = null; for (String fieldName: ImmutableList.copyOf(root.getFieldNames())) { switch(fieldName) { - case PropertyFilter.PROPERTY_NAME: + case LinkAttributeFilter.LINK_ATTRIBUTE: if (null != filterClass) { throw new JsonParseException(PARSE_ERROR_MESSAGE, parser.getCurrentLocation()); } - filterClass = PropertyFilter.class; + filterClass = LinkAttributeFilter.class; break; case LinkNameFilter.LINK_NAME: if (null != filterClass) { http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Service.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Service.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Service.java index 600872f..7724852 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Service.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Service.java @@ -39,6 +39,14 @@ public class Service { @JsonProperty("filters") private List<Filter> filters; + static Service create(String name, List<Filter> filters, List<Component> components) { + Service service = new Service(); + service.setName(name); + service.setFilters(filters); + service.setComponents(components); + return service; + } + public String getName() { return name; } http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/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 190e61b..f6b7dfa 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 @@ -120,8 +120,8 @@ public class QuickLinksConfigurationModuleTest { @Test public void testResolveOverrideProperties() throws Exception{ - QuickLinks[] results = resolveQuickLinks("parent_quicklinks_with_properties.json", - "child_quicklinks_with_properties.json"); + QuickLinks[] results = resolveQuickLinks("parent_quicklinks_with_attributes.json", + "child_quicklinks_with_attributes.json"); QuickLinks parentQuickLinks = results[0]; QuickLinks childQuickLinks = results[1]; @@ -139,13 +139,13 @@ public class QuickLinksConfigurationModuleTest { } assertEquals("Links are not properly overridden for foo_ui", Lists.newArrayList("authenticated", "sso"), - linksByName.get("foo_ui").getProperties()); + linksByName.get("foo_ui").getAttributes()); assertEquals("Parent links for foo_jmx are not inherited.", Lists.newArrayList("authenticated"), - linksByName.get("foo_jmx").getProperties()); + linksByName.get("foo_jmx").getAttributes()); assertEquals("Links are not properly overridden for foo_logs", new ArrayList<>(), - linksByName.get("foo_logs").getProperties()); + linksByName.get("foo_logs").getAttributes()); } private QuickLinks[] resolveQuickLinks(String parentJson, String childJson) throws AmbariException{ http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/EvaluatorTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/EvaluatorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/EvaluatorTest.java new file mode 100644 index 0000000..bff2e39 --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/EvaluatorTest.java @@ -0,0 +1,204 @@ +/* + * 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.quicklinksprofile; + +import static org.apache.ambari.server.state.quicklinksprofile.Filter.acceptAllFilter; +import static org.apache.ambari.server.state.quicklinksprofile.Filter.linkNameFilter; +import static org.apache.ambari.server.state.quicklinksprofile.Filter.linkAttributeFilter; +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + + +import org.apache.ambari.server.state.quicklinks.Link; +import org.junit.Test; + +import com.google.common.collect.Lists; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; + +public class EvaluatorTest { + + static final String NAMENODE = "NAMENODE"; + static final String NAMENODE_UI = "namenode_ui"; + static final String AUTHENTICATED = "authenticated"; + static final String NAMENODE_JMX = "namenode_jmx"; + static final String SSO = "sso"; + + private Link namenodeUi; + private Link nameNodeJmx; + + public EvaluatorTest() { + namenodeUi = new Link(); + namenodeUi.setComponentName(NAMENODE); + namenodeUi.setName(NAMENODE_UI); + namenodeUi.setAttributes(ImmutableList.of(AUTHENTICATED)); + + nameNodeJmx = new Link(); + nameNodeJmx.setComponentName(NAMENODE); + nameNodeJmx.setName(NAMENODE_JMX); + } + + /** + * Evaluators should work when initialized with {@code null} or an empty list of filters. + */ + @Test + public void testWithEmptyFilters() throws Exception { + Evaluator evaluator = new Evaluator(new ArrayList<Filter>()); + assertEquals(Optional.absent(), evaluator.isVisible(namenodeUi)); + + Evaluator evaluator2 = new Evaluator(null); + assertEquals(Optional.absent(), evaluator2.isVisible(namenodeUi)); + } + + /** + * Evaluator should return {@link Optional#absent()} when the link doesn't match any filters + */ + @Test + public void testNoMatchingFilter() throws Exception { + List<Filter> filters = Lists.newArrayList( + linkNameFilter(NAMENODE_JMX, true), + linkAttributeFilter(SSO, false)); + Evaluator evaluator = new Evaluator(filters); + assertEquals(Optional.absent(), evaluator.isVisible(namenodeUi)); + } + + /** + * Link name filters should be evaluated first + */ + @Test + public void testLinkNameFiltersEvaluatedFirst() throws Exception { + List<Filter> filters = Lists.newArrayList( + acceptAllFilter(false), + linkNameFilter(NAMENODE_UI, true), + linkNameFilter(NAMENODE_JMX, false), + linkAttributeFilter(AUTHENTICATED, false), + linkAttributeFilter(SSO, false)); + Evaluator evaluator = new Evaluator(filters); + assertEquals(Optional.of(true), evaluator.isVisible(namenodeUi)); + } + + /** + * Link attribute filters should be evaluated only if the link does not match any link name filters. + */ + @Test + public void testLinkAttributeFiltersEvaluatedSecondly() throws Exception { + List<Filter> filters = Lists.newArrayList( + acceptAllFilter(false), + linkNameFilter(NAMENODE_JMX, false), + linkAttributeFilter(AUTHENTICATED, true), + linkAttributeFilter(SSO, true)); + Evaluator evaluator = new Evaluator(filters); + assertEquals(Optional.of(true), evaluator.isVisible(namenodeUi)); + } + + /** + * Link attribute filters work with links with null attributes. (No NPE is thrown) + */ + @Test + public void testLinkAttributeFiltersWorkWithNullAttributes() throws Exception { + List<Filter> filters = Lists.newArrayList( + acceptAllFilter(true), + linkAttributeFilter(AUTHENTICATED, false), + linkAttributeFilter(SSO, false)); + Evaluator evaluator = new Evaluator(filters); + assertEquals(Optional.of(true), evaluator.isVisible(nameNodeJmx)); + } + + + /** + * If the link matches both a show and hide type link attribute filter, then it will be evaluated as hidden. + */ + @Test + public void testHideFilterTakesPrecedence() throws Exception { + List<Filter> filters = Lists.<Filter>newArrayList( + linkAttributeFilter(AUTHENTICATED, false), + linkAttributeFilter(SSO, true)); + Evaluator evaluator = new Evaluator(filters); + namenodeUi.setAttributes(ImmutableList.of(AUTHENTICATED, SSO)); + assertEquals(Optional.of(false), evaluator.isVisible(namenodeUi)); + } + + /** + * Accept-all filters are only evaluated if the link does not match any link name or link attribute filters. + */ + @Test + public void acceptAllFilterEvaluatedLast() throws Exception { + List<Filter> filters = Lists.newArrayList( + acceptAllFilter(false), + linkNameFilter(NAMENODE_JMX, true), + linkAttributeFilter(SSO, true)); + Evaluator evaluator = new Evaluator(filters); + assertEquals(Optional.of(false), evaluator.isVisible(namenodeUi)); + } + + /** + * Contradicting link name filters should result in {@link QuickLinksProfileEvaluatorException}. + */ + @Test(expected = QuickLinksProfileEvaluatorException.class) + public void contradictingLinkNameFiltersRejected() throws Exception { + List<Filter> filters = Lists.newArrayList( + linkNameFilter(NAMENODE_JMX, true), + linkNameFilter(NAMENODE_JMX, false), + linkAttributeFilter(SSO, true)); + new Evaluator(filters); + } + + /** + * Contradicting link attribute filters should result in {@link QuickLinksProfileEvaluatorException}. + */ + @Test(expected = QuickLinksProfileEvaluatorException.class) + public void contradictingLinkAttributeFiltersRejected() throws Exception { + List<Filter> filters = Lists.<Filter>newArrayList( + linkAttributeFilter(SSO, true), + linkAttributeFilter(SSO, false)); + new Evaluator(filters); + } + + /** + * Contradicting accept-all filters should result in {@link QuickLinksProfileEvaluatorException}. + */ + @Test(expected = QuickLinksProfileEvaluatorException.class) + public void contradictingAcceptAllFiltersRejected() throws Exception { + List<Filter> filters = Lists.newArrayList( + linkNameFilter(NAMENODE_JMX, true), + linkAttributeFilter(SSO, true), + acceptAllFilter(true), + acceptAllFilter(false)); + new Evaluator(filters); + } + + /** + * Duplicate filter declarations are ok if their visibility rule is the same + */ + @Test + public void duplicateFiltersAreOkIfDoNotContradict() throws Exception { + List<Filter> filters = Lists.newArrayList( + acceptAllFilter(true), + acceptAllFilter(true), + linkNameFilter(NAMENODE_JMX, false), + linkNameFilter(NAMENODE_JMX, false), + linkAttributeFilter(SSO, false), + linkAttributeFilter(SSO, false)); + Evaluator evaluator = new Evaluator(filters); + assertEquals(Optional.of(true), evaluator.isVisible(namenodeUi)); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluatorTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluatorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluatorTest.java new file mode 100644 index 0000000..a770e0f --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileEvaluatorTest.java @@ -0,0 +1,167 @@ +/* + * 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.quicklinksprofile; + +import static org.junit.Assert.*; + +import com.google.common.collect.ImmutableList; +import org.apache.ambari.server.state.quicklinks.Link; +import org.junit.Test; + + +public class QuickLinksProfileEvaluatorTest { + + static final String AUTHENTICATED = "authenticated"; + static final String SSO = "sso"; + static final String NAMENODE = "NAMENODE"; + static final String HDFS = "HDFS"; + static final String NAMENODE_UI = "namenode_ui"; + + + private Link namenodeUi; + + public QuickLinksProfileEvaluatorTest() { + namenodeUi = new Link(); + namenodeUi.setComponentName(NAMENODE); + namenodeUi.setName(NAMENODE_UI); + namenodeUi.setAttributes(ImmutableList.of(AUTHENTICATED)); + } + + /** + * Test to prove that {@link QuickLinksProfileEvaluator} can accept quicklink profiles with null values. + */ + @Test + public void testNullsAreAccepted() throws Exception { + QuickLinksProfile profile = new QuickLinksProfile(); + QuickLinksProfileEvaluator evaluator = new QuickLinksProfileEvaluator(profile); + assertFalse("Link should be hidden as there are no applicable filters", evaluator.isVisible(HDFS, namenodeUi)); + + Service service = Service.create(HDFS, null, null); + profile = QuickLinksProfile.create(null, ImmutableList.of(service)); + evaluator = new QuickLinksProfileEvaluator(profile); + assertFalse("Link should be hidden as there are no applicable filters", evaluator.isVisible(HDFS, namenodeUi)); + } + + /** + * Test to prove that {@link Link}'s with unset {@code componentName} fields are handled properly. + */ + @Test + public void testLinkWithNoComponentField() throws Exception { + Component component = Component.create(NAMENODE, + ImmutableList.<Filter>of(Filter.linkNameFilter(NAMENODE_UI, true))); + + Service service = Service.create(HDFS, ImmutableList.<Filter>of(), ImmutableList.of(component)); + + QuickLinksProfile profile = QuickLinksProfile.create(ImmutableList.<Filter>of(), ImmutableList.of(service)); + QuickLinksProfileEvaluator evaluator = new QuickLinksProfileEvaluator(profile); + namenodeUi.setComponentName(null); + assertFalse("Link should be hidden as there are no applicable filters", evaluator.isVisible(HDFS, namenodeUi)); + } + + /** + * Test to prove that component level filters are evaluated first. + */ + @Test + public void testComponentLevelFiltersEvaluatedFirst() throws Exception { + Component component = Component.create( + NAMENODE, + ImmutableList.<Filter>of(Filter.linkAttributeFilter(AUTHENTICATED, true))); + + Service service = Service.create( + HDFS, + ImmutableList.<Filter>of(Filter.linkAttributeFilter(AUTHENTICATED, false)), + ImmutableList.of(component)); + + QuickLinksProfile profile = QuickLinksProfile.create( + ImmutableList.<Filter>of(Filter.acceptAllFilter(false)), + ImmutableList.of(service)); + + QuickLinksProfileEvaluator evaluator = new QuickLinksProfileEvaluator(profile); + assertTrue("Component level filter should have been applied.", evaluator.isVisible(HDFS, namenodeUi)); + } + + /** + * Test to prove that service level filters are evaluated secondly. + */ + @Test + public void testServiceLevelFiltersEvaluatedSecondly() throws Exception { + Component component = Component.create(NAMENODE, + ImmutableList.<Filter>of(Filter.linkAttributeFilter(SSO, false))); + + Service service = Service.create(HDFS, + ImmutableList.<Filter>of(Filter.linkAttributeFilter(AUTHENTICATED, true)), + ImmutableList.of(component)); + + QuickLinksProfile profile = QuickLinksProfile.create( + ImmutableList.<Filter>of(Filter.acceptAllFilter(false)), + ImmutableList.of(service)); + + QuickLinksProfileEvaluator evaluator = new QuickLinksProfileEvaluator(profile); + assertTrue("Component level filter should have been applied.", evaluator.isVisible(HDFS, namenodeUi)); + } + + /** + * Test to prove that global filters are evaluated last. + */ + @Test + public void testGlobalFiltersEvaluatedLast() throws Exception { + Component component = Component.create(NAMENODE, + ImmutableList.<Filter>of(Filter.linkAttributeFilter(SSO, false))); + + Service service = Service.create(HDFS, + ImmutableList.<Filter>of(Filter.linkAttributeFilter(SSO, false)), + ImmutableList.of(component)); + + QuickLinksProfile profile = QuickLinksProfile.create( + ImmutableList.<Filter>of(Filter.acceptAllFilter(true)), + ImmutableList.of(service)); + + QuickLinksProfileEvaluator evaluator = new QuickLinksProfileEvaluator(profile); + assertTrue("Global filter should have been applied.", evaluator.isVisible(HDFS, namenodeUi)); + } + + /** + * Test to prove that the link is hidden if no filters apply. + */ + @Test + public void testNoMatchingRule() throws Exception { + Component component1 = Component.create(NAMENODE, + ImmutableList.<Filter>of(Filter.linkAttributeFilter(SSO, true))); + + Component component2 = Component.create("DATANODE", + ImmutableList.<Filter>of(Filter.acceptAllFilter(true))); + + Service service1 = Service.create(HDFS, + ImmutableList.<Filter>of(Filter.linkAttributeFilter(SSO, true)), + ImmutableList.of(component1, component2)); + + Service service2 = Service.create("YARN", + ImmutableList.<Filter>of(Filter.acceptAllFilter(true)), + ImmutableList.<Component>of()); + + QuickLinksProfile profile = QuickLinksProfile.create( + ImmutableList.<Filter>of(Filter.linkAttributeFilter(SSO, true)), + ImmutableList.of(service1, service2)); + + QuickLinksProfileEvaluator evaluator = new QuickLinksProfileEvaluator(profile); + assertFalse("No filters should have been applied, so default false should have been returned.", + evaluator.isVisible(HDFS, namenodeUi)); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParserTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParserTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParserTest.java index 5f93475..6f5dd07 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParserTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParserTest.java @@ -35,7 +35,7 @@ public class QuickLinksProfileParserTest { QuickLinksProfile profile = parser.parse(Resources.getResource(profileName)); assertEquals(1, profile.getFilters().size()); assertEquals( - Filter.propertyFilter("sso", true), + Filter.linkAttributeFilter("sso", true), profile.getFilters().get(0)); assertEquals(2, profile.getServices().size()); @@ -44,7 +44,7 @@ public class QuickLinksProfileParserTest { assertEquals(1, hdfs.getFilters().size()); assertEquals(1, hdfs.getComponents().size()); assertEquals( - Filter.propertyFilter("authenticated", true), + Filter.linkAttributeFilter("authenticated", true), hdfs.getFilters().get(0)); Component nameNode = hdfs.getComponents().get(0); http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/test/resources/TestAmbaryServer.samples/dummy_common_services/HIVE/0.11.0.2.0.5.0/package/.hash ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/TestAmbaryServer.samples/dummy_common_services/HIVE/0.11.0.2.0.5.0/package/.hash b/ambari-server/src/test/resources/TestAmbaryServer.samples/dummy_common_services/HIVE/0.11.0.2.0.5.0/package/.hash deleted file mode 100644 index 9550dab..0000000 --- a/ambari-server/src/test/resources/TestAmbaryServer.samples/dummy_common_services/HIVE/0.11.0.2.0.5.0/package/.hash +++ /dev/null @@ -1 +0,0 @@ -dummy_hash \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/test/resources/TestAmbaryServer.samples/dummy_stack/HIVE/package/.hash ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/TestAmbaryServer.samples/dummy_stack/HIVE/package/.hash b/ambari-server/src/test/resources/TestAmbaryServer.samples/dummy_stack/HIVE/package/.hash deleted file mode 100644 index 9550dab..0000000 --- a/ambari-server/src/test/resources/TestAmbaryServer.samples/dummy_stack/HIVE/package/.hash +++ /dev/null @@ -1 +0,0 @@ -dummy_hash \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/test/resources/child_quicklinks_with_attributes.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/child_quicklinks_with_attributes.json b/ambari-server/src/test/resources/child_quicklinks_with_attributes.json new file mode 100644 index 0000000..cc91ab9 --- /dev/null +++ b/ambari-server/src/test/resources/child_quicklinks_with_attributes.json @@ -0,0 +1,64 @@ +{ + "name": "default", + "description": "default quick links configuration", + "configuration": { + "protocol": + { + "type":"http", + "checks":[ + { + "property":"foo.http.policy", + "desired":"HTTP_ONLY", + "site":"foo-site" + } + ] + }, + + "links": [ + { + "name": "foo_ui", + "label": "Foo UI", + "requires_user_name": "false", + "url": "%@://%@:%@", + "attributes": ["authenticated", "sso"], + "port":{ + "http_property": "foo.ui.webapp.address", + "http_default_port": "19888", + "https_property": "foo.ui.webapp.https.address", + "https_default_port": "8090", + "regex": "\\w*:(\\d+)", + "site": "foo-site" + } + }, + { + "name":"foo_jmx", + "label":"Foo JMX", + "requires_user_name":"false", + "url":"%@://%@:%@/jmx", + "port":{ + "http_property": "foo.jmx.webapp.address", + "http_default_port": "19888", + "https_property": "foo.jmx.webapp.https.address", + "https_default_port": "8090", + "regex": "\\w*:(\\d+)", + "site": "foo-site" + } + }, + { + "name": "foo_logs", + "label": "Foo logs", + "requires_user_name": "false", + "url": "%@://%@:%@/logs", + "attributes": [], + "port":{ + "http_property": "foo.logs.webapp.address", + "http_default_port": "19888", + "https_property": "foo.webapp.https.address", + "https_default_port": "8090", + "regex": "\\w*:(\\d+)", + "site": "foo-site" + } + } + ] + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/test/resources/child_quicklinks_with_properties.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/child_quicklinks_with_properties.json b/ambari-server/src/test/resources/child_quicklinks_with_properties.json deleted file mode 100644 index 36cd4f3..0000000 --- a/ambari-server/src/test/resources/child_quicklinks_with_properties.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "name": "default", - "description": "default quick links configuration", - "configuration": { - "protocol": - { - "type":"http", - "checks":[ - { - "property":"foo.http.policy", - "desired":"HTTP_ONLY", - "site":"foo-site" - } - ] - }, - - "links": [ - { - "name": "foo_ui", - "label": "Foo UI", - "requires_user_name": "false", - "url": "%@://%@:%@", - "properties": ["authenticated", "sso"], - "port":{ - "http_property": "foo.ui.webapp.address", - "http_default_port": "19888", - "https_property": "foo.ui.webapp.https.address", - "https_default_port": "8090", - "regex": "\\w*:(\\d+)", - "site": "foo-site" - } - }, - { - "name":"foo_jmx", - "label":"Foo JMX", - "requires_user_name":"false", - "url":"%@://%@:%@/jmx", - "port":{ - "http_property": "foo.jmx.webapp.address", - "http_default_port": "19888", - "https_property": "foo.jmx.webapp.https.address", - "https_default_port": "8090", - "regex": "\\w*:(\\d+)", - "site": "foo-site" - } - }, - { - "name": "foo_logs", - "label": "Foo logs", - "requires_user_name": "false", - "url": "%@://%@:%@/logs", - "properties": [], - "port":{ - "http_property": "foo.logs.webapp.address", - "http_default_port": "19888", - "https_property": "foo.webapp.https.address", - "https_default_port": "8090", - "regex": "\\w*:(\\d+)", - "site": "foo-site" - } - } - ] - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/test/resources/example_quicklinks_profile.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/example_quicklinks_profile.json b/ambari-server/src/test/resources/example_quicklinks_profile.json index 028d011..2fa33a4 100644 --- a/ambari-server/src/test/resources/example_quicklinks_profile.json +++ b/ambari-server/src/test/resources/example_quicklinks_profile.json @@ -1,7 +1,7 @@ { "filters": [ { - "property_name": "sso", + "link_attribute": "sso", "visible": true } ], @@ -10,7 +10,7 @@ "name": "HDFS", "filters": [ { - "property_name": "authenticated", + "link_attribute": "authenticated", "visible": true } ], http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/test/resources/inconsistent_quicklinks_profile.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/inconsistent_quicklinks_profile.json b/ambari-server/src/test/resources/inconsistent_quicklinks_profile.json index e5bc310..aa4e5e0 100644 --- a/ambari-server/src/test/resources/inconsistent_quicklinks_profile.json +++ b/ambari-server/src/test/resources/inconsistent_quicklinks_profile.json @@ -1,7 +1,7 @@ { "filters": [ { - "property_name": "sso", + "link_attribute": "sso", "link_name": "namenode_ui", "visible": true } http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/test/resources/parent_quicklinks_with_attributes.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/parent_quicklinks_with_attributes.json b/ambari-server/src/test/resources/parent_quicklinks_with_attributes.json new file mode 100644 index 0000000..525e38e --- /dev/null +++ b/ambari-server/src/test/resources/parent_quicklinks_with_attributes.json @@ -0,0 +1,65 @@ +{ + "name": "default", + "description": "default quick links configuration", + "configuration": { + "protocol": + { + "type":"http", + "checks":[ + { + "property":"foo.http.policy", + "desired":"HTTP_ONLY", + "site":"foo-site" + } + ] + }, + + "links": [ + { + "name": "foo_ui", + "label": "Foo UI", + "requires_user_name": "false", + "url": "%@://%@:%@", + "attributes": ["authenticated"], + "port":{ + "http_property": "foo.ui.webapp.address", + "http_default_port": "19888", + "https_property": "foo.ui.webapp.https.address", + "https_default_port": "8090", + "regex": "\\w*:(\\d+)", + "site": "foo-site" + } + }, + { + "name":"foo_jmx", + "label":"Foo JMX", + "requires_user_name":"false", + "url":"%@://%@:%@/jmx", + "attributes": ["authenticated"], + "port":{ + "http_property": "foo.jmx.webapp.address", + "http_default_port": "19888", + "https_property": "foo.jmx.webapp.https.address", + "https_default_port": "8090", + "regex": "\\w*:(\\d+)", + "site": "foo-site" + } + }, + { + "name": "foo_logs", + "label": "Foo logs", + "requires_user_name": "false", + "url": "%@://%@:%@/logs", + "attributes": ["authenticated"], + "port":{ + "http_property": "foo.logs.webapp.address", + "http_default_port": "19888", + "https_property": "foo.webapp.https.address", + "https_default_port": "8090", + "regex": "\\w*:(\\d+)", + "site": "foo-site" + } + } + ] + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/83f3b6fb/ambari-server/src/test/resources/parent_quicklinks_with_properties.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/resources/parent_quicklinks_with_properties.json b/ambari-server/src/test/resources/parent_quicklinks_with_properties.json deleted file mode 100644 index a315f3f..0000000 --- a/ambari-server/src/test/resources/parent_quicklinks_with_properties.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "default", - "description": "default quick links configuration", - "configuration": { - "protocol": - { - "type":"http", - "checks":[ - { - "property":"foo.http.policy", - "desired":"HTTP_ONLY", - "site":"foo-site" - } - ] - }, - - "links": [ - { - "name": "foo_ui", - "label": "Foo UI", - "requires_user_name": "false", - "url": "%@://%@:%@", - "properties": ["authenticated"], - "port":{ - "http_property": "foo.ui.webapp.address", - "http_default_port": "19888", - "https_property": "foo.ui.webapp.https.address", - "https_default_port": "8090", - "regex": "\\w*:(\\d+)", - "site": "foo-site" - } - }, - { - "name":"foo_jmx", - "label":"Foo JMX", - "requires_user_name":"false", - "url":"%@://%@:%@/jmx", - "properties": ["authenticated"], - "port":{ - "http_property": "foo.jmx.webapp.address", - "http_default_port": "19888", - "https_property": "foo.jmx.webapp.https.address", - "https_default_port": "8090", - "regex": "\\w*:(\\d+)", - "site": "foo-site" - } - }, - { - "name": "foo_logs", - "label": "Foo logs", - "requires_user_name": "false", - "url": "%@://%@:%@/logs", - "properties": ["authenticated"], - "port":{ - "http_property": "foo.logs.webapp.address", - "http_default_port": "19888", - "https_property": "foo.webapp.https.address", - "https_default_port": "8090", - "regex": "\\w*:(\\d+)", - "site": "foo-site" - } - } - ] - } -} \ No newline at end of file