From 4097f78786618917b3d617caca4d76fc2184c77e Mon Sep 17 00:00:00 2001 From: cxorm Date: Sat, 28 Dec 2019 18:25:52 +0800 Subject: [PATCH 01/12] Update description of return --- .../org/apache/hadoop/ozone/client/protocol/ClientProtocol.java | 2 +- .../apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java index 23308e83d574..6d12ff99a89d 100644 --- a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java +++ b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java @@ -342,7 +342,7 @@ List listTrash(String volumeName, String bucketName, * @param bucketName - The bucket name. * @param keyName - The key user want to recover. * @param destinationBucket - The bucket user want to recover to. - * @return The recoverTrash + * @return The result of recovering operation is success or not. * @throws IOException */ boolean recoverTrash(String volumeName, String bucketName, String keyName, diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java index 4a5e8a19c40d..c7241551d276 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java @@ -500,7 +500,7 @@ List listTrash(String volumeName, String bucketName, * @param bucketName - The bucket name. * @param keyName - The key user want to recover. * @param destinationBucket - The bucket user want to recover to. - * @return The recoverTrash + * @return The result of recovering operation is success or not. * @throws IOException */ boolean recoverTrash(String volumeName, String bucketName, String keyName, From 9cd630c1132f035ec4d6beddfa51f7bb8d864067 Mon Sep 17 00:00:00 2001 From: cxorm Date: Sat, 28 Dec 2019 19:29:57 +0800 Subject: [PATCH 02/12] Update OMMetadataManager --- .../apache/hadoop/ozone/om/OMMetadataManager.java | 12 ++++++++++++ .../hadoop/ozone/om/OmMetadataManagerImpl.java | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java index 9a9cf8070f3d..e5432daf3d61 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMetadataManager.java @@ -202,6 +202,18 @@ List listKeys(String volumeName, List listTrash(String volumeName, String bucketName, String startKeyName, String keyPrefix, int maxKeys) throws IOException; + /** + * Recover trash allows the user to recover the keys + * that were marked as deleted, but not actually deleted by Ozone Manager. + * @param volumeName - The volume name. + * @param bucketName - The bucket name. + * @param keyName - The key user want to recover. + * @param destinationBucket - The bucket user want to recover to. + * @return The result of recovering operation is success or not. + */ + boolean recoverTrash(String volumeName, String bucketName, + String keyName, String destinationBucket) throws IOException; + /** * Returns a list of volumes owned by a given user; if user is null, returns * all volumes. diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java index bcc26fc6622f..b19d8fdea8ae 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java @@ -807,6 +807,16 @@ public List listTrash(String volumeName, String bucketName, /** * @param userName volume owner, null for listing all volumes. */ + @Override + public boolean recoverTrash(String volumeName, String bucketName, + String keyName, String destinationBucket) throws IOException { + + // TODO: core logic stub would be added in later patch. + + boolean recoverOperation = true; + return recoverOperation; + } + @Override public List listVolumes(String userName, String prefix, String startKey, int maxKeys) throws IOException { From dbd1f6e8b9f46955b19c842727564294326ae0df Mon Sep 17 00:00:00 2001 From: cxorm Date: Sat, 28 Dec 2019 19:32:44 +0800 Subject: [PATCH 03/12] Update KeyManager --- .../java/org/apache/hadoop/ozone/om/KeyManager.java | 12 ++++++++++++ .../org/apache/hadoop/ozone/om/KeyManagerImpl.java | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java index 2088f5da71c1..08a74f964a07 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java @@ -169,6 +169,18 @@ List listKeys(String volumeName, List listTrash(String volumeName, String bucketName, String startKeyName, String keyPrefix, int maxKeys) throws IOException; + /** + * Recover trash allows the user to recover the keys + * that were marked as deleted, but not actually deleted by Ozone Manager. + * @param volumeName - The volume name. + * @param bucketName - The bucket name. + * @param keyName - The key user want to recover. + * @param destinationBucket - The bucket user want to recover to. + * @return The result of recovering operation is success or not. + */ + boolean recoverTrash(String volumeName, String bucketName, + String keyName, String destinationBucket) throws IOException; + /** * Returns a list of pending deletion key info that ups to the given count. * Each entry is a {@link BlockGroup}, which contains the info about the diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java index d0377b59ad8f..acced9052871 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java @@ -886,6 +886,19 @@ public List listTrash(String volumeName, startKeyName, keyPrefix, maxKeys); } + @Override + public boolean recoverTrash(String volumeName, String bucketName, + String keyName, String destinationBucket) throws IOException { + + Preconditions.checkNotNull(volumeName); + Preconditions.checkNotNull(bucketName); + Preconditions.checkNotNull(keyName); + Preconditions.checkNotNull(destinationBucket); + + return metadataManager.recoverTrash(volumeName, bucketName, keyName, + destinationBucket); + } + @Override public List getPendingDeletionKeys(final int count) throws IOException { From cacad8c89f7f086929987e21f409a4f4366b75a0 Mon Sep 17 00:00:00 2001 From: cxorm Date: Sat, 28 Dec 2019 19:33:11 +0800 Subject: [PATCH 04/12] Update OzoneManager --- .../apache/hadoop/ozone/om/OzoneManager.java | 15 ++++++++++++--- .../protocolPB/OzoneManagerRequestHandler.java | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java index 347f55e5d36f..d5c0ced4bb95 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java @@ -2319,13 +2319,22 @@ public List listTrash(String volumeName, } } - // TODO: HDDS-2424. recover-trash command server side handling. @Override public boolean recoverTrash(String volumeName, String bucketName, String keyName, String destinationBucket) throws IOException { - boolean recoverOperation = true; - return recoverOperation; + if (isAclEnabled) { + checkAcls(ResourceType.KEY, StoreType.OZONE, ACLType.DELETE, + volumeName, bucketName, keyName); + } + + //TODO: audit log and metric would be updated in later patch. + try { + return keyManager.recoverTrash(volumeName, bucketName, keyName, + destinationBucket); + } catch (IOException ex) { + throw ex; + } } /** diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java index a11397d5a79a..c3ee11e7e07d 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java @@ -61,6 +61,8 @@ import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListKeysResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListTrashRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListTrashResponse; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RecoverTrashRequest; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RecoverTrashResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListVolumeRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListVolumeResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LookupKeyRequest; @@ -422,6 +424,21 @@ private ListTrashResponse listTrash(ListTrashRequest request) return resp.build(); } + private RecoverTrashResponse recoverTrash(RecoverTrashRequest request) + throws IOException { + + RecoverTrashResponse.Builder resp = + RecoverTrashResponse.newBuilder(); + + boolean recoverKeys = impl.recoverTrash( + request.getVolumeName(), + request.getBucketName(), + request.getKeyName(), + request.getDestinationBucket()); + + return resp.setResponse(recoverKeys).build(); + } + private AllocateBlockResponse allocateBlock(AllocateBlockRequest request) throws IOException { AllocateBlockResponse.Builder resp = From 0124f7d911181e426a27cb4dea8e84db548ebb06 Mon Sep 17 00:00:00 2001 From: cxorm Date: Sat, 28 Dec 2019 19:34:05 +0800 Subject: [PATCH 05/12] Update UT --- .../org/apache/hadoop/ozone/om/TestTrashService.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestTrashService.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestTrashService.java index 087bf17f9cbc..5141d94d04d5 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestTrashService.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestTrashService.java @@ -86,11 +86,10 @@ public void testRecoverTrash() throws IOException { String destinationBucket = "destBucket"; createAndDeleteKey(keyName); - /* TODO:HDDS-2424. */ - // boolean recoverOperation = - // ozoneManager.recoverTrash( - // volumeName, bucketName, keyName, destinationBucket); - // Assert.assertTrue(recoverOperation); + boolean recoverOperation = + keyManager.recoverTrash( + volumeName, bucketName, keyName, destinationBucket); + Assert.assertTrue(recoverOperation); } private void createAndDeleteKey(String keyName) throws IOException { From 11141637abb43018e59a9d42aeb045c7720b832a Mon Sep 17 00:00:00 2001 From: cxorm Date: Mon, 30 Dec 2019 20:47:51 +0800 Subject: [PATCH 06/12] Add JIRA tickets track TODO item --- .../org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java index b19d8fdea8ae..a0bf1487f311 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java @@ -811,7 +811,9 @@ public List listTrash(String volumeName, String bucketName, public boolean recoverTrash(String volumeName, String bucketName, String keyName, String destinationBucket) throws IOException { - // TODO: core logic stub would be added in later patch. + /* TODO: HDDS-2425 and HDDS-2426 + core logic stub would be added in later patch. + */ boolean recoverOperation = true; return recoverOperation; From 4dcc334ddef1874d1e1bc811bb3c8bfa88a80577 Mon Sep 17 00:00:00 2001 From: cxorm Date: Sat, 18 Jan 2020 18:13:02 +0800 Subject: [PATCH 07/12] Fix request type to write --- .../common/src/main/java/org/apache/hadoop/ozone/OmUtils.java | 2 +- .../src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java | 2 +- .../hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java index ff615fb5c1c2..4a3998df1cd6 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java @@ -229,7 +229,6 @@ public static boolean isReadOnly( case LookupKey: case ListKeys: case ListTrash: - case RecoverTrash: case ServiceList: case ListMultiPartUploadParts: case GetFileStatus: @@ -264,6 +263,7 @@ public static boolean isReadOnly( case SetAcl: case AddAcl: case PurgeKeys: + case RecoverTrash: return false; default: LOG.error("CmdType {} is not categorized as readOnly or not.", cmdType); diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java index d5c0ced4bb95..b6e780461748 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java @@ -2324,7 +2324,7 @@ public boolean recoverTrash(String volumeName, String bucketName, String keyName, String destinationBucket) throws IOException { if (isAclEnabled) { - checkAcls(ResourceType.KEY, StoreType.OZONE, ACLType.DELETE, + checkAcls(ResourceType.KEY, StoreType.OZONE, ACLType.WRITE, volumeName, bucketName, keyName); } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java index d2057c99e29e..9f199076fbee 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java @@ -34,6 +34,7 @@ import org.apache.hadoop.ozone.om.request.key.OMKeyDeleteRequest; import org.apache.hadoop.ozone.om.request.key.OMKeyPurgeRequest; import org.apache.hadoop.ozone.om.request.key.OMKeyRenameRequest; +import org.apache.hadoop.ozone.om.request.key.OMTrashRecoverRequest; import org.apache.hadoop.ozone.om.request.key.acl.OMKeyAddAclRequest; import org.apache.hadoop.ozone.om.request.key.acl.OMKeyRemoveAclRequest; import org.apache.hadoop.ozone.om.request.key.acl.OMKeySetAclRequest; @@ -140,6 +141,8 @@ public static OMClientRequest createClientRequest(OMRequest omRequest) { return new OMRenewDelegationTokenRequest(omRequest); case GetS3Secret: return new S3GetSecretRequest(omRequest); + case RecoverTrash: + return new OMTrashRecoverRequest(omRequest); default: throw new IllegalStateException("Unrecognized write command " + "type request" + cmdType); From a77b242c09de719912942381d8bbe6ac97349a3d Mon Sep 17 00:00:00 2001 From: cxorm Date: Sat, 18 Jan 2020 20:47:35 +0800 Subject: [PATCH 08/12] Fix request to builder --- .../OzoneManagerProtocolClientSideTranslatorPB.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java index 0b951fa8a340..c75f7dec9dca 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java @@ -1639,15 +1639,14 @@ public boolean recoverTrash(String volumeName, String bucketName, "The destination bucket name cannot be null or empty. " + "Please enter a valid destination bucket name."); - RecoverTrashRequest recoverRequest = RecoverTrashRequest.newBuilder() + RecoverTrashRequest.Builder req = RecoverTrashRequest.newBuilder() .setVolumeName(volumeName) .setBucketName(bucketName) .setKeyName(keyName) - .setDestinationBucket(destinationBucket) - .build(); + .setDestinationBucket(destinationBucket); OMRequest omRequest = createOMRequest(Type.RecoverTrash) - .setRecoverTrashRequest(recoverRequest) + .setRecoverTrashRequest(req) .build(); RecoverTrashResponse recoverResponse = From e0e59485e11f4546329a1e6b3bbde71fa97e1e9e Mon Sep 17 00:00:00 2001 From: cxorm Date: Sat, 18 Jan 2020 20:50:46 +0800 Subject: [PATCH 09/12] Add recovering trash response --- .../java/org/apache/hadoop/ozone/OmUtils.java | 14 ++++ .../response/key/OMTrashRecoverResponse.java | 64 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMTrashRecoverResponse.java diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java index 4a3998df1cd6..12220cd7b528 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java @@ -502,4 +502,18 @@ public static long getOMClientRpcTimeOut(Configuration configuration) { return OzoneConfiguration.of(configuration) .getObject(OMClientConfig.class).getRpcTimeOut(); } + + /** + * Return OmKeyInfo that would be recovered. + */ + public static OmKeyInfo prepareKeyForRecover(OmKeyInfo keyInfo, + RepeatedOmKeyInfo repeatedOmKeyInfo) { + + /* TODO: HDDS-2425. HDDS-2426.*/ + if (repeatedOmKeyInfo.getOmKeyInfoList().contains(keyInfo)) { + return keyInfo; + } else { + return null; + } + } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMTrashRecoverResponse.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMTrashRecoverResponse.java new file mode 100644 index 000000000000..fb330a309046 --- /dev/null +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMTrashRecoverResponse.java @@ -0,0 +1,64 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.ozone.om.response.key; + +import org.apache.hadoop.ozone.OmUtils; +import org.apache.hadoop.ozone.om.OMMetadataManager; +import org.apache.hadoop.ozone.om.helpers.OmKeyInfo; +import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo; +import org.apache.hadoop.ozone.om.response.OMClientResponse; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos + .OMResponse; +import org.apache.hadoop.hdds.utils.db.BatchOperation; + +import java.io.IOException; +import javax.annotation.Nullable; +import javax.annotation.Nonnull; + +/** + * Response for RecoverTrash request. + */ +public class OMTrashRecoverResponse extends OMClientResponse { + private OmKeyInfo omKeyInfo; + + public OMTrashRecoverResponse(@Nullable OmKeyInfo omKeyInfo, + @Nonnull OMResponse omResponse) { + super(omResponse); + this.omKeyInfo = omKeyInfo; + } + + @Override + public void addToDBBatch(OMMetadataManager omMetadataManager, + BatchOperation batchOperation) throws IOException { + + /* TODO: HDDS-2425. HDDS-2426. */ + String trashKey = omMetadataManager + .getOzoneKey(omKeyInfo.getVolumeName(), + omKeyInfo.getBucketName(), omKeyInfo.getKeyName()); + RepeatedOmKeyInfo repeatedOmKeyInfo = omMetadataManager + .getDeletedTable().get(trashKey); + omKeyInfo = OmUtils.prepareKeyForRecover(omKeyInfo, repeatedOmKeyInfo); + omMetadataManager.getDeletedTable() + .deleteWithBatch(batchOperation, omKeyInfo.getKeyName()); + /* TODO: trashKey should be updated to destinationBucket. */ + omMetadataManager.getKeyTable() + .putWithBatch(batchOperation, trashKey, omKeyInfo); + } + +} From a2b4608a22f46dde6fd97d0c24bdb913dfe6207a Mon Sep 17 00:00:00 2001 From: cxorm Date: Sat, 18 Jan 2020 20:51:42 +0800 Subject: [PATCH 10/12] Handle recovering request with OMHA --- .../om/request/key/OMTrashRecoverRequest.java | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java new file mode 100644 index 000000000000..f41ec38e7f46 --- /dev/null +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java @@ -0,0 +1,138 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.ozone.om.request.key; + +import java.io.IOException; + +import com.google.common.base.Preconditions; +import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper; +import org.apache.hadoop.ozone.om.response.key.OMTrashRecoverResponse; +import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer; +import org.apache.hadoop.ozone.security.acl.OzoneObj; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.hadoop.ozone.om.OMMetadataManager; +import org.apache.hadoop.ozone.om.OzoneManager; +import org.apache.hadoop.ozone.om.response.OMClientResponse; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos + .RecoverTrashRequest; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos + .OMResponse; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos + .OMRequest; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Type; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status; + +import static org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.BUCKET_LOCK; + +/** + * Handles RecoverTrash request. + */ +public class OMTrashRecoverRequest extends OMKeyRequest { + private static final Logger LOG = + LoggerFactory.getLogger(OMTrashRecoverRequest.class); + + public OMTrashRecoverRequest(OMRequest omRequest) { + super(omRequest); + } + + @Override + public OMRequest preExecute(OzoneManager ozoneManager) { + RecoverTrashRequest recoverTrashRequest = getOmRequest() + .getRecoverTrashRequest(); + Preconditions.checkNotNull(recoverTrashRequest); + + return getOmRequest().toBuilder().build(); + } + + @Override + public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, + long transactionLogIndex, + OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper) { + RecoverTrashRequest recoverTrashRequest = getOmRequest() + .getRecoverTrashRequest(); + Preconditions.checkNotNull(recoverTrashRequest); + + String volumeName = recoverTrashRequest.getVolumeName(); + String bucketName = recoverTrashRequest.getBucketName(); + String keyName = recoverTrashRequest.getKeyName(); + String destinationBucket = recoverTrashRequest.getDestinationBucket(); + + /** TODO: HDDS-2818. New Metrics for Trash Key Recover and Fails. + * OMMetrics omMetrics = ozoneManager.getMetrics(); + */ + + OMResponse.Builder omResponse = OMResponse.newBuilder() + .setCmdType(Type.RecoverTrash).setStatus(Status.OK) + .setSuccess(true); + + OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager(); + boolean acquireLock = false; + OMClientResponse omClientResponse = null; + try { + + // check Acl + checkKeyAcls(ozoneManager, volumeName, destinationBucket, keyName, + IAccessAuthorizer.ACLType.WRITE, OzoneObj.ResourceType.KEY); + + acquireLock = omMetadataManager.getLock() + .acquireWriteLock(BUCKET_LOCK, volumeName, destinationBucket); + + // Validate. + validateBucketAndVolume(omMetadataManager, volumeName, bucketName); + validateBucketAndVolume(omMetadataManager, volumeName, destinationBucket); + + + /** TODO: HDDS-2425. HDDS-2426. + * Update cache. + * omMetadataManager.getKeyTable().addCacheEntry( + * new CacheKey<>(), + * new CacheValue<>() + * ); + * + * Execute recovering trash in non-existing bucket. + * Execute recovering trash in existing bucket. + * omClientResponse = new OMTrashRecoverResponse(omKeyInfo, + * omResponse.setRecoverTrashResponse( + * RecoverTrashResponse.newBuilder()) + * .build()); + */ + omClientResponse = null; + + } catch (IOException ex) { + LOG.error("Fail for recovering trash.", ex); + omClientResponse = new OMTrashRecoverResponse(null, + createErrorOMResponse(omResponse, ex)); + } finally { + if (omClientResponse != null) { + omClientResponse.setFlushFuture( + ozoneManagerDoubleBufferHelper.add(omClientResponse, + transactionLogIndex)); + } + if (acquireLock) { + omMetadataManager.getLock().releaseWriteLock(BUCKET_LOCK, volumeName, + destinationBucket); + } + } + + return omClientResponse; + } + +} From 632bc91e1a4a4289cde29efb5309c8ac4b93920e Mon Sep 17 00:00:00 2001 From: cxorm Date: Mon, 13 Apr 2020 05:24:21 +0800 Subject: [PATCH 11/12] Address comments --- .../java/org/apache/hadoop/ozone/om/KeyManager.java | 12 ------------ .../org/apache/hadoop/ozone/om/KeyManagerImpl.java | 13 ------------- .../hadoop/ozone/om/OmMetadataManagerImpl.java | 6 +++--- .../org/apache/hadoop/ozone/om/OzoneManager.java | 9 ++------- .../ozone/om/request/key/OMTrashRecoverRequest.java | 8 +++----- .../apache/hadoop/ozone/om/TestTrashService.java | 10 +++++----- 6 files changed, 13 insertions(+), 45 deletions(-) diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java index 08a74f964a07..2088f5da71c1 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java @@ -169,18 +169,6 @@ List listKeys(String volumeName, List listTrash(String volumeName, String bucketName, String startKeyName, String keyPrefix, int maxKeys) throws IOException; - /** - * Recover trash allows the user to recover the keys - * that were marked as deleted, but not actually deleted by Ozone Manager. - * @param volumeName - The volume name. - * @param bucketName - The bucket name. - * @param keyName - The key user want to recover. - * @param destinationBucket - The bucket user want to recover to. - * @return The result of recovering operation is success or not. - */ - boolean recoverTrash(String volumeName, String bucketName, - String keyName, String destinationBucket) throws IOException; - /** * Returns a list of pending deletion key info that ups to the given count. * Each entry is a {@link BlockGroup}, which contains the info about the diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java index acced9052871..d0377b59ad8f 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java @@ -886,19 +886,6 @@ public List listTrash(String volumeName, startKeyName, keyPrefix, maxKeys); } - @Override - public boolean recoverTrash(String volumeName, String bucketName, - String keyName, String destinationBucket) throws IOException { - - Preconditions.checkNotNull(volumeName); - Preconditions.checkNotNull(bucketName); - Preconditions.checkNotNull(keyName); - Preconditions.checkNotNull(destinationBucket); - - return metadataManager.recoverTrash(volumeName, bucketName, keyName, - destinationBucket); - } - @Override public List getPendingDeletionKeys(final int count) throws IOException { diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java index a0bf1487f311..54f1452ed64d 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java @@ -804,9 +804,6 @@ public List listTrash(String volumeName, String bucketName, return deletedKeys; } - /** - * @param userName volume owner, null for listing all volumes. - */ @Override public boolean recoverTrash(String volumeName, String bucketName, String keyName, String destinationBucket) throws IOException { @@ -819,6 +816,9 @@ public boolean recoverTrash(String volumeName, String bucketName, return recoverOperation; } + /** + * @param userName volume owner, null for listing all volumes. + */ @Override public List listVolumes(String userName, String prefix, String startKey, int maxKeys) throws IOException { diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java index b6e780461748..b4beaf79488b 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java @@ -2323,15 +2323,10 @@ public List listTrash(String volumeName, public boolean recoverTrash(String volumeName, String bucketName, String keyName, String destinationBucket) throws IOException { - if (isAclEnabled) { - checkAcls(ResourceType.KEY, StoreType.OZONE, ACLType.WRITE, - volumeName, bucketName, keyName); - } - //TODO: audit log and metric would be updated in later patch. try { - return keyManager.recoverTrash(volumeName, bucketName, keyName, - destinationBucket); + return metadataManager + .recoverTrash(volumeName, bucketName, keyName, destinationBucket); } catch (IOException ex) { throw ex; } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java index f41ec38e7f46..eac7842f84e2 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMTrashRecoverRequest.java @@ -24,7 +24,6 @@ import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper; import org.apache.hadoop.ozone.om.response.key.OMTrashRecoverResponse; import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer; -import org.apache.hadoop.ozone.security.acl.OzoneObj; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,10 +86,9 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, boolean acquireLock = false; OMClientResponse omClientResponse = null; try { - - // check Acl - checkKeyAcls(ozoneManager, volumeName, destinationBucket, keyName, - IAccessAuthorizer.ACLType.WRITE, OzoneObj.ResourceType.KEY); + // Check acl for the destination bucket. + checkBucketAcls(ozoneManager, volumeName, destinationBucket, keyName, + IAccessAuthorizer.ACLType.WRITE); acquireLock = omMetadataManager.getLock() .acquireWriteLock(BUCKET_LOCK, volumeName, destinationBucket); diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestTrashService.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestTrashService.java index 5141d94d04d5..cf9e62649deb 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestTrashService.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestTrashService.java @@ -55,6 +55,7 @@ public class TestTrashService { public TemporaryFolder tempFolder = new TemporaryFolder(); private KeyManager keyManager; + private OmMetadataManagerImpl omMetadataManager; private String volumeName; private String bucketName; @@ -69,8 +70,8 @@ public void setup() throws IOException { System.setProperty(DBConfigFromFile.CONFIG_DIR, "/"); ServerUtils.setOzoneMetaDirPath(configuration, folder.toString()); - OmMetadataManagerImpl omMetadataManager = - new OmMetadataManagerImpl(configuration); + omMetadataManager = new OmMetadataManagerImpl(configuration); + keyManager = new KeyManagerImpl( new ScmBlockLocationTestingClient(null, null, 0), omMetadataManager, configuration, UUID.randomUUID().toString(), null); @@ -86,9 +87,8 @@ public void testRecoverTrash() throws IOException { String destinationBucket = "destBucket"; createAndDeleteKey(keyName); - boolean recoverOperation = - keyManager.recoverTrash( - volumeName, bucketName, keyName, destinationBucket); + boolean recoverOperation = omMetadataManager + .recoverTrash(volumeName, bucketName, keyName, destinationBucket); Assert.assertTrue(recoverOperation); } From 8e0d302f8d5ebf4d2a75d31f5d1c4ed2a935cc23 Mon Sep 17 00:00:00 2001 From: cxorm Date: Mon, 13 Apr 2020 05:42:01 +0800 Subject: [PATCH 12/12] write-request cleanup --- .../ozone/om/protocol/OzoneManagerProtocol.java | 6 ++++-- .../apache/hadoop/ozone/om/OzoneManager.java | 13 ------------- .../protocolPB/OzoneManagerRequestHandler.java | 17 ----------------- 3 files changed, 4 insertions(+), 32 deletions(-) diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java index c7241551d276..e434ef8fc532 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java @@ -503,7 +503,9 @@ List listTrash(String volumeName, String bucketName, * @return The result of recovering operation is success or not. * @throws IOException */ - boolean recoverTrash(String volumeName, String bucketName, String keyName, - String destinationBucket) throws IOException; + default boolean recoverTrash(String volumeName, String bucketName, + String keyName, String destinationBucket) throws IOException { + return false; + } } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java index b4beaf79488b..f1318fd0d1cf 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java @@ -2319,19 +2319,6 @@ public List listTrash(String volumeName, } } - @Override - public boolean recoverTrash(String volumeName, String bucketName, - String keyName, String destinationBucket) throws IOException { - - //TODO: audit log and metric would be updated in later patch. - try { - return metadataManager - .recoverTrash(volumeName, bucketName, keyName, destinationBucket); - } catch (IOException ex) { - throw ex; - } - } - /** * Sets bucket property from args. * diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java index c3ee11e7e07d..a11397d5a79a 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java @@ -61,8 +61,6 @@ import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListKeysResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListTrashRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListTrashResponse; -import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RecoverTrashRequest; -import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RecoverTrashResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListVolumeRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListVolumeResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LookupKeyRequest; @@ -424,21 +422,6 @@ private ListTrashResponse listTrash(ListTrashRequest request) return resp.build(); } - private RecoverTrashResponse recoverTrash(RecoverTrashRequest request) - throws IOException { - - RecoverTrashResponse.Builder resp = - RecoverTrashResponse.newBuilder(); - - boolean recoverKeys = impl.recoverTrash( - request.getVolumeName(), - request.getBucketName(), - request.getKeyName(), - request.getDestinationBucket()); - - return resp.setResponse(recoverKeys).build(); - } - private AllocateBlockResponse allocateBlock(AllocateBlockRequest request) throws IOException { AllocateBlockResponse.Builder resp =