Browse Source

HADOOP-14399. Configuration does not correctly XInclude absolute file URIs.
Contributed by Jonathan Eagles

(cherry picked from commit 1ba9704eec22c75f8aec653ee15eb6767b5a7f4b)

Steve Loughran 8 năm trước cách đây
mục cha
commit
07c14b35ec

+ 23 - 14
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/conf/Configuration.java

@@ -2638,6 +2638,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
       StringBuilder token = new StringBuilder();
       String confName = null;
       String confValue = null;
+      String confInclude = null;
       boolean confFinal = false;
       boolean fallbackAllowed = false;
       boolean fallbackEntered = false;
@@ -2681,7 +2682,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
             break;
           case "include":
             // Determine href for xi:include
-            String confInclude = null;
+            confInclude = null;
             attrCount = reader.getAttributeCount();
             for (int i = 0; i < attrCount; i++) {
               String attrName = reader.getAttributeLocalName(i);
@@ -2700,18 +2701,25 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
               Resource classpathResource = new Resource(include, name);
               loadResource(properties, classpathResource, quiet);
             } else {
-              File href = new File(confInclude);
-              if (!href.isAbsolute()) {
-                // Included resources are relative to the current resource
-                File baseFile = new File(name).getParentFile();
-                href = new File(baseFile, href.getPath());
+              URL url;
+              try {
+                url = new URL(confInclude);
+                url.openConnection().connect();
+              } catch (IOException ioe) {
+                File href = new File(confInclude);
+                if (!href.isAbsolute()) {
+                  // Included resources are relative to the current resource
+                  File baseFile = new File(name).getParentFile();
+                  href = new File(baseFile, href.getPath());
+                }
+                if (!href.exists()) {
+                  // Resource errors are non-fatal iff there is 1 xi:fallback
+                  fallbackAllowed = true;
+                  break;
+                }
+                url = href.toURI().toURL();
               }
-              if (!href.exists()) {
-                // Resource errors are non-fatal iff there is 1 xi:fallback
-                fallbackAllowed = true;
-                break;
-              }
-              Resource uriResource = new Resource(href.toURI().toURL(), name);
+              Resource uriResource = new Resource(url, name);
               loadResource(properties, uriResource, quiet);
             }
             break;
@@ -2752,8 +2760,9 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
             break;
           case "include":
             if (fallbackAllowed && !fallbackEntered) {
-              throw new IOException("Fetch fail on include with no "
-                  + "fallback while loading '" + name + "'");
+              throw new IOException("Fetch fail on include for '"
+                  + confInclude + "' with no fallback while loading '"
+                  + name + "'");
             }
             fallbackAllowed = false;
             fallbackEntered = false;

+ 19 - 4
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/conf/TestConfiguration.java

@@ -29,6 +29,7 @@ import java.io.OutputStreamWriter;
 import java.io.StringWriter;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -61,6 +62,9 @@ public class TestConfiguration extends TestCase {
   final static String CONFIG = new File("./test-config-TestConfiguration.xml").getAbsolutePath();
   final static String CONFIG2 = new File("./test-config2-TestConfiguration.xml").getAbsolutePath();
   final static String CONFIG_FOR_ENUM = new File("./test-config-enum-TestConfiguration.xml").getAbsolutePath();
+  final static String CONFIG_FOR_URI = "file://"
+      + new File("./test-config-uri-TestConfiguration.xml").getAbsolutePath();
+
   private static final String CONFIG_MULTI_BYTE = new File(
     "./test-config-multi-byte-TestConfiguration.xml").getAbsolutePath();
   private static final String CONFIG_MULTI_BYTE_SAVED = new File(
@@ -85,6 +89,7 @@ public class TestConfiguration extends TestCase {
     new File(CONFIG).delete();
     new File(CONFIG2).delete();
     new File(CONFIG_FOR_ENUM).delete();
+    new File(new URI(CONFIG_FOR_URI)).delete();
     new File(CONFIG_MULTI_BYTE).delete();
     new File(CONFIG_MULTI_BYTE_SAVED).delete();
   }
@@ -428,13 +433,21 @@ public class TestConfiguration extends TestCase {
     appendProperty("a","b");
     appendProperty("c","d");
     endConfig();
+    File fileUri = new File(new URI(CONFIG_FOR_URI));
+    out=new BufferedWriter(new FileWriter(fileUri));
+    startConfig();
+    appendProperty("e", "f");
+    appendProperty("g", "h");
+    endConfig();
 
     out=new BufferedWriter(new FileWriter(CONFIG));
     startConfig();
     startInclude(CONFIG2);
     endInclude();
-    appendProperty("e","f");
-    appendProperty("g","h");
+    startInclude(CONFIG_FOR_URI);
+    endInclude();
+    appendProperty("i", "j");
+    appendProperty("k", "l");
     endConfig();
 
     // verify that the includes file contains all properties
@@ -442,8 +455,10 @@ public class TestConfiguration extends TestCase {
     conf.addResource(fileResource);
     assertEquals(conf.get("a"), "b"); 
     assertEquals(conf.get("c"), "d"); 
-    assertEquals(conf.get("e"), "f"); 
-    assertEquals(conf.get("g"), "h"); 
+    assertEquals(conf.get("e"), "f");
+    assertEquals(conf.get("g"), "h");
+    assertEquals(conf.get("i"), "j");
+    assertEquals(conf.get("k"), "l");
     tearDown();
   }