From c3abfcefdd256650b2a45ae2aac53c4a22721a46 Mon Sep 17 00:00:00 2001 From: Ayush Saxena Date: Mon, 2 Sep 2019 07:24:04 +0530 Subject: [PATCH] HDFS-13843. RBF: Add optional parameter -d for detailed listing of mount points. Contributed by Ayush Saxena. --- .../hdfs/tools/federation/RouterAdmin.java | 59 ++++++++++++++----- .../federation/router/TestRouterAdminCLI.java | 48 ++++++++++++--- .../src/site/markdown/HDFSCommands.md | 4 +- 3 files changed, 84 insertions(+), 27 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/tools/federation/RouterAdmin.java b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/tools/federation/RouterAdmin.java index b39ed96037..8ba06aaaa3 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/tools/federation/RouterAdmin.java +++ b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/tools/federation/RouterAdmin.java @@ -152,7 +152,7 @@ public class RouterAdmin extends Configured implements Tool { } else if (cmd.equals("-rm")) { return "\t[-rm ]"; } else if (cmd.equals("-ls")) { - return "\t[-ls ]"; + return "\t[-ls [-d] ]"; } else if (cmd.equals("-getDestination")) { return "\t[-getDestination ]"; } else if (cmd.equals("-setQuota")) { @@ -180,9 +180,9 @@ public class RouterAdmin extends Configured implements Tool { */ private void validateMax(String[] arg) { if (arg[0].equals("-ls")) { - if (arg.length > 2) { + if (arg.length > 3) { throw new IllegalArgumentException( - "Too many arguments, Max=1 argument allowed"); + "Too many arguments, Max=2 argument allowed"); } } else if (arg[0].equals("-getDestination")) { if (arg.length > 2) { @@ -320,11 +320,7 @@ public class RouterAdmin extends Configured implements Tool { i++; } } else if ("-ls".equals(cmd)) { - if (argv.length > 1) { - listMounts(argv[i]); - } else { - listMounts("/"); - } + listMounts(argv, i); } else if ("-getDestination".equals(cmd)) { getDestination(argv[i]); } else if ("-setQuota".equals(cmd)) { @@ -732,7 +728,22 @@ public class RouterAdmin extends Configured implements Tool { * @param path Path to list. * @throws IOException If it cannot be listed. */ - public void listMounts(String path) throws IOException { + public void listMounts(String[] argv, int i) throws IOException { + String path; + boolean detail = false; + if (argv.length == 1) { + path = "/"; + } else if (argv[i].equals("-d")) { // Check if -d parameter is specified. + detail = true; + if (argv.length == 2) { + path = "/"; // If no path is provide with -ls -d. + } else { + path = argv[++i]; + } + } else { + path = argv[i]; + } + path = normalizeFileSystemPath(path); MountTableManager mountTable = client.getMountTableManager(); GetMountTableEntriesRequest request = @@ -740,14 +751,20 @@ public class RouterAdmin extends Configured implements Tool { GetMountTableEntriesResponse response = mountTable.getMountTableEntries(request); List entries = response.getEntries(); - printMounts(entries); + printMounts(entries, detail); } - private static void printMounts(List entries) { + private static void printMounts(List entries, boolean detail) { System.out.println("Mount Table Entries:"); - System.out.println(String.format( - "%-25s %-25s %-25s %-25s %-25s %-25s", - "Source", "Destinations", "Owner", "Group", "Mode", "Quota/Usage")); + if (detail) { + System.out.println( + String.format("%-25s %-25s %-25s %-25s %-10s %-30s %-10s %-10s %-15s", + "Source", "Destinations", "Owner", "Group", "Mode", "Quota/Usage", + "Order", "ReadOnly", "FaultTolerant")); + } else { + System.out.println(String.format("%-25s %-25s %-25s %-25s %-10s %-30s", + "Source", "Destinations", "Owner", "Group", "Mode", "Quota/Usage")); + } for (MountTable entry : entries) { StringBuilder destBuilder = new StringBuilder(); for (RemoteLocation location : entry.getDestinations()) { @@ -760,10 +777,20 @@ public class RouterAdmin extends Configured implements Tool { System.out.print(String.format("%-25s %-25s", entry.getSourcePath(), destBuilder.toString())); - System.out.print(String.format(" %-25s %-25s %-25s", + System.out.print(String.format(" %-25s %-25s %-10s", entry.getOwnerName(), entry.getGroupName(), entry.getMode())); - System.out.println(String.format(" %-25s", entry.getQuota())); + System.out.print(String.format(" %-30s", entry.getQuota())); + + if (detail) { + System.out.print(String.format(" %-10s", entry.getDestOrder())); + + System.out.print( + String.format(" %-10s", entry.isReadOnly() ? "Read-Only" : "")); + + System.out.println(String.format(" %-15s", + entry.isFaultTolerant() ? "Fault-Tolerant" : "")); + } } } diff --git a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterAdminCLI.java b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterAdminCLI.java index 6de74c26c2..fc6cf700ac 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterAdminCLI.java +++ b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterAdminCLI.java @@ -300,19 +300,22 @@ public class TestRouterAdminCLI { stateStore.loadCache(MountTableStoreImpl.class, true); argv = new String[] {"-ls", src}; assertEquals(0, ToolRunner.run(admin, argv)); - assertTrue(out.toString().contains(src)); + String response = out.toString(); + assertTrue("Wrong response: " + response, response.contains(src)); // Test with not-normalized src input argv = new String[] {"-ls", srcWithSlash}; assertEquals(0, ToolRunner.run(admin, argv)); - assertTrue(out.toString().contains(src)); + response = out.toString(); + assertTrue("Wrong response: " + response, response.contains(src)); // Test with wrong number of arguments argv = new String[] {"-ls", srcWithSlash, "check", "check2"}; System.setErr(new PrintStream(err)); ToolRunner.run(admin, argv); - assertTrue( - err.toString().contains("Too many arguments, Max=1 argument allowed")); + response = err.toString(); + assertTrue("Wrong response: " + response, + response.contains("Too many arguments, Max=2 argument allowed")); out.reset(); GetMountTableEntriesRequest getRequest = GetMountTableEntriesRequest @@ -324,14 +327,41 @@ public class TestRouterAdminCLI { // mount table under root path. argv = new String[] {"-ls"}; assertEquals(0, ToolRunner.run(admin, argv)); - assertTrue(out.toString().contains(src)); - String outStr = out.toString(); + response = out.toString(); + assertTrue("Wrong response: " + response, response.contains(src)); // verify if all the mount table are listed - for(MountTable entry: getResponse.getEntries()) { - assertTrue(outStr.contains(entry.getSourcePath())); + for (MountTable entry : getResponse.getEntries()) { + assertTrue("Wrong response: " + response, + response.contains(entry.getSourcePath())); } } + @Test + public void testListWithDetails() throws Exception { + // Create mount entry. + String[] argv = new String[] {"-add", "/testLsWithDetails", "ns0,ns1", + "/dest", "-order", "HASH_ALL", "-readonly", "-faulttolerant"}; + assertEquals(0, ToolRunner.run(admin, argv)); + System.setOut(new PrintStream(out)); + stateStore.loadCache(MountTableStoreImpl.class, true); + + // Test list with detail for a mount entry. + argv = new String[] {"-ls", "-d", "/testLsWithDetails"}; + assertEquals(0, ToolRunner.run(admin, argv)); + String response = out.toString(); + assertTrue(response.contains("Read-Only")); + assertTrue(response.contains("Fault-Tolerant")); + out.reset(); + + // Test list with detail without path. + argv = new String[] {"-ls", "-d"}; + assertEquals(0, ToolRunner.run(admin, argv)); + response = out.toString(); + assertTrue("Wrong response: " + response, response.contains("Read-Only")); + assertTrue("Wrong response: " + response, + response.contains("Fault-Tolerant")); + } + @Test public void testListNestedMountTable() throws Exception { String dir1 = "/test-ls"; @@ -627,7 +657,7 @@ public class TestRouterAdminCLI { + " [-faulttolerant true|false] " + "[-order HASH|LOCAL|RANDOM|HASH_ALL|SPACE] " + "-owner -group -mode ]\n" + "\t[-rm ]\n" - + "\t[-ls ]\n" + + "\t[-ls [-d] ]\n" + "\t[-getDestination ]\n" + "\t[-setQuota -nsQuota -ssQuota " + "]\n" + "\t[-clrQuota ]\n" diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/site/markdown/HDFSCommands.md b/hadoop-hdfs-project/hadoop-hdfs/src/site/markdown/HDFSCommands.md index fd4b2061fe..d2185d7995 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/site/markdown/HDFSCommands.md +++ b/hadoop-hdfs-project/hadoop-hdfs/src/site/markdown/HDFSCommands.md @@ -435,7 +435,7 @@ Usage: [-add [-readonly] [-faulttolerant] [-order HASH|LOCAL|RANDOM|HASH_ALL] -owner -group -mode ] [-update [ ] [-readonly true|false] [-faulttolerant true|false] [-order HASH|LOCAL|RANDOM|HASH_ALL] -owner -group -mode ] [-rm ] - [-ls ] + [-ls [-d] ] [-getDestination ] [-setQuota -nsQuota -ssQuota ] [-clrQuota ] @@ -450,7 +450,7 @@ Usage: | `-add` *source* *nameservices* *destination* | Add a mount table entry or update if it exists. | | `-update` *source* *nameservices* *destination* | Update a mount table entry attribures. | | `-rm` *source* | Remove mount point of specified path. | -| `-ls` *path* | List mount points under specified path. | +| `-ls` `[-d]` *path* | List mount points under specified path. Specify -d parameter to get detailed listing.| | `-getDestination` *path* | Get the subcluster where a file is or should be created. | | `-setQuota` *path* `-nsQuota` *nsQuota* `-ssQuota` *ssQuota* | Set quota for specified path. See [HDFS Quotas Guide](./HdfsQuotaAdminGuide.html) for the quota detail. | | `-clrQuota` *path* | Clear quota of given mount point. See [HDFS Quotas Guide](./HdfsQuotaAdminGuide.html) for the quota detail. |