diff --git a/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/inotify/Event.java b/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/inotify/Event.java index dee17a9192e..6f2b5e22ac9 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/inotify/Event.java +++ b/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/inotify/Event.java @@ -51,6 +51,7 @@ public abstract class Event { /** * Sent when a file is closed after append or create. */ + @InterfaceAudience.Public public static class CloseEvent extends Event { private String path; private long fileSize; @@ -81,11 +82,20 @@ public abstract class Event { public long getTimestamp() { return timestamp; } + + @Override + @InterfaceStability.Unstable + public String toString() { + return "CloseEvent [path=" + path + ", fileSize=" + fileSize + + ", timestamp=" + timestamp + "]"; + } + } /** * Sent when a new file is created (including overwrite). */ + @InterfaceAudience.Public public static class CreateEvent extends Event { public static enum INodeType { @@ -232,6 +242,25 @@ public abstract class Event { public long getDefaultBlockSize() { return defaultBlockSize; } + + @Override + @InterfaceStability.Unstable + public String toString() { + StringBuilder content = new StringBuilder(); + content.append("CreateEvent [INodeType=" + iNodeType + ", path=" + path + + ", ctime=" + ctime + ", replication=" + replication + + ", ownerName=" + ownerName + ", groupName=" + groupName + + ", perms=" + perms + ", "); + + if (symlinkTarget != null) { + content.append("symlinkTarget=" + symlinkTarget + ", "); + } + + content.append("overwrite=" + overwrite + ", defaultBlockSize=" + + defaultBlockSize + "]"); + return content.toString(); + } + } /** @@ -242,6 +271,7 @@ public abstract class Event { * metadataType of the MetadataUpdateEvent will be null or will have their default * values. */ + @InterfaceAudience.Public public static class MetadataUpdateEvent extends Event { public static enum MetadataType { @@ -400,11 +430,45 @@ public abstract class Event { return xAttrsRemoved; } + @Override + @InterfaceStability.Unstable + public String toString() { + StringBuilder content = new StringBuilder(); + content.append("MetadataUpdateEvent [path=" + path + ", metadataType=" + + metadataType); + switch (metadataType) { + case TIMES: + content.append(", mtime=" + mtime + ", atime=" + atime); + break; + case REPLICATION: + content.append(", replication=" + replication); + break; + case OWNER: + content.append(", ownerName=" + ownerName + + ", groupName=" + groupName); + break; + case PERMS: + content.append(", perms=" + perms); + break; + case ACLS: + content.append(", acls=" + acls); + break; + case XATTRS: + content.append(", xAttrs=" + xAttrs + ", xAttrsRemoved=" + + xAttrsRemoved); + break; + default: + break; + } + content.append(']'); + return content.toString(); + } } /** * Sent when a file, directory, or symlink is renamed. */ + @InterfaceAudience.Public public static class RenameEvent extends Event { private String srcPath; private String dstPath; @@ -456,11 +520,20 @@ public abstract class Event { public long getTimestamp() { return timestamp; } + + @Override + @InterfaceStability.Unstable + public String toString() { + return "RenameEvent [srcPath=" + srcPath + ", dstPath=" + dstPath + + ", timestamp=" + timestamp + "]"; + } + } /** * Sent when an existing file is opened for append. */ + @InterfaceAudience.Public public static class AppendEvent extends Event { private String path; private boolean newBlock; @@ -497,11 +570,19 @@ public abstract class Event { public boolean toNewBlock() { return newBlock; } + + @Override + @InterfaceStability.Unstable + public String toString() { + return "AppendEvent [path=" + path + ", newBlock=" + newBlock + "]"; + } + } /** * Sent when a file, directory, or symlink is deleted. */ + @InterfaceAudience.Public public static class UnlinkEvent extends Event { private String path; private long timestamp; @@ -541,11 +622,18 @@ public abstract class Event { public long getTimestamp() { return timestamp; } + + @Override + @InterfaceStability.Unstable + public String toString() { + return "UnlinkEvent [path=" + path + ", timestamp=" + timestamp + "]"; + } } /** * Sent when a file is truncated. */ + @InterfaceAudience.Public public static class TruncateEvent extends Event { private String path; private long fileSize; @@ -576,5 +664,12 @@ public abstract class Event { public long getTimestamp() { return timestamp; } + + @Override + @InterfaceStability.Unstable + public String toString() { + return "TruncateEvent [path=" + path + ", fileSize=" + fileSize + + ", timestamp=" + timestamp + "]"; + } } } diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 086ce7de189..42eef55fe7b 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -407,6 +407,9 @@ Release 2.8.0 - UNRELEASED HDFS-6682. Add a metric to expose the timestamp of the oldest under-replicated block. (aajisaka) + HDFS-8735. Inotify: All events classes should implement toString() API. + (Surendra Singh Lilhore via aajisaka) + OPTIMIZATIONS HDFS-8026. Trace FSOutputSummer#writeChecksumChunks rather than diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSInotifyEventInputStream.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSInotifyEventInputStream.java index 385d6534783..65569d03133 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSInotifyEventInputStream.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSInotifyEventInputStream.java @@ -151,6 +151,8 @@ public class TestDFSInotifyEventInputStream { Assert.assertEquals("/file4", re.getDstPath()); Assert.assertEquals("/file", re.getSrcPath()); Assert.assertTrue(re.getTimestamp() > 0); + LOG.info(re.toString()); + Assert.assertTrue(re.toString().startsWith("RenameEvent [srcPath=")); long eventsBehind = eis.getTxidsBehindEstimate(); @@ -163,6 +165,7 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(re2.getDstPath().equals("/file2")); Assert.assertTrue(re2.getSrcPath().equals("/file4")); Assert.assertTrue(re.getTimestamp() > 0); + LOG.info(re2.toString()); // AddOp with overwrite batch = waitForNextEvents(eis); @@ -177,6 +180,8 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(ce.getSymlinkTarget() == null); Assert.assertTrue(ce.getOverwrite()); Assert.assertEquals(BLOCK_SIZE, ce.getDefaultBlockSize()); + LOG.info(ce.toString()); + Assert.assertTrue(ce.toString().startsWith("CreateEvent [INodeType=")); // CloseOp batch = waitForNextEvents(eis); @@ -187,6 +192,8 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(ce2.getPath().equals("/file2")); Assert.assertTrue(ce2.getFileSize() > 0); Assert.assertTrue(ce2.getTimestamp() > 0); + LOG.info(ce2.toString()); + Assert.assertTrue(ce2.toString().startsWith("CloseEvent [path=")); // AppendOp batch = waitForNextEvents(eis); @@ -196,6 +203,8 @@ public class TestDFSInotifyEventInputStream { Event.AppendEvent append2 = (Event.AppendEvent)batch.getEvents()[0]; Assert.assertEquals("/file2", append2.getPath()); Assert.assertFalse(append2.toNewBlock()); + LOG.info(append2.toString()); + Assert.assertTrue(append2.toString().startsWith("AppendEvent [path=")); // CloseOp batch = waitForNextEvents(eis); @@ -213,6 +222,8 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(mue.getPath().equals("/file2")); Assert.assertTrue(mue.getMetadataType() == Event.MetadataUpdateEvent.MetadataType.TIMES); + LOG.info(mue.toString()); + Assert.assertTrue(mue.toString().startsWith("MetadataUpdateEvent [path=")); // SetReplicationOp batch = waitForNextEvents(eis); @@ -224,6 +235,7 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(mue2.getMetadataType() == Event.MetadataUpdateEvent.MetadataType.REPLICATION); Assert.assertTrue(mue2.getReplication() == 1); + LOG.info(mue2.toString()); // ConcatDeleteOp batch = waitForNextEvents(eis); @@ -235,6 +247,8 @@ public class TestDFSInotifyEventInputStream { Event.UnlinkEvent ue2 = (Event.UnlinkEvent) batch.getEvents()[1]; Assert.assertTrue(ue2.getPath().equals("/file3")); Assert.assertTrue(ue2.getTimestamp() > 0); + LOG.info(ue2.toString()); + Assert.assertTrue(ue2.toString().startsWith("UnlinkEvent [path=")); Assert.assertTrue(batch.getEvents()[2].getEventType() == Event.EventType.CLOSE); Event.CloseEvent ce3 = (Event.CloseEvent) batch.getEvents()[2]; Assert.assertTrue(ce3.getPath().equals("/file2")); @@ -248,6 +262,7 @@ public class TestDFSInotifyEventInputStream { Event.UnlinkEvent ue = (Event.UnlinkEvent) batch.getEvents()[0]; Assert.assertTrue(ue.getPath().equals("/file2")); Assert.assertTrue(ue.getTimestamp() > 0); + LOG.info(ue.toString()); // MkdirOp batch = waitForNextEvents(eis); @@ -261,6 +276,7 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(ce4.getCtime() > 0); Assert.assertTrue(ce4.getReplication() == 0); Assert.assertTrue(ce4.getSymlinkTarget() == null); + LOG.info(ce4.toString()); // SetPermissionsOp batch = waitForNextEvents(eis); @@ -272,6 +288,7 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(mue3.getMetadataType() == Event.MetadataUpdateEvent.MetadataType.PERMS); Assert.assertTrue(mue3.getPerms().toString().contains("rw-rw-rw-")); + LOG.info(mue3.toString()); // SetOwnerOp batch = waitForNextEvents(eis); @@ -284,6 +301,7 @@ public class TestDFSInotifyEventInputStream { Event.MetadataUpdateEvent.MetadataType.OWNER); Assert.assertTrue(mue4.getOwnerName().equals("username")); Assert.assertTrue(mue4.getGroupName().equals("groupname")); + LOG.info(mue4.toString()); // SymlinkOp batch = waitForNextEvents(eis); @@ -297,6 +315,7 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(ce5.getCtime() > 0); Assert.assertTrue(ce5.getReplication() == 0); Assert.assertTrue(ce5.getSymlinkTarget().equals("/dir")); + LOG.info(ce5.toString()); // SetXAttrOp batch = waitForNextEvents(eis); @@ -310,6 +329,7 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(mue5.getxAttrs().size() == 1); Assert.assertTrue(mue5.getxAttrs().get(0).getName().contains("field")); Assert.assertTrue(!mue5.isxAttrsRemoved()); + LOG.info(mue5.toString()); // RemoveXAttrOp batch = waitForNextEvents(eis); @@ -323,6 +343,7 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(mue6.getxAttrs().size() == 1); Assert.assertTrue(mue6.getxAttrs().get(0).getName().contains("field")); Assert.assertTrue(mue6.isxAttrsRemoved()); + LOG.info(mue6.toString()); // SetAclOp (1) batch = waitForNextEvents(eis); @@ -335,6 +356,7 @@ public class TestDFSInotifyEventInputStream { Event.MetadataUpdateEvent.MetadataType.ACLS); Assert.assertTrue(mue7.getAcls().contains( AclEntry.parseAclEntry("user::rwx", true))); + LOG.info(mue7.toString()); // SetAclOp (2) batch = waitForNextEvents(eis); @@ -346,6 +368,7 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(mue8.getMetadataType() == Event.MetadataUpdateEvent.MetadataType.ACLS); Assert.assertTrue(mue8.getAcls() == null); + LOG.info(mue8.toString()); // RenameOp (2) batch = waitForNextEvents(eis); @@ -356,6 +379,7 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(re3.getDstPath().equals("/dir/file5")); Assert.assertTrue(re3.getSrcPath().equals("/file5")); Assert.assertTrue(re.getTimestamp() > 0); + LOG.info(re3.toString()); // TruncateOp batch = waitForNextEvents(eis); @@ -368,6 +392,8 @@ public class TestDFSInotifyEventInputStream { Assert.assertTrue(et.getPath().equals("/truncate_file")); Assert.assertTrue(et.getFileSize() == BLOCK_SIZE); Assert.assertTrue(et.getTimestamp() > 0); + LOG.info(et.toString()); + Assert.assertTrue(et.toString().startsWith("TruncateEvent [path=")); // Returns null when there are no further events Assert.assertTrue(eis.poll() == null);