HDFS-5279. Merging change r1528308 from trunk to branch-2.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1528310 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
09d2301b63
commit
a5d9aaad12
|
@ -144,6 +144,9 @@ Release 2.1.2 - UNRELEASED
|
||||||
HDFS-5255. Distcp job fails with hsftp when https is enabled in insecure
|
HDFS-5255. Distcp job fails with hsftp when https is enabled in insecure
|
||||||
cluster. (Arpit Agarwal)
|
cluster. (Arpit Agarwal)
|
||||||
|
|
||||||
|
HDFS-5279. Guard against NullPointerException in NameNode JSP pages before
|
||||||
|
initialization of FSNamesystem. (cnauroth)
|
||||||
|
|
||||||
Release 2.1.1-beta - 2013-09-23
|
Release 2.1.1-beta - 2013-09-23
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -30,6 +30,7 @@ import java.net.URLEncoder;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -209,6 +210,9 @@ class NamenodeJspHelper {
|
||||||
|
|
||||||
static void generateSnapshotReport(JspWriter out, FSNamesystem fsn)
|
static void generateSnapshotReport(JspWriter out, FSNamesystem fsn)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
if (fsn == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
out.println("<div id=\"snapshotstats\"><div class=\"dfstable\">"
|
out.println("<div id=\"snapshotstats\"><div class=\"dfstable\">"
|
||||||
+ "<table class=\"storage\" title=\"Snapshot Summary\">\n"
|
+ "<table class=\"storage\" title=\"Snapshot Summary\">\n"
|
||||||
+ "<thead><tr><td><b>Snapshottable directories</b></td>"
|
+ "<thead><tr><td><b>Snapshottable directories</b></td>"
|
||||||
|
@ -651,7 +655,8 @@ class NamenodeJspHelper {
|
||||||
.getAttribute(JspHelper.CURRENT_CONF);
|
.getAttribute(JspHelper.CURRENT_CONF);
|
||||||
// We can't redirect if there isn't a DN to redirect to.
|
// We can't redirect if there isn't a DN to redirect to.
|
||||||
// Lets instead show a proper error message.
|
// Lets instead show a proper error message.
|
||||||
if (nn.getNamesystem().getNumLiveDataNodes() < 1) {
|
FSNamesystem fsn = nn.getNamesystem();
|
||||||
|
if (fsn == null || fsn.getNumLiveDataNodes() < 1) {
|
||||||
throw new IOException("Can't browse the DFS since there are no " +
|
throw new IOException("Can't browse the DFS since there are no " +
|
||||||
"live nodes available to redirect to.");
|
"live nodes available to redirect to.");
|
||||||
}
|
}
|
||||||
|
@ -687,6 +692,20 @@ class NamenodeJspHelper {
|
||||||
resp.sendRedirect(redirectLocation);
|
resp.sendRedirect(redirectLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a descriptive label for the running NameNode. If the NameNode has
|
||||||
|
* initialized to the point of running its RPC server, then this label consists
|
||||||
|
* of the host and port of the RPC server. Otherwise, the label is a message
|
||||||
|
* stating that the NameNode is still initializing.
|
||||||
|
*
|
||||||
|
* @param nn NameNode to describe
|
||||||
|
* @return String NameNode label
|
||||||
|
*/
|
||||||
|
static String getNameNodeLabel(NameNode nn) {
|
||||||
|
return nn.getRpcServer() != null ? nn.getNameNodeAddressHostPortString() :
|
||||||
|
"initializing";
|
||||||
|
}
|
||||||
|
|
||||||
static class NodeListJsp {
|
static class NodeListJsp {
|
||||||
private int rowNum = 0;
|
private int rowNum = 0;
|
||||||
|
|
||||||
|
@ -841,6 +860,9 @@ class NamenodeJspHelper {
|
||||||
HttpServletRequest request) throws IOException {
|
HttpServletRequest request) throws IOException {
|
||||||
final NameNode nn = NameNodeHttpServer.getNameNodeFromContext(context);
|
final NameNode nn = NameNodeHttpServer.getNameNodeFromContext(context);
|
||||||
final FSNamesystem ns = nn.getNamesystem();
|
final FSNamesystem ns = nn.getNamesystem();
|
||||||
|
if (ns == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final DatanodeManager dm = ns.getBlockManager().getDatanodeManager();
|
final DatanodeManager dm = ns.getBlockManager().getDatanodeManager();
|
||||||
|
|
||||||
final List<DatanodeDescriptor> live = new ArrayList<DatanodeDescriptor>();
|
final List<DatanodeDescriptor> live = new ArrayList<DatanodeDescriptor>();
|
||||||
|
@ -1018,14 +1040,16 @@ class NamenodeJspHelper {
|
||||||
final BlockManager blockManager;
|
final BlockManager blockManager;
|
||||||
|
|
||||||
XMLBlockInfo(FSNamesystem fsn, Long blockId) {
|
XMLBlockInfo(FSNamesystem fsn, Long blockId) {
|
||||||
this.blockManager = fsn.getBlockManager();
|
this.blockManager = fsn != null ? fsn.getBlockManager() : null;
|
||||||
|
|
||||||
if (blockId == null) {
|
if (blockId == null) {
|
||||||
this.block = null;
|
this.block = null;
|
||||||
this.inode = null;
|
this.inode = null;
|
||||||
} else {
|
} else {
|
||||||
this.block = new Block(blockId);
|
this.block = new Block(blockId);
|
||||||
this.inode = ((INode)blockManager.getBlockCollection(block)).asFile();
|
this.inode = blockManager != null ?
|
||||||
|
((INode)blockManager.getBlockCollection(block)).asFile() :
|
||||||
|
null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1099,7 +1123,9 @@ class NamenodeJspHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.startTag("replicas");
|
doc.startTag("replicas");
|
||||||
for(final Iterator<DatanodeDescriptor> it = blockManager.datanodeIterator(block);
|
for (final Iterator<DatanodeDescriptor> it = blockManager != null ?
|
||||||
|
blockManager.datanodeIterator(block) :
|
||||||
|
Collections.<DatanodeDescriptor>emptyList().iterator();
|
||||||
it.hasNext();) {
|
it.hasNext();) {
|
||||||
doc.startTag("replica");
|
doc.startTag("replica");
|
||||||
|
|
||||||
|
@ -1136,7 +1162,7 @@ class NamenodeJspHelper {
|
||||||
|
|
||||||
XMLCorruptBlockInfo(FSNamesystem fsn, Configuration conf,
|
XMLCorruptBlockInfo(FSNamesystem fsn, Configuration conf,
|
||||||
int numCorruptBlocks, Long startingBlockId) {
|
int numCorruptBlocks, Long startingBlockId) {
|
||||||
this.blockManager = fsn.getBlockManager();
|
this.blockManager = fsn != null ? fsn.getBlockManager() : null;
|
||||||
this.conf = conf;
|
this.conf = conf;
|
||||||
this.numCorruptBlocks = numCorruptBlocks;
|
this.numCorruptBlocks = numCorruptBlocks;
|
||||||
this.startingBlockId = startingBlockId;
|
this.startingBlockId = startingBlockId;
|
||||||
|
@ -1159,16 +1185,19 @@ class NamenodeJspHelper {
|
||||||
doc.endTag();
|
doc.endTag();
|
||||||
|
|
||||||
doc.startTag("num_missing_blocks");
|
doc.startTag("num_missing_blocks");
|
||||||
doc.pcdata(""+blockManager.getMissingBlocksCount());
|
doc.pcdata("" + (blockManager != null ?
|
||||||
|
blockManager.getMissingBlocksCount() : 0));
|
||||||
doc.endTag();
|
doc.endTag();
|
||||||
|
|
||||||
doc.startTag("num_corrupt_replica_blocks");
|
doc.startTag("num_corrupt_replica_blocks");
|
||||||
doc.pcdata(""+blockManager.getCorruptReplicaBlocksCount());
|
doc.pcdata("" + (blockManager != null ?
|
||||||
|
blockManager.getCorruptReplicaBlocksCount() : 0));
|
||||||
doc.endTag();
|
doc.endTag();
|
||||||
|
|
||||||
doc.startTag("corrupt_replica_block_ids");
|
doc.startTag("corrupt_replica_block_ids");
|
||||||
final long[] corruptBlockIds = blockManager.getCorruptReplicaBlockIds(
|
final long[] corruptBlockIds = blockManager != null ?
|
||||||
numCorruptBlocks, startingBlockId);
|
blockManager.getCorruptReplicaBlockIds(numCorruptBlocks,
|
||||||
|
startingBlockId) : null;
|
||||||
if (corruptBlockIds != null) {
|
if (corruptBlockIds != null) {
|
||||||
for (Long blockId: corruptBlockIds) {
|
for (Long blockId: corruptBlockIds) {
|
||||||
doc.startTag("block_id");
|
doc.startTag("block_id");
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
import="org.apache.hadoop.fs.Path"
|
import="org.apache.hadoop.fs.Path"
|
||||||
import="org.apache.hadoop.ha.HAServiceProtocol.HAServiceState"
|
import="org.apache.hadoop.ha.HAServiceProtocol.HAServiceState"
|
||||||
import="java.util.Collection"
|
import="java.util.Collection"
|
||||||
|
import="java.util.Collections"
|
||||||
import="java.util.Arrays" %>
|
import="java.util.Arrays" %>
|
||||||
<%!//for java.io.Serializable
|
<%!//for java.io.Serializable
|
||||||
private static final long serialVersionUID = 1L;%>
|
private static final long serialVersionUID = 1L;%>
|
||||||
|
@ -34,9 +35,10 @@
|
||||||
HAServiceState nnHAState = nn.getServiceState();
|
HAServiceState nnHAState = nn.getServiceState();
|
||||||
boolean isActive = (nnHAState == HAServiceState.ACTIVE);
|
boolean isActive = (nnHAState == HAServiceState.ACTIVE);
|
||||||
String namenodeRole = nn.getRole().toString();
|
String namenodeRole = nn.getRole().toString();
|
||||||
String namenodeLabel = nn.getNameNodeAddressHostPortString();
|
String namenodeLabel = NamenodeJspHelper.getNameNodeLabel(nn);
|
||||||
Collection<FSNamesystem.CorruptFileBlockInfo> corruptFileBlocks =
|
Collection<FSNamesystem.CorruptFileBlockInfo> corruptFileBlocks = fsn != null ?
|
||||||
fsn.listCorruptFileBlocks("/", null);
|
fsn.listCorruptFileBlocks("/", null) :
|
||||||
|
Collections.<FSNamesystem.CorruptFileBlockInfo>emptyList();
|
||||||
int corruptFileCount = corruptFileBlocks.size();
|
int corruptFileCount = corruptFileBlocks.size();
|
||||||
%>
|
%>
|
||||||
|
|
||||||
|
@ -48,7 +50,7 @@
|
||||||
<h1><%=namenodeRole%> '<%=namenodeLabel%>'</h1>
|
<h1><%=namenodeRole%> '<%=namenodeLabel%>'</h1>
|
||||||
<%=NamenodeJspHelper.getVersionTable(fsn)%>
|
<%=NamenodeJspHelper.getVersionTable(fsn)%>
|
||||||
<br>
|
<br>
|
||||||
<% if (isActive) { %>
|
<% if (isActive && fsn != null) { %>
|
||||||
<b><a href="/nn_browsedfscontent.jsp">Browse the filesystem</a></b>
|
<b><a href="/nn_browsedfscontent.jsp">Browse the filesystem</a></b>
|
||||||
<br>
|
<br>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
|
@ -34,29 +34,20 @@
|
||||||
boolean isActive = (nnHAState == HAServiceState.ACTIVE);
|
boolean isActive = (nnHAState == HAServiceState.ACTIVE);
|
||||||
String namenodeRole = nn.getRole().toString();
|
String namenodeRole = nn.getRole().toString();
|
||||||
String namenodeState = nnHAState.toString();
|
String namenodeState = nnHAState.toString();
|
||||||
String namenodeLabel = nn.getRpcServer() != null ?
|
String namenodeLabel = NamenodeJspHelper.getNameNodeLabel(nn);
|
||||||
nn.getNameNodeAddressHostPortString() : null;
|
|
||||||
%>
|
%>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
|
<link rel="stylesheet" type="text/css" href="/static/hadoop.css">
|
||||||
<% if (namenodeLabel != null) { %>
|
|
||||||
<title>Hadoop <%=namenodeRole%> <%=namenodeLabel%></title>
|
<title>Hadoop <%=namenodeRole%> <%=namenodeLabel%></title>
|
||||||
<% } else { %>
|
|
||||||
<title>Hadoop <%=namenodeRole%></title>
|
|
||||||
<% } %>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<% if (namenodeLabel != null) { %>
|
|
||||||
<h1><%=namenodeRole%> '<%=namenodeLabel%>' (<%=namenodeState%>)</h1>
|
<h1><%=namenodeRole%> '<%=namenodeLabel%>' (<%=namenodeState%>)</h1>
|
||||||
<% } else { %>
|
|
||||||
<h1><%=namenodeRole%> (<%=namenodeState%>)</h1>
|
|
||||||
<% } %>
|
|
||||||
<%= NamenodeJspHelper.getVersionTable(fsn) %>
|
<%= NamenodeJspHelper.getVersionTable(fsn) %>
|
||||||
<br />
|
<br />
|
||||||
<% if (isActive) { %>
|
<% if (isActive && fsn != null) { %>
|
||||||
<b><a href="/nn_browsedfscontent.jsp">Browse the filesystem</a></b><br>
|
<b><a href="/nn_browsedfscontent.jsp">Browse the filesystem</a></b><br>
|
||||||
<% } %>
|
<% } %>
|
||||||
<b><a href="/logs/"><%=namenodeRole%> Logs</a></b>
|
<b><a href="/logs/"><%=namenodeRole%> Logs</a></b>
|
||||||
|
|
|
@ -33,7 +33,7 @@ String namenodeRole = nn.getRole().toString();
|
||||||
FSNamesystem fsn = nn.getNamesystem();
|
FSNamesystem fsn = nn.getNamesystem();
|
||||||
HAServiceState nnHAState = nn.getServiceState();
|
HAServiceState nnHAState = nn.getServiceState();
|
||||||
boolean isActive = (nnHAState == HAServiceState.ACTIVE);
|
boolean isActive = (nnHAState == HAServiceState.ACTIVE);
|
||||||
String namenodeLabel = nn.getNameNodeAddressHostPortString();
|
String namenodeLabel = NamenodeJspHelper.getNameNodeLabel(nn);
|
||||||
%>
|
%>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
@ -46,7 +46,7 @@ String namenodeLabel = nn.getNameNodeAddressHostPortString();
|
||||||
<h1><%=namenodeRole%> '<%=namenodeLabel%>'</h1>
|
<h1><%=namenodeRole%> '<%=namenodeLabel%>'</h1>
|
||||||
<%= NamenodeJspHelper.getVersionTable(fsn) %>
|
<%= NamenodeJspHelper.getVersionTable(fsn) %>
|
||||||
<br />
|
<br />
|
||||||
<% if (isActive) { %>
|
<% if (isActive && fsn != null) { %>
|
||||||
<b><a href="/nn_browsedfscontent.jsp">Browse the filesystem</a></b><br>
|
<b><a href="/nn_browsedfscontent.jsp">Browse the filesystem</a></b><br>
|
||||||
<% } %>
|
<% } %>
|
||||||
<b><a href="/logs/"><%=namenodeRole%> Logs</a></b><br>
|
<b><a href="/logs/"><%=namenodeRole%> Logs</a></b><br>
|
||||||
|
|
|
@ -25,12 +25,15 @@ import static org.apache.hadoop.hdfs.server.namenode.startupprogress.Phase.SAVIN
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.jsp.JspWriter;
|
import javax.servlet.jsp.JspWriter;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
@ -45,6 +48,7 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.znerd.xmlenc.XMLOutputter;
|
||||||
|
|
||||||
public class TestNameNodeJspHelper {
|
public class TestNameNodeJspHelper {
|
||||||
|
|
||||||
|
@ -117,6 +121,75 @@ public class TestNameNodeJspHelper {
|
||||||
Assert.assertEquals("", NamenodeJspHelper.getRollingUpgradeText(null));
|
Assert.assertEquals("", NamenodeJspHelper.getRollingUpgradeText(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for non-null, non-empty NameNode label.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetNameNodeLabel() {
|
||||||
|
String nameNodeLabel = NamenodeJspHelper.getNameNodeLabel(
|
||||||
|
cluster.getNameNode());
|
||||||
|
Assert.assertNotNull(nameNodeLabel);
|
||||||
|
Assert.assertFalse(nameNodeLabel.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for non-null, non-empty NameNode label when called before
|
||||||
|
* initialization of the NameNode RPC server.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetNameNodeLabelNullRpcServer() {
|
||||||
|
NameNode nn = mock(NameNode.class);
|
||||||
|
when(nn.getRpcServer()).thenReturn(null);
|
||||||
|
String nameNodeLabel = NamenodeJspHelper.getNameNodeLabel(
|
||||||
|
cluster.getNameNode());
|
||||||
|
Assert.assertNotNull(nameNodeLabel);
|
||||||
|
Assert.assertFalse(nameNodeLabel.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that passing a null FSNamesystem to generateSnapshotReport does not
|
||||||
|
* throw NullPointerException.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGenerateSnapshotReportNullNamesystem() throws Exception {
|
||||||
|
NamenodeJspHelper.generateSnapshotReport(mock(JspWriter.class), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that redirectToRandomDataNode does not throw NullPointerException if
|
||||||
|
* it finds a null FSNamesystem.
|
||||||
|
*/
|
||||||
|
@Test(expected=IOException.class)
|
||||||
|
public void testRedirectToRandomDataNodeNullNamesystem() throws Exception {
|
||||||
|
NameNode nn = mock(NameNode.class);
|
||||||
|
when(nn.getNamesystem()).thenReturn(null);
|
||||||
|
ServletContext context = mock(ServletContext.class);
|
||||||
|
when(context.getAttribute("name.node")).thenReturn(nn);
|
||||||
|
NamenodeJspHelper.redirectToRandomDataNode(context,
|
||||||
|
mock(HttpServletRequest.class), mock(HttpServletResponse.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that XMLBlockInfo does not throw NullPointerException if it finds a
|
||||||
|
* null FSNamesystem.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testXMLBlockInfoNullNamesystem() throws IOException {
|
||||||
|
XMLOutputter doc = new XMLOutputter(mock(JspWriter.class), "UTF-8");
|
||||||
|
new NamenodeJspHelper.XMLBlockInfo(null, 1L).toXML(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that XMLCorruptBlockInfo does not throw NullPointerException if it
|
||||||
|
* finds a null FSNamesystem.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testXMLCorruptBlockInfoNullNamesystem() throws IOException {
|
||||||
|
XMLOutputter doc = new XMLOutputter(mock(JspWriter.class), "UTF-8");
|
||||||
|
new NamenodeJspHelper.XMLCorruptBlockInfo(null, mock(Configuration.class),
|
||||||
|
10, 1L).toXML(doc);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the list contains any string that partially matches the regex.
|
* Checks if the list contains any string that partially matches the regex.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue