AMBARI-20877.Custom RM principal causes zookeeper HA state store to be inaccessible. (Attila Magyar via stoader)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/89797ea2 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/89797ea2 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/89797ea2 Branch: refs/heads/branch-feature-AMBARI-12556 Commit: 89797ea2c56ae0387899890756527e1019ffd3f3 Parents: e2fbd0f Author: Attila Magyar <amag...@hortonworks.com> Authored: Thu Jun 8 15:46:51 2017 +0200 Committer: Toader, Sebastian <stoa...@hortonworks.com> Committed: Thu Jun 8 15:46:51 2017 +0200 ---------------------------------------------------------------------- .../security/kerberos/kerberos_descriptor.md | 5 +- .../server/controller/KerberosHelperImpl.java | 19 ++- .../state/kerberos/KerberosDescriptor.java | 51 ++++++++ .../kerberos/VariableReplacementHelper.java | 23 +++- .../YARN/3.0.0.3.0/kerberos.json | 4 +- .../stacks/HDP/2.6/services/YARN/kerberos.json | 4 +- .../server/controller/KerberosHelperTest.java | 129 +++++++++--------- .../state/kerberos/KerberosDescriptorTest.java | 9 ++ .../kerberos/VariableReplacementHelperTest.java | 130 +++++++++++-------- 9 files changed, 242 insertions(+), 132 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/89797ea2/ambari-server/docs/security/kerberos/kerberos_descriptor.md ---------------------------------------------------------------------- diff --git a/ambari-server/docs/security/kerberos/kerberos_descriptor.md b/ambari-server/docs/security/kerberos/kerberos_descriptor.md index 54af50f..a59564c 100644 --- a/ambari-server/docs/security/kerberos/kerberos_descriptor.md +++ b/ambari-server/docs/security/kerberos/kerberos_descriptor.md @@ -288,8 +288,9 @@ the configuration type and containing values for each relevant property. Each property name and value may be a concrete value or contain variables to be replaced using values from the stack-level `properties` block or any available configuration. Properties from the `properties` -block are referenced by name (`${property_name}`) and configuration properties are reference by -configuration specification (`${config-type/property_name}`). +block are referenced by name (`${property_name}`), configuration properties are reference by +configuration specification (`${config-type/property_name}`) and kerberos principals are referenced by the principal path +(`principals/SERVICE/COMPONENT/principal_name`). ``` "configurations" : [ http://git-wip-us.apache.org/repos/asf/ambari/blob/89797ea2/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java index 87c826d..61674cf 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java @@ -1241,10 +1241,21 @@ public class KerberosHelperImpl implements KerberosHelper { @Override public Map<String, Map<String, String>> calculateConfigurations(Cluster cluster, String hostname, Map<String, String> kerberosDescriptorProperties) - throws AmbariException { - return addAdditionalConfigurations(cluster, - calculateExistingConfigurations(cluster, hostname), - hostname, kerberosDescriptorProperties); + throws AmbariException + { + Map<String, Map<String, String>> configuration = addAdditionalConfigurations(cluster, + calculateExistingConfigurations(cluster, hostname), + hostname, kerberosDescriptorProperties); + configuration.put("principals", principalNames(cluster, configuration)); + return configuration; + } + + private Map<String, String> principalNames(Cluster cluster, Map<String, Map<String, String>> configuration) throws AmbariException { + Map<String, String> result = new HashMap<>(); + for (Map.Entry<String, String> each : getKerberosDescriptor(cluster).principals().entrySet()) { + result.put(each.getKey(), variableReplacementHelper.replaceVariables(each.getValue(), configuration)); + } + return result; } @Override http://git-wip-us.apache.org/repos/asf/ambari/blob/89797ea2/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java index a1b9e5c..f9dfa4a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java @@ -20,12 +20,16 @@ package org.apache.ambari.server.state.kerberos; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import org.apache.ambari.server.AmbariException; +import org.apache.commons.lang.StringUtils; + /** * KerberosDescriptor is an implementation of an AbstractKerberosDescriptorContainer that * encapsulates an entire Kerberos descriptor hierarchy. @@ -418,4 +422,51 @@ public class KerberosDescriptor extends AbstractKerberosDescriptorContainer { return authToLocalProperties; } + + /** + * Get a map of principals, where the key is the principal path (SERVICE/COMPONENT/principal_name or SERVICE/principal_name) and the value is the principal. + * + * For example if the kerberos principal of the HISTORYSERVER is defined in the kerberos.json: + * "name": "history_server_jhs", + * "principal": { + * "value": "jhs/_HOST@${realm}", + * "type" : "service", + * }, + * Then "jhs/_h...@example.com" will be put into the map under the "MAPREDUCE2/HISTORYSERVER/history_server_jhs" key. + */ + public Map<String, String> principals() throws AmbariException { + Map<String,String> result = new HashMap<>(); + for (AbstractKerberosDescriptorContainer each : nullToEmpty(getChildContainers())) { + if ((each instanceof KerberosServiceDescriptor)) { + collectFromComponents(each.getName(), nullToEmpty(((KerberosServiceDescriptor) each).getComponents()).values(), result); + collectFromIdentities(each.getName(), "", nullToEmpty(each.getIdentities()), result); + } + } + return result; + } + + private static void collectFromComponents(String service, Collection<KerberosComponentDescriptor> components, Map<String, String> result) { + for (KerberosComponentDescriptor each : components) { + collectFromIdentities(service, each.getName(), nullToEmpty(each.getIdentities()), result); + } + } + + private static void collectFromIdentities(String service, String component, Collection<KerberosIdentityDescriptor> identities, Map<String, String> result) { + for (KerberosIdentityDescriptor each : identities) { + if (each.getPrincipalDescriptor() != null && !each.getReferencedServiceName().isPresent() && !each.getName().startsWith("/")) { + String path = StringUtils.isBlank(component) + ? String.format("%s/%s", service, each.getName()) + : String.format("%s/%s/%s", service, component, each.getName()); + result.put(path, each.getPrincipalDescriptor().getName()); + } + } + } + + private static <T> Collection<T> nullToEmpty(Collection<T> collection) { + return collection == null ? Collections.<T>emptyList() : collection; + } + + private static <K,V> Map<K,V> nullToEmpty(Map<K,V> collection) { + return collection == null ? Collections.<K,V>emptyMap() : collection; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/89797ea2/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelper.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelper.java index b9e2841..a83f080 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelper.java @@ -43,7 +43,7 @@ public class VariableReplacementHelper { /** * a regular expression Pattern used to find "variable" placeholders in strings */ - private static final Pattern PATTERN_VARIABLE = Pattern.compile("\\$\\{(?:([\\w\\-\\.]+)/)?([\\w\\-\\.]+)(?:\\s*\\|\\s*(.+?))?\\}"); + private static final Pattern PATTERN_VARIABLE = Pattern.compile("\\$\\{(?:([\\w\\-\\.]+)/)?([\\w\\-\\./]+)(?:\\s*\\|\\s*(.+?))?\\}"); /** * a regular expression Pattern used to parse "function" declarations: name(arg1, arg2, ...) @@ -59,6 +59,7 @@ public class VariableReplacementHelper { put("toLower", new ToLowerFunction()); put("replace", new ReplaceValue()); put("append", new AppendFunction()); + put("principalPrimary", new PrincipalPrimary()); } }; @@ -411,4 +412,24 @@ public class VariableReplacementHelper { return sourceData; } } + + /** + * Get the primary part of a Kerberos principal. + * The format of a typical Kerberos principal is primary/instance@REALM. + */ + private static class PrincipalPrimary implements Function { + @Override + public String perform(String[] args, String data, Map<String, Map<String, String>> replacementsMap) { + if (data == null) { + return null; + } + if (data.contains("/")) { + return data.split("/")[0]; + } else if (data.contains("@")) { + return data.split("@")[0]; + } else { + return data; + } + } + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/89797ea2/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/kerberos.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/kerberos.json b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/kerberos.json index ae4db4f..b1501b8 100644 --- a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/kerberos.json +++ b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/kerberos.json @@ -32,9 +32,9 @@ "yarn.resourcemanager.proxyuser.*.hosts": "", "yarn.resourcemanager.proxyuser.*.users": "", "yarn.resourcemanager.proxy-user-privileges.enabled": "true", - "yarn.resourcemanager.zk-acl" : "sasl:rm:rwcda", + "yarn.resourcemanager.zk-acl" : "sasl:${principals/YARN/RESOURCEMANAGER/resource_manager_rm|principalPrimary()}:rwcda", "hadoop.registry.secure" : "true", - "hadoop.registry.system.accounts" : "sasl:yarn,sasl:mapred,sasl:hadoop,sasl:hdfs,sasl:rm,sasl:hive", + "hadoop.registry.system.accounts" : "sasl:${principals/YARN/APP_TIMELINE_SERVER/app_timeline_server_yarn|principalPrimary()},sasl:${principals/MAPREDUCE2/HISTORYSERVER/history_server_jhs|principalPrimary()},sasl:${principals/HDFS/NAMENODE/hdfs|principalPrimary()},sasl:${principals/YARN/RESOURCEMANAGER/resource_manager_rm|principalPrimary()},sasl:${principals/HIVE/HIVE_SERVER/hive_server_hive|principalPrimary()}", "hadoop.registry.client.auth" : "kerberos", "hadoop.registry.jaas.context" : "Client" } http://git-wip-us.apache.org/repos/asf/ambari/blob/89797ea2/ambari-server/src/main/resources/stacks/HDP/2.6/services/YARN/kerberos.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/YARN/kerberos.json b/ambari-server/src/main/resources/stacks/HDP/2.6/services/YARN/kerberos.json index ae4db4f..b1501b8 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/YARN/kerberos.json +++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/YARN/kerberos.json @@ -32,9 +32,9 @@ "yarn.resourcemanager.proxyuser.*.hosts": "", "yarn.resourcemanager.proxyuser.*.users": "", "yarn.resourcemanager.proxy-user-privileges.enabled": "true", - "yarn.resourcemanager.zk-acl" : "sasl:rm:rwcda", + "yarn.resourcemanager.zk-acl" : "sasl:${principals/YARN/RESOURCEMANAGER/resource_manager_rm|principalPrimary()}:rwcda", "hadoop.registry.secure" : "true", - "hadoop.registry.system.accounts" : "sasl:yarn,sasl:mapred,sasl:hadoop,sasl:hdfs,sasl:rm,sasl:hive", + "hadoop.registry.system.accounts" : "sasl:${principals/YARN/APP_TIMELINE_SERVER/app_timeline_server_yarn|principalPrimary()},sasl:${principals/MAPREDUCE2/HISTORYSERVER/history_server_jhs|principalPrimary()},sasl:${principals/HDFS/NAMENODE/hdfs|principalPrimary()},sasl:${principals/YARN/RESOURCEMANAGER/resource_manager_rm|principalPrimary()},sasl:${principals/HIVE/HIVE_SERVER/hive_server_hive|principalPrimary()}", "hadoop.registry.client.auth" : "kerberos", "hadoop.registry.jaas.context" : "Client" } http://git-wip-us.apache.org/repos/asf/ambari/blob/89797ea2/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java index 98241eb..18a6754 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java @@ -1001,30 +1001,30 @@ public class KerberosHelperTest extends EasyMockSupport { expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient)).anyTimes(); - final Service serviceKerberos = createStrictMock(Service.class); + final Service serviceKerberos = createNiceMock(Service.class); expect(serviceKerberos.getDesiredStackId()).andReturn(stackId).anyTimes(); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) - .times(1); + .anyTimes(); serviceKerberos.setSecurityState(SecurityState.SECURED_KERBEROS); expectLastCall().once(); - final Service service1 = createStrictMock(Service.class); + final Service service1 = createNiceMock(Service.class); expect(service1.getDesiredStackId()).andReturn(stackId).anyTimes(); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(1); + .anyTimes(); service1.setSecurityState(SecurityState.SECURED_KERBEROS); expectLastCall().once(); - final Service service2 = createStrictMock(Service.class); + final Service service2 = createNiceMock(Service.class); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getDesiredStackId()).andReturn(stackId).anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(1); + .anyTimes(); service2.setSecurityState(SecurityState.SECURED_KERBEROS); expectLastCall().once(); @@ -1090,7 +1090,7 @@ public class KerberosHelperTest extends EasyMockSupport { expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).once(); expect(kerberosDescriptor.getService("SERVICE2")).andReturn(serviceDescriptor2).once(); - setupKerberosDescriptor(kerberosDescriptor, 1); + setupKerberosDescriptor(kerberosDescriptor); setupStageFactory(); // This is a STRICT mock to help ensure that the end result is what we want. @@ -1203,7 +1203,7 @@ public class KerberosHelperTest extends EasyMockSupport { expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient)).anyTimes(); final Service serviceKerberos = createNiceMock(Service.class); - expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) @@ -1212,7 +1212,7 @@ public class KerberosHelperTest extends EasyMockSupport { expectLastCall().once(); final Service service1 = createNiceMock(Service.class); - expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) @@ -1221,7 +1221,7 @@ public class KerberosHelperTest extends EasyMockSupport { expectLastCall().once(); final Service service2 = createNiceMock(Service.class); - expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) @@ -1287,7 +1287,7 @@ public class KerberosHelperTest extends EasyMockSupport { expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).atLeastOnce(); expect(kerberosDescriptor.getService("SERVICE2")).andReturn(serviceDescriptor2).atLeastOnce(); - setupKerberosDescriptor(kerberosDescriptor, 1); + setupKerberosDescriptor(kerberosDescriptor); setupStageFactory(); // This is a STRICT mock to help ensure that the end result is what we want. @@ -1426,25 +1426,25 @@ public class KerberosHelperTest extends EasyMockSupport { expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(map).anyTimes(); final Service serviceKerberos = createStrictMock(Service.class); - expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) - .times(1); + .anyTimes(); final Service service1 = createStrictMock(Service.class); - expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(1); + .anyTimes(); final Service service2 = createStrictMock(Service.class); - expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(1); + .anyTimes(); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("kdc_type")).andReturn("mit-kdc").anyTimes(); @@ -1509,7 +1509,7 @@ public class KerberosHelperTest extends EasyMockSupport { expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).atLeastOnce(); expect(kerberosDescriptor.getService("SERVICE2")).andReturn(serviceDescriptor2).atLeastOnce(); - setupKerberosDescriptor(kerberosDescriptor, 1); + setupKerberosDescriptor(kerberosDescriptor); setupStageFactory(); final RequestStageContainer requestStageContainer; @@ -2050,7 +2050,7 @@ public class KerberosHelperTest extends EasyMockSupport { expect(kerberosDescriptor.getIdentities(eq(true), EasyMock.<Map<String, Object>>anyObject())).andReturn(null).atLeastOnce(); expect(kerberosDescriptor.getAuthToLocalProperties()).andReturn(Collections.singleton("core-site/auth.to.local")).atLeastOnce(); - setupKerberosDescriptor(kerberosDescriptor, 2); + setupKerberosDescriptor(kerberosDescriptor); RecommendationResponse.BlueprintConfigurations coreSiteRecommendation = createNiceMock(RecommendationResponse .BlueprintConfigurations.class); @@ -2485,7 +2485,7 @@ public class KerberosHelperTest extends EasyMockSupport { expectLastCall().once(); } - setupKerberosDescriptor(kerberosDescriptor, 1); + setupKerberosDescriptor(kerberosDescriptor); Map<String, Map<String, String>> existingConfigurations = new HashMap<>(); existingConfigurations.put("kerberos-env", propertiesKerberosEnv); @@ -2612,7 +2612,7 @@ public class KerberosHelperTest extends EasyMockSupport { expect(kerberosDescriptor.getProperties()).andReturn(kerberosDescriptorProperties); expect(kerberosDescriptor.getService("SERVICE1")).andReturn(service1KerberosDescriptor).times(1); - setupKerberosDescriptor(kerberosDescriptor, 1); + setupKerberosDescriptor(kerberosDescriptor); Map<String, Map<String, String>> existingConfigurations = new HashMap<>(); existingConfigurations.put("kerberos-env", propertiesKerberosEnv); @@ -2648,9 +2648,10 @@ public class KerberosHelperTest extends EasyMockSupport { assertEquals(0, capturedPrincipalsForKeytab.size()); } - private void setupKerberosDescriptor(KerberosDescriptor kerberosDescriptor, int expectedCalls) throws Exception { + private void setupKerberosDescriptor(KerberosDescriptor kerberosDescriptor) throws Exception { // cluster.getCurrentStackVersion expectation is already specified in main test method - expect(metaInfo.getKerberosDescriptor("HDP", "2.2")).andReturn(kerberosDescriptor).times(expectedCalls); + expect(metaInfo.getKerberosDescriptor("HDP", "2.2")).andReturn(kerberosDescriptor).anyTimes(); + expect(kerberosDescriptor.principals()).andReturn(Collections.<String, String>emptyMap()).anyTimes(); } private void setupStageFactory() { @@ -2736,25 +2737,25 @@ public class KerberosHelperTest extends EasyMockSupport { ).anyTimes(); final Service serviceKerberos = createStrictMock(Service.class); - expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) - .times(1); + .anyTimes(); final Service service1 = createStrictMock(Service.class); - expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(1); + .anyTimes(); final Service service2 = createStrictMock(Service.class); - expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(1); + .anyTimes(); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("kdc_type")).andReturn("mit-kdc").anyTimes(); @@ -2904,7 +2905,7 @@ public class KerberosHelperTest extends EasyMockSupport { expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).times(1); } - setupKerberosDescriptor(kerberosDescriptor, 1); + setupKerberosDescriptor(kerberosDescriptor); setupStageFactory(); // This is a STRICT mock to help ensure that the end result is what we want. @@ -2995,25 +2996,25 @@ public class KerberosHelperTest extends EasyMockSupport { expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient)).anyTimes(); final Service serviceKerberos = createStrictMock(Service.class); - expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) - .times(1); + .anyTimes(); final Service service1 = createStrictMock(Service.class); - expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(1); + .anyTimes(); final Service service2 = createStrictMock(Service.class); - expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(1); + .anyTimes(); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("kdc_type")).andReturn("mit-kdc").anyTimes(); @@ -3110,7 +3111,7 @@ public class KerberosHelperTest extends EasyMockSupport { expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).times(1); expect(kerberosDescriptor.getService("SERVICE3")).andReturn(serviceDescriptor3).times(1); - setupKerberosDescriptor(kerberosDescriptor, 1); + setupKerberosDescriptor(kerberosDescriptor); setupStageFactory(); // This is a STRICT mock to help ensure that the end result is what we want. @@ -3210,26 +3211,26 @@ public class KerberosHelperTest extends EasyMockSupport { expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient)).anyTimes(); - final Service serviceKerberos = createStrictMock(Service.class); - expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + final Service serviceKerberos = createNiceMock(Service.class); + expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) - .times(2); + .anyTimes(); - final Service service1 = createStrictMock(Service.class); - expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + final Service service1 = createNiceMock(Service.class); + expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(2); + .anyTimes(); - final Service service2 = createStrictMock(Service.class); - expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + final Service service2 = createNiceMock(Service.class); + expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(2); + .anyTimes(); expect(cluster.getClusterName()).andReturn("c1").anyTimes(); @@ -3291,7 +3292,7 @@ public class KerberosHelperTest extends EasyMockSupport { final KerberosDescriptor kerberosDescriptor = createStrictMock(KerberosDescriptor.class); expect(kerberosDescriptor.getProperties()).andReturn(null).once(); - setupKerberosDescriptor(kerberosDescriptor, 1); + setupKerberosDescriptor(kerberosDescriptor); setupStageFactory(); // Preparation Stage @@ -3384,26 +3385,26 @@ public class KerberosHelperTest extends EasyMockSupport { expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient)).anyTimes(); - final Service serviceKerberos = createStrictMock(Service.class); - expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + final Service serviceKerberos = createNiceMock(Service.class); + expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) - .times(2); + .anyTimes(); - final Service service1 = createStrictMock(Service.class); - expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + final Service service1 = createNiceMock(Service.class); + expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(2); + .anyTimes(); - final Service service2 = createStrictMock(Service.class); - expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + final Service service2 = createNiceMock(Service.class); + expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) - .times(2); + .anyTimes(); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("kdc_type")).andReturn("mit-kdc").anyTimes(); @@ -3466,7 +3467,7 @@ public class KerberosHelperTest extends EasyMockSupport { final KerberosDescriptor kerberosDescriptor = createStrictMock(KerberosDescriptor.class); expect(kerberosDescriptor.getProperties()).andReturn(null).once(); - setupKerberosDescriptor(kerberosDescriptor, 1); + setupKerberosDescriptor(kerberosDescriptor); setupStageFactory(); // This is a STRICT mock to help ensure that the end result is what we want. @@ -3558,22 +3559,22 @@ public class KerberosHelperTest extends EasyMockSupport { expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient1)).anyTimes(); - final Service serviceKerberos = createStrictMock(Service.class); - expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + final Service serviceKerberos = createNiceMock(Service.class); + expect(serviceKerberos.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) .anyTimes(); - final Service service1 = createStrictMock(Service.class); - expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + final Service service1 = createNiceMock(Service.class); + expect(service1.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .anyTimes(); - final Service service2 = createStrictMock(Service.class); - expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")); + final Service service2 = createNiceMock(Service.class); + expect(service2.getDesiredStackId()).andReturn(new StackId("HDP-2.2")).anyTimes(); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) @@ -3779,7 +3780,7 @@ public class KerberosHelperTest extends EasyMockSupport { expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).anyTimes(); expect(kerberosDescriptor.getService("SERVICE2")).andReturn(serviceDescriptor2).anyTimes(); - setupKerberosDescriptor(kerberosDescriptor, 1); + setupKerberosDescriptor(kerberosDescriptor); replayAll(); http://git-wip-us.apache.org/repos/asf/ambari/blob/89797ea2/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java index a63da61..7fb5624 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java @@ -493,4 +493,13 @@ public class KerberosDescriptorTest { }}); Assert.assertEquals(1, identities.size()); } + + @Test + public void testCollectPrincipalNames() throws Exception { + URL systemResourceURL = ClassLoader.getSystemResource("kerberos/test_get_referenced_identity_descriptor.json"); + KerberosDescriptor descriptor = KERBEROS_DESCRIPTOR_FACTORY.createInstance(new File(systemResourceURL.getFile())); + Map<String, String> principalsPerComponent = descriptor.principals(); + Assert.assertEquals("service2_component1@${realm}", principalsPerComponent.get("SERVICE2/SERVICE2_COMPONENT1/service2_component1_identity")); + Assert.assertEquals("service1@${realm}", principalsPerComponent.get("SERVICE1/service1_identity")); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/89797ea2/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelperTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelperTest.java index f00f694..e46294a 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelperTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelperTest.java @@ -18,6 +18,8 @@ package org.apache.ambari.server.state.kerberos; +import static junit.framework.Assert.assertEquals; + import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -72,63 +74,63 @@ public class VariableReplacementHelperTest { } }; - Assert.assertEquals("concrete", - helper.replaceVariables("concrete", configurations)); + assertEquals("concrete", + helper.replaceVariables("concrete", configurations)); - Assert.assertEquals("Hello World", - helper.replaceVariables("${global_variable}", configurations)); + assertEquals("Hello World", + helper.replaceVariables("${global_variable}", configurations)); - Assert.assertEquals("Replacement1", - helper.replaceVariables("${config-type/variable.name}", configurations)); + assertEquals("Replacement1", + helper.replaceVariables("${config-type/variable.name}", configurations)); - Assert.assertEquals("Replacement1|Replacement2", - helper.replaceVariables("${config-type/variable.name}|${config-type2/variable.name}", configurations)); + assertEquals("Replacement1|Replacement2", + helper.replaceVariables("${config-type/variable.name}|${config-type2/variable.name}", configurations)); - Assert.assertEquals("Replacement1|Replacement2|${config-type3/variable.name}", - helper.replaceVariables("${config-type/variable.name}|${config-type2/variable.name}|${config-type3/variable.name}", configurations)); + assertEquals("Replacement1|Replacement2|${config-type3/variable.name}", + helper.replaceVariables("${config-type/variable.name}|${config-type2/variable.name}|${config-type3/variable.name}", configurations)); - Assert.assertEquals("Replacement2|Replacement2", - helper.replaceVariables("${config-type/variable.name1}|${config-type2/variable.name}", configurations)); + assertEquals("Replacement2|Replacement2", + helper.replaceVariables("${config-type/variable.name1}|${config-type2/variable.name}", configurations)); - Assert.assertEquals("Replacement1_reference", - helper.replaceVariables("${config-type/variable.name}_reference", configurations)); + assertEquals("Replacement1_reference", + helper.replaceVariables("${config-type/variable.name}_reference", configurations)); - Assert.assertEquals("dash", - helper.replaceVariables("${variable-name}", configurations)); + assertEquals("dash", + helper.replaceVariables("${variable-name}", configurations)); - Assert.assertEquals("underscore", - helper.replaceVariables("${variable_name}", configurations)); + assertEquals("underscore", + helper.replaceVariables("${variable_name}", configurations)); - Assert.assertEquals("config_type_dot", - helper.replaceVariables("${config_type/variable.name}", configurations)); + assertEquals("config_type_dot", + helper.replaceVariables("${config_type/variable.name}", configurations)); - Assert.assertEquals("config_type_dash", - helper.replaceVariables("${config_type/variable-name}", configurations)); + assertEquals("config_type_dash", + helper.replaceVariables("${config_type/variable-name}", configurations)); - Assert.assertEquals("config_type_underscore", - helper.replaceVariables("${config_type/variable_name}", configurations)); + assertEquals("config_type_underscore", + helper.replaceVariables("${config_type/variable_name}", configurations)); - Assert.assertEquals("config.type_dot", - helper.replaceVariables("${config.type/variable.name}", configurations)); + assertEquals("config.type_dot", + helper.replaceVariables("${config.type/variable.name}", configurations)); - Assert.assertEquals("config.type_dash", - helper.replaceVariables("${config.type/variable-name}", configurations)); + assertEquals("config.type_dash", + helper.replaceVariables("${config.type/variable-name}", configurations)); - Assert.assertEquals("config.type_underscore", - helper.replaceVariables("${config.type/variable_name}", configurations)); + assertEquals("config.type_underscore", + helper.replaceVariables("${config.type/variable_name}", configurations)); - Assert.assertEquals("dot", - helper.replaceVariables("${variable.name}", configurations)); + assertEquals("dot", + helper.replaceVariables("${variable.name}", configurations)); // Replacement yields an empty string - Assert.assertEquals("", - helper.replaceVariables("${config-type/variable.name2}", configurations)); + assertEquals("", + helper.replaceVariables("${config-type/variable.name2}", configurations)); // This might cause an infinite loop... we assume protection is in place... try { - Assert.assertEquals("${config-type2/self_reference}", - helper.replaceVariables("${config-type2/self_reference}", configurations)); + assertEquals("${config-type2/self_reference}", + helper.replaceVariables("${config-type2/self_reference}", configurations)); Assert.fail(String.format("%s expected to be thrown", AmbariException.class.getName())); } catch (AmbariException e) { // This is expected... @@ -146,14 +148,14 @@ public class VariableReplacementHelperTest { } }; - Assert.assertEquals("hive.metastore.local=false,hive.metastore.uris=thrift://c6401.ambari.apache.org:9083,hive.metastore.sasl.enabled=true,hive.metastore.execute.setugi=true,hive.metastore.warehouse.dir=/apps/hive/warehouse,hive.exec.mode.local.auto=false,hive.metastore.kerberos.principal=hive/_h...@example.com", - helper.replaceVariables("hive.metastore.local=false,hive.metastore.uris=thrift://${host}:9083,hive.metastore.sasl.enabled=true,hive.metastore.execute.setugi=true,hive.metastore.warehouse.dir=/apps/hive/warehouse,hive.exec.mode.local.auto=false,hive.metastore.kerberos.principal=hive/_HOST@${realm}", configurations)); + assertEquals("hive.metastore.local=false,hive.metastore.uris=thrift://c6401.ambari.apache.org:9083,hive.metastore.sasl.enabled=true,hive.metastore.execute.setugi=true,hive.metastore.warehouse.dir=/apps/hive/warehouse,hive.exec.mode.local.auto=false,hive.metastore.kerberos.principal=hive/_h...@example.com", + helper.replaceVariables("hive.metastore.local=false,hive.metastore.uris=thrift://${host}:9083,hive.metastore.sasl.enabled=true,hive.metastore.execute.setugi=true,hive.metastore.warehouse.dir=/apps/hive/warehouse,hive.exec.mode.local.auto=false,hive.metastore.kerberos.principal=hive/_HOST@${realm}", configurations)); - Assert.assertEquals("Hello my realm is {EXAMPLE.COM}", - helper.replaceVariables("Hello my realm is {${realm}}", configurations)); + assertEquals("Hello my realm is {EXAMPLE.COM}", + helper.replaceVariables("Hello my realm is {${realm}}", configurations)); - Assert.assertEquals("$c6401.ambari.apache.org", - helper.replaceVariables("$${host}", configurations)); + assertEquals("$c6401.ambari.apache.org", + helper.replaceVariables("$${host}", configurations)); } @Test @@ -168,7 +170,7 @@ public class VariableReplacementHelperTest { put("kafka-broker", new HashMap<String, String>() {{ put("listeners", "PLAINTEXT://localhost:6667"); }}); - + put("clusterHostInfo", new HashMap<String, String>() {{ put("hive_metastore_host", "host1.unit.test, host2.unit.test , host3.unit.test"); // spaces are there on purpose. }}); @@ -182,11 +184,11 @@ public class VariableReplacementHelperTest { } }; - Assert.assertEquals("test=thrift://one:9083\\,thrift://two:9083\\,thrift://three:9083\\,thrift://four:9083", - helper.replaceVariables("test=${delimited.data|each(thrift://%s:9083, \\\\,, \\s*\\,\\s*)}", configurations)); + assertEquals("test=thrift://one:9083\\,thrift://two:9083\\,thrift://three:9083\\,thrift://four:9083", + helper.replaceVariables("test=${delimited.data|each(thrift://%s:9083, \\\\,, \\s*\\,\\s*)}", configurations)); - Assert.assertEquals("hive.metastore.local=false,hive.metastore.uris=thrift://host1.unit.test:9083\\,thrift://host2.unit.test:9083\\,thrift://host3.unit.test:9083,hive.metastore.sasl.enabled=true,hive.metastore.execute.setugi=true,hive.metastore.warehouse.dir=/apps/hive/warehouse,hive.exec.mode.local.auto=false,hive.metastore.kerberos.principal=hive/_h...@unit.test", - helper.replaceVariables("hive.metastore.local=false,hive.metastore.uris=${clusterHostInfo/hive_metastore_host | each(thrift://%s:9083, \\\\,, \\s*\\,\\s*)},hive.metastore.sasl.enabled=true,hive.metastore.execute.setugi=true,hive.metastore.warehouse.dir=/apps/hive/warehouse,hive.exec.mode.local.auto=false,hive.metastore.kerberos.principal=hive/_HOST@${realm}", configurations)); + assertEquals("hive.metastore.local=false,hive.metastore.uris=thrift://host1.unit.test:9083\\,thrift://host2.unit.test:9083\\,thrift://host3.unit.test:9083,hive.metastore.sasl.enabled=true,hive.metastore.execute.setugi=true,hive.metastore.warehouse.dir=/apps/hive/warehouse,hive.exec.mode.local.auto=false,hive.metastore.kerberos.principal=hive/_h...@unit.test", + helper.replaceVariables("hive.metastore.local=false,hive.metastore.uris=${clusterHostInfo/hive_metastore_host | each(thrift://%s:9083, \\\\,, \\s*\\,\\s*)},hive.metastore.sasl.enabled=true,hive.metastore.execute.setugi=true,hive.metastore.warehouse.dir=/apps/hive/warehouse,hive.exec.mode.local.auto=false,hive.metastore.kerberos.principal=hive/_HOST@${realm}", configurations)); List<String> expected; List<String> actual; @@ -195,38 +197,52 @@ public class VariableReplacementHelperTest { actual = new LinkedList<>(Arrays.asList(helper.replaceVariables("${foobar-site/hello | append(foobar-site/data, \\,, true)}", configurations).split(","))); Collections.sort(expected); Collections.sort(actual); - Assert.assertEquals(expected, actual); + assertEquals(expected, actual); expected = new LinkedList<>(Arrays.asList("four", "hello", "one", "there", "three", "two")); actual = new LinkedList<>(Arrays.asList(helper.replaceVariables("${foobar-site/hello_there | append(foobar-site/data, \\,, true)}", configurations).split(","))); Collections.sort(expected); Collections.sort(actual); - Assert.assertEquals(expected, actual); + assertEquals(expected, actual); expected = new LinkedList<>(Arrays.asList("four", "hello", "one", "there", "three", "two")); actual = new LinkedList<>(Arrays.asList(helper.replaceVariables("${foobar-site/hello_there_one | append(foobar-site/data, \\,, true)}", configurations).split(","))); Collections.sort(expected); Collections.sort(actual); - Assert.assertEquals(expected, actual); + assertEquals(expected, actual); expected = new LinkedList<>(Arrays.asList("four", "hello", "one", "one", "there", "three", "two")); actual = new LinkedList<>(Arrays.asList(helper.replaceVariables("${foobar-site/hello_there_one | append(foobar-site/data, \\,, false)}", configurations).split(","))); Collections.sort(expected); Collections.sort(actual); - Assert.assertEquals(expected, actual); + assertEquals(expected, actual); // Test invalid number of arguments. try { helper.replaceVariables("${foobar-site/hello_there_one | append(foobar-site/data, \\,)}", configurations); Assert.fail("Expected IllegalArgumentException"); - } - catch (IllegalArgumentException e) { + } catch (IllegalArgumentException e) { // Ignore this is expected. } - Assert.assertEquals("test=unit.test", helper.replaceVariables("test=${realm|toLower()}", configurations)); - - Assert.assertEquals("PLAINTEXTSASL://localhost:6667", helper.replaceVariables("${kafka-broker/listeners|replace(\\bPLAINTEXT\\b,PLAINTEXTSASL)}", configurations)); + assertEquals("test=unit.test", helper.replaceVariables("test=${realm|toLower()}", configurations)); + + assertEquals("PLAINTEXTSASL://localhost:6667", helper.replaceVariables("${kafka-broker/listeners|replace(\\bPLAINTEXT\\b,PLAINTEXTSASL)}", configurations)); } -} + @Test + public void testReplacePrincipalWithPrimary() throws AmbariException { + Map<String, Map<String, String>> config = new HashMap<String, Map<String, String>>() { + { + put("principals", new HashMap<String, String>() {{ + put("resource_manager_rm", "rm/h...@example.com"); + put("hive_server_hive", "h...@example.com"); + put("hdfs", "hdfs"); + }}); + } + }; + assertEquals("hdfs", helper.replaceVariables("${principals/hdfs|principalPrimary()}", config)); + assertEquals("rm", helper.replaceVariables("${principals/resource_manager_rm|principalPrimary()}", config)); + assertEquals("hive", helper.replaceVariables("${principals/hive_server_hive|principalPrimary()}", config)); + } +} \ No newline at end of file