You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2016/12/20 14:35:05 UTC
[03/15] ambari git commit: AMBARI-18978. Create Quick link profile
data model and json parser. (Balazs Bence Sari via stoader)
AMBARI-18978. Create Quick link profile data model and json parser. (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/61dcdc3f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/61dcdc3f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/61dcdc3f
Branch: refs/heads/branch-dev-patch-upgrade
Commit: 61dcdc3f1db0f8091ab3314f6746dace68847178
Parents: fce9d6e
Author: Balazs Bence Sari <bs...@hortonworks.com>
Authored: Mon Dec 19 10:47:47 2016 +0100
Committer: Toader, Sebastian <st...@hortonworks.com>
Committed: Mon Dec 19 10:47:47 2016 +0100
----------------------------------------------------------------------
.../quicklinksprofile/AcceptAllFilter.java | 46 ++++++++
.../state/quicklinksprofile/Component.java | 57 ++++++++++
.../server/state/quicklinksprofile/Filter.java | 78 ++++++++++++++
.../state/quicklinksprofile/LinkNameFilter.java | 61 +++++++++++
.../state/quicklinksprofile/PropertyFilter.java | 60 +++++++++++
.../quicklinksprofile/QuickLinksProfile.java | 70 ++++++++++++
.../QuickLinksProfileParser.java | 108 +++++++++++++++++++
.../server/state/quicklinksprofile/Service.java | 72 +++++++++++++
.../QuickLinksConfigurationModuleTest.java | 2 -
.../QuickLinksProfileParserTest.java | 70 ++++++++++++
.../resources/example_quicklinks_profile.json | 48 +++++++++
.../inconsistent_quicklinks_profile.json | 10 ++
12 files changed, 680 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/61dcdc3f/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
new file mode 100644
index 0000000..5124241
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/AcceptAllFilter.java
@@ -0,0 +1,46 @@
+/*
+ * 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 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.
+ */
+public class AcceptAllFilter extends Filter {
+
+ @Override
+ public boolean accept(Link link) {
+ return true;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AcceptAllFilter that = (AcceptAllFilter) o;
+ return isVisible() == that.isVisible();
+ }
+
+ @Override
+ public int hashCode() {
+ return java.util.Objects.hash(isVisible());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/61dcdc3f/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
new file mode 100644
index 0000000..7ef0259
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Component.java
@@ -0,0 +1,57 @@
+/*
+ * 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.List;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+/**
+ * Class to represent component-level filter definitions
+ */
+@JsonSerialize(include= JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Component {
+ @JsonProperty("name")
+ private String name;
+
+ @JsonProperty("filters")
+ private List<Filter> filters;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the quicklink filters for this component
+ */
+ public List<Filter> getFilters() {
+ return filters;
+ }
+
+ public void setFilters(List<Filter> filters) {
+ this.filters = filters;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/61dcdc3f/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
new file mode 100644
index 0000000..1711628
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Filter.java
@@ -0,0 +1,78 @@
+/*
+ * 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 org.apache.ambari.server.state.quicklinks.Link;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+@JsonSerialize(include= JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+/**
+ * Base class to represent a quicklink filter. A quicklink filter has two important features:
+ * <ul>
+ * <li>It can tell if it applies to a link (see {@link #accept(Link)} method).</li>
+ * <li>It can specify the visibility of the links it applies to (see {@link #isVisible()} method).</li>
+ * </ul>
+ */
+public abstract class Filter {
+
+ @JsonProperty("visible")
+ private boolean visible;
+
+ /**
+ * @return a boolean indicating whether links accepted by this filter should be shown or hidden
+ */
+ public boolean isVisible() {
+ return visible;
+ }
+
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ }
+
+ /**
+ * @param link the link to examine
+ * @return if this filter applies to the link in the parameter
+ */
+ public abstract boolean accept(Link link);
+
+ // Factory methods
+
+ static AcceptAllFilter acceptAllFilter(boolean visible) {
+ AcceptAllFilter acceptAllFilter = new AcceptAllFilter();
+ acceptAllFilter.setVisible(visible);
+ return acceptAllFilter;
+ }
+
+ static LinkNameFilter linkNameFilter(String linkName, boolean visible) {
+ LinkNameFilter linkNameFilter = new LinkNameFilter();
+ linkNameFilter.setLinkName(linkName);
+ linkNameFilter.setVisible(visible);
+ return linkNameFilter;
+ }
+
+ static PropertyFilter propertyFilter(String propertyName, boolean visible) {
+ PropertyFilter propertyFilter = new PropertyFilter();
+ propertyFilter.setPropertyName(propertyName);
+ propertyFilter.setVisible(visible);
+ return propertyFilter;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/61dcdc3f/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/LinkNameFilter.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/LinkNameFilter.java b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/LinkNameFilter.java
new file mode 100644
index 0000000..b874295
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/LinkNameFilter.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 filter that accepts quicklinks based on name match.
+ */
+public class LinkNameFilter extends Filter {
+
+ static final String LINK_NAME = "link_name";
+
+ @JsonProperty(LINK_NAME)
+ private String linkName;
+
+ public String getLinkName() {
+ return linkName;
+ }
+
+ public void setLinkName(String linkName) {
+ this.linkName = linkName;
+ }
+
+ @Override
+ public boolean accept(Link link) {
+ return Objects.equals(link.getName(), linkName);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ LinkNameFilter that = (LinkNameFilter) o;
+ return isVisible() == that.isVisible() && Objects.equals(linkName, that.linkName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(isVisible(), linkName);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/61dcdc3f/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
new file mode 100644
index 0000000..7b5eba0
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/PropertyFilter.java
@@ -0,0 +1,60 @@
+/*
+ * 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/61dcdc3f/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
new file mode 100644
index 0000000..1a1488b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfile.java
@@ -0,0 +1,70 @@
+/*
+ * 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.List;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+/**
+ * A quicklinks profile is essentially a set of filters defined on three levels:
+ * <ul>
+ * <li>global level</li>
+ * <li>service level</li>
+ * <li>component level (within a service)</li>
+ * </ul>
+ *
+ * For each link, filters are evaluated bottom up: component level filters take priority to service level filters
+ * and service level filters take priority to global filters.
+ */
+@JsonSerialize(include= JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class QuickLinksProfile {
+
+ @JsonProperty("filters")
+ private List<Filter> filters;
+
+ @JsonProperty("services")
+ private List<Service> services;
+
+ /**
+ * @return service-specific quicklink filter definitions
+ */
+ public List<Service> getServices() {
+ return services;
+ }
+
+ public void setServices(List<Service> services) {
+ this.services = services;
+ }
+
+ /**
+ * @return the global quicklink filters
+ */
+ public List<Filter> getFilters() {
+ return filters;
+ }
+
+ public void setFilters(List<Filter> filters) {
+ this.filters = filters;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/61dcdc3f/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
new file mode 100644
index 0000000..c1f3c86
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParser.java
@@ -0,0 +1,108 @@
+/*
+ * 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.io.IOException;
+import java.net.URL;
+
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.Version;
+import org.codehaus.jackson.map.DeserializationContext;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.deser.std.StdDeserializer;
+import org.codehaus.jackson.map.module.SimpleModule;
+import org.codehaus.jackson.node.ObjectNode;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.io.Resources;
+
+/**
+ * Loads and parses JSON quicklink profiles.
+ */
+public class QuickLinksProfileParser {
+ private final ObjectMapper mapper = new ObjectMapper();
+
+ public QuickLinksProfileParser() {
+ SimpleModule module =
+ new SimpleModule("Quick Links Parser", new Version(1, 0, 0, null));
+ module.addDeserializer(Filter.class, new QuickLinksFilterDeserializer());
+ mapper.registerModule(module);
+ }
+
+
+ public QuickLinksProfile parse(byte[] input) throws IOException {
+ return mapper.readValue(input, QuickLinksProfile.class);
+ }
+
+ public QuickLinksProfile parse(URL url) throws IOException {
+ return parse(Resources.toByteArray(url));
+ }
+}
+
+/**
+ * Custom deserializer is needed to handle filter polymorphism.
+ */
+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.";
+
+ QuickLinksFilterDeserializer() {
+ super(Filter.class);
+ }
+
+ /**
+ * 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_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>neither of the above fields, it will be parsed as {@link AcceptAllFilter}</li>
+ * </ul>
+ *
+ * @throws JsonParseException if ambiguous filter definitions are found, or any JSON syntax error.
+ */
+ @Override
+ public Filter deserialize (JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
+ ObjectMapper mapper = (ObjectMapper) parser.getCodec();
+ ObjectNode root = (ObjectNode) mapper.readTree(parser);
+ Class<? extends Filter> filterClass = null;
+ for (String fieldName: ImmutableList.copyOf(root.getFieldNames())) {
+ switch(fieldName) {
+ case PropertyFilter.PROPERTY_NAME:
+ if (null != filterClass) {
+ throw new JsonParseException(PARSE_ERROR_MESSAGE, parser.getCurrentLocation());
+ }
+ filterClass = PropertyFilter.class;
+ break;
+ case LinkNameFilter.LINK_NAME:
+ if (null != filterClass) {
+ throw new JsonParseException(PARSE_ERROR_MESSAGE, parser.getCurrentLocation());
+ }
+ filterClass = LinkNameFilter.class;
+ break;
+ }
+ }
+ if (null == filterClass) {
+ filterClass = AcceptAllFilter.class;
+ }
+ return mapper.readValue(root, filterClass);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/61dcdc3f/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
new file mode 100644
index 0000000..600872f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/quicklinksprofile/Service.java
@@ -0,0 +1,72 @@
+/*
+ * 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.List;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+/**
+ * Class to represent component-level filter definitions
+ */
+@JsonSerialize(include= JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Service {
+ @JsonProperty("name")
+ private String name;
+
+ @JsonProperty("components")
+ private List<Component> components;
+
+ @JsonProperty("filters")
+ private List<Filter> filters;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return component-specific quicklink filter definitions for components of this service
+ */
+ public List<Component> getComponents() {
+ return components;
+ }
+
+ public void setComponents(List<Component> components) {
+ this.components = components;
+ }
+
+ /**
+ * @return service-specific filters for this service
+ */
+ public List<Filter> getFilters() {
+ return filters;
+ }
+
+ public void setFilters(List<Filter> filters) {
+ this.filters = filters;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/61dcdc3f/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 6f9827d..190e61b 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
@@ -146,10 +146,8 @@ public class QuickLinksConfigurationModuleTest {
assertEquals("Links are not properly overridden for foo_logs",
new ArrayList<>(),
linksByName.get("foo_logs").getProperties());
-
}
-
private QuickLinks[] resolveQuickLinks(String parentJson, String childJson) throws AmbariException{
File parentQuiclinksFile = new File(this.getClass().getClassLoader().getResource(parentJson).getFile());
File childQuickLinksFile = new File(this.getClass().getClassLoader().getResource(childJson).getFile());
http://git-wip-us.apache.org/repos/asf/ambari/blob/61dcdc3f/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
new file mode 100644
index 0000000..0644027
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/quicklinksprofile/QuickLinksProfileParserTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.assertEquals;
+
+import com.google.common.io.Resources;
+import org.codehaus.jackson.JsonParseException;
+import org.junit.Test;
+
+
+public class QuickLinksProfileParserTest {
+
+
+ @Test
+ public void testParseProfile() throws Exception {
+ String profileName = "example_quicklinks_profile.json";
+ QuickLinksProfileParser parser = new QuickLinksProfileParser();
+ QuickLinksProfile profile = parser.parse(Resources.getResource(profileName));
+ assertEquals(1, profile.getFilters().size());
+ assertEquals(
+ Filter.propertyFilter("sso", true),
+ profile.getFilters().get(0));
+ assertEquals(2, profile.getServices().size());
+
+ Service hdfs = profile.getServices().get(0);
+ assertEquals("HDFS", hdfs.getName());
+ assertEquals(1, hdfs.getFilters().size());
+ assertEquals(1, hdfs.getComponents().size());
+ assertEquals(
+ Filter.propertyFilter("authenticated", true),
+ hdfs.getFilters().get(0));
+
+ Component nameNode = hdfs.getComponents().get(0);
+ assertEquals(2, nameNode.getFilters().size());
+ assertEquals(
+ Filter.linkNameFilter("namenode_ui", false),
+ nameNode.getFilters().get(0));
+
+ Component historyServer = profile.getServices().get(1).getComponents().get(0);
+ assertEquals(1, historyServer.getFilters().size());
+ assertEquals(
+ Filter.acceptAllFilter(true),
+ historyServer.getFilters().get(0));
+ }
+
+ @Test(expected = JsonParseException.class)
+ public void testParseInconsistentProfile() throws Exception {
+ String profileName = "inconsistent_quicklinks_profile.json";
+ QuickLinksProfileParser parser = new QuickLinksProfileParser();
+ QuickLinksProfile profile = parser.parse(Resources.getResource(profileName));
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/61dcdc3f/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
new file mode 100644
index 0000000..028d011
--- /dev/null
+++ b/ambari-server/src/test/resources/example_quicklinks_profile.json
@@ -0,0 +1,48 @@
+{
+ "filters": [
+ {
+ "property_name": "sso",
+ "visible": true
+ }
+ ],
+ "services": [
+ {
+ "name": "HDFS",
+ "filters": [
+ {
+ "property_name": "authenticated",
+ "visible": true
+ }
+ ],
+ "components": [
+ {
+ "name": "NAMENODE",
+ "filters": [
+ {
+ "link_name": "namenode_ui",
+ "visible": false
+ },
+ {
+ "link_name": "namenode_jmx",
+ "visible": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "name": "MAPREDUCE2",
+ "filters": [],
+ "components": [
+ {
+ "name": "HISTORYSERVER",
+ "filters": [
+ {
+ "visible": true
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/61dcdc3f/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
new file mode 100644
index 0000000..e5bc310
--- /dev/null
+++ b/ambari-server/src/test/resources/inconsistent_quicklinks_profile.json
@@ -0,0 +1,10 @@
+{
+ "filters": [
+ {
+ "property_name": "sso",
+ "link_name": "namenode_ui",
+ "visible": true
+ }
+ ],
+ "services": []
+}
\ No newline at end of file