use of org.apache.hadoop.ipc.CallerContext in project hadoop by apache.
the class TestAuditLogger method testAuditLoggerWithCallContext.
/**
* Verify that the audit logger is aware of the call context
*/
@Test
public void testAuditLoggerWithCallContext() throws IOException {
Configuration conf = new HdfsConfiguration();
conf.setBoolean(HADOOP_CALLER_CONTEXT_ENABLED_KEY, true);
conf.setInt(HADOOP_CALLER_CONTEXT_MAX_SIZE_KEY, 128);
conf.setInt(HADOOP_CALLER_CONTEXT_SIGNATURE_MAX_SIZE_KEY, 40);
MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).build();
LogCapturer auditlog = LogCapturer.captureLogs(FSNamesystem.auditLog);
try {
cluster.waitClusterUp();
final FileSystem fs = cluster.getFileSystem();
final long time = System.currentTimeMillis();
final Path p = new Path("/");
assertNull(CallerContext.getCurrent());
// context-only
CallerContext context = new CallerContext.Builder("setTimes").build();
CallerContext.setCurrent(context);
LOG.info("Set current caller context as {}", CallerContext.getCurrent());
fs.setTimes(p, time, time);
assertTrue(auditlog.getOutput().endsWith(String.format("callerContext=setTimes%n")));
auditlog.clearOutput();
// context with signature
context = new CallerContext.Builder("setTimes").setSignature("L".getBytes(CallerContext.SIGNATURE_ENCODING)).build();
CallerContext.setCurrent(context);
LOG.info("Set current caller context as {}", CallerContext.getCurrent());
fs.setTimes(p, time, time);
assertTrue(auditlog.getOutput().endsWith(String.format("callerContext=setTimes:L%n")));
auditlog.clearOutput();
// long context is truncated
final String longContext = StringUtils.repeat("foo", 100);
context = new CallerContext.Builder(longContext).setSignature("L".getBytes(CallerContext.SIGNATURE_ENCODING)).build();
CallerContext.setCurrent(context);
LOG.info("Set current caller context as {}", CallerContext.getCurrent());
fs.setTimes(p, time, time);
assertTrue(auditlog.getOutput().endsWith(String.format("callerContext=%s:L%n", longContext.substring(0, 128))));
auditlog.clearOutput();
// empty context is ignored
context = new CallerContext.Builder("").setSignature("L".getBytes(CallerContext.SIGNATURE_ENCODING)).build();
CallerContext.setCurrent(context);
LOG.info("Set empty caller context");
fs.setTimes(p, time, time);
assertFalse(auditlog.getOutput().contains("callerContext="));
auditlog.clearOutput();
// caller context is inherited in child thread
context = new CallerContext.Builder("setTimes").setSignature("L".getBytes(CallerContext.SIGNATURE_ENCODING)).build();
CallerContext.setCurrent(context);
LOG.info("Set current caller context as {}", CallerContext.getCurrent());
Thread child = new Thread(new Runnable() {
@Override
public void run() {
try {
fs.setTimes(p, time, time);
} catch (IOException e) {
fail("Unexpected exception found." + e);
}
}
});
child.start();
try {
child.join();
} catch (InterruptedException ignored) {
// Ignore
}
assertTrue(auditlog.getOutput().endsWith(String.format("callerContext=setTimes:L%n")));
auditlog.clearOutput();
// caller context is overridden in child thread
final CallerContext childContext = new CallerContext.Builder("setPermission").setSignature("L".getBytes(CallerContext.SIGNATURE_ENCODING)).build();
LOG.info("Set current caller context as {}", CallerContext.getCurrent());
child = new Thread(new Runnable() {
@Override
public void run() {
try {
CallerContext.setCurrent(childContext);
fs.setPermission(p, new FsPermission((short) 777));
} catch (IOException e) {
fail("Unexpected exception found." + e);
}
}
});
child.start();
try {
child.join();
} catch (InterruptedException ignored) {
// Ignore
}
assertTrue(auditlog.getOutput().endsWith(String.format("callerContext=setPermission:L%n")));
auditlog.clearOutput();
// reuse the current context's signature
context = new CallerContext.Builder("mkdirs").setSignature(CallerContext.getCurrent().getSignature()).build();
CallerContext.setCurrent(context);
LOG.info("Set current caller context as {}", CallerContext.getCurrent());
fs.mkdirs(new Path("/reuse-context-signature"));
assertTrue(auditlog.getOutput().endsWith(String.format("callerContext=mkdirs:L%n")));
auditlog.clearOutput();
// too long signature is ignored
context = new CallerContext.Builder("setTimes").setSignature(new byte[41]).build();
CallerContext.setCurrent(context);
LOG.info("Set current caller context as {}", CallerContext.getCurrent());
fs.setTimes(p, time, time);
assertTrue(auditlog.getOutput().endsWith(String.format("callerContext=setTimes%n")));
auditlog.clearOutput();
// null signature is ignored
context = new CallerContext.Builder("setTimes").setSignature(null).build();
CallerContext.setCurrent(context);
LOG.info("Set current caller context as {}", CallerContext.getCurrent());
fs.setTimes(p, time, time);
assertTrue(auditlog.getOutput().endsWith(String.format("callerContext=setTimes%n")));
auditlog.clearOutput();
// empty signature is ignored
context = new CallerContext.Builder("mkdirs").setSignature("".getBytes(CallerContext.SIGNATURE_ENCODING)).build();
CallerContext.setCurrent(context);
LOG.info("Set current caller context as {}", CallerContext.getCurrent());
fs.mkdirs(new Path("/empty-signature"));
assertTrue(auditlog.getOutput().endsWith(String.format("callerContext=mkdirs%n")));
auditlog.clearOutput();
// invalid context is not passed to the rpc
context = new CallerContext.Builder(null).build();
CallerContext.setCurrent(context);
LOG.info("Set current caller context as {}", CallerContext.getCurrent());
fs.mkdirs(new Path("/empty-signature"));
assertFalse(auditlog.getOutput().contains("callerContext="));
auditlog.clearOutput();
} finally {
cluster.shutdown();
}
}
Aggregations