From b7ee3938e989b31866ee9ba72586a581aeda20c9 Mon Sep 17 00:00:00 2001 From: Ayush Saxena Date: Mon, 23 Sep 2019 21:22:50 +0530 Subject: [PATCH] HDFS-14853. NPE in DFSNetworkTopology#chooseRandomWithStorageType() when the excludedNode is not present. Contributed by Ranith Sardar. --- .../hadoop/hdfs/net/DFSNetworkTopology.java | 3 +++ .../hadoop/hdfs/net/TestDFSNetworkTopology.java | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/net/DFSNetworkTopology.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/net/DFSNetworkTopology.java index 7889ef49677..0884fc002c3 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/net/DFSNetworkTopology.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/net/DFSNetworkTopology.java @@ -226,6 +226,9 @@ public class DFSNetworkTopology extends NetworkTopology { String nodeLocation = excludedNode.getNetworkLocation() + "/" + excludedNode.getName(); DatanodeDescriptor dn = (DatanodeDescriptor)getNode(nodeLocation); + if (dn == null) { + continue; + } availableCount -= dn.hasStorageType(type)? 1 : 0; } else { LOG.error("Unexpected node type: {}.", excludedNode.getClass()); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/net/TestDFSNetworkTopology.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/net/TestDFSNetworkTopology.java index 42b1928e46e..3360d68f2bd 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/net/TestDFSNetworkTopology.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/net/TestDFSNetworkTopology.java @@ -23,6 +23,8 @@ import org.slf4j.LoggerFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.StorageType; import org.apache.hadoop.hdfs.DFSTestUtil; +import org.apache.hadoop.hdfs.protocol.DatanodeID; +import org.apache.hadoop.hdfs.protocol.DatanodeInfo.DatanodeInfoBuilder; import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeDescriptor; import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeStorageInfo; import org.apache.hadoop.net.Node; @@ -37,9 +39,11 @@ import java.util.HashSet; import java.util.Set; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; + /** * This class tests the correctness of storage type info stored in * DFSNetworkTopology. @@ -368,6 +372,18 @@ public class TestDFSNetworkTopology { } } + @Test + public void testChooseRandomWithStorageTypeWithExcludedforNullCheck() + throws Exception { + HashSet excluded = new HashSet<>(); + + excluded.add(new DatanodeInfoBuilder() + .setNodeID(DatanodeID.EMPTY_DATANODE_ID).build()); + Node node = CLUSTER.chooseRandomWithStorageType("/", "/l1/d1/r1", excluded, + StorageType.ARCHIVE); + + assertNotNull(node); + } /** * This test tests the wrapper method. The wrapper method only takes one scope