浏览代码

HADOOP-17086. ABFS: Making the ListStatus response ignore unknown properties. (#2101)

Contributed by Bilahari T H.

Change-Id: I82e4683fba8481aef2abab7a6a99e5752f6fffa9
bilaharith 4 年之前
父节点
当前提交
19fb204011

+ 2 - 0
hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/contracts/services/ListResultEntrySchema.java

@@ -18,6 +18,7 @@
 
 package org.apache.hadoop.fs.azurebfs.contracts.services;
 
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
 import org.codehaus.jackson.annotate.JsonProperty;
 
 import org.apache.hadoop.classification.InterfaceStability;
@@ -26,6 +27,7 @@ import org.apache.hadoop.classification.InterfaceStability;
  * The ListResultEntrySchema model.
  */
 @InterfaceStability.Evolving
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class ListResultEntrySchema {
   /**
    * The name property.

+ 2 - 0
hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/contracts/services/ListResultSchema.java

@@ -20,6 +20,7 @@ package org.apache.hadoop.fs.azurebfs.contracts.services;
 
 import java.util.List;
 
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
 import org.codehaus.jackson.annotate.JsonProperty;
 
 import org.apache.hadoop.classification.InterfaceStability;
@@ -28,6 +29,7 @@ import org.apache.hadoop.classification.InterfaceStability;
  * The ListResultSchema model.
  */
 @InterfaceStability.Evolving
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class ListResultSchema {
   /**
    * The paths property.

+ 157 - 0
hadoop-tools/hadoop-azure/src/test/java/org/apache/hadoop/fs/azurebfs/contract/ListResultSchemaTest.java

@@ -0,0 +1,157 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.fs.azurebfs.contract;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Test;
+
+import org.apache.hadoop.fs.azurebfs.contracts.services.ListResultEntrySchema;
+import org.apache.hadoop.fs.azurebfs.contracts.services.ListResultSchema;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests the JSON parsing for the listfilestatus response to ListResultSchema
+ */
+public class ListResultSchemaTest {
+
+  /**
+   * Test parsing a JSON which matches the properties in the ListResultSchema
+   * and ListResultEntrySchema
+   * <p>
+   * {
+   * "paths": [
+   * {
+   * "contentLength": "0",
+   * "etag": "0x8D8186452785ADA",
+   * "group": "$superuser",
+   * "lastModified": "Wed, 24 Jun 2020 17:30:43 GMT",
+   * "name": "dest/filename",
+   * "owner": "$superuser",
+   * "permissions": "rw-r--r--"
+   * }
+   * ]
+   * }
+   */
+  @Test
+  public void testMatchingJSON() throws IOException {
+
+    String matchingJson =
+        "{ \"paths\": [ { \"contentLength\": \"0\", \"etag\": "
+            + "\"0x8D8186452785ADA\", \"group\": \"$superuser\", "
+            + "\"lastModified\": \"Wed, 24 Jun 2020 17:30:43 GMT\", \"name\": "
+            + "\"dest/filename\", \"owner\": \"$superuser\", \"permissions\": "
+            + "\"rw-r--r--\" } ] } ";
+
+    final ObjectMapper objectMapper = new ObjectMapper();
+    final ListResultSchema listResultSchema = objectMapper
+        .readValue(matchingJson, ListResultSchema.class);
+
+    assertThat(listResultSchema.paths().size())
+        .describedAs("Only one path is expected as present in the input JSON")
+        .isEqualTo(1);
+
+    ListResultEntrySchema path = listResultSchema.paths().get(0);
+    assertThat(path.contentLength())
+        .describedAs("contentLength should match the value in the input JSON")
+        .isEqualTo(0L);
+    assertThat(path.eTag())
+        .describedAs("eTag should match the value in the input JSON")
+        .isEqualTo("0x8D8186452785ADA");
+    assertThat(path.group())
+        .describedAs("group should match the value in the input JSON")
+        .isEqualTo("$superuser");
+    assertThat(path.lastModified())
+        .describedAs("lastModified should match the value in the input JSON")
+        .isEqualTo("Wed, 24 Jun 2020 17:30:43 GMT");
+    assertThat(path.name())
+        .describedAs("lastModified should match the value in the input JSON")
+        .isEqualTo("dest/filename");
+    assertThat(path.owner())
+        .describedAs("lastModified should match the value in the input JSON")
+        .isEqualTo("$superuser");
+    assertThat(path.permissions())
+        .describedAs("lastModified should match the value in the input JSON")
+        .isEqualTo("rw-r--r--");
+  }
+
+  /**
+   * Test parsing a JSON which matches the properties in the ListResultSchema
+   * and ListResultEntrySchema along with an unknown property
+   * <p>
+   * {
+   * "paths": [
+   * {
+   * "contentLength": "0",
+   * "unknownProperty": "132374934429527192",
+   * "etag": "0x8D8186452785ADA",
+   * "group": "$superuser",
+   * "lastModified": "Wed, 24 Jun 2020 17:30:43 GMT",
+   * "name": "dest/filename",
+   * "owner": "$superuser",
+   * "permissions": "rw-r--r--"
+   * }
+   * ]
+   * }
+   */
+  @Test
+  public void testJSONWithUnknownFields() throws IOException {
+
+    String matchingJson = "{ \"paths\": [ { \"contentLength\": \"0\", "
+        + "\"unknownProperty\": \"132374934429527192\", \"etag\": "
+        + "\"0x8D8186452785ADA\", \"group\": \"$superuser\", "
+        + "\"lastModified\": \"Wed, 24 Jun 2020 17:30:43 GMT\", \"name\": "
+        + "\"dest/filename\", \"owner\": \"$superuser\", \"permissions\": "
+        + "\"rw-r--r--\" } ] } ";
+
+    final ObjectMapper objectMapper = new ObjectMapper();
+    final ListResultSchema listResultSchema = objectMapper
+        .readValue(matchingJson, ListResultSchema.class);
+
+    assertThat(listResultSchema.paths().size())
+        .describedAs("Only one path is expected as present in the input JSON")
+        .isEqualTo(1);
+
+    ListResultEntrySchema path = listResultSchema.paths().get(0);
+    assertThat(path.contentLength())
+        .describedAs("contentLength should match the value in the input JSON")
+        .isEqualTo(0L);
+    assertThat(path.eTag())
+        .describedAs("eTag should match the value in the input JSON")
+        .isEqualTo("0x8D8186452785ADA");
+    assertThat(path.group())
+        .describedAs("group should match the value in the input JSON")
+        .isEqualTo("$superuser");
+    assertThat(path.lastModified())
+        .describedAs("lastModified should match the value in the input JSON")
+        .isEqualTo("Wed, 24 Jun 2020 17:30:43 GMT");
+    assertThat(path.name())
+        .describedAs("lastModified should match the value in the input JSON")
+        .isEqualTo("dest/filename");
+    assertThat(path.owner())
+        .describedAs("lastModified should match the value in the input JSON")
+        .isEqualTo("$superuser");
+    assertThat(path.permissions())
+        .describedAs("lastModified should match the value in the input JSON")
+        .isEqualTo("rw-r--r--");
+  }
+
+}