HDFS-8290. WebHDFS calls before namesystem initialization can cause NullPointerException. Contributed by Chris Nauroth.

(cherry picked from commit c4578760b67d5b5169949a1b059f4472a268ff1b)
This commit is contained in:
cnauroth 2015-05-04 11:35:04 -07:00
parent 99b49a8181
commit a43080a2cf
3 changed files with 28 additions and 2 deletions

View File

@ -286,6 +286,9 @@ Release 2.8.0 - UNRELEASED
HDFS-8309. Skip unit test using DataNodeTestUtils#injectDataDirFailure() on Windows. HDFS-8309. Skip unit test using DataNodeTestUtils#injectDataDirFailure() on Windows.
(xyao) (xyao)
HDFS-8290. WebHDFS calls before namesystem initialization can cause
NullPointerException. (cnauroth)
Release 2.7.1 - UNRELEASED Release 2.7.1 - UNRELEASED
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -69,6 +69,7 @@
import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeDescriptor; import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeDescriptor;
import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeStorageInfo; import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeStorageInfo;
import org.apache.hadoop.hdfs.server.common.JspHelper; 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.namenode.NameNode;
import org.apache.hadoop.hdfs.server.protocol.NamenodeProtocols; import org.apache.hadoop.hdfs.server.protocol.NamenodeProtocols;
import org.apache.hadoop.hdfs.web.JsonUtil; import org.apache.hadoop.hdfs.web.JsonUtil;
@ -164,7 +165,11 @@ private static NamenodeProtocols getRPCServer(NameNode namenode)
static DatanodeInfo chooseDatanode(final NameNode namenode, static DatanodeInfo chooseDatanode(final NameNode namenode,
final String path, final HttpOpParam.Op op, final long openOffset, final String path, final HttpOpParam.Op op, final long openOffset,
final long blocksize, final String excludeDatanodes) throws IOException { 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<Node> excludes = new HashSet<Node>(); HashSet<Node> excludes = new HashSet<Node>();
if (excludeDatanodes != null) { if (excludeDatanodes != null) {

View File

@ -17,6 +17,9 @@
*/ */
package org.apache.hadoop.hdfs.server.namenode.web.resources; 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.Arrays;
import java.util.List; import java.util.List;
@ -42,7 +45,9 @@
import org.apache.hadoop.hdfs.web.resources.PutOpParam; import org.apache.hadoop.hdfs.web.resources.PutOpParam;
import org.apache.log4j.Level; import org.apache.log4j.Level;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException;
/** /**
* Test WebHDFS which provides data locality using HTTP redirection. * 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 RACK1 = "/rack1";
private static final String RACK2 = "/rack2"; private static final String RACK2 = "/rack2";
@Rule
public final ExpectedException exception = ExpectedException.none();
@Test @Test
public void testDataLocality() throws Exception { public void testDataLocality() throws Exception {
final Configuration conf = WebHdfsTestUtil.createConf(); final Configuration conf = WebHdfsTestUtil.createConf();
@ -213,4 +221,14 @@ public void testExcludeDataNodes() throws Exception {
cluster.shutdown(); cluster.shutdown();
} }
} }
}
@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);
}
}