Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.security.PrivilegedExceptionAction;
import java.util.Map;
import java.util.concurrent.TimeUnit;

Expand All @@ -45,6 +46,7 @@
import org.apache.hadoop.hdfs.tools.NNHAServiceTarget;
import org.apache.hadoop.hdfs.web.URLConnectionFactory;
import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.security.SecurityUtil;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
Expand Down Expand Up @@ -339,8 +341,11 @@ protected NamenodeStatusReport getNamenodeStatusReport() {
// should be required at some point for QoS
updateSafeModeParameters(serviceURI, report);

// Read the stats from JMX (optional)
updateJMXParameters(webAddress, report);
// Read the stats from JMX (optional) using the login user credentials
SecurityUtil.doAsLoginUser((PrivilegedExceptionAction<Void>) () -> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like we should do this at a higher level eg. NamenodeHeartbeatService.periodicInvoke(). That way the other operations, such as the rpc call to each NN, also run as the login user.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the JMX call is having issues authenticating, but I agree we should expect all requests to be made in the same context. I'll expand the scope of this.

updateJMXParameters(webAddress, report);
return null;
});

// Try to get the HA status
updateHAStatusParameters(report);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import static org.apache.hadoop.hdfs.server.federation.FederationTestUtils.NAMENODES;
import static org.apache.hadoop.hdfs.server.federation.FederationTestUtils.NAMESERVICES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

Expand All @@ -36,6 +37,7 @@
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.contract.router.SecurityConfUtil;
import org.apache.hadoop.hdfs.DFSUtil;
import org.apache.hadoop.hdfs.HdfsConfiguration;
import org.apache.hadoop.hdfs.server.federation.MockResolver;
Expand Down Expand Up @@ -318,4 +320,31 @@ private Configuration generateNamenodeConfiguration(

return conf;
}

@Test
public void testNamendodeHeartbeatWithSecurity() throws Exception {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Typo "namendode" -> "namenode"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Thanks!

Configuration conf = SecurityConfUtil.initSecurity();
MiniRouterDFSCluster testCluster = null;
try {
testCluster = new MiniRouterDFSCluster(true, 1, conf);
// Start Namenodes and routers
testCluster.startCluster(conf);
testCluster.startRouters();

// Register Namenodes to generate a NamenodeStatusReport
testCluster.registerNamenodes();
testCluster.waitNamenodeRegistration();

for (MiniRouterDFSCluster.RouterContext routerContext : testCluster.getRouters()) {
ActiveNamenodeResolver resolver = routerContext.getRouter().getNamenodeResolver();
// Validate that NamenodeStatusReport has been registered
assertNotNull(resolver.getNamespaces());
assertFalse(resolver.getNamespaces().isEmpty());
}
} finally {
if (testCluster != null) {
testCluster.shutdown();
}
}
}
}