Search in sources :

Example 6 with CallerContext

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();
    }
}
Also used : Path(org.apache.hadoop.fs.Path) MiniDFSCluster(org.apache.hadoop.hdfs.MiniDFSCluster) CallerContext(org.apache.hadoop.ipc.CallerContext) Configuration(org.apache.hadoop.conf.Configuration) HdfsConfiguration(org.apache.hadoop.hdfs.HdfsConfiguration) IOException(java.io.IOException) HdfsConfiguration(org.apache.hadoop.hdfs.HdfsConfiguration) FileSystem(org.apache.hadoop.fs.FileSystem) LogCapturer(org.apache.hadoop.test.GenericTestUtils.LogCapturer) FsPermission(org.apache.hadoop.fs.permission.FsPermission) Test(org.junit.Test)

Aggregations

CallerContext (org.apache.hadoop.ipc.CallerContext)6 IOException (java.io.IOException)3 Configuration (org.apache.hadoop.conf.Configuration)2 ApplicationId (org.apache.hadoop.yarn.api.records.ApplicationId)2 InetAddress (java.net.InetAddress)1 ByteBuffer (java.nio.ByteBuffer)1 AccessControlException (java.security.AccessControlException)1 FileSystem (org.apache.hadoop.fs.FileSystem)1 Path (org.apache.hadoop.fs.Path)1 FsPermission (org.apache.hadoop.fs.permission.FsPermission)1 HdfsConfiguration (org.apache.hadoop.hdfs.HdfsConfiguration)1 MiniDFSCluster (org.apache.hadoop.hdfs.MiniDFSCluster)1 RpcHeaderProtos (org.apache.hadoop.ipc.protobuf.RpcHeaderProtos)1 UserGroupInformation (org.apache.hadoop.security.UserGroupInformation)1 LogCapturer (org.apache.hadoop.test.GenericTestUtils.LogCapturer)1 SubmitApplicationResponse (org.apache.hadoop.yarn.api.protocolrecords.SubmitApplicationResponse)1 ApplicationSubmissionContext (org.apache.hadoop.yarn.api.records.ApplicationSubmissionContext)1 ReservationId (org.apache.hadoop.yarn.api.records.ReservationId)1 ApplicationNotFoundException (org.apache.hadoop.yarn.exceptions.ApplicationNotFoundException)1 YarnException (org.apache.hadoop.yarn.exceptions.YarnException)1