|
@@ -35,6 +35,87 @@ import org.mortbay.util.ajax.JSON;
|
|
|
*/
|
|
|
public class TestFSNamesystemMBean {
|
|
|
|
|
|
+ /**
|
|
|
+ * MBeanClient tries to access FSNamesystem/FSNamesystemState/NameNodeInfo
|
|
|
+ * JMX properties. If it can access all the properties, the test is
|
|
|
+ * considered successful.
|
|
|
+ */
|
|
|
+ private static class MBeanClient extends Thread {
|
|
|
+ private boolean succeeded = false;
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ try {
|
|
|
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
|
|
+
|
|
|
+ // Metrics that belong to "FSNamesystem", these are metrics that
|
|
|
+ // come from hadoop metrics framework for the class FSNamesystem.
|
|
|
+ ObjectName mxbeanNamefsn = new ObjectName(
|
|
|
+ "Hadoop:service=NameNode,name=FSNamesystem");
|
|
|
+ Integer blockCapacity = (Integer) (mbs.getAttribute(mxbeanNamefsn,
|
|
|
+ "BlockCapacity"));
|
|
|
+
|
|
|
+ // Metrics that belong to "FSNamesystemState".
|
|
|
+ // These are metrics that FSNamesystem registers directly with MBeanServer.
|
|
|
+ ObjectName mxbeanNameFsns = new ObjectName(
|
|
|
+ "Hadoop:service=NameNode,name=FSNamesystemState");
|
|
|
+ String FSState = (String) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "FSState"));
|
|
|
+ Long blocksTotal = (Long) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "BlocksTotal"));
|
|
|
+ Long capacityTotal = (Long) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "CapacityTotal"));
|
|
|
+ Long capacityRemaining = (Long) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "CapacityRemaining"));
|
|
|
+ Long capacityUsed = (Long) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "CapacityUsed"));
|
|
|
+ Long filesTotal = (Long) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "FilesTotal"));
|
|
|
+ Long pendingReplicationBlocks = (Long) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "PendingReplicationBlocks"));
|
|
|
+ Long underReplicatedBlocks = (Long) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "UnderReplicatedBlocks"));
|
|
|
+ Long scheduledReplicationBlocks = (Long) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "ScheduledReplicationBlocks"));
|
|
|
+ Integer totalLoad = (Integer) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "TotalLoad"));
|
|
|
+ Integer numLiveDataNodes = (Integer) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "NumLiveDataNodes"));
|
|
|
+ Integer numDeadDataNodes = (Integer) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "NumDeadDataNodes"));
|
|
|
+ Integer numStaleDataNodes = (Integer) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "NumStaleDataNodes"));
|
|
|
+ Integer numDecomLiveDataNodes = (Integer) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "NumDecomLiveDataNodes"));
|
|
|
+ Integer numDecomDeadDataNodes = (Integer) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "NumDecomDeadDataNodes"));
|
|
|
+ Integer numDecommissioningDataNodes = (Integer) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "NumDecommissioningDataNodes"));
|
|
|
+ String snapshotStats = (String) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "SnapshotStats"));
|
|
|
+ Long MaxObjects = (Long) (mbs.getAttribute(mxbeanNameFsns,
|
|
|
+ "MaxObjects"));
|
|
|
+
|
|
|
+ // Metrics that belong to "NameNodeInfo".
|
|
|
+ // These are metrics that FSNamesystem registers directly with MBeanServer.
|
|
|
+ ObjectName mxbeanNameNni = new ObjectName(
|
|
|
+ "Hadoop:service=NameNode,name=NameNodeInfo");
|
|
|
+ String safemode = (String) (mbs.getAttribute(mxbeanNameNni,
|
|
|
+ "Safemode"));
|
|
|
+ String liveNodes = (String) (mbs.getAttribute(mxbeanNameNni,
|
|
|
+ "LiveNodes"));
|
|
|
+ String deadNodes = (String) (mbs.getAttribute(mxbeanNameNni,
|
|
|
+ "DeadNodes"));
|
|
|
+ String decomNodes = (String) (mbs.getAttribute(mxbeanNameNni,
|
|
|
+ "DecomNodes"));
|
|
|
+ String corruptFiles = (String) (mbs.getAttribute(mxbeanNameNni,
|
|
|
+ "CorruptFiles"));
|
|
|
+
|
|
|
+ succeeded = true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@Test
|
|
|
public void test() throws Exception {
|
|
|
Configuration conf = new Configuration();
|
|
@@ -73,4 +154,35 @@ public class TestFSNamesystemMBean {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+
|
|
|
+ // The test makes sure JMX request can be processed even if namesystem's
|
|
|
+ // writeLock is owned by another thread.
|
|
|
+ @Test
|
|
|
+ public void testWithFSNamesystemWriteLock() throws Exception {
|
|
|
+ Configuration conf = new Configuration();
|
|
|
+ MiniDFSCluster cluster = null;
|
|
|
+ FSNamesystem fsn = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ cluster = new MiniDFSCluster.Builder(conf).build();
|
|
|
+ cluster.waitActive();
|
|
|
+
|
|
|
+ fsn = cluster.getNameNode().namesystem;
|
|
|
+ fsn.writeLock();
|
|
|
+
|
|
|
+ MBeanClient client = new MBeanClient();
|
|
|
+ client.start();
|
|
|
+ client.join(20000);
|
|
|
+ assertTrue("JMX calls are blocked when FSNamesystem's writerlock" +
|
|
|
+ "is owned by another thread", client.succeeded);
|
|
|
+ client.interrupt();
|
|
|
+ } finally {
|
|
|
+ if (fsn != null && fsn.hasWriteLock()) {
|
|
|
+ fsn.writeUnlock();
|
|
|
+ }
|
|
|
+ if (cluster != null) {
|
|
|
+ cluster.shutdown();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|