sadanand48 commented on code in PR #4675:
URL: https://github.com/apache/ozone/pull/4675#discussion_r1188895412
##########
hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/keys/DeleteKeyHandler.java:
##########
@@ -45,6 +64,81 @@ protected void execute(OzoneClient client, OzoneAddress
address)
OzoneVolume vol = client.getObjectStore().getVolume(volumeName);
OzoneBucket bucket = vol.getBucket(bucketName);
- bucket.deleteKey(keyName);
+
+ float hadoopTrashInterval = getConf().getFloat(
+ FS_TRASH_INTERVAL_KEY, FS_TRASH_INTERVAL_DEFAULT);
+
+ long trashInterval =
+ (long) (getConf().getFloat(
+ OMConfigKeys.OZONE_FS_TRASH_INTERVAL_KEY,
+ hadoopTrashInterval) * 10000);
+
+ // If Bucket layout is FSO and Trash is enabled
+ // In this case during delete operation move key to trash
+ if (bucket.getBucketLayout().isFileSystemOptimized() && trashInterval > 0
+ && !skipTrash && !keyName.contains(".Trash")) {
+
+ keyName = OzoneFSUtils.removeTrailingSlashIfNeeded(keyName);
+ try {
+ // Check if key exists in Ozone
+ OzoneKeyDetails key = bucket.getKey(keyName);
+ if (key == null) {
+ out().printf("Key not found %s", keyName);
+ return;
+ }
+ // Check whether directory is empty or not
+ Iterator<? extends OzoneKey> ozoneKeyIterator =
+ bucket.listKeys(keyName, keyName);
+ int count = 0;
+ while (ozoneKeyIterator.hasNext()) {
+ ozoneKeyIterator.next();
+ if (++count > 1) {
+ // Assume FSO Tree: /a/b1/c1/k1.txt
+ // And we are trying to delete key /a/b1/c1
+ // In this case count is 2 which is greater than 1
+ // /a/b1/c1/ and /a/b1/c1/k1.txt
+ out().printf("Directory is not empty");
+ return;
+ }
+ }
+ } catch (Exception e) {
+ out().printf("Key not found %s", keyName);
+ return;
+ }
+
+ final String username =
+ UserGroupInformation.getCurrentUser().getShortUserName();
+ Path trashRoot = new Path(OZONE_URI_DELIMITER, TRASH_PREFIX);
+ Path userTrash = new Path(trashRoot, username);
+ Path userTrashCurrent = new Path(userTrash, CURRENT);
+
+ String trashDirectory = (keyName.contains("/")
+ ? new Path(userTrashCurrent, keyName.substring(0,
+ keyName.lastIndexOf("/")))
+ : userTrashCurrent).toUri().getPath();
+
+ String toKeyName = new Path(userTrashCurrent, keyName).toUri().getPath();
+ OzoneKeyDetails toKeyDetails = null;
+ try {
+ // check whether key already exist in trash
+ toKeyDetails = bucket.getKey(toKeyName);
+ } catch (IOException e) {
+ // Key doesn't exist inside trash.
+ }
+
+ if (toKeyDetails != null) {
+ // if key(directory) already exist in trash, just delete the key
+ bucket.deleteKey(keyName);
+ return;
+ }
+ // Create directory inside trash
+ bucket.createDirectory(trashDirectory);
Review Comment:
Ok, what happens if the trashDirectory already exists here. doesn't it
throw directory already exists or some error. We could check for existence here.
##########
hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/keys/DeleteKeyHandler.java:
##########
@@ -35,16 +47,110 @@
description = "deletes an existing key")
public class DeleteKeyHandler extends KeyHandler {
+ @CommandLine.Option(names = "--skipTrash",
+ description = "Specify whether to skip Trash ")
+ private boolean skipTrash = false;
+
+ private static final Path CURRENT = new Path("Current");
+
@Override
protected void execute(OzoneClient client, OzoneAddress address)
throws IOException, OzoneClientException {
String volumeName = address.getVolumeName();
String bucketName = address.getBucketName();
+ OzoneVolume vol = client.getObjectStore().getVolume(volumeName);
+ OzoneBucket bucket = vol.getBucket(bucketName);
+ String keyName = address.getKeyName();
+
+ if (bucket.getBucketLayout().isFileSystemOptimized()) {
+ // Handle FSO delete key which supports trash also
+ deleteFSOKey(client, address);
+ } else {
+ bucket.deleteKey(keyName);
+ }
+ }
+
+ private void deleteFSOKey(OzoneClient client, OzoneAddress address)
Review Comment:
minor nit : deleteFSOKey(OzoneBucket bucket, String keyName)
##########
hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/keys/DeleteKeyHandler.java:
##########
@@ -45,6 +64,81 @@ protected void execute(OzoneClient client, OzoneAddress
address)
OzoneVolume vol = client.getObjectStore().getVolume(volumeName);
OzoneBucket bucket = vol.getBucket(bucketName);
- bucket.deleteKey(keyName);
+
+ float hadoopTrashInterval = getConf().getFloat(
+ FS_TRASH_INTERVAL_KEY, FS_TRASH_INTERVAL_DEFAULT);
+
+ long trashInterval =
+ (long) (getConf().getFloat(
+ OMConfigKeys.OZONE_FS_TRASH_INTERVAL_KEY,
+ hadoopTrashInterval) * 10000);
+
+ // If Bucket layout is FSO and Trash is enabled
+ // In this case during delete operation move key to trash
+ if (bucket.getBucketLayout().isFileSystemOptimized() && trashInterval > 0
+ && !skipTrash && !keyName.contains(".Trash")) {
+
+ keyName = OzoneFSUtils.removeTrailingSlashIfNeeded(keyName);
+ try {
+ // Check if key exists in Ozone
+ OzoneKeyDetails key = bucket.getKey(keyName);
+ if (key == null) {
+ out().printf("Key not found %s", keyName);
+ return;
+ }
+ // Check whether directory is empty or not
+ Iterator<? extends OzoneKey> ozoneKeyIterator =
+ bucket.listKeys(keyName, keyName);
+ int count = 0;
+ while (ozoneKeyIterator.hasNext()) {
+ ozoneKeyIterator.next();
+ if (++count > 1) {
+ // Assume FSO Tree: /a/b1/c1/k1.txt
+ // And we are trying to delete key /a/b1/c1
+ // In this case count is 2 which is greater than 1
+ // /a/b1/c1/ and /a/b1/c1/k1.txt
+ out().printf("Directory is not empty");
+ return;
+ }
+ }
+ } catch (Exception e) {
+ out().printf("Key not found %s", keyName);
+ return;
+ }
+
+ final String username =
+ UserGroupInformation.getCurrentUser().getShortUserName();
+ Path trashRoot = new Path(OZONE_URI_DELIMITER, TRASH_PREFIX);
+ Path userTrash = new Path(trashRoot, username);
+ Path userTrashCurrent = new Path(userTrash, CURRENT);
+
+ String trashDirectory = (keyName.contains("/")
+ ? new Path(userTrashCurrent, keyName.substring(0,
+ keyName.lastIndexOf("/")))
+ : userTrashCurrent).toUri().getPath();
+
+ String toKeyName = new Path(userTrashCurrent, keyName).toUri().getPath();
+ OzoneKeyDetails toKeyDetails = null;
+ try {
+ // check whether key already exist in trash
+ toKeyDetails = bucket.getKey(toKeyName);
+ } catch (IOException e) {
+ // Key doesn't exist inside trash.
+ }
+
+ if (toKeyDetails != null) {
+ // if key(directory) already exist in trash, just delete the key
Review Comment:
Although it makes sense, I still see a problem here, Lets say we create 2
versions of same key.
create key1
delete key1 -> move to trash-> trash has key1
create key1 again -> delete again -> this will not move the second key to
trash instead delete it.
How filesystem trash handles duplicate keys is by appending timestamp if it
is the key with same name.
See
[TrashPolicyOzone#moveToTrash](https://github.com/apache/ozone/blob/5e8b806f058a74dc854164118947c703977f94a6/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/TrashPolicyOzone.java#L204).
The above problem you are mentioning occurs probably due to parent dir
creation inside trash and would happen only on directories. We can distinguish
the logic based on whether object is key/directory.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]