commit fd264668f0bb93e33e5631ec3cc8a7670c01e6e7 Author: Gera Shegalov Date: Sat Jun 27 10:35:34 2015 -0700 YARN-3768.002.patch diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/Shell.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/Shell.java index 45c1588..ed83e8d 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/Shell.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/Shell.java @@ -221,10 +221,12 @@ static private OSType getOSType() { new String[] { "kill", "-" + code, isSetsidAvailable ? "-" + pid : pid }; } + public static final String ENV_NAME_REGEX = "[A-Za-z_][A-Za-z0-9_]*"; /** Return a regular expression string that match environment variables */ public static String getEnvironmentVariableRegex() { - return (WINDOWS) ? "%([A-Za-z_][A-Za-z0-9_]*?)%" : - "\\$([A-Za-z_][A-Za-z0-9_]*)"; + return (WINDOWS) + ? "%(" + ENV_NAME_REGEX + "?)%" + : "\\$(" + ENV_NAME_REGEX + ")"; } /** diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java index cf3940f..4d25bae 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java @@ -44,6 +44,14 @@ public class Apps { public static final String APP = "application"; public static final String ID = "ID"; + private static final Pattern VAR_SUBBER = + Pattern.compile(Shell.getEnvironmentVariableRegex()); + private static final Pattern VARVAL_SPLITTER = Pattern.compile( + "(?<=^|,)" // preceded by ',' or line begin + + "(" + Shell.ENV_NAME_REGEX + ")" // var group + + "=" + + "([^=,]+)" // val group + ); public static ApplicationId toAppID(String aid) { Iterator it = _split(aid).iterator(); @@ -73,11 +81,10 @@ public static void throwParseException(String name, String s) { public static void setEnvFromInputString(Map env, String envString, String classPathSeparator) { if (envString != null && envString.length() > 0) { - String childEnvs[] = envString.split(","); - Pattern p = Pattern.compile(Shell.getEnvironmentVariableRegex()); - for (String cEnv : childEnvs) { - String[] parts = cEnv.split("="); // split on '=' - Matcher m = p.matcher(parts[1]); + Matcher varValMatcher = VARVAL_SPLITTER.matcher(envString); + while (varValMatcher.find()) { + String envVar = varValMatcher.group(1); + Matcher m = VAR_SUBBER.matcher(varValMatcher.group(2)); StringBuffer sb = new StringBuffer(); while (m.find()) { String var = m.group(1); @@ -93,7 +100,7 @@ public static void setEnvFromInputString(Map env, m.appendReplacement(sb, Matcher.quoteReplacement(replace)); } m.appendTail(sb); - addToEnvironment(env, parts[0], sb.toString(), classPathSeparator); + addToEnvironment(env, envVar, sb.toString(), classPathSeparator); } } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestApps.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestApps.java new file mode 100644 index 0000000..bcdc967 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestApps.java @@ -0,0 +1,59 @@ +/** +* 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.hadoop.yarn.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.apache.hadoop.util.Shell; +import org.junit.Test; + +public class TestApps { + @Test + public void testSetEnvFromInputString() { + Map environment = new HashMap(); + environment.put("JAVA_HOME", "/path/jdk"); + String goodEnv = "a1=1,b_2=2,c-3=3,d=4,e=,f_win=%JAVA_HOME%" + + ",g_nix=$JAVA_HOME"; + Apps.setEnvFromInputString(environment, goodEnv, File.pathSeparator); + assertEquals("1", environment.get("a1")); + assertEquals("2", environment.get("b_2")); + assertNull(environment.get("c-3")); + assertEquals("4", environment.get("d")); + assertNull(environment.get("e")); + if (Shell.WINDOWS) { + assertEquals("$JAVA_HOME", environment.get("g_nix")); + assertEquals("/path/jdk", environment.get("f_win")); + } else { + assertEquals("/path/jdk", environment.get("g_nix")); + assertEquals("%JAVA_HOME%", environment.get("f_win")); + } + String badEnv = "1,,2=a=b,3=a=,4==,5==a,==,a==1"; + environment.clear(); + Apps.setEnvFromInputString(environment, badEnv, File.pathSeparator); + assertEquals(environment.size(), 0); + } +}