HDDS-190. Improve shell error message for unrecognized option.

Contributed by Elek, Marton.
This commit is contained in:
Anu Engineer 2018-09-07 12:53:46 -07:00
parent 410dd3faa5
commit 73fcbdd296
19 changed files with 628 additions and 988 deletions

View File

@ -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<Void> {
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<Void> {
}
return ozoneConf;
}
public boolean isVerbose() {
return verbose;
}
@VisibleForTesting
public picocli.CommandLine getCmd() {
return cmd;
}
}

View File

@ -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<String> arguments = new ArrayList(Arrays.asList(args));
LOG.info("Executing shell command with args {}", arguments);
CommandLine cmd = shell.getCmd();
IExceptionHandler2<List<Object>> exceptionHandler =
new IExceptionHandler2<List<Object>>() {
@Override
public List<Object> handleParseException(ParameterException ex,
String[] args) {
throw ex;
}
@Override
public List<Object> 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<VolumeInfo>) 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<VolumeInfo>) 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<VolumeInfo>) 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<VolumeInfo>) 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<BucketInfo>) 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<BucketInfo>) 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<BucketInfo>) 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<BucketInfo>) 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<KeyInfo>) 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<KeyInfo>) 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<KeyInfo>) 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<KeyInfo>) 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;

View File

@ -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<Void> {
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();
}
}

View File

@ -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 " +
"<volumeURI> -root -user <userName>\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 <volumeURI>" +
" -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 <ozoneURI>" +
"-user <username> -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 <volumeURI> -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 <bucketURI>");
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 <bucketURI> " +
"-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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<OzoneBucket> bucketIterator = vol.listBuckets(prefix, startBucket);
List<BucketInfo> 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;
}
}

View File

@ -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<OzoneAcl> 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<OzoneAcl> 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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<OzoneVolume> 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;
}
}

View File

@ -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;
}
}