/* * 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 com.google.common.collect.Sets.newHashSet; import static org.apache.ambari.server.state.quicklinksprofile.QuickLinksProfileBuilder.COMPONENTS; import static org.apache.ambari.server.state.quicklinksprofile.QuickLinksProfileBuilder.FILTERS; import static org.apache.ambari.server.state.quicklinksprofile.QuickLinksProfileBuilder.NAME; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.junit.Test; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; public class QuickLinksProfileBuilderTest { @Test public void testBuildProfileOnlyGlobalFilters() throws Exception { Set<Map<String, String>> filters = newHashSet( filter("namenode_ui", null, true), filter(null, "sso", true), filter(null, null, false) ); String profileJson = new QuickLinksProfileBuilder().buildQuickLinksProfile(filters, null); //verify QuickLinksProfile profile = new QuickLinksProfileParser().parse(profileJson.getBytes()); assertFilterExists(profile, null, null, Filter.linkNameFilter("namenode_ui", true)); assertFilterExists(profile, null, null, Filter.linkAttributeFilter("sso", true)); assertFilterExists(profile, null, null, Filter.acceptAllFilter(false)); } @Test public void testBuildProfileOnlyServiceFilters() throws Exception { Map<String, Object> nameNode = component("NAMENODE", newHashSet(filter("namenode_ui", null, false))); Map<String, Object> hdfs = service("HDFS", newHashSet(nameNode), newHashSet(filter(null, "sso", true))); Set<Map<String, Object>> services = Sets.newHashSet(hdfs); String profileJson = new QuickLinksProfileBuilder().buildQuickLinksProfile(null, services); //verify QuickLinksProfile profile = new QuickLinksProfileParser().parse(profileJson.getBytes()); assertFilterExists(profile, "HDFS", "NAMENODE", Filter.linkNameFilter("namenode_ui", false)); assertFilterExists(profile, "HDFS", null, Filter.linkAttributeFilter("sso", true)); } @Test public void testBuildProfileBothGlobalAndServiceFilters() throws Exception { Set<Map<String, String>> globalFilters = newHashSet( filter(null, null, false) ); Map<String, Object> nameNode = component("NAMENODE", newHashSet(filter("namenode_ui", null, false))); Map<String, Object> hdfs = service("HDFS", newHashSet(nameNode), newHashSet(filter(null, "sso", true))); Set<Map<String, Object>> services = Sets.newHashSet(hdfs); String profileJson = new QuickLinksProfileBuilder().buildQuickLinksProfile(globalFilters, services); // verify QuickLinksProfile profile = new QuickLinksProfileParser().parse(profileJson.getBytes()); assertFilterExists(profile, null, null, Filter.acceptAllFilter(false)); assertFilterExists(profile, "HDFS", "NAMENODE", Filter.linkNameFilter("namenode_ui", false)); assertFilterExists(profile, "HDFS", null, Filter.linkAttributeFilter("sso", true)); } @Test(expected = QuickLinksProfileEvaluationException.class) public void testBuildProfileBadInputStructure() throws Exception { new QuickLinksProfileBuilder().buildQuickLinksProfile("Hello", "World"); } @Test(expected = QuickLinksProfileEvaluationException.class) public void testBuildProfileMissingDataServiceName() throws Exception { Map<String, Object> nameNode = component("NAMENODE", newHashSet(filter("namenode_ui", null, false))); Map<String, Object> hdfs = service(null, // intentionally omitting service name newHashSet(nameNode), newHashSet(filter(null, "sso", true))); Set<Map<String, Object>> services = Sets.newHashSet(hdfs); new QuickLinksProfileBuilder().buildQuickLinksProfile(null, services); } @Test(expected = QuickLinksProfileEvaluationException.class) public void testBuildProfileMissingDataComponentName() throws Exception { Map<String, Object> nameNode = component(null, // intentionally omitting component name newHashSet(filter("namenode_ui", null, false))); Map<String, Object> hdfs = service("HDFS", newHashSet(nameNode), newHashSet(filter(null, "sso", true))); Set<Map<String, Object>> services = Sets.newHashSet(hdfs); new QuickLinksProfileBuilder().buildQuickLinksProfile(null, services); } @Test(expected = QuickLinksProfileEvaluationException.class) public void testBuildProfileInvalidProfileDefiniton_contradictingFilters() throws Exception { // Contradicting rules in the profile Set<Map<String, String>> filters = newHashSet( filter(null, "sso", true), filter(null, "sso", false) ); new QuickLinksProfileBuilder().buildQuickLinksProfile(filters, null); } @Test(expected = QuickLinksProfileEvaluationException.class) public void testBuildProfileInvalidProfileDefiniton_invalidAttribute() throws Exception { Map<String, String> badFilter = ImmutableMap.of("visible", "true", "linkkk_atirbuteee", "sso"); Set<Map<String, String>> filters = newHashSet(badFilter); new QuickLinksProfileBuilder().buildQuickLinksProfile(filters, null); } /** * Verifies that the filter specified by the arguments exists in the received {@link QuickLinksProfile} * @param profile the {@link QuickLinksProfile} to examine * @param serviceName the service name where the filter is defined. {@code null} means the searched filter is a global * filter * @param componentName the component name where the filter is defined. Only makes sense when serviceName is defined * too. {@code null} means the searched filter is a service level filter, not component level one. * filter * @param filter the {@link Filter} to look for. */ private static void assertFilterExists(@Nonnull QuickLinksProfile profile, @Nullable String serviceName, @Nullable String componentName, @Nonnull Filter filter) { // looking for a global filter if (null == serviceName) { if (!profile.getFilters().contains(filter)) { throw new AssertionError("Expected global filter not found: " + filter); } } // looking for a filter defined on service or component level else { Service service = findService(profile.getServices(), serviceName); // looking for a filter defined on service level if (null == componentName) { if (!service.getFilters().contains(filter)) { throw new AssertionError(String.format("Expected filter not found. Service: %s, Filter: %s", serviceName, filter)); } } // looking for a filter defined on component level else { Component component = findComponent(service.getComponents(), componentName); if (!component.getFilters().contains(filter)) { throw new AssertionError(String.format("Expected filter not found. Service: %s, Component: %s, Filter: %s", serviceName, componentName, filter)); } } } } private static Component findComponent(List<Component> components, String componentName) { for (Component component: components) { if (component.getName().equals(componentName)) { return component; } } throw new AssertionError("Expected component not found: " + componentName); } private static Service findService(List<Service> services, String serviceName) { for (Service service: services) { if (service.getName().equals(serviceName)) { return service; } } throw new AssertionError("Expected service not found: " + serviceName); } public static Map<String, String> filter(@Nullable String linkName, @Nullable String attributeName, boolean visible) { Map<String, String> map = new HashMap<>(3); if (null != linkName) { map.put(LinkNameFilter.LINK_NAME, linkName); } if (null != attributeName) { map.put(LinkAttributeFilter.LINK_ATTRIBUTE, attributeName); } map.put(Filter.VISIBLE, Boolean.toString(visible)); return map; } public static Map<String, Object> component(String componentName, Set<Map<String, String>> filters) { Map<String, Object> map = new HashMap<>(); map.put(NAME, componentName); map.put(FILTERS, filters); return map; } public static Map<String, Object> service(String serviceName, Set<Map<String, Object>> components, Set<Map<String, String>> filters) { Map<String, Object> map = new HashMap<>(); map.put(NAME, serviceName); if (null != components) { map.put(COMPONENTS, components); } if (null != filters) { map.put(FILTERS, filters); } return map; } }