From c4578760b67d5b5169949a1b059f4472a268ff1b Mon Sep 17 00:00:00 2001 From: cnauroth Date: Mon, 4 May 2015 11:35:04 -0700 Subject: [PATCH] HDFS-8290. WebHDFS calls before namesystem initialization can cause NullPointerException. Contributed by Chris Nauroth. --- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 3 +++ .../web/resources/NamenodeWebHdfsMethods.java | 7 ++++++- .../resources/TestWebHdfsDataLocality.java | 20 ++++++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index e525800c29..a365b865b6 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -610,6 +610,9 @@ Release 2.8.0 - UNRELEASED HDFS-8309. Skip unit test using DataNodeTestUtils#injectDataDirFailure() on Windows. (xyao) + HDFS-8290. WebHDFS calls before namesystem initialization can cause + NullPointerException. (cnauroth) + Release 2.7.1 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java index 2c1148e4d0..d33721c0fd 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/web/resources/NamenodeWebHdfsMethods.java @@ -69,6 +69,7 @@ import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeDescriptor; import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeStorageInfo; import org.apache.hadoop.hdfs.server.common.JspHelper; +import org.apache.hadoop.hdfs.server.namenode.FSNamesystem; import org.apache.hadoop.hdfs.server.namenode.NameNode; import org.apache.hadoop.hdfs.server.protocol.NamenodeProtocols; import org.apache.hadoop.hdfs.web.JsonUtil; @@ -164,7 +165,11 @@ private static NamenodeProtocols getRPCServer(NameNode namenode) static DatanodeInfo chooseDatanode(final NameNode namenode, final String path, final HttpOpParam.Op op, final long openOffset, final long blocksize, final String excludeDatanodes) throws IOException { - final BlockManager bm = namenode.getNamesystem().getBlockManager(); + FSNamesystem fsn = namenode.getNamesystem(); + if (fsn == null) { + throw new IOException("Namesystem has not been intialized yet."); + } + final BlockManager bm = fsn.getBlockManager(); HashSet excludes = new HashSet(); if (excludeDatanodes != null) { diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/web/resources/TestWebHdfsDataLocality.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/web/resources/TestWebHdfsDataLocality.java index 077361c1cf..15e1c04b81 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/web/resources/TestWebHdfsDataLocality.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/web/resources/TestWebHdfsDataLocality.java @@ -17,6 +17,9 @@ */ package org.apache.hadoop.hdfs.server.namenode.web.resources; +import static org.mockito.Mockito.*; + +import java.io.IOException; import java.util.Arrays; import java.util.List; @@ -42,7 +45,9 @@ import org.apache.hadoop.hdfs.web.resources.PutOpParam; import org.apache.log4j.Level; import org.junit.Assert; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; /** * Test WebHDFS which provides data locality using HTTP redirection. @@ -57,6 +62,9 @@ public class TestWebHdfsDataLocality { private static final String RACK1 = "/rack1"; private static final String RACK2 = "/rack2"; + @Rule + public final ExpectedException exception = ExpectedException.none(); + @Test public void testDataLocality() throws Exception { final Configuration conf = WebHdfsTestUtil.createConf(); @@ -213,4 +221,14 @@ public void testExcludeDataNodes() throws Exception { cluster.shutdown(); } } -} \ No newline at end of file + + @Test + public void testChooseDatanodeBeforeNamesystemInit() throws Exception { + NameNode nn = mock(NameNode.class); + when(nn.getNamesystem()).thenReturn(null); + exception.expect(IOException.class); + exception.expectMessage("Namesystem has not been intialized yet."); + NamenodeWebHdfsMethods.chooseDatanode(nn, "/path", PutOpParam.Op.CREATE, 0, + DFSConfigKeys.DFS_BLOCK_SIZE_DEFAULT, null); + } +}