diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/cli/GenericCli.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/cli/GenericCli.java index 2b3e6c003fc..f829d825e1b 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/cli/GenericCli.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/cli/GenericCli.java @@ -23,6 +23,7 @@ import java.util.concurrent.Callable; import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import com.google.common.annotations.VisibleForTesting; import picocli.CommandLine; import picocli.CommandLine.ExecutionException; import picocli.CommandLine.Option; @@ -49,13 +50,18 @@ public class GenericCli implements Callable { public void run(String[] argv) { try { - cmd.parseWithHandler(new RunLast(), argv); + execute(argv); } catch (ExecutionException ex) { printError(ex.getCause()); System.exit(-1); } } + @VisibleForTesting + public void execute(String[] argv) { + cmd.parseWithHandler(new RunLast(), argv); + } + private void printError(Throwable error) { if (verbose) { error.printStackTrace(System.err); @@ -79,4 +85,13 @@ public class GenericCli implements Callable { } return ozoneConf; } + + public boolean isVerbose() { + return verbose; + } + + @VisibleForTesting + public picocli.CommandLine getCmd() { + return cmd; + } } diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java index 386b1d23ca8..f50de4b96b4 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/ozShell/TestOzoneShell.java @@ -17,12 +17,6 @@ */ package org.apache.hadoop.ozone.ozShell; -import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_REPLICATION; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; @@ -38,17 +32,15 @@ import java.util.Random; import java.util.UUID; import java.util.stream.Collectors; -import com.google.common.base.Strings; -import org.apache.commons.lang3.RandomStringUtils; import org.apache.hadoop.fs.FileUtil; import org.apache.hadoop.hdds.client.ReplicationFactor; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.proto.HddsProtos; import org.apache.hadoop.hdfs.DFSUtil; import org.apache.hadoop.ozone.MiniOzoneCluster; import org.apache.hadoop.ozone.OzoneAcl; import org.apache.hadoop.ozone.OzoneAcl.OzoneACLRights; import org.apache.hadoop.ozone.OzoneAcl.OzoneACLType; -import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.ozone.OzoneConsts; import org.apache.hadoop.ozone.client.OzoneBucket; import org.apache.hadoop.ozone.client.OzoneKey; @@ -67,10 +59,17 @@ import org.apache.hadoop.ozone.web.response.KeyInfo; import org.apache.hadoop.ozone.web.response.VolumeInfo; import org.apache.hadoop.ozone.web.utils.JsonUtils; import org.apache.hadoop.test.GenericTestUtils; -import org.apache.hadoop.util.ToolRunner; + +import com.google.common.base.Strings; +import org.apache.commons.lang3.RandomStringUtils; +import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_REPLICATION; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -80,6 +79,12 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import picocli.CommandLine; +import picocli.CommandLine.ExecutionException; +import picocli.CommandLine.IExceptionHandler2; +import picocli.CommandLine.ParameterException; +import picocli.CommandLine.ParseResult; +import picocli.CommandLine.RunLast; /** * This test class specified for testing Ozone shell command. @@ -134,7 +139,6 @@ public class TestOzoneShell { baseDir.mkdirs(); shell = new Shell(); - shell.setConf(conf); cluster = MiniOzoneCluster.newBuilder(conf) .setNumDatanodes(3) @@ -206,7 +210,7 @@ public class TestOzoneShell { testCreateVolume("/////", "Volume name is required " + "to create a volume"); testCreateVolume("/////vol/123", - "Illegal argument: Bucket or Volume name has " + + "Bucket or Volume name has " + "an unsupported character : /"); } @@ -218,10 +222,10 @@ public class TestOzoneShell { "-user", userName, "-root"}; if (Strings.isNullOrEmpty(errorMsg)) { - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); + } else { - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains(errorMsg)); + executeWithError(shell, args, errorMsg); return; } @@ -232,6 +236,29 @@ public class TestOzoneShell { assertEquals(userName, volumeInfo.getOwner()); } + private void execute(Shell shell, String[] args) { + List arguments = new ArrayList(Arrays.asList(args)); + LOG.info("Executing shell command with args {}", arguments); + CommandLine cmd = shell.getCmd(); + + IExceptionHandler2> exceptionHandler = + new IExceptionHandler2>() { + @Override + public List handleParseException(ParameterException ex, + String[] args) { + throw ex; + } + + @Override + public List handleExecutionException(ExecutionException ex, + ParseResult parseResult) { + throw ex; + } + }; + cmd.parseWithHandlers(new RunLast(), + exceptionHandler, args); + } + @Test public void testDeleteVolume() throws Exception { LOG.info("Running testDeleteVolume"); @@ -244,9 +271,8 @@ public class TestOzoneShell { OzoneVolume volume = client.getVolumeDetails(volumeName); assertNotNull(volume); - String[] args = new String[] {"-deleteVolume", url + "/" + volumeName, - "-root"}; - assertEquals(0, ToolRunner.run(shell, args)); + String[] args = new String[] {"-deleteVolume", url + "/" + volumeName}; + execute(shell, args); String output = out.toString(); assertTrue(output.contains("Volume " + volumeName + " is deleted")); @@ -270,9 +296,8 @@ public class TestOzoneShell { .build(); client.createVolume(volumeName, volumeArgs); - String[] args = new String[] {"-infoVolume", url + "/" + volumeName, - "-root"}; - assertEquals(0, ToolRunner.run(shell, args)); + String[] args = new String[] {"-infoVolume", url + "/" + volumeName}; + execute(shell, args); String output = out.toString(); assertTrue(output.contains(volumeName)); @@ -280,10 +305,8 @@ public class TestOzoneShell { && output.contains(OzoneConsts.OZONE_TIME_ZONE)); // get info for non-exist volume - args = new String[] {"-infoVolume", url + "/invalid-volume", "-root"}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Info Volume failed, error:VOLUME_NOT_FOUND")); + args = new String[] {"-infoVolume", url + "/invalid-volume"}; + executeWithError(shell, args, "VOLUME_NOT_FOUND"); } @Test @@ -301,32 +324,58 @@ public class TestOzoneShell { assertEquals(OzoneQuota.parseQuota("100TB").sizeInBytes(), vol.getQuota()); String[] args = new String[] {"-updateVolume", url + "/" + volumeName, - "-quota", "500MB", "-root"}; - assertEquals(0, ToolRunner.run(shell, args)); + "-quota", "500MB"}; + execute(shell, args); vol = client.getVolumeDetails(volumeName); assertEquals(userName, vol.getOwner()); assertEquals(OzoneQuota.parseQuota("500MB").sizeInBytes(), vol.getQuota()); String newUser = "new-user"; args = new String[] {"-updateVolume", url + "/" + volumeName, - "-user", newUser, "-root"}; - assertEquals(0, ToolRunner.run(shell, args)); + "-user", newUser}; + execute(shell, args); vol = client.getVolumeDetails(volumeName); assertEquals(newUser, vol.getOwner()); // test error conditions args = new String[] {"-updateVolume", url + "/invalid-volume", - "-user", newUser, "-root"}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Info Volume failed, error:VOLUME_NOT_FOUND")); + "-user", newUser}; + executeWithError(shell, args, "Info Volume failed, error:VOLUME_NOT_FOUND"); err.reset(); args = new String[] {"-updateVolume", url + "/invalid-volume", - "-quota", "500MB", "-root"}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Info Volume failed, error:VOLUME_NOT_FOUND")); + "-quota", "500MB"}; + executeWithError(shell, args, "Info Volume failed, error:VOLUME_NOT_FOUND"); + } + + /** + * Execute command, assert exeception message and returns true if error + * was thrown. + */ + private void executeWithError(Shell shell, String[] args, + String expectedError) { + if (Strings.isNullOrEmpty(expectedError)) { + execute(shell, args); + } else { + try { + execute(shell, args); + fail("Exception is expected from command execution " + Arrays + .asList(args)); + } catch (Exception ex) { + if (!Strings.isNullOrEmpty(expectedError)) { + Throwable exceptionToCheck = ex; + if (exceptionToCheck.getCause() != null) { + exceptionToCheck = exceptionToCheck.getCause(); + } + Assert.assertTrue( + String.format( + "Error of shell code doesn't contain the " + + "exception [%s] in [%s]", + expectedError, exceptionToCheck.getMessage()), + exceptionToCheck.getMessage().contains(expectedError)); + } + } + } } @Test @@ -364,15 +413,13 @@ public class TestOzoneShell { String[] args = new String[] {"-listVolume", url + "/abcde", "-user", user1, "-length", "100"}; - assertEquals(1, ToolRunner.run(shell, args)); - commandError = err.toString(); - Assert.assertTrue(commandError.contains("Invalid URI:")); + executeWithError(shell, args, "Invalid URI"); err.reset(); // test -length option args = new String[] {"-listVolume", url + "/", "-user", user1, "-length", "100"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); volumes = (List) JsonUtils .toJsonList(commandOutput, VolumeInfo.class); @@ -386,7 +433,7 @@ public class TestOzoneShell { out.reset(); args = new String[] {"-listVolume", url + "/", "-user", user1, "-length", "2"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); volumes = (List) JsonUtils .toJsonList(commandOutput, VolumeInfo.class); @@ -397,7 +444,7 @@ public class TestOzoneShell { out.reset(); args = new String[] {"-listVolume", url + "/", "-user", user1, "-length", "100", "-prefix", "test-vol-" + protocol + "1" }; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); volumes = (List) JsonUtils .toJsonList(commandOutput, VolumeInfo.class); @@ -414,7 +461,7 @@ public class TestOzoneShell { out.reset(); args = new String[] {"-listVolume", url + "/", "-user", user2, "-length", "100", "-start", "test-vol-" + protocol + "15" }; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); volumes = (List) JsonUtils .toJsonList(commandOutput, VolumeInfo.class); @@ -430,16 +477,12 @@ public class TestOzoneShell { err.reset(); args = new String[] {"-listVolume", url + "/", "-user", user2, "-length", "-1"}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "the vaule should be a positive number")); + executeWithError(shell, args, "the length should be a positive number"); err.reset(); args = new String[] {"-listVolume", url + "/", "-user", user2, "-length", "invalid-length"}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "the vaule should be digital")); + executeWithError(shell, args, "For input string: \"invalid-length\""); } @Test @@ -450,7 +493,7 @@ public class TestOzoneShell { String[] args = new String[] {"-createBucket", url + "/" + vol.getName() + "/" + bucketName}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); OzoneBucket bucketInfo = vol.getBucket(bucketName); assertEquals(vol.getName(), bucketInfo.getVolumeName()); @@ -460,9 +503,7 @@ public class TestOzoneShell { args = new String[] {"-createBucket", url + "/invalid-volume/" + bucketName}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Info Volume failed, error:VOLUME_NOT_FOUND")); + executeWithError(shell, args, "Info Volume failed, error:VOLUME_NOT_FOUND"); } @Test @@ -476,7 +517,7 @@ public class TestOzoneShell { String[] args = new String[] {"-deleteBucket", url + "/" + vol.getName() + "/" + bucketName}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); // verify if bucket has been deleted in volume try { @@ -490,17 +531,14 @@ public class TestOzoneShell { // test delete bucket in a non-exist volume args = new String[] {"-deleteBucket", url + "/invalid-volume" + "/" + bucketName}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Info Volume failed, error:VOLUME_NOT_FOUND")); + executeWithError(shell, args, "Info Volume failed, error:VOLUME_NOT_FOUND"); err.reset(); // test delete non-exist bucket args = new String[] {"-deleteBucket", url + "/" + vol.getName() + "/invalid-bucket"}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Delete Bucket failed, error:BUCKET_NOT_FOUND")); + executeWithError(shell, args, + "Delete Bucket failed, error:BUCKET_NOT_FOUND"); } @Test @@ -512,7 +550,7 @@ public class TestOzoneShell { String[] args = new String[] {"-infoBucket", url + "/" + vol.getName() + "/" + bucketName}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); String output = out.toString(); assertTrue(output.contains(bucketName)); @@ -522,9 +560,8 @@ public class TestOzoneShell { // test get info from a non-exist bucket args = new String[] {"-infoBucket", url + "/" + vol.getName() + "/invalid-bucket" + bucketName}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Info Bucket failed, error: BUCKET_NOT_FOUND")); + executeWithError(shell, args, + "Info Bucket failed, error: BUCKET_NOT_FOUND"); } @Test @@ -539,7 +576,7 @@ public class TestOzoneShell { String[] args = new String[] {"-updateBucket", url + "/" + vol.getName() + "/" + bucketName, "-addAcl", "user:frodo:rw,group:samwise:r"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); String output = out.toString(); assertTrue(output.contains("createdOn") && output.contains(OzoneConsts.OZONE_TIME_ZONE)); @@ -555,7 +592,7 @@ public class TestOzoneShell { args = new String[] {"-updateBucket", url + "/" + vol.getName() + "/" + bucketName, "-removeAcl", "user:frodo:rw"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); bucket = vol.getBucket(bucketName); acl = bucket.getAcls().get(aclSize); @@ -568,9 +605,8 @@ public class TestOzoneShell { args = new String[] {"-updateBucket", url + "/" + vol.getName() + "/invalid-bucket", "-addAcl", "user:frodo:rw"}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Info Bucket failed, error: BUCKET_NOT_FOUND")); + executeWithError(shell, args, + "Info Bucket failed, error: BUCKET_NOT_FOUND"); } @Test @@ -594,7 +630,7 @@ public class TestOzoneShell { // test -length option String[] args = new String[] {"-listBucket", url + "/" + vol.getName(), "-length", "100"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); buckets = (List) JsonUtils.toJsonList(commandOutput, BucketInfo.class); @@ -614,7 +650,7 @@ public class TestOzoneShell { out.reset(); args = new String[] {"-listBucket", url + "/" + vol.getName(), "-length", "3"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); buckets = (List) JsonUtils.toJsonList(commandOutput, BucketInfo.class); @@ -630,7 +666,7 @@ public class TestOzoneShell { out.reset(); args = new String[] {"-listBucket", url + "/" + vol.getName(), "-length", "100", "-prefix", "test-bucket1"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); buckets = (List) JsonUtils.toJsonList(commandOutput, BucketInfo.class); @@ -644,7 +680,7 @@ public class TestOzoneShell { out.reset(); args = new String[] {"-listBucket", url + "/" + vol.getName(), "-length", "100", "-start", "test-bucket7"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); buckets = (List) JsonUtils.toJsonList(commandOutput, BucketInfo.class); @@ -657,9 +693,7 @@ public class TestOzoneShell { err.reset(); args = new String[] {"-listBucket", url + "/" + vol.getName(), "-length", "-1"}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "the vaule should be a positive number")); + executeWithError(shell, args, "the length should be a positive number"); } @Test @@ -673,7 +707,7 @@ public class TestOzoneShell { String[] args = new String[] {"-putKey", url + "/" + volumeName + "/" + bucketName + "/" + keyName, "-file", createTmpFile()}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); OzoneKey keyInfo = bucket.getKey(keyName); assertEquals(keyName, keyInfo.getName()); @@ -682,9 +716,8 @@ public class TestOzoneShell { args = new String[] {"-putKey", url + "/" + volumeName + "/invalid-bucket/" + keyName, "-file", createTmpFile()}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Info Bucket failed, error: BUCKET_NOT_FOUND")); + executeWithError(shell, args, + "Info Bucket failed, error: BUCKET_NOT_FOUND"); } @Test @@ -706,7 +739,7 @@ public class TestOzoneShell { String[] args = new String[] {"-getKey", url + "/" + volumeName + "/" + bucketName + "/" + keyName, "-file", tmpPath}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); byte[] dataBytes = new byte[dataStr.length()]; try (FileInputStream randFile = new FileInputStream(new File(tmpPath))) { @@ -718,7 +751,7 @@ public class TestOzoneShell { args = new String[] {"-getKey", url + "/" + volumeName + "/" + bucketName + "/" + keyName, "-file", baseDir.getAbsolutePath()}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); dataBytes = new byte[dataStr.length()]; try (FileInputStream randFile = new FileInputStream(new File(tmpPath))) { @@ -745,7 +778,7 @@ public class TestOzoneShell { String[] args = new String[] {"-deleteKey", url + "/" + volumeName + "/" + bucketName + "/" + keyName}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); // verify if key has been deleted in the bucket try { @@ -759,17 +792,14 @@ public class TestOzoneShell { // test delete key in a non-exist bucket args = new String[] {"-deleteKey", url + "/" + volumeName + "/invalid-bucket/" + keyName}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Info Bucket failed, error: BUCKET_NOT_FOUND")); + executeWithError(shell, args, + "Info Bucket failed, error: BUCKET_NOT_FOUND"); err.reset(); // test delete a non-exist key in bucket args = new String[] {"-deleteKey", url + "/" + volumeName + "/" + bucketName + "/invalid-key"}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Delete key failed, error:KEY_NOT_FOUND")); + executeWithError(shell, args, "Delete key failed, error:KEY_NOT_FOUND"); } @Test @@ -789,9 +819,8 @@ public class TestOzoneShell { url + "/" + volumeName + "/" + bucketName + "/" + keyName}; // verify the response output - int a = ToolRunner.run(shell, args); + execute(shell, args); String output = out.toString(); - assertEquals(0, a); assertTrue(output.contains(keyName)); assertTrue( @@ -810,9 +839,7 @@ public class TestOzoneShell { // verify the response output // get the non-exist key info should be failed - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "Lookup key failed, error:KEY_NOT_FOUND")); + executeWithError(shell, args, "Lookup key failed, error:KEY_NOT_FOUND"); } @Test @@ -831,21 +858,15 @@ public class TestOzoneShell { String[] args = new String[] {"-infoKey", url + "/" + volumeName + "/" + bucketName + "/" + dirKeyName}; // verify the response output - int a = ToolRunner.run(shell, args); + execute(shell, args); String output = out.toString(); - assertEquals(0, a); assertTrue(output.contains(dirKeyName)); assertTrue(output.contains("createdOn") && output.contains("modifiedOn") && output.contains(OzoneConsts.OZONE_TIME_ZONE)); args = new String[] {"-infoKey", url + "/" + volumeName + "/" + bucketName + "/" + keyNameOnly}; - a = ToolRunner.run(shell, args); - output = out.toString(); - assertEquals(1, a); - assertTrue(err.toString().contains( - "Lookup key failed, error:KEY_NOT_FOUND")); - // reset stream + executeWithError(shell, args, "Lookup key failed, error:KEY_NOT_FOUND"); out.reset(); err.reset(); } @@ -875,7 +896,7 @@ public class TestOzoneShell { // test -length option String[] args = new String[] {"-listKey", url + "/" + volumeName + "/" + bucketName, "-length", "100"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); keys = (List) JsonUtils.toJsonList(commandOutput, KeyInfo.class); @@ -897,7 +918,7 @@ public class TestOzoneShell { out.reset(); args = new String[] {"-listKey", url + "/" + volumeName + "/" + bucketName, "-length", "3"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); keys = (List) JsonUtils.toJsonList(commandOutput, KeyInfo.class); @@ -912,7 +933,7 @@ public class TestOzoneShell { out.reset(); args = new String[] {"-listKey", url + "/" + volumeName + "/" + bucketName, "-length", "100", "-prefix", "test-key1"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); keys = (List) JsonUtils.toJsonList(commandOutput, KeyInfo.class); @@ -926,7 +947,7 @@ public class TestOzoneShell { out.reset(); args = new String[] {"-listKey", url + "/" + volumeName + "/" + bucketName, "-length", "100", "-start", "test-key7"}; - assertEquals(0, ToolRunner.run(shell, args)); + execute(shell, args); commandOutput = out.toString(); keys = (List) JsonUtils.toJsonList(commandOutput, KeyInfo.class); @@ -938,9 +959,7 @@ public class TestOzoneShell { err.reset(); args = new String[] {"-listKey", url + "/" + volumeName + "/" + bucketName, "-length", "-1"}; - assertEquals(1, ToolRunner.run(shell, args)); - assertTrue(err.toString().contains( - "the vaule should be a positive number")); + executeWithError(shell, args, "the length should be a positive number"); } private OzoneVolume creatVolume() throws OzoneException, IOException { @@ -949,7 +968,12 @@ public class TestOzoneShell { .setOwner("bilbo") .setQuota("100TB") .build(); - client.createVolume(volumeName, volumeArgs); + try { + client.createVolume(volumeName, volumeArgs); + } catch (Exception ex) { + Assert.assertEquals("PartialGroupNameException", + ex.getCause().getClass().getSimpleName()); + } OzoneVolume volume = client.getVolumeDetails(volumeName); return volume; diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Handler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Handler.java index a66e227d5cc..45413f8f19a 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Handler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Handler.java @@ -20,6 +20,7 @@ package org.apache.hadoop.ozone.web.ozShell; import org.apache.commons.cli.CommandLine; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hdds.cli.HddsVersionProvider; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.ozone.client.OzoneClient; import org.apache.hadoop.ozone.client.OzoneClientFactory; @@ -32,18 +33,27 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.util.concurrent.Callable; import static org.apache.hadoop.ozone.OzoneConsts.OZONE_HTTP_SCHEME; import static org.apache.hadoop.ozone.OzoneConsts.OZONE_URI_SCHEME; +import picocli.CommandLine.Command; +import picocli.CommandLine.ParentCommand; /** * Common interface for command handling. */ -public abstract class Handler { +@Command(mixinStandardHelpOptions = true, + versionProvider = HddsVersionProvider.class) +public abstract class Handler implements Callable { protected static final Logger LOG = LoggerFactory.getLogger(Handler.class); + protected OzoneClient client; + @ParentCommand + private Shell parent; + /** * Executes the Client command. * @@ -52,8 +62,15 @@ public abstract class Handler { * @throws OzoneException * @throws URISyntaxException */ - protected abstract void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException; + protected void execute(CommandLine cmd) + throws IOException, OzoneException, URISyntaxException { + throw new UnsupportedOperationException(); + } + + @Override + public Void call() throws Exception { + throw new UnsupportedOperationException(); + } /** * verifies user provided URI. @@ -148,4 +165,8 @@ public abstract class Handler { throw new IllegalArgumentException(e); } } + + public boolean isVerbose() { + return parent.isVerbose(); + } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Shell.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Shell.java index 41eef1abf97..27cf732fe8d 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Shell.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/Shell.java @@ -18,16 +18,12 @@ package org.apache.hadoop.ozone.web.ozShell; -import org.apache.commons.cli.BasicParser; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.conf.Configured; -import org.apache.hadoop.hdds.conf.OzoneConfiguration; -import org.apache.hadoop.ozone.client.rest.OzoneException; +import org.apache.hadoop.hdds.cli.GenericCli; +import org.apache.hadoop.hdds.cli.HddsVersionProvider; +import org.apache.hadoop.ozone.web.ozShell.bucket.CreateBucketHandler; +import org.apache.hadoop.ozone.web.ozShell.bucket.DeleteBucketHandler; +import org.apache.hadoop.ozone.web.ozShell.bucket.InfoBucketHandler; +import org.apache.hadoop.ozone.web.ozShell.bucket.ListBucketHandler; import org.apache.hadoop.ozone.web.ozShell.bucket.UpdateBucketHandler; import org.apache.hadoop.ozone.web.ozShell.keys.DeleteKeyHandler; import org.apache.hadoop.ozone.web.ozShell.keys.GetKeyHandler; @@ -39,17 +35,10 @@ import org.apache.hadoop.ozone.web.ozShell.volume.DeleteVolumeHandler; import org.apache.hadoop.ozone.web.ozShell.volume.InfoVolumeHandler; import org.apache.hadoop.ozone.web.ozShell.volume.ListVolumeHandler; import org.apache.hadoop.ozone.web.ozShell.volume.UpdateVolumeHandler; -import org.apache.hadoop.ozone.web.ozShell.bucket.CreateBucketHandler; -import org.apache.hadoop.ozone.web.ozShell.bucket.DeleteBucketHandler; -import org.apache.hadoop.ozone.web.ozShell.bucket.InfoBucketHandler; -import org.apache.hadoop.ozone.web.ozShell.bucket.ListBucketHandler; -import org.apache.hadoop.util.Tool; -import org.apache.hadoop.util.ToolRunner; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URISyntaxException; +import picocli.CommandLine.Command; /** * Ozone user interface commands. @@ -57,47 +46,50 @@ import java.net.URISyntaxException; * This class uses dispatch method to make calls * to appropriate handlers that execute the ozone functions. */ -public class Shell extends Configured implements Tool { +@Command(name = "ozone oz", + description = "Client for the Ozone object store", + subcommands = { + InfoVolumeHandler.class, + ListVolumeHandler.class, + CreateVolumeHandler.class, + UpdateVolumeHandler.class, + DeleteVolumeHandler.class, + InfoBucketHandler.class, + ListBucketHandler.class, + CreateBucketHandler.class, + UpdateBucketHandler.class, + DeleteBucketHandler.class, + InfoKeyHandler.class, + ListKeyHandler.class, + PutKeyHandler.class, + GetKeyHandler.class, + DeleteKeyHandler.class + }, + versionProvider = HddsVersionProvider.class, + mixinStandardHelpOptions = true) +public class Shell extends GenericCli { + + private static final Logger LOG = LoggerFactory.getLogger(Shell.class); + public static final String OZONE_URI_DESCRIPTION = "Ozone URI could start " + + "with o3:// or http(s):// or without prefix. REST protocol will " + + "be used for http(s), RPC otherwise. URI may contain the host and port " + + "of the SCM server. Both are optional. " + + "If they are not specified it will be identified from " + + "the config files."; + + public static final String OZONE_VOLUME_URI_DESCRIPTION = + "URI of the volume.\n" + OZONE_URI_DESCRIPTION; + + public static final String OZONE_BUCKET_URI_DESCRIPTION = + "URI of the volume/bucket.\n" + OZONE_URI_DESCRIPTION; + + public static final String OZONE_KEY_URI_DESCRIPTION = + "URI of the volume/bucket/key.\n" + OZONE_URI_DESCRIPTION; + // General options public static final int DEFAULT_OZONE_PORT = 50070; - public static final String VERBOSE = "v"; - - // volume related command line arguments - public static final String RUNAS = "root"; - public static final String USER = "user"; - public static final String OWNER = "owner"; - public static final String QUOTA = "quota"; - public static final String CREATE_VOLUME = "createVolume"; - public static final String UPDATE_VOLUME = "updateVolume"; - public static final String DELETE_VOLUME = "deleteVolume"; - public static final String LIST_VOLUME = "listVolume"; - public static final String INFO_VOLUME = "infoVolume"; - - // bucket related command line arguments - public static final String CREATE_BUCKET = "createBucket"; - public static final String UPDATE_BUCKET = "updateBucket"; - public static final String DELETE_BUCKET = "deleteBucket"; - public static final String LIST_BUCKET = "listBucket"; - public static final String INFO_BUCKET = "infoBucket"; - public static final String ADD_ACLS = "addAcl"; - public static final String REMOVE_ACLS = "removeAcl"; - // TODO : Support versioning and StorageType for buckets - - //Object related command line arguments - public static final String PUT_KEY = "putKey"; - public static final String GET_KEY = "getKey"; - public static final String INFO_KEY = "infoKey"; - public static final String DELETE_KEY = "deleteKey"; - public static final String LIST_KEY = "listKey"; - public static final String FILE = "file"; - public static final String REPLICATION_FACTOR = "replicationFactor"; - - // Listing related command line arguments - public static final String LIST_LENGTH = "length"; - public static final String START = "start"; - public static final String PREFIX = "prefix"; /** * Main for the ozShell Command handling. @@ -106,315 +98,10 @@ public class Shell extends Configured implements Tool { * @throws Exception */ public static void main(String[] argv) throws Exception { - Shell shell = new Shell(); - Configuration conf = new OzoneConfiguration(); - conf.setQuietMode(false); - shell.setConf(conf); - int res = 0; - try { - res = ToolRunner.run(shell, argv); - } catch (Exception ex) { - System.err.println("ERROR: " + ex.getMessage()); - System.exit(1); - } - System.exit(res); - } - - /** - * Execute the command with the given arguments. - * - * @param args command specific arguments. - * - * @return exit code. - * - * @throws Exception - */ - @Override - public int run(String[] args) throws Exception { - Options opts = getOpts(); - CommandLine cmd = parseArgs(args, opts); - return dispatch(cmd, opts); - } - - /** - * returns the Command Line Options. - * - * @return Options - */ - private Options getOpts() { - Options opts = new Options(); - addVolumeCommands(opts); - addBucketCommands(opts); - addKeyCommands(opts); - addListingCommands(opts); - return opts; - } - - /** - * This function parses all command line arguments - * and returns the appropriate values. - * - * @param argv - Argv from main - * - * @return CommandLine - */ - private CommandLine parseArgs(String[] argv, Options opts) - throws org.apache.commons.cli.ParseException { - try { - BasicParser parser = new BasicParser(); - return parser.parse(opts, argv); - } catch (ParseException ex) { - System.out.printf(ex.getMessage()); - } - - return null; + new Shell().run(argv); } - /** - * All volume related commands are added in this function for the command - * parser. - * - * @param options - Command Options class. - */ - private void addVolumeCommands(Options options) { - Option verbose = new Option(VERBOSE, false, "verbose information output."); - options.addOption(verbose); - Option runas = new Option(RUNAS, false, "Run the command as \"hdfs\" user"); - options.addOption(runas); - - Option userName = new Option(USER, true, - "Name of the user in volume management " + - "functions"); - options.addOption(userName); - - Option quota = new Option(QUOTA, true, "Quota for the volume. E.g. 10TB"); - options.addOption(quota); - - - Option createVolume = new Option(CREATE_VOLUME, true, "creates a volume" + - "for the specified user.\n \t For example : hdfs o3 -createVolume " + - " -root -user \n"); - options.addOption(createVolume); - - Option deleteVolume = new Option(DELETE_VOLUME, true, "deletes a volume" + - "if it is empty.\n \t For example : ozone oz -deleteVolume " + - " -root \n"); - options.addOption(deleteVolume); - - Option listVolume = - new Option(LIST_VOLUME, true, "List the volumes of a given user.\n" + - "For example : ozone oz -listVolume " + - "-user -root or ozone oz " + - "-listVolume"); - listVolume.setOptionalArg(true); - options.addOption(listVolume); - - Option updateVolume = - new Option(UPDATE_VOLUME, true, "updates an existing volume.\n" + - "\t For example : ozone oz " + - "-updateVolume -quota " + - "100TB\n"); - options.addOption(updateVolume); - - Option infoVolume = new Option(INFO_VOLUME, true, - "returns information about a specific " + - "volume."); - options.addOption(infoVolume); - } - - /** - * All bucket related commands for ozone. - * - * @param opts - Options - */ - private void addBucketCommands(Options opts) { - Option createBucket = new Option(CREATE_BUCKET, true, - "creates a bucket in a given volume." + - "For example: ozone oz -createBucket "); - opts.addOption(createBucket); - - Option infoBucket = - new Option(INFO_BUCKET, true, "returns information about a bucket."); - opts.addOption(infoBucket); - - Option deleteBucket = - new Option(DELETE_BUCKET, true, "deletes an empty bucket."); - opts.addOption(deleteBucket); - - Option listBucket = - new Option(LIST_BUCKET, true, "lists the buckets in a volume."); - opts.addOption(listBucket); - - Option updateBucket = - new Option(UPDATE_BUCKET, true, "allows changing bucket attributes.\n" + - " For example: ozone oz -updateBucket " + - "-addAcl user:frodo:rw"); - opts.addOption(updateBucket); - - Option addAcl = - new Option(ADD_ACLS, true, "allows user to add acls to a bucket."); - opts.addOption(addAcl); - - Option removeAcl = - new Option(REMOVE_ACLS, true, "allows user to remove acls from a " + - "bucket."); - opts.addOption(removeAcl); - } - - /** - * All key commands. - * - * @param opts - options - */ - private void addKeyCommands(Options opts) { - Option putKey = - new Option(PUT_KEY, true, "creates or overwrites an existing key"); - opts.addOption(putKey); - - Option deleteKey = - new Option(DELETE_KEY, true, "deletes an existing key"); - opts.addOption(deleteKey); - - Option infoKey = - new Option(INFO_KEY, true, "returns information about an existing key"); - opts.addOption(infoKey); - - Option listKey = - new Option(LIST_KEY, true, "list all keys in a given bucket"); - opts.addOption(listKey); - - Option getKey = - new Option(GET_KEY, true, "Gets a specific key from ozone server."); - opts.addOption(getKey); - - Option fileArgument = - new Option(FILE, true, "Data file path"); - opts.addOption(fileArgument); - - Option repFactor = - new Option(REPLICATION_FACTOR, true, "Replication factor (1 or 3)"); - opts.addOption(repFactor); - } - - /** - * Sub commands for list command. - * @param opts - */ - private void addListingCommands(Options opts) { - Option maxKeys = new Option(LIST_LENGTH, true, - "Specify the max length of listing result."); - opts.addOption(maxKeys); - - Option prevKey = new Option(START, true, - "Specify the start key where to start listing from."); - opts.addOption(prevKey); - - Option prefix = new Option(PREFIX, true, - "Specify the prefix to filter the listing result."); - opts.addOption(prefix); - } - - /** - * Dispatches calls to the right command Handler classes. - * - * @param cmd - CommandLine - * - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException - */ - private int dispatch(CommandLine cmd, Options opts) - throws IOException, OzoneException, URISyntaxException { - Handler handler = null; - final int eightyColumn = 80; - - try { - - // volume functions - if (cmd.hasOption(Shell.CREATE_VOLUME)) { - handler = new CreateVolumeHandler(); - } - - if (cmd.hasOption(Shell.DELETE_VOLUME)) { - handler = new DeleteVolumeHandler(); - } - - if (cmd.hasOption(Shell.LIST_VOLUME)) { - handler = new ListVolumeHandler(); - } - - if (cmd.hasOption(Shell.UPDATE_VOLUME)) { - handler = new UpdateVolumeHandler(); - } - - if (cmd.hasOption(Shell.INFO_VOLUME)) { - handler = new InfoVolumeHandler(); - } - - // bucket functions - if (cmd.hasOption(Shell.CREATE_BUCKET)) { - handler = new CreateBucketHandler(); - } - - if (cmd.hasOption(Shell.DELETE_BUCKET)) { - handler = new DeleteBucketHandler(); - } - - if (cmd.hasOption(Shell.INFO_BUCKET)) { - handler = new InfoBucketHandler(); - } - - if (cmd.hasOption(Shell.LIST_BUCKET)) { - handler = new ListBucketHandler(); - } - - if(cmd.hasOption(Shell.UPDATE_BUCKET)){ - handler = new UpdateBucketHandler(); - } - - //Key Functions - - if(cmd.hasOption(Shell.PUT_KEY)) { - handler = new PutKeyHandler(); - } - - if(cmd.hasOption(Shell.DELETE_KEY)) { - handler = new DeleteKeyHandler(); - } - - if(cmd.hasOption(Shell.INFO_KEY)) { - handler = new InfoKeyHandler(); - } - - if(cmd.hasOption(Shell.LIST_KEY)) { - handler = new ListKeyHandler(); - } - - if(cmd.hasOption(Shell.GET_KEY)) { - handler = new GetKeyHandler(); - } - - if (handler != null) { - handler.execute(cmd); - return 0; - } else { - HelpFormatter helpFormatter = new HelpFormatter(); - helpFormatter.printHelp(eightyColumn, "ozone oz -command uri [args]", - "Ozone Commands", - opts, "Please correct your command and try again."); - return 1; - } - } catch (IOException | URISyntaxException ex) { - System.err.printf("Command Failed : %s%n", ex.getMessage()); - } catch (OzoneException ex) { - System.err.printf("Command Failed : %s%n", ex.toJsonString()); - LOG.debug("Command Failed.", ex); - } catch (IllegalArgumentException ex) { - System.err.printf("Illegal argument: %s%n", ex.getMessage()); - } - return 1; - } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/CreateBucketHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/CreateBucketHandler.java index 0788f9e20a3..5fe5c7ba144 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/CreateBucketHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/CreateBucketHandler.java @@ -17,59 +17,48 @@ */ package org.apache.hadoop.ozone.web.ozShell.bucket; -import org.apache.commons.cli.CommandLine; +import java.net.URI; +import java.nio.file.Path; +import java.nio.file.Paths; + import org.apache.hadoop.ozone.client.OzoneBucket; +import org.apache.hadoop.ozone.client.OzoneClientException; import org.apache.hadoop.ozone.client.OzoneClientUtils; import org.apache.hadoop.ozone.client.OzoneVolume; -import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; import org.apache.hadoop.ozone.web.ozShell.Handler; import org.apache.hadoop.ozone.web.ozShell.Shell; import org.apache.hadoop.ozone.web.utils.JsonUtils; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; +import picocli.CommandLine.Command; +import picocli.CommandLine.Parameters; /** * create bucket handler. */ +@Command(name = "-createBucket", + description = "creates a bucket in a given volume") public class CreateBucketHandler extends Handler { - private String volumeName; - private String bucketName; + @Parameters(arity = "1..1", description = Shell.OZONE_BUCKET_URI_DESCRIPTION) + private String uri; /** * Executes create bucket. - * - * @param cmd - CommandLine - * - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { - if (!cmd.hasOption(Shell.CREATE_BUCKET)) { - throw new OzoneClientException( - "Incorrect call : createBucket is missing"); - } + public Void call() throws Exception { - String ozoneURIString = cmd.getOptionValue(Shell.CREATE_BUCKET); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); Path path = Paths.get(ozoneURI.getPath()); if (path.getNameCount() < 2) { throw new OzoneClientException( "volume and bucket name required in createBucket"); } - volumeName = path.getName(0).toString(); - bucketName = path.getName(1).toString(); + String volumeName = path.getName(0).toString(); + String bucketName = path.getName(1).toString(); - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Volume Name : %s%n", volumeName); System.out.printf("Bucket Name : %s%n", bucketName); } @@ -77,10 +66,11 @@ public class CreateBucketHandler extends Handler { OzoneVolume vol = client.getObjectStore().getVolume(volumeName); vol.createBucket(bucketName); - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { OzoneBucket bucket = vol.getBucket(bucketName); System.out.printf(JsonUtils.toJsonStringWithDefaultPrettyPrinter( JsonUtils.toJsonString(OzoneClientUtils.asBucketInfo(bucket)))); } + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/DeleteBucketHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/DeleteBucketHandler.java index 5fc443e632a..5a9b5c5a755 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/DeleteBucketHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/DeleteBucketHandler.java @@ -18,60 +18,51 @@ package org.apache.hadoop.ozone.web.ozShell.bucket; -import org.apache.commons.cli.CommandLine; -import org.apache.hadoop.ozone.client.OzoneVolume; +import java.net.URI; +import java.nio.file.Path; +import java.nio.file.Paths; + import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; +import org.apache.hadoop.ozone.client.OzoneVolume; import org.apache.hadoop.ozone.web.ozShell.Handler; import org.apache.hadoop.ozone.web.ozShell.Shell; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; +import picocli.CommandLine.Command; +import picocli.CommandLine.Parameters; /** * Delete bucket Handler. */ +@Command(name = "-deleteBucket", + description = "deletes an empty bucket") public class DeleteBucketHandler extends Handler { - private String volumeName; - private String bucketName; + + @Parameters(arity = "1..1", description = Shell.OZONE_BUCKET_URI_DESCRIPTION) + private String uri; /** * Executes the Client Calls. - * - * @param cmd - CommandLine - * - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { - if (!cmd.hasOption(Shell.DELETE_BUCKET)) { - throw new OzoneClientException( - "Incorrect call : deleteBucket is missing"); - } + public Void call() throws Exception { - String ozoneURIString = cmd.getOptionValue(Shell.DELETE_BUCKET); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); Path path = Paths.get(ozoneURI.getPath()); if (path.getNameCount() < 2) { throw new OzoneClientException( "volume and bucket name required in delete Bucket"); } - volumeName = path.getName(0).toString(); - bucketName = path.getName(1).toString(); + String volumeName = path.getName(0).toString(); + String bucketName = path.getName(1).toString(); - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Volume Name : %s%n", volumeName); System.out.printf("Bucket Name : %s%n", bucketName); } OzoneVolume vol = client.getObjectStore().getVolume(volumeName); vol.deleteBucket(bucketName); + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/InfoBucketHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/InfoBucketHandler.java index b3ca4e5565c..aa1ce8713aa 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/InfoBucketHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/InfoBucketHandler.java @@ -17,49 +17,38 @@ */ package org.apache.hadoop.ozone.web.ozShell.bucket; +import java.net.URI; +import java.nio.file.Path; +import java.nio.file.Paths; -import org.apache.commons.cli.CommandLine; import org.apache.hadoop.ozone.client.OzoneBucket; +import org.apache.hadoop.ozone.client.OzoneClientException; import org.apache.hadoop.ozone.client.OzoneClientUtils; import org.apache.hadoop.ozone.client.OzoneVolume; -import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; import org.apache.hadoop.ozone.web.ozShell.Handler; import org.apache.hadoop.ozone.web.ozShell.Shell; import org.apache.hadoop.ozone.web.utils.JsonUtils; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; +import picocli.CommandLine.Command; +import picocli.CommandLine.Parameters; /** * Executes Info bucket. */ +@Command(name = "-infoBucket", + description = "returns information about a bucket") public class InfoBucketHandler extends Handler { - private String volumeName; - private String bucketName; + + @Parameters(arity = "1..1", description = Shell.OZONE_BUCKET_URI_DESCRIPTION) + private String uri; /** * Executes the Client Calls. - * - * @param cmd - CommandLine - * - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { - if (!cmd.hasOption(Shell.INFO_BUCKET)) { - throw new OzoneClientException( - "Incorrect call : infoBucket is missing"); - } - - String ozoneURIString = cmd.getOptionValue(Shell.INFO_BUCKET); - URI ozoneURI = verifyURI(ozoneURIString); + public Void call() throws Exception { + String volumeName, bucketName; + URI ozoneURI = verifyURI(uri); Path path = Paths.get(ozoneURI.getPath()); if (path.getNameCount() < 2) { @@ -70,7 +59,7 @@ public class InfoBucketHandler extends Handler { volumeName = path.getName(0).toString(); bucketName = path.getName(1).toString(); - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Volume Name : %s%n", volumeName); System.out.printf("Bucket Name : %s%n", bucketName); } @@ -80,6 +69,7 @@ public class InfoBucketHandler extends Handler { System.out.printf("%s%n", JsonUtils.toJsonStringWithDefaultPrettyPrinter( JsonUtils.toJsonString(OzoneClientUtils.asBucketInfo(bucket)))); + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/ListBucketHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/ListBucketHandler.java index 655022ad1ea..3d429cf65fa 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/ListBucketHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/ListBucketHandler.java @@ -18,95 +18,91 @@ package org.apache.hadoop.ozone.web.ozShell.bucket; -import org.apache.commons.cli.CommandLine; -import org.apache.hadoop.ozone.client.OzoneBucket; -import org.apache.hadoop.ozone.client.OzoneClientUtils; -import org.apache.hadoop.ozone.client.OzoneVolume; -import org.apache.hadoop.ozone.client.rest.response.BucketInfo; -import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; -import org.apache.hadoop.ozone.web.ozShell.Handler; -import org.apache.hadoop.ozone.web.ozShell.Shell; -import org.apache.hadoop.ozone.web.utils.JsonUtils; -import org.apache.hadoop.ozone.web.utils.OzoneUtils; - -import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.apache.hadoop.ozone.client.OzoneBucket; +import org.apache.hadoop.ozone.client.OzoneClientException; +import org.apache.hadoop.ozone.client.OzoneClientUtils; +import org.apache.hadoop.ozone.client.OzoneVolume; +import org.apache.hadoop.ozone.client.rest.response.BucketInfo; +import org.apache.hadoop.ozone.web.ozShell.Handler; +import org.apache.hadoop.ozone.web.ozShell.Shell; +import org.apache.hadoop.ozone.web.utils.JsonUtils; + +import picocli.CommandLine.Command; +import picocli.CommandLine.Help.Visibility; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; + /** * Executes List Bucket. */ +@Command(name = "-listBucket", + description = "lists the buckets in a volume.") public class ListBucketHandler extends Handler { - private String volumeName; + @Parameters(arity = "1..1", description = Shell.OZONE_VOLUME_URI_DESCRIPTION) + private String uri; + + @Option(names = {"--length", "-length", "-l"}, + description = "Limit of the max results", + defaultValue = "100", + showDefaultValue = Visibility.ALWAYS) + private int maxBuckets; + + @Option(names = {"--start", "-start", "-s"}, + description = "The first bucket to start the listing") + private String startBucket; + + @Option(names = {"--prefix", "-prefix", "-p"}, + description = "Prefix to filter the buckets") + private String prefix; /** * Executes the Client Calls. - * - * @param cmd - CommandLine - * - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { - if (!cmd.hasOption(Shell.LIST_BUCKET)) { - throw new OzoneClientException( - "Incorrect call : listBucket is missing"); - } + public Void call() throws Exception { - String ozoneURIString = cmd.getOptionValue(Shell.LIST_BUCKET); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); Path path = Paths.get(ozoneURI.getPath()); if (path.getNameCount() < 1) { throw new OzoneClientException("volume is required in listBucket"); } - volumeName = path.getName(0).toString(); + if (maxBuckets < 1) { + throw new IllegalArgumentException( + "the length should be a positive number"); + } - if (cmd.hasOption(Shell.VERBOSE)) { + String volumeName = path.getName(0).toString(); + + if (isVerbose()) { System.out.printf("Volume Name : %s%n", volumeName); } - int maxBuckets = Integer.MAX_VALUE; - if (cmd.hasOption(Shell.LIST_LENGTH)) { - String length = cmd.getOptionValue(Shell.LIST_LENGTH); - OzoneUtils.verifyMaxKeyLength(length); - maxBuckets = Integer.parseInt(length); - } - - String startBucket = null; - if (cmd.hasOption(Shell.START)) { - startBucket = cmd.getOptionValue(Shell.START); - } - - String prefix = null; - if (cmd.hasOption(Shell.PREFIX)) { - prefix = cmd.getOptionValue(Shell.PREFIX); - } OzoneVolume vol = client.getObjectStore().getVolume(volumeName); Iterator bucketIterator = vol.listBuckets(prefix, startBucket); List bucketList = new ArrayList<>(); while (maxBuckets > 0 && bucketIterator.hasNext()) { - BucketInfo bucketInfo = OzoneClientUtils.asBucketInfo(bucketIterator.next()); + BucketInfo bucketInfo = + OzoneClientUtils.asBucketInfo(bucketIterator.next()); bucketList.add(bucketInfo); maxBuckets -= 1; } - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Found : %d buckets for volume : %s ", bucketList.size(), volumeName); } System.out.println(JsonUtils.toJsonStringWithDefaultPrettyPrinter( JsonUtils.toJsonString(bucketList))); + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/UpdateBucketHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/UpdateBucketHandler.java index aff0e19c5aa..3728740db82 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/UpdateBucketHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/bucket/UpdateBucketHandler.java @@ -17,43 +17,50 @@ */ package org.apache.hadoop.ozone.web.ozShell.bucket; -import org.apache.commons.cli.CommandLine; -import org.apache.hadoop.ozone.OzoneAcl; -import org.apache.hadoop.ozone.client.OzoneBucket; -import org.apache.hadoop.ozone.client.OzoneClientUtils; -import org.apache.hadoop.ozone.client.OzoneVolume; -import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; -import org.apache.hadoop.ozone.web.ozShell.Handler; -import org.apache.hadoop.ozone.web.ozShell.Shell; -import org.apache.hadoop.ozone.web.utils.JsonUtils; - -import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; +import org.apache.hadoop.ozone.OzoneAcl; +import org.apache.hadoop.ozone.client.OzoneBucket; +import org.apache.hadoop.ozone.client.OzoneClientException; +import org.apache.hadoop.ozone.client.OzoneClientUtils; +import org.apache.hadoop.ozone.client.OzoneVolume; +import org.apache.hadoop.ozone.web.ozShell.Handler; +import org.apache.hadoop.ozone.web.ozShell.Shell; +import org.apache.hadoop.ozone.web.utils.JsonUtils; + +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; + /** * Allows users to add and remove acls and from a bucket. */ +@Command(name = "-updateBucket", + description = "allows changing bucket attributes") public class UpdateBucketHandler extends Handler { - private String volumeName; - private String bucketName; + + @Parameters(arity = "1..1", description = Shell.OZONE_BUCKET_URI_DESCRIPTION) + private String uri; + + @Option(names = {"--addAcl", "-addAcl"}, + description = "Comma separated list of acl rules to add (eg. " + + "user:bilbo:rw)") + private String addAcl; + + @Option(names = {"--removeAcl", "-removeAcl"}, + description = "Comma separated list of acl rules to remove (eg. " + + "user:bilbo:rw)") + private String removeAcl; @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { - if (!cmd.hasOption(Shell.UPDATE_BUCKET)) { - throw new OzoneClientException( - "Incorrect call : updateBucket is missing"); - } + public Void call() throws Exception { - String ozoneURIString = cmd.getOptionValue(Shell.UPDATE_BUCKET); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); Path path = Paths.get(ozoneURI.getPath()); if (path.getNameCount() < 2) { @@ -61,28 +68,26 @@ public class UpdateBucketHandler extends Handler { "volume and bucket name required in update bucket"); } - volumeName = path.getName(0).toString(); - bucketName = path.getName(1).toString(); + String volumeName = path.getName(0).toString(); + String bucketName = path.getName(1).toString(); - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Volume Name : %s%n", volumeName); System.out.printf("Bucket Name : %s%n", bucketName); } OzoneVolume vol = client.getObjectStore().getVolume(volumeName); OzoneBucket bucket = vol.getBucket(bucketName); - if (cmd.hasOption(Shell.ADD_ACLS)) { - String aclString = cmd.getOptionValue(Shell.ADD_ACLS); - String[] aclArray = aclString.split(","); + if (addAcl != null) { + String[] aclArray = addAcl.split(","); List aclList = Arrays.stream(aclArray).map(acl -> OzoneAcl.parseAcl(acl)) .collect(Collectors.toList()); bucket.addAcls(aclList); } - if (cmd.hasOption(Shell.REMOVE_ACLS)) { - String aclString = cmd.getOptionValue(Shell.REMOVE_ACLS); - String[] aclArray = aclString.split(","); + if (removeAcl != null) { + String[] aclArray = removeAcl.split(","); List aclList = Arrays.stream(aclArray).map(acl -> OzoneAcl.parseAcl(acl)) .collect(Collectors.toList()); @@ -91,5 +96,6 @@ public class UpdateBucketHandler extends Handler { System.out.printf("%s%n", JsonUtils.toJsonStringWithDefaultPrettyPrinter( JsonUtils.toJsonString(OzoneClientUtils.asBucketInfo(bucket)))); + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/DeleteKeyHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/DeleteKeyHandler.java index fccabe7188a..8c9aab7ba09 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/DeleteKeyHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/DeleteKeyHandler.java @@ -18,58 +18,47 @@ package org.apache.hadoop.ozone.web.ozShell.keys; -import org.apache.commons.cli.CommandLine; +import java.net.URI; +import java.nio.file.Path; +import java.nio.file.Paths; + import org.apache.hadoop.ozone.client.OzoneBucket; -import org.apache.hadoop.ozone.client.OzoneVolume; import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; +import org.apache.hadoop.ozone.client.OzoneVolume; import org.apache.hadoop.ozone.web.ozShell.Handler; import org.apache.hadoop.ozone.web.ozShell.Shell; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; +import picocli.CommandLine.Command; +import picocli.CommandLine.Parameters; /** * Executes Delete Key. */ +@Command(name = "-deleteKey", + description = "deletes an existing key") public class DeleteKeyHandler extends Handler { - private String volumeName; - private String bucketName; - private String keyName; + + @Parameters(arity = "1..1", description = Shell.OZONE_KEY_URI_DESCRIPTION) + private String uri; /** * Executes the Client Calls. - * - * @param cmd - CommandLine - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { - if (!cmd.hasOption(Shell.DELETE_KEY)) { - throw new OzoneClientException( - "Incorrect call : deleteKey is missing"); - } + public Void call() throws Exception { - String ozoneURIString = cmd.getOptionValue(Shell.DELETE_KEY); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); Path path = Paths.get(ozoneURI.getPath()); if (path.getNameCount() < 3) { throw new OzoneClientException( "volume/bucket/key name required in deleteKey"); } - volumeName = path.getName(0).toString(); - bucketName = path.getName(1).toString(); - keyName = path.getName(2).toString(); + String volumeName = path.getName(0).toString(); + String bucketName = path.getName(1).toString(); + String keyName = path.getName(2).toString(); - - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Volume Name : %s%n", volumeName); System.out.printf("Bucket Name : %s%n", bucketName); System.out.printf("Key Name : %s%n", keyName); @@ -78,5 +67,6 @@ public class DeleteKeyHandler extends Handler { OzoneVolume vol = client.getObjectStore().getVolume(volumeName); OzoneBucket bucket = vol.getBucket(bucketName); bucket.deleteKey(keyName); + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/GetKeyHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/GetKeyHandler.java index 2d059e0c8c3..9843fd8a9e3 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/GetKeyHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/GetKeyHandler.java @@ -18,83 +18,67 @@ package org.apache.hadoop.ozone.web.ozShell.keys; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.hadoop.hdds.conf.OzoneConfiguration; -import org.apache.hadoop.io.IOUtils; -import org.apache.hadoop.ozone.client.OzoneBucket; -import org.apache.hadoop.ozone.client.OzoneVolume; -import org.apache.hadoop.ozone.client.io.OzoneInputStream; -import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; -import org.apache.hadoop.ozone.web.ozShell.Handler; -import org.apache.hadoop.ozone.web.ozShell.Shell; - import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; -import static org.apache.hadoop.hdds.scm.ScmConfigKeys - .OZONE_SCM_CHUNK_SIZE_DEFAULT; -import static org.apache.hadoop.hdds.scm.ScmConfigKeys - .OZONE_SCM_CHUNK_SIZE_KEY; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.apache.hadoop.io.IOUtils; +import org.apache.hadoop.ozone.client.OzoneBucket; +import org.apache.hadoop.ozone.client.OzoneClientException; +import org.apache.hadoop.ozone.client.OzoneVolume; +import org.apache.hadoop.ozone.client.io.OzoneInputStream; +import org.apache.hadoop.ozone.web.ozShell.Handler; +import org.apache.hadoop.ozone.web.ozShell.Shell; + +import org.apache.commons.codec.digest.DigestUtils; +import static org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_CHUNK_SIZE_DEFAULT; +import static org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_CHUNK_SIZE_KEY; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; /** * Gets an existing key. */ +@Command(name = "-getKey", + description = "Gets a specific key from ozone server") public class GetKeyHandler extends Handler { - private String volumeName; - private String bucketName; - private String keyName; + @Parameters(arity = "1..1", description = Shell.OZONE_KEY_URI_DESCRIPTION) + private String uri; + + @Option(names = {"-f", "--file", "-file"}, + description = "File path to download the key to", + required = true) + private String fileName; /** * Executes the Client Calls. - * - * @param cmd - CommandLine - * - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { - if (!cmd.hasOption(Shell.GET_KEY)) { - throw new OzoneClientException("Incorrect call : getKey is missing"); - } + public Void call() throws Exception { - if (!cmd.hasOption(Shell.FILE)) { - throw new OzoneClientException( - "get key needs a file path to download to"); - } - - String ozoneURIString = cmd.getOptionValue(Shell.GET_KEY); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); Path path = Paths.get(ozoneURI.getPath()); if (path.getNameCount() < 3) { throw new OzoneClientException( "volume/bucket/key name required in putKey"); } - volumeName = path.getName(0).toString(); - bucketName = path.getName(1).toString(); - keyName = path.getName(2).toString(); + String volumeName = path.getName(0).toString(); + String bucketName = path.getName(1).toString(); + String keyName = path.getName(2).toString(); - - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Volume Name : %s%n", volumeName); System.out.printf("Bucket Name : %s%n", bucketName); System.out.printf("Key Name : %s%n", keyName); } - - String fileName = cmd.getOptionValue(Shell.FILE); Path dataFilePath = Paths.get(fileName); File dataFile = new File(fileName); @@ -120,12 +104,12 @@ public class GetKeyHandler extends Handler { throw new OzoneClientException( "Can not access the file \"" + fileName + "\""); } - if(cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { FileInputStream stream = new FileInputStream(dataFile); String hash = DigestUtils.md5Hex(stream); System.out.printf("Downloaded file hash : %s%n", hash); stream.close(); } - + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/InfoKeyHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/InfoKeyHandler.java index 53a3264db90..18c75911f29 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/InfoKeyHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/InfoKeyHandler.java @@ -18,61 +18,55 @@ package org.apache.hadoop.ozone.web.ozShell.keys; -import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; -import org.apache.commons.cli.CommandLine; import org.apache.hadoop.ozone.OzoneConsts; -import org.apache.hadoop.ozone.client.*; -import org.apache.hadoop.ozone.client.rest.OzoneException; +import org.apache.hadoop.ozone.client.OzoneBucket; +import org.apache.hadoop.ozone.client.OzoneClientException; +import org.apache.hadoop.ozone.client.OzoneClientUtils; +import org.apache.hadoop.ozone.client.OzoneKeyDetails; +import org.apache.hadoop.ozone.client.OzoneVolume; import org.apache.hadoop.ozone.web.ozShell.Handler; import org.apache.hadoop.ozone.web.ozShell.Shell; import org.apache.hadoop.ozone.web.utils.JsonUtils; +import picocli.CommandLine.Command; +import picocli.CommandLine.Parameters; + /** * Executes Info Object. */ +@Command(name = "-infoKey", + description = "returns information about an existing key") public class InfoKeyHandler extends Handler { - private String volumeName; - private String bucketName; - private String keyName; + @Parameters(arity = "1..1", description = Shell.OZONE_KEY_URI_DESCRIPTION) + private String uri; /** * Executes the Client Calls. - * - * @param cmd - CommandLine - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { - if (!cmd.hasOption(Shell.INFO_KEY)) { - throw new OzoneClientException("Incorrect call : infoKey is missing"); - } - - String ozoneURIString = cmd.getOptionValue(Shell.INFO_KEY); - URI ozoneURI = verifyURI(ozoneURIString); + public Void call() throws Exception { + URI ozoneURI = verifyURI(uri); Path path = Paths.get(ozoneURI.getPath()); if (path.getNameCount() < 3) { throw new OzoneClientException( "volume/bucket/key name required in infoKey"); } - volumeName = path.getName(0).toString(); - bucketName = path.getName(1).toString(); + String volumeName = path.getName(0).toString(); + String bucketName = path.getName(1).toString(); String searchString = volumeName + OzoneConsts.OZONE_URI_DELIMITER + bucketName + OzoneConsts.OZONE_URI_DELIMITER; - keyName = ozoneURIString.substring(ozoneURIString.indexOf(searchString) + + String keyName = + uri.substring(uri.indexOf(searchString) + searchString.length()); - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Volume Name : %s%n", volumeName); System.out.printf("Bucket Name : %s%n", bucketName); System.out.printf("Key Name : %s%n", keyName); @@ -84,5 +78,6 @@ public class InfoKeyHandler extends Handler { System.out.printf("%s%n", JsonUtils.toJsonStringWithDefaultPrettyPrinter( JsonUtils.toJsonString(OzoneClientUtils.asKeyInfoDetails(key)))); + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/ListKeyHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/ListKeyHandler.java index 6e266fd3bee..f69693dc2f7 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/ListKeyHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/ListKeyHandler.java @@ -18,78 +18,72 @@ package org.apache.hadoop.ozone.web.ozShell.keys; -import org.apache.commons.cli.CommandLine; -import org.apache.hadoop.ozone.client.*; -import org.apache.hadoop.ozone.client.rest.response.KeyInfo; -import org.apache.hadoop.ozone.client.rest.OzoneException; -import org.apache.hadoop.ozone.web.ozShell.Handler; -import org.apache.hadoop.ozone.web.ozShell.Shell; -import org.apache.hadoop.ozone.web.utils.JsonUtils; -import org.apache.hadoop.ozone.web.utils.OzoneUtils; - -import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.apache.hadoop.ozone.client.OzoneBucket; +import org.apache.hadoop.ozone.client.OzoneClientException; +import org.apache.hadoop.ozone.client.OzoneClientUtils; +import org.apache.hadoop.ozone.client.OzoneKey; +import org.apache.hadoop.ozone.client.OzoneVolume; +import org.apache.hadoop.ozone.client.rest.response.KeyInfo; +import org.apache.hadoop.ozone.web.ozShell.Handler; +import org.apache.hadoop.ozone.web.ozShell.Shell; +import org.apache.hadoop.ozone.web.utils.JsonUtils; + +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; + /** * Executes List Keys. */ +@Command(name = "-listKey", + description = "list all keys in a given bucket") public class ListKeyHandler extends Handler { - private String volumeName; - private String bucketName; + + @Parameters(arity = "1..1", description = Shell.OZONE_BUCKET_URI_DESCRIPTION) + private String uri; + + @Option(names = {"--length", "-length", "-l"}, + description = "Limit of the max results", + defaultValue = "100") + private int maxKeys; + + @Option(names = {"--start", "-start", "-s"}, + description = "The first key to start the listing") + private String startKey; + + @Option(names = {"--prefix", "-prefix", "-p"}, + description = "Prefix to filter the key") + private String prefix; /** * Executes the Client Calls. - * - * @param cmd - CommandLine - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { + public Void call() throws Exception { - if (!cmd.hasOption(Shell.LIST_KEY)) { - throw new OzoneClientException( - "Incorrect call : listKey is missing"); - } - - int maxKeys = Integer.MAX_VALUE; - if (cmd.hasOption(Shell.LIST_LENGTH)) { - String length = cmd.getOptionValue(Shell.LIST_LENGTH); - OzoneUtils.verifyMaxKeyLength(length); - maxKeys = Integer.parseInt(length); - } - - String startKey = null; - if (cmd.hasOption(Shell.START)) { - startKey = cmd.getOptionValue(Shell.START); - } - - String prefix = null; - if (cmd.hasOption(Shell.PREFIX)) { - prefix = cmd.getOptionValue(Shell.PREFIX); - } - - String ozoneURIString = cmd.getOptionValue(Shell.LIST_KEY); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); Path path = Paths.get(ozoneURI.getPath()); if (path.getNameCount() < 2) { throw new OzoneClientException( "volume/bucket is required in listKey"); } - volumeName = path.getName(0).toString(); - bucketName = path.getName(1).toString(); + if (maxKeys < 1) { + throw new IllegalArgumentException( + "the length should be a positive number"); + } + String volumeName = path.getName(0).toString(); + String bucketName = path.getName(1).toString(); - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Volume Name : %s%n", volumeName); System.out.printf("bucket Name : %s%n", bucketName); } @@ -105,12 +99,13 @@ public class ListKeyHandler extends Handler { maxKeys -= 1; } - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Found : %d keys for bucket %s in volume : %s ", keyInfos.size(), bucketName, volumeName); } System.out.println(JsonUtils.toJsonStringWithDefaultPrettyPrinter( JsonUtils.toJsonString(keyInfos))); + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/PutKeyHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/PutKeyHandler.java index c73307dd823..bea68f21c9b 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/PutKeyHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/keys/PutKeyHandler.java @@ -18,86 +18,80 @@ package org.apache.hadoop.ozone.web.ozShell.keys; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hdds.conf.OzoneConfiguration; -import org.apache.hadoop.io.IOUtils; -import org.apache.hadoop.ozone.client.OzoneBucket; -import org.apache.hadoop.ozone.client.OzoneVolume; -import org.apache.hadoop.hdds.client.ReplicationFactor; -import org.apache.hadoop.hdds.client.ReplicationType; -import org.apache.hadoop.ozone.client.io.OzoneOutputStream; -import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; -import org.apache.hadoop.ozone.web.ozShell.Handler; -import org.apache.hadoop.ozone.web.ozShell.Shell; - import java.io.File; import java.io.FileInputStream; -import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hdds.client.ReplicationFactor; +import org.apache.hadoop.hdds.client.ReplicationType; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.apache.hadoop.io.IOUtils; +import org.apache.hadoop.ozone.client.OzoneBucket; +import org.apache.hadoop.ozone.client.OzoneClientException; +import org.apache.hadoop.ozone.client.OzoneVolume; +import org.apache.hadoop.ozone.client.io.OzoneOutputStream; +import org.apache.hadoop.ozone.web.ozShell.Handler; +import org.apache.hadoop.ozone.web.ozShell.Shell; + +import org.apache.commons.codec.digest.DigestUtils; import static org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_CHUNK_SIZE_DEFAULT; import static org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_CHUNK_SIZE_KEY; import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_REPLICATION; import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_REPLICATION_DEFAULT; import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_REPLICATION_TYPE; import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_REPLICATION_TYPE_DEFAULT; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; /** * Puts a file into an ozone bucket. */ +@Command(name = "-putKey", + description = "creates or overwrites an existing key") public class PutKeyHandler extends Handler { - private String volumeName; - private String bucketName; - private String keyName; + @Parameters(arity = "1..1", description = Shell.OZONE_KEY_URI_DESCRIPTION) + private String uri; + + @Option(names = {"-f", "--file", "-file"}, + description = "File to upload", + required = true) + private String fileName; + + @Option(names = {"-r", "--replication", "-replicationFactor"}, + description = "Replication factor of the new key. (use ONE or THREE) " + + "Default is specified in the cluster-wide config.") + private ReplicationFactor replicationFactor; /** * Executes the Client Calls. - * - * @param cmd - CommandLine - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { - if (!cmd.hasOption(Shell.PUT_KEY)) { - throw new OzoneClientException("Incorrect call : putKey is missing"); - } + public Void call() throws Exception { - if (!cmd.hasOption(Shell.FILE)) { - throw new OzoneClientException("put key needs a file to put"); - } - - String ozoneURIString = cmd.getOptionValue(Shell.PUT_KEY); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); Path path = Paths.get(ozoneURI.getPath()); if (path.getNameCount() < 3) { throw new OzoneClientException( "volume/bucket/key name required in putKey"); } - volumeName = path.getName(0).toString(); - bucketName = path.getName(1).toString(); - keyName = path.getName(2).toString(); + String volumeName = path.getName(0).toString(); + String bucketName = path.getName(1).toString(); + String keyName = path.getName(2).toString(); - - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Volume Name : %s%n", volumeName); System.out.printf("Bucket Name : %s%n", bucketName); System.out.printf("Key Name : %s%n", keyName); } - String fileName = cmd.getOptionValue(Shell.FILE); File dataFile = new File(fileName); - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { FileInputStream stream = new FileInputStream(dataFile); String hash = DigestUtils.md5Hex(stream); System.out.printf("File Hash : %s%n", hash); @@ -105,11 +99,7 @@ public class PutKeyHandler extends Handler { } Configuration conf = new OzoneConfiguration(); - ReplicationFactor replicationFactor; - if (cmd.hasOption(Shell.REPLICATION_FACTOR)) { - replicationFactor = ReplicationFactor.valueOf(Integer.parseInt(cmd - .getOptionValue(Shell.REPLICATION_FACTOR))); - } else { + if (replicationFactor == null) { replicationFactor = ReplicationFactor.valueOf( conf.getInt(OZONE_REPLICATION, OZONE_REPLICATION_DEFAULT)); } @@ -126,6 +116,7 @@ public class PutKeyHandler extends Handler { conf.getInt(OZONE_SCM_CHUNK_SIZE_KEY, OZONE_SCM_CHUNK_SIZE_DEFAULT)); outputStream.close(); fileInputStream.close(); + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/CreateVolumeHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/CreateVolumeHandler.java index 0057282631d..25e207a8224 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/CreateVolumeHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/CreateVolumeHandler.java @@ -18,77 +18,72 @@ package org.apache.hadoop.ozone.web.ozShell.volume; -import org.apache.commons.cli.CommandLine; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; + import org.apache.hadoop.ozone.client.OzoneClientUtils; import org.apache.hadoop.ozone.client.OzoneVolume; import org.apache.hadoop.ozone.client.VolumeArgs; import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; import org.apache.hadoop.ozone.web.ozShell.Handler; import org.apache.hadoop.ozone.web.ozShell.Shell; import org.apache.hadoop.ozone.web.utils.JsonUtils; -import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; /** * Executes the create volume call for the shell. */ +@Command(name = "-createVolume", + description = "Creates a volume for the specified user") public class CreateVolumeHandler extends Handler { - private String rootName; + @Parameters(arity = "1..1", description = Shell.OZONE_VOLUME_URI_DESCRIPTION) + private String uri; + + @Option(names = {"--user", "-user"}, + description = "Owner of of the volume", required = + true) private String userName; - private String volumeName; + + @Option(names = {"--quota", "-quota"}, + description = + "Quota of the newly created volume (eg. 1G)") private String quota; + @Option(names = {"--root", "-root"}, + description = "Development flag to execute the " + + "command as the admin (hdfs) user.") + private boolean root; + /** * Executes the Create Volume. - * - * @param cmd - CommandLine - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { - if (!cmd.hasOption(Shell.CREATE_VOLUME)) { - throw new OzoneClientException( - "Incorrect call : createVolume is missing"); - } + public Void call() throws Exception { - String ozoneURIString = cmd.getOptionValue(Shell.CREATE_VOLUME); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); // we need to skip the slash in the URI path // getPath returns /volumeName needs to remove the initial slash. - volumeName = ozoneURI.getPath().replaceAll("^/+", ""); + String volumeName = ozoneURI.getPath().replaceAll("^/+", ""); if (volumeName.isEmpty()) { throw new OzoneClientException( "Volume name is required to create a volume"); } - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Volume name : %s%n", volumeName); } - if (cmd.hasOption(Shell.RUNAS)) { + + String rootName; + if (root) { rootName = "hdfs"; } else { rootName = System.getProperty("user.name"); } - if (!cmd.hasOption(Shell.USER)) { - throw new OzoneClientException( - "User name is needed in createVolume call."); - } - - if (cmd.hasOption(Shell.QUOTA)) { - quota = cmd.getOptionValue(Shell.QUOTA); - } - - userName = cmd.getOptionValue(Shell.USER); - VolumeArgs.Builder volumeArgsBuilder = VolumeArgs.newBuilder() .setAdmin(rootName) .setOwner(userName); @@ -97,11 +92,13 @@ public class CreateVolumeHandler extends Handler { } client.getObjectStore().createVolume(volumeName, volumeArgsBuilder.build()); - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { OzoneVolume vol = client.getObjectStore().getVolume(volumeName); System.out.printf("%s%n", JsonUtils.toJsonStringWithDefaultPrettyPrinter( JsonUtils.toJsonString(OzoneClientUtils.asVolumeInfo(vol)))); } + return null; } + } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/DeleteVolumeHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/DeleteVolumeHandler.java index 2df788a9371..e6444e7c9e8 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/DeleteVolumeHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/DeleteVolumeHandler.java @@ -18,55 +18,46 @@ package org.apache.hadoop.ozone.web.ozShell.volume; -import org.apache.commons.cli.CommandLine; +import java.net.URI; + import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; import org.apache.hadoop.ozone.web.ozShell.Handler; import org.apache.hadoop.ozone.web.ozShell.Shell; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; +import picocli.CommandLine.Command; +import picocli.CommandLine.Parameters; /** * Executes deleteVolume call for the shell. */ +@Command(name = "-deleteVolume", + description = "deletes a volume if it is empty") public class DeleteVolumeHandler extends Handler { - private String volumeName; + @Parameters(arity = "1..1", description = Shell.OZONE_VOLUME_URI_DESCRIPTION) + private String uri; /** * Executes the delete volume call. - * - * @param cmd - CommandLine - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { + public Void call() throws Exception { - if (!cmd.hasOption(Shell.DELETE_VOLUME)) { - throw new OzoneClientException( - "Incorrect call : deleteVolume call is missing"); - } - - String ozoneURIString = cmd.getOptionValue(Shell.DELETE_VOLUME); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); if (ozoneURI.getPath().isEmpty()) { throw new OzoneClientException( "Volume name is required to delete a volume"); } // we need to skip the slash in the URI path - volumeName = ozoneURI.getPath().substring(1); + String volumeName = ozoneURI.getPath().substring(1); - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Volume name : %s%n", volumeName); } client.getObjectStore().deleteVolume(volumeName); System.out.printf("Volume %s is deleted%n", volumeName); + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/InfoVolumeHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/InfoVolumeHandler.java index b5be2c65e38..9ee3dcec04d 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/InfoVolumeHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/InfoVolumeHandler.java @@ -18,56 +18,47 @@ package org.apache.hadoop.ozone.web.ozShell.volume; -import org.apache.commons.cli.CommandLine; +import java.net.URI; + +import org.apache.hadoop.ozone.client.OzoneClientException; import org.apache.hadoop.ozone.client.OzoneClientUtils; import org.apache.hadoop.ozone.client.OzoneVolume; -import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; import org.apache.hadoop.ozone.web.ozShell.Handler; import org.apache.hadoop.ozone.web.ozShell.Shell; import org.apache.hadoop.ozone.web.utils.JsonUtils; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; +import picocli.CommandLine.Command; +import picocli.CommandLine.Parameters; /** * Executes volume Info calls. */ +@Command(name = "-infoVolume", + description = "returns information about a specific volume") public class InfoVolumeHandler extends Handler{ - private String volumeName; + @Parameters(arity = "1..1", description = Shell.OZONE_VOLUME_URI_DESCRIPTION) + private String uri; /** * Executes volume Info. - * - * @param cmd - CommandLine - * - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { + public Void call() throws Exception { - if (!cmd.hasOption(Shell.INFO_VOLUME)) { - throw new OzoneClientException( - "Incorrect call : infoVolume is missing"); - } - - String ozoneURIString = cmd.getOptionValue(Shell.INFO_VOLUME); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); if (ozoneURI.getPath().isEmpty()) { throw new OzoneClientException( "Volume name is required to get info of a volume"); } // we need to skip the slash in the URI path - volumeName = ozoneURI.getPath().substring(1); + String volumeName = ozoneURI.getPath().substring(1); OzoneVolume vol = client.getObjectStore().getVolume(volumeName); System.out.printf("%s%n", JsonUtils.toJsonStringWithDefaultPrettyPrinter( JsonUtils.toJsonString(OzoneClientUtils.asVolumeInfo(vol)))); + return null; } + } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/ListVolumeHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/ListVolumeHandler.java index 85b7b2b2fdb..058ef2e7164 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/ListVolumeHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/ListVolumeHandler.java @@ -19,20 +19,19 @@ package org.apache.hadoop.ozone.web.ozShell.volume; import com.google.common.base.Strings; -import org.apache.commons.cli.CommandLine; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; + import org.apache.hadoop.ozone.client.OzoneClientUtils; import org.apache.hadoop.ozone.client.OzoneVolume; import org.apache.hadoop.ozone.client.rest.response.VolumeInfo; import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; import org.apache.hadoop.ozone.web.ozShell.Handler; import org.apache.hadoop.ozone.web.ozShell.Shell; import org.apache.hadoop.ozone.web.utils.JsonUtils; -import org.apache.hadoop.ozone.web.utils.OzoneUtils; -import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -40,49 +39,39 @@ import java.util.List; /** * Executes List Volume call. */ +@Command(name = "-listVolume", + description = "List the volumes of a given user") public class ListVolumeHandler extends Handler { + + @Parameters(arity = "1..1", + description = Shell.OZONE_VOLUME_URI_DESCRIPTION, + defaultValue = "/") + private String uri; + + @Option(names = {"--length", "-length", "-l"}, + description = "Limit of the max results", + defaultValue = "100") + private int maxVolumes; + + @Option(names = {"--start", "-start", "-s"}, + description = "The first volume to start the listing") + private String startVolume; + + @Option(names = {"--prefix", "-prefix", "-p"}, + description = "Prefix to filter the volumes") + private String prefix; + + @Option(names = {"--user", "-user", "-u"}, + description = "Owner of the volumes to list.") private String userName; /** * Executes the Client Calls. - * - * @param cmd - CommandLine - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { + public Void call() throws Exception { - if (!cmd.hasOption(Shell.LIST_VOLUME)) { - throw new OzoneClientException( - "Incorrect call : listVolume is missing"); - } - - int maxVolumes = Integer.MAX_VALUE; - if (cmd.hasOption(Shell.LIST_LENGTH)) { - String length = cmd.getOptionValue(Shell.LIST_LENGTH); - OzoneUtils.verifyMaxKeyLength(length); - - maxVolumes = Integer.parseInt(length); - } - - String startVolume = null; - if (cmd.hasOption(Shell.START)) { - startVolume = cmd.getOptionValue(Shell.START); - } - - String prefix = null; - if (cmd.hasOption(Shell.PREFIX)) { - prefix = cmd.getOptionValue(Shell.PREFIX); - } - - String ozoneURIString = cmd.getOptionValue(Shell.LIST_VOLUME); - if (Strings.isNullOrEmpty(ozoneURIString)) { - ozoneURIString = "/"; - } - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); if (!Strings.isNullOrEmpty(ozoneURI.getPath()) && !ozoneURI.getPath() .equals("/")) { throw new OzoneClientException( @@ -90,12 +79,15 @@ public class ListVolumeHandler extends Handler { .getPath()); } - if (cmd.hasOption(Shell.USER)) { - userName = cmd.getOptionValue(Shell.USER); - } else { + if (userName == null) { userName = System.getProperty("user.name"); } + if (maxVolumes < 1) { + throw new IllegalArgumentException( + "the length should be a positive number"); + } + Iterator volumeIterator; if(userName != null) { volumeIterator = client.getObjectStore() @@ -112,12 +104,13 @@ public class ListVolumeHandler extends Handler { maxVolumes -= 1; } - if (cmd.hasOption(Shell.VERBOSE)) { + if (isVerbose()) { System.out.printf("Found : %d volumes for user : %s ", volumeInfos.size(), userName); } System.out.println(JsonUtils.toJsonStringWithDefaultPrettyPrinter( JsonUtils.toJsonString(volumeInfos))); + return null; } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/UpdateVolumeHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/UpdateVolumeHandler.java index 3738cb4a4e3..aa692bd8c7e 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/UpdateVolumeHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/web/ozShell/volume/UpdateVolumeHandler.java @@ -18,61 +18,53 @@ package org.apache.hadoop.ozone.web.ozShell.volume; -import org.apache.commons.cli.CommandLine; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import picocli.CommandLine.Parameters; + import org.apache.hadoop.hdds.client.OzoneQuota; import org.apache.hadoop.ozone.client.OzoneVolume; import org.apache.hadoop.ozone.client.OzoneClientUtils; import org.apache.hadoop.ozone.client.OzoneClientException; -import org.apache.hadoop.ozone.client.rest.OzoneException; import org.apache.hadoop.ozone.web.ozShell.Handler; import org.apache.hadoop.ozone.web.ozShell.Shell; import org.apache.hadoop.ozone.web.utils.JsonUtils; -import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; /** * Executes update volume calls. */ +@Command(name = "-updateVolume", + description = "Updates parameter of the volumes") public class UpdateVolumeHandler extends Handler { + + @Parameters(arity = "1..1", description = Shell.OZONE_VOLUME_URI_DESCRIPTION) + private String uri; + + @Option(names = {"--user", "-user"}, + description = "Owner of the volume to set") private String ownerName; - private String volumeName; + + @Option(names = {"--quota", "-quota"}, + description = "Quota of the volume to set" + + "(eg. 1G)") private String quota; /** - * Executes update volume calls. - * - * @param cmd - CommandLine - * @throws IOException - * @throws OzoneException - * @throws URISyntaxException + * Executes the Client Calls. */ @Override - protected void execute(CommandLine cmd) - throws IOException, OzoneException, URISyntaxException { - if (!cmd.hasOption(Shell.UPDATE_VOLUME)) { - throw new OzoneClientException( - "Incorrect call : updateVolume is missing"); - } + public Void call() throws Exception { - String ozoneURIString = cmd.getOptionValue(Shell.UPDATE_VOLUME); - URI ozoneURI = verifyURI(ozoneURIString); + URI ozoneURI = verifyURI(uri); if (ozoneURI.getPath().isEmpty()) { throw new OzoneClientException( "Volume name is required to update a volume"); } // we need to skip the slash in the URI path - volumeName = ozoneURI.getPath().substring(1); - - if (cmd.hasOption(Shell.QUOTA)) { - quota = cmd.getOptionValue(Shell.QUOTA); - } - - if (cmd.hasOption(Shell.USER)) { - ownerName = cmd.getOptionValue(Shell.USER); - } + String volumeName = ozoneURI.getPath().substring(1); OzoneVolume volume = client.getObjectStore().getVolume(volumeName); if (quota != null && !quota.isEmpty()) { @@ -85,5 +77,6 @@ public class UpdateVolumeHandler extends Handler { System.out.printf("%s%n", JsonUtils.toJsonStringWithDefaultPrettyPrinter( JsonUtils.toJsonString(OzoneClientUtils.asVolumeInfo(volume)))); + return null; } }