This is an automated email from the ASF dual-hosted git repository.

Gargi-jais11 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new db8f56eb9cf HDDS-15511. Implement Ozone client API's for bucket 
tagging (#10533).
db8f56eb9cf is described below

commit db8f56eb9cfc883b1bd7a1199559e42647855d18
Author: Gargi Jaiswal <[email protected]>
AuthorDate: Tue Jun 30 13:01:53 2026 +0530

    HDDS-15511. Implement Ozone client API's for bucket tagging (#10533).
---
 .../apache/hadoop/ozone/client/OzoneBucket.java    |  27 +++
 .../ozone/client/protocol/ClientProtocol.java      |  27 +++
 .../apache/hadoop/ozone/client/rpc/RpcClient.java  |  49 +++++
 .../ozone/om/protocol/OzoneManagerProtocol.java    |  20 ++-
 ...OzoneManagerProtocolClientSideTranslatorPB.java |  65 +++++++
 .../ozone/client/rpc/OzoneRpcClientTests.java      |  96 ++++++++++
 ...equest.java => S3BucketTaggingRequestBase.java} | 100 +++++------
 .../s3/tagging/S3DeleteBucketTaggingRequest.java   | 195 ++++++++------------
 .../s3/tagging/S3PutBucketTaggingRequest.java      | 200 ++++++++-------------
 .../hadoop/ozone/client/ClientProtocolStub.java    |  15 ++
 .../hadoop/ozone/client/OzoneBucketStub.java       |  20 +++
 11 files changed, 507 insertions(+), 307 deletions(-)

diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
index ff5bce7f508..3c8714d8e39 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
@@ -1214,6 +1214,33 @@ public void deleteObjectTagging(String keyName) throws 
IOException {
     proxy.deleteObjectTagging(volumeName, name, keyName);
   }
 
+  /**
+   * Gets the bucketTags for this bucket.
+   * @return Tags for this bucket.
+   * @throws IOException
+   */
+  @JsonIgnore
+  public Map<String, String> getBucketTagging() throws IOException {
+    return proxy.getBucketTagging(volumeName, name);
+  }
+
+  /**
+   * Sets bucketTags on this bucket (replaces existing tag set).
+   * @param tags Tags to set on the bucket.
+   * @throws IOException
+   */
+  public void putBucketTagging(Map<String, String> tags) throws IOException {
+    proxy.putBucketTagging(volumeName, name, tags);
+  }
+
+  /**
+   * Removes all bucketTags from this bucket.
+   * @throws IOException
+   */
+  public void deleteBucketTagging() throws IOException {
+    proxy.deleteBucketTagging(volumeName, name);
+  }
+
   public void setSourcePathExist(boolean b) {
     this.sourcePathExist = b;
   }
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 ee5facd8edd..518a9b772da 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
@@ -1507,4 +1507,31 @@ void putObjectTagging(String volumeName, String 
bucketName, String keyName,
   void deleteObjectTagging(String volumeName, String bucketName, String 
keyName)
       throws IOException;
 
+  /**
+   * Gets the tags for an existing bucket.
+   * @param volumeName Volume name.
+   * @param bucketName Bucket name.
+   * @return Tags for the specified bucket.
+   * @throws IOException
+   */
+  Map<String, String> getBucketTagging(String volumeName, String bucketName)
+      throws IOException;
+
+  /**
+   * Sets tags on an existing bucket (replaces existing tag set).
+   * @param volumeName Volume name.
+   * @param bucketName Bucket name.
+   * @param tags Tags to set on the bucket.
+   * @throws IOException
+   */
+  void putBucketTagging(String volumeName, String bucketName,
+      Map<String, String> tags) throws IOException;
+
+  /**
+   * Removes all tags from the specified bucket.
+   * @param volumeName Volume name.
+   * @param bucketName Bucket name.
+   * @throws IOException
+   */
+  void deleteBucketTagging(String volumeName, String bucketName) throws 
IOException;
 }
diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
index 9aec4702e28..57d358e393e 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
@@ -2894,6 +2894,55 @@ public void deleteObjectTagging(String volumeName, 
String bucketName,
     ozoneManagerClient.deleteObjectTagging(keyArgs);
   }
 
+  @Override
+  public Map<String, String> getBucketTagging(String volumeName, String 
bucketName)
+      throws IOException {
+    if (omVersion.compareTo(OzoneManagerVersion.S3_BUCKET_TAGGING_API) < 0) {
+      throw new IOException("OzoneManager does not support S3 bucket tagging 
API");
+    }
+
+    verifyVolumeName(volumeName);
+    verifyBucketName(bucketName);
+    OmBucketArgs bucketArgs = new OmBucketArgs.Builder()
+        .setVolumeName(volumeName)
+        .setBucketName(bucketName)
+        .build();
+    return ozoneManagerClient.getBucketTagging(bucketArgs);
+  }
+
+  @Override
+  public void putBucketTagging(String volumeName, String bucketName,
+      Map<String, String> tags) throws IOException {
+    if (omVersion.compareTo(OzoneManagerVersion.S3_BUCKET_TAGGING_API) < 0) {
+      throw new IOException("OzoneManager does not support S3 bucket tagging 
API");
+    }
+
+    verifyVolumeName(volumeName);
+    verifyBucketName(bucketName);
+    OmBucketArgs bucketArgs = new OmBucketArgs.Builder()
+        .setVolumeName(volumeName)
+        .setBucketName(bucketName)
+        .addAllTags(tags)
+        .build();
+    ozoneManagerClient.putBucketTagging(bucketArgs);
+  }
+
+  @Override
+  public void deleteBucketTagging(String volumeName, String bucketName)
+      throws IOException {
+    if (omVersion.compareTo(OzoneManagerVersion.S3_BUCKET_TAGGING_API) < 0) {
+      throw new IOException("OzoneManager does not support S3 bucket tagging 
API");
+    }
+
+    verifyVolumeName(volumeName);
+    verifyBucketName(bucketName);
+    OmBucketArgs bucketArgs = new OmBucketArgs.Builder()
+        .setVolumeName(volumeName)
+        .setBucketName(bucketName)
+        .build();
+    ozoneManagerClient.deleteBucketTagging(bucketArgs);
+  }
+
   private static ExecutorService createThreadPoolExecutor(
        int corePoolSize, int maximumPoolSize, String threadNameFormat) {
     return new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
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 92d5fad53a6..34a239d5c38 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
@@ -1219,10 +1219,24 @@ default void deleteObjectTagging(OmKeyArgs args) throws 
IOException {
    * @return Tags associated with the bucket.
    */
   @Override
-  default Map<String, String> getBucketTagging(OmBucketArgs args) throws 
IOException {
-    // This will be removed in the follow-up ticket HDDS-15511.
+  Map<String, String> getBucketTagging(OmBucketArgs args) throws IOException;
+
+  /**
+   * Sets tags on an existing bucket (replaces existing tag set).
+   * @param args Bucket args
+   */
+  default void putBucketTagging(OmBucketArgs args) throws IOException {
+    throw new UnsupportedOperationException("OzoneManager does not require " +
+        "this to be implemented, as write requests use a new approach.");
+  }
+
+  /**
+   * Removes all tags from the specified bucket.
+   * @param args Bucket args
+   */
+  default void deleteBucketTagging(OmBucketArgs args) throws IOException {
     throw new UnsupportedOperationException("OzoneManager does not require " +
-        "this to be implemented, as bucket tagging client support is 
pending.");
+        "this to be implemented, as write requests use a new approach.");
   }
 
   /**
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 405c3beacae..9de50cd0d35 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
@@ -120,6 +120,7 @@
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DBUpdatesRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DBUpdatesResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteBucketRequest;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteBucketTaggingRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteKeyArgs;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteKeyRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteKeysRequest;
@@ -136,6 +137,8 @@
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.FinalizeUpgradeResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetAclRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetAclResponse;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetBucketTaggingRequest;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetBucketTaggingResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetDelegationTokenResponseProto;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetFileStatusRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetFileStatusResponse;
@@ -191,6 +194,7 @@
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareStatusRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareStatusResponse;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PutBucketTaggingRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PutObjectTaggingRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RangerBGSyncRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RangerBGSyncResponse;
@@ -2755,6 +2759,67 @@ public void deleteObjectTagging(OmKeyArgs args) throws 
IOException {
     handleError(omResponse);
   }
 
+  @Override
+  public Map<String, String> getBucketTagging(OmBucketArgs args) throws 
IOException {
+    BucketArgs bucketArgs = BucketArgs.newBuilder()
+        .setVolumeName(args.getVolumeName())
+        .setBucketName(args.getBucketName())
+        .build();
+
+    GetBucketTaggingRequest req =
+        GetBucketTaggingRequest.newBuilder()
+            .setBucketArgs(bucketArgs)
+            .build();
+
+    OMRequest omRequest = createOMRequest(Type.GetBucketTagging)
+        .setGetBucketTaggingRequest(req)
+        .build();
+
+    GetBucketTaggingResponse resp =
+        handleError(submitRequest(omRequest)).getGetBucketTaggingResponse();
+
+    return KeyValueUtil.getFromProtobuf(resp.getTagsList());
+  }
+
+  @Override
+  public void putBucketTagging(OmBucketArgs args) throws IOException {
+    BucketArgs bucketArgs = BucketArgs.newBuilder()
+        .setVolumeName(args.getVolumeName())
+        .setBucketName(args.getBucketName())
+        .addAllTags(KeyValueUtil.toProtobuf(args.getTags()))
+        .build();
+
+    PutBucketTaggingRequest req =
+        PutBucketTaggingRequest.newBuilder()
+            .setBucketArgs(bucketArgs)
+            .build();
+
+    OMRequest omRequest = createOMRequest(Type.PutBucketTagging)
+        .setPutBucketTaggingRequest(req)
+        .build();
+
+    handleError(submitRequest(omRequest));
+  }
+
+  @Override
+  public void deleteBucketTagging(OmBucketArgs args) throws IOException {
+    BucketArgs bucketArgs = BucketArgs.newBuilder()
+        .setVolumeName(args.getVolumeName())
+        .setBucketName(args.getBucketName())
+        .build();
+
+    DeleteBucketTaggingRequest req =
+        DeleteBucketTaggingRequest.newBuilder()
+            .setBucketArgs(bucketArgs)
+            .build();
+
+    OMRequest omRequest = createOMRequest(Type.DeleteBucketTagging)
+        .setDeleteBucketTaggingRequest(req)
+        .build();
+
+    handleError(submitRequest(omRequest));
+  }
+
   private SafeMode toProtoBuf(SafeModeAction action) {
     switch (action) {
     case ENTER:
diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/OzoneRpcClientTests.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/OzoneRpcClientTests.java
index 494ec2473cd..8beb5d01118 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/OzoneRpcClientTests.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/OzoneRpcClientTests.java
@@ -5710,4 +5710,100 @@ public void testCreateEmptyFileNotSkipBlockAllocation()
         
getCluster().getStorageContainerManager().getPipelineManager().getMetrics().getTotalNumBlocksAllocated();
     assertEquals(initialAllocatedBlocks + 1, currentAllocatedBlocks);
   }
+
+  @ParameterizedTest
+  @MethodSource("bucketLayouts")
+  public void testPutBucketTagging(BucketLayout bucketLayout) throws Exception 
{
+    String volumeName = UUID.randomUUID().toString();
+    String bucketName = UUID.randomUUID().toString();
+
+    store.createVolume(volumeName);
+    OzoneVolume volume = store.getVolume(volumeName);
+    BucketArgs bucketArgs =
+        BucketArgs.newBuilder().setBucketLayout(bucketLayout).build();
+    volume.createBucket(bucketName, bucketArgs);
+
+    // initially bucket has no tags
+    OzoneBucket bucket = volume.getBucket(bucketName);
+    assertTrue(bucket.getBucketTagging().isEmpty());
+    Instant modificationTimeBeforePut = bucket.getModificationTime();
+
+    Map<String, String> tags = new HashMap<>();
+    tags.put("tag-key-1", "tag-value-1");
+    tags.put("tag-key-2", "tag-value-2");
+
+    bucket.putBucketTagging(tags);
+
+    OzoneBucket updatedBucket = volume.getBucket(bucketName);
+    assertEquals(tags.size(), updatedBucket.getBucketTagging().size());
+    assertThat(updatedBucket.getBucketTagging()).containsAllEntriesOf(tags);
+    assertThat(updatedBucket.getModificationTime())
+        .isAfterOrEqualTo(modificationTimeBeforePut);
+
+    // 2nd put should replace the previous tags
+    Map<String, String> secondTags = new HashMap<>();
+    secondTags.put("tag-key-3", "tag-value-3");
+
+    bucket.putBucketTagging(secondTags);
+
+    OzoneBucket updatedBucket2 = volume.getBucket(bucketName);
+    assertEquals(secondTags.size(), updatedBucket2.getBucketTagging().size());
+    
assertThat(updatedBucket2.getBucketTagging()).containsAllEntriesOf(secondTags);
+    
assertThat(updatedBucket2.getBucketTagging()).doesNotContainKeys("tag-key-1", 
"tag-key-2");
+    assertThat(updatedBucket2.getModificationTime())
+        .isAfterOrEqualTo(updatedBucket.getModificationTime());
+  }
+
+  @ParameterizedTest
+  @MethodSource("bucketLayouts")
+  public void testDeleteBucketTagging(BucketLayout bucketLayout) throws 
Exception {
+    String volumeName = UUID.randomUUID().toString();
+    String bucketName = UUID.randomUUID().toString();
+
+    store.createVolume(volumeName);
+    OzoneVolume volume = store.getVolume(volumeName);
+    BucketArgs bucketArgs =
+        BucketArgs.newBuilder().setBucketLayout(bucketLayout).build();
+    volume.createBucket(bucketName, bucketArgs);
+    OzoneBucket bucket = volume.getBucket(bucketName);
+
+    Map<String, String> tags = new HashMap<>();
+    tags.put("tag-key-1", "tag-value-1");
+    tags.put("tag-key-2", "tag-value-2");
+
+    bucket.putBucketTagging(tags);
+    OzoneBucket bucketAfterPut = volume.getBucket(bucketName);
+    assertFalse(bucketAfterPut.getBucketTagging().isEmpty());
+
+    bucket.deleteBucketTagging();
+    OzoneBucket updatedBucket = volume.getBucket(bucketName);
+    assertTrue(updatedBucket.getBucketTagging().isEmpty());
+    assertThat(updatedBucket.getModificationTime())
+        .isAfterOrEqualTo(bucketAfterPut.getModificationTime());
+    
assertThat(updatedBucket.getBucketTagging()).doesNotContainKeys("tag-key-1", 
"tag-key-2");
+  }
+
+  @ParameterizedTest
+  @MethodSource("bucketLayouts")
+  public void testGetBucketTagging(BucketLayout bucketLayout) throws Exception 
{
+    String volumeName = UUID.randomUUID().toString();
+    String bucketName = UUID.randomUUID().toString();
+
+    store.createVolume(volumeName);
+    OzoneVolume volume = store.getVolume(volumeName);
+    BucketArgs bucketArgs =
+        BucketArgs.newBuilder().setBucketLayout(bucketLayout).build();
+    volume.createBucket(bucketName, bucketArgs);
+    OzoneBucket bucket = volume.getBucket(bucketName);
+
+    Map<String, String> tags = new HashMap<>();
+    tags.put("tag-key-1", "tag-value-1");
+    tags.put("tag-key-2", "tag-value-2");
+
+    bucket.putBucketTagging(tags);
+
+    OzoneBucket updatedBucket = volume.getBucket(bucketName);
+    assertEquals(tags.size(), updatedBucket.getBucketTagging().size());
+    assertThat(updatedBucket.getBucketTagging()).containsAllEntriesOf(tags);
+  }
 }
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3PutBucketTaggingRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3BucketTaggingRequestBase.java
similarity index 69%
copy from 
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3PutBucketTaggingRequest.java
copy to 
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3BucketTaggingRequestBase.java
index f192cbf5e08..2c19dcbdcf6 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3PutBucketTaggingRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3BucketTaggingRequestBase.java
@@ -21,7 +21,6 @@
 
 import java.io.IOException;
 import java.util.Map;
-import java.util.Objects;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.hadoop.hdds.utils.db.cache.CacheKey;
 import org.apache.hadoop.hdds.utils.db.cache.CacheValue;
@@ -32,7 +31,6 @@
 import org.apache.hadoop.ozone.om.OzoneManagerUtils;
 import org.apache.hadoop.ozone.om.ResolvedBucket;
 import org.apache.hadoop.ozone.om.execution.flowcontrol.ExecutionContext;
-import org.apache.hadoop.ozone.om.helpers.KeyValueUtil;
 import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
 import org.apache.hadoop.ozone.om.request.OMClientRequest;
@@ -42,8 +40,6 @@
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.BucketArgs;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
-import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PutBucketTaggingRequest;
-import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PutBucketTaggingResponse;
 import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
 import org.apache.hadoop.ozone.security.acl.OzoneObj;
 import org.apache.hadoop.util.Time;
@@ -51,25 +47,22 @@
 import org.slf4j.LoggerFactory;
 
 /**
- * Handles PutBucketTagging (S3 bucket tagging).
+ * Base class for S3 bucket tagging write requests (put / delete).
  */
-public class S3PutBucketTaggingRequest extends OMClientRequest {
+public abstract class S3BucketTaggingRequestBase extends OMClientRequest {
 
   private static final Logger LOG =
-      LoggerFactory.getLogger(S3PutBucketTaggingRequest.class);
+      LoggerFactory.getLogger(S3BucketTaggingRequestBase.class);
 
-  public S3PutBucketTaggingRequest(OMRequest omRequest) {
+  protected S3BucketTaggingRequestBase(OMRequest omRequest) {
     super(omRequest);
   }
 
   @Override
-  public OMRequest preExecute(OzoneManager ozoneManager)
-      throws IOException {
-    PutBucketTaggingRequest putBucketTaggingRequest =
-        getOmRequest().getPutBucketTaggingRequest();
-    Objects.requireNonNull(putBucketTaggingRequest, "putBucketTaggingRequest 
== null");
+  public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
+    OMRequest baseRequest = super.preExecute(ozoneManager);
+    BucketArgs bucketArgs = getRequestBucketArgs(baseRequest);
 
-    BucketArgs bucketArgs = putBucketTaggingRequest.getBucketArgs();
     OmBucketArgs omBucketArgs = OmBucketArgs.getFromProtobuf(bucketArgs);
     String volumeName = bucketArgs.getVolumeName();
     String bucketName = bucketArgs.getBucketName();
@@ -84,20 +77,14 @@ public OMRequest preExecute(OzoneManager ozoneManager)
             resolvedBucket.realVolume(), resolvedBucket.realBucket(), null);
       } catch (IOException ex) {
         markForAudit(ozoneManager.getAuditLogger(), buildAuditMessage(
-            OMAction.PUT_BUCKET_TAGGING,
+            getAuditAction(),
             resolvedBucket.audit(omBucketArgs.toAuditMap()), ex,
             getOmRequest().getUserInfo()));
         throw ex;
       }
     }
-
-    PutBucketTaggingRequest.Builder req = putBucketTaggingRequest.toBuilder();
-    req.setModificationTime(Time.now());
-    req.setBucketArgs(resolvedBucket.update(bucketArgs));
-    return getOmRequest().toBuilder()
-        .setPutBucketTaggingRequest(req.build())
-        .setUserInfo(getUserInfo())
-        .build();
+    return buildUpdatedOMRequest(baseRequest,
+        resolvedBucket.update(bucketArgs), Time.now());
   }
 
   @Override
@@ -105,24 +92,20 @@ public OMClientResponse 
validateAndUpdateCache(OzoneManager ozoneManager,
       ExecutionContext context) {
     final long transactionLogIndex = context.getIndex();
 
-    PutBucketTaggingRequest putBucketTaggingRequest =
-        getOmRequest().getPutBucketTaggingRequest();
-    Objects.requireNonNull(putBucketTaggingRequest, "putBucketTaggingRequest 
== null");
-
-    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
-    OMMetrics omMetrics = ozoneManager.getMetrics();
-    omMetrics.incNumPutBucketTagging();
+    OMRequest omRequest = getOmRequest();
+    BucketArgs bucketArgs = getRequestBucketArgs(omRequest);
 
-    BucketArgs bucketArgs = putBucketTaggingRequest.getBucketArgs();
     OmBucketArgs omBucketArgs = OmBucketArgs.getFromProtobuf(bucketArgs);
-
     String volumeName = bucketArgs.getVolumeName();
     String bucketName = bucketArgs.getBucketName();
+    long modificationTime = getModificationTime(omRequest);
 
-    OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(
-        getOmRequest());
-    OmBucketInfo omBucketInfo = null;
+    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
+    OMMetrics omMetrics = ozoneManager.getMetrics();
+    incRequestMetric(omMetrics);
 
+    OMResponse.Builder omResponse =
+        OmResponseUtil.getOMResponseBuilder(omRequest);
     Exception exception = null;
     boolean acquiredBucketLock = false;
     boolean success = true;
@@ -130,27 +113,23 @@ public OMClientResponse 
validateAndUpdateCache(OzoneManager ozoneManager,
     try {
       mergeOmLockDetails(omMetadataManager.getLock().acquireWriteLock(
           BUCKET_LOCK, volumeName, bucketName));
-      acquiredBucketLock = getOmLockDetails().isLockAcquired();
 
+      acquiredBucketLock = getOmLockDetails().isLockAcquired();
       String bucketKey = omMetadataManager.getBucketKey(volumeName, 
bucketName);
       OmBucketInfo dbBucketInfo = OzoneManagerUtils.getBucketInfo(
           omMetadataManager, volumeName, bucketName);
 
-      Map<String, String> tags =
-          KeyValueUtil.getFromProtobuf(bucketArgs.getTagsList());
-
-      omBucketInfo = dbBucketInfo.toBuilder()
+      Map<String, String> tags = getTagsToApply(bucketArgs);
+      OmBucketInfo omBucketInfo = dbBucketInfo.toBuilder()
           .setTags(tags)
           .setUpdateID(transactionLogIndex)
-          .setModificationTime(putBucketTaggingRequest.getModificationTime())
+          .setModificationTime(modificationTime)
           .build();
 
       omMetadataManager.getBucketTable().addCacheEntry(
           new CacheKey<>(bucketKey),
           CacheValue.get(transactionLogIndex, omBucketInfo));
-
-      omResponse.setPutBucketTaggingResponse(
-          PutBucketTaggingResponse.newBuilder().build());
+      setSuccessResponse(omResponse);
       omClientResponse = new OMBucketSetPropertyResponse(
           omResponse.build(), omBucketInfo);
     } catch (IOException ex) {
@@ -169,17 +148,36 @@ public OMClientResponse 
validateAndUpdateCache(OzoneManager ozoneManager,
     }
     Map<String, String> auditMap = omBucketArgs.toAuditMap();
     markForAudit(ozoneManager.getAuditLogger(), buildAuditMessage(
-        OMAction.PUT_BUCKET_TAGGING, auditMap, exception,
-        getOmRequest().getUserInfo()));
+        getAuditAction(), auditMap, exception, getOmRequest().getUserInfo()));
 
     if (success) {
-      LOG.debug("Put bucket tagging for bucket:{} in volume:{}",
-          bucketName, volumeName);
+      LOG.debug("{} bucket tagging succeeded for bucket:{} in volume:{}",
+          getOperationName(), bucketName, volumeName);
       return omClientResponse;
     }
-    omMetrics.incNumPutBucketTaggingFails();
-    LOG.error("Put bucket tagging failed for bucket:{} in volume:{}",
-        bucketName, volumeName, exception);
+
+    incRequestFailMetric(omMetrics);
+    LOG.error("{} bucket tagging failed for bucket:{} in volume:{}",
+        getOperationName(), bucketName, volumeName, exception);
     return omClientResponse;
   }
+
+  protected abstract BucketArgs getRequestBucketArgs(OMRequest omRequest);
+
+  protected abstract long getModificationTime(OMRequest omRequest);
+
+  protected abstract OMRequest buildUpdatedOMRequest(OMRequest baseRequest,
+      BucketArgs bucketArgs, long modificationTime) throws IOException;
+
+  protected abstract Map<String, String> getTagsToApply(BucketArgs bucketArgs);
+
+  protected abstract void setSuccessResponse(OMResponse.Builder omResponse);
+
+  protected abstract OMAction getAuditAction();
+
+  protected abstract void incRequestMetric(OMMetrics omMetrics);
+
+  protected abstract void incRequestFailMetric(OMMetrics omMetrics);
+
+  protected abstract String getOperationName();
 }
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3DeleteBucketTaggingRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3DeleteBucketTaggingRequest.java
index 826c7f7ebb1..7e9b53373c4 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3DeleteBucketTaggingRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3DeleteBucketTaggingRequest.java
@@ -17,171 +17,116 @@
 
 package org.apache.hadoop.ozone.om.request.s3.tagging;
 
-import static 
org.apache.hadoop.ozone.om.lock.OzoneManagerLock.LeveledResource.BUCKET_LOCK;
-
 import java.io.IOException;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Objects;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.hadoop.hdds.utils.db.cache.CacheKey;
-import org.apache.hadoop.hdds.utils.db.cache.CacheValue;
 import org.apache.hadoop.ozone.audit.OMAction;
-import org.apache.hadoop.ozone.om.OMMetadataManager;
 import org.apache.hadoop.ozone.om.OMMetrics;
-import org.apache.hadoop.ozone.om.OzoneManager;
-import org.apache.hadoop.ozone.om.OzoneManagerUtils;
-import org.apache.hadoop.ozone.om.ResolvedBucket;
-import org.apache.hadoop.ozone.om.execution.flowcontrol.ExecutionContext;
-import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
-import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
-import org.apache.hadoop.ozone.om.request.OMClientRequest;
-import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
-import org.apache.hadoop.ozone.om.response.OMClientResponse;
-import org.apache.hadoop.ozone.om.response.bucket.OMBucketSetPropertyResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.BucketArgs;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteBucketTaggingRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteBucketTaggingResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
-import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
-import org.apache.hadoop.ozone.security.acl.OzoneObj;
-import org.apache.hadoop.util.Time;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Handles DeleteBucketTagging (S3 bucket tagging).
  */
-public class S3DeleteBucketTaggingRequest extends OMClientRequest {
-
-  private static final Logger LOG =
-      LoggerFactory.getLogger(S3DeleteBucketTaggingRequest.class);
+public class S3DeleteBucketTaggingRequest extends S3BucketTaggingRequestBase {
 
+  /**
+   * Creates a delete-bucket-tagging request from the incoming OM RPC payload.
+   */
   public S3DeleteBucketTaggingRequest(OMRequest omRequest) {
     super(omRequest);
   }
 
+  /**
+   * Returns bucket args from the delete-bucket-tagging sub-request.
+   */
   @Override
-  public OMRequest preExecute(OzoneManager ozoneManager)
-      throws IOException {
+  protected BucketArgs getRequestBucketArgs(OMRequest omRequest) {
     DeleteBucketTaggingRequest deleteBucketTaggingRequest =
-        getOmRequest().getDeleteBucketTaggingRequest();
+        omRequest.getDeleteBucketTaggingRequest();
     Objects.requireNonNull(deleteBucketTaggingRequest,
         "deleteBucketTaggingRequest == null");
+    return deleteBucketTaggingRequest.getBucketArgs();
+  }
 
-    BucketArgs bucketArgs = deleteBucketTaggingRequest.getBucketArgs();
-    OmBucketArgs omBucketArgs = OmBucketArgs.getFromProtobuf(bucketArgs);
-    String volumeName = bucketArgs.getVolumeName();
-    String bucketName = bucketArgs.getBucketName();
-
-    ResolvedBucket resolvedBucket = ozoneManager.resolveBucketLink(
-        Pair.of(volumeName, bucketName), this);
+  /**
+   *  Returns the modification time stamped during preExecute.
+   */
+  @Override
+  protected long getModificationTime(OMRequest omRequest) {
+    return omRequest.getDeleteBucketTaggingRequest().getModificationTime();
+  }
 
-    if (ozoneManager.getAclsEnabled()) {
-      try {
-        checkAcls(ozoneManager, OzoneObj.ResourceType.BUCKET,
-            OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.WRITE,
-            resolvedBucket.realVolume(), resolvedBucket.realBucket(), null);
-      } catch (IOException ex) {
-        markForAudit(ozoneManager.getAuditLogger(), buildAuditMessage(
-            OMAction.DELETE_BUCKET_TAGGING,
-            resolvedBucket.audit(omBucketArgs.toAuditMap()), ex,
-            getOmRequest().getUserInfo()));
-        throw ex;
-      }
-    }
+  /**
+   * Rebuilds the OM request with resolved bucket args and modification time.
+   */
+  @Override
+  protected OMRequest buildUpdatedOMRequest(OMRequest baseRequest,
+      BucketArgs bucketArgs, long modificationTime) throws IOException {
+    DeleteBucketTaggingRequest deleteBucketTaggingRequest =
+        baseRequest.getDeleteBucketTaggingRequest();
 
     DeleteBucketTaggingRequest.Builder req =
         deleteBucketTaggingRequest.toBuilder();
-    req.setModificationTime(Time.now());
-    req.setBucketArgs(resolvedBucket.update(bucketArgs));
+    req.setModificationTime(modificationTime);
+    req.setBucketArgs(bucketArgs);
 
-    return getOmRequest().toBuilder()
+    return baseRequest.toBuilder()
         .setDeleteBucketTaggingRequest(req.build())
         .setUserInfo(getUserInfo())
         .build();
   }
 
+  /**
+   * Clears all tags when deleting bucket tagging.
+   */
   @Override
-  public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
-      ExecutionContext context) {
-    final long transactionLogIndex = context.getIndex();
-
-    DeleteBucketTaggingRequest deleteBucketTaggingRequest =
-        getOmRequest().getDeleteBucketTaggingRequest();
-    Objects.requireNonNull(deleteBucketTaggingRequest,
-        "deleteBucketTaggingRequest == null");
-
-    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
-    OMMetrics omMetrics = ozoneManager.getMetrics();
-    omMetrics.incNumDeleteBucketTagging();
-
-    BucketArgs bucketArgs = deleteBucketTaggingRequest.getBucketArgs();
-    OmBucketArgs omBucketArgs = OmBucketArgs.getFromProtobuf(bucketArgs);
-
-    String volumeName = bucketArgs.getVolumeName();
-    String bucketName = bucketArgs.getBucketName();
-
-    OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(
-        getOmRequest());
-    OmBucketInfo omBucketInfo = null;
-
-    Exception exception = null;
-    boolean acquiredBucketLock = false;
-    boolean success = true;
-    OMClientResponse omClientResponse = null;
-    try {
-      mergeOmLockDetails(omMetadataManager.getLock().acquireWriteLock(
-          BUCKET_LOCK, volumeName, bucketName));
-      acquiredBucketLock = getOmLockDetails().isLockAcquired();
-
-      String bucketKey = omMetadataManager.getBucketKey(volumeName, 
bucketName);
-      OmBucketInfo dbBucketInfo = OzoneManagerUtils.getBucketInfo(
-          omMetadataManager, volumeName, bucketName);
-
-      omBucketInfo = dbBucketInfo.toBuilder()
-          .setTags(Collections.emptyMap())
-          .setUpdateID(transactionLogIndex)
-          
.setModificationTime(deleteBucketTaggingRequest.getModificationTime())
-          .build();
+  protected Map<String, String> getTagsToApply(BucketArgs bucketArgs) {
+    return Collections.emptyMap();
+  }
 
-      omMetadataManager.getBucketTable().addCacheEntry(
-          new CacheKey<>(bucketKey),
-          CacheValue.get(transactionLogIndex, omBucketInfo));
+  /**
+   * Sets the successful delete-bucket-tagging response on the OM response.
+   */
+  @Override
+  protected void setSuccessResponse(OMResponse.Builder omResponse) {
+    omResponse.setDeleteBucketTaggingResponse(
+        DeleteBucketTaggingResponse.newBuilder().build());
+  }
 
-      omResponse.setDeleteBucketTaggingResponse(
-          DeleteBucketTaggingResponse.newBuilder().build());
-      omClientResponse = new OMBucketSetPropertyResponse(
-          omResponse.build(), omBucketInfo);
-    } catch (IOException ex) {
-      success = false;
-      exception = ex;
-      omClientResponse = new OMBucketSetPropertyResponse(
-          createErrorOMResponse(omResponse, exception));
-    } finally {
-      if (acquiredBucketLock) {
-        mergeOmLockDetails(omMetadataManager.getLock()
-            .releaseWriteLock(BUCKET_LOCK, volumeName, bucketName));
-      }
-      if (omClientResponse != null) {
-        omClientResponse.setOmLockDetails(getOmLockDetails());
-      }
-    }
+  /**
+   * Returns the audit action for delete bucket tagging.
+   */
+  @Override
+  protected OMAction getAuditAction() {
+    return OMAction.DELETE_BUCKET_TAGGING;
+  }
 
-    Map<String, String> auditMap = omBucketArgs.toAuditMap();
-    markForAudit(ozoneManager.getAuditLogger(), buildAuditMessage(
-        OMAction.DELETE_BUCKET_TAGGING, auditMap, exception,
-        getOmRequest().getUserInfo()));
+  /**
+   * Increments the delete-bucket-tagging request metric.
+   */
+  @Override
+  protected void incRequestMetric(OMMetrics omMetrics) {
+    omMetrics.incNumDeleteBucketTagging();
+  }
 
-    if (success) {
-      LOG.debug("Delete bucket tagging for bucket:{} in volume:{}",
-          bucketName, volumeName);
-      return omClientResponse;
-    }
+  /**
+   * Increments the delete-bucket-tagging failure metric.
+   */
+  @Override
+  protected void incRequestFailMetric(OMMetrics omMetrics) {
     omMetrics.incNumDeleteBucketTaggingFails();
-    LOG.error("Delete bucket tagging failed for bucket:{} in volume:{}",
-        bucketName, volumeName, exception);
-    return omClientResponse;
+  }
+
+  /**
+   * Returns the operation label used in debug and error logs.
+   */
+  @Override
+  protected String getOperationName() {
+    return "Delete";
   }
 }
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3PutBucketTaggingRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3PutBucketTaggingRequest.java
index f192cbf5e08..88261fee158 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3PutBucketTaggingRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tagging/S3PutBucketTaggingRequest.java
@@ -17,169 +17,113 @@
 
 package org.apache.hadoop.ozone.om.request.s3.tagging;
 
-import static 
org.apache.hadoop.ozone.om.lock.OzoneManagerLock.LeveledResource.BUCKET_LOCK;
-
 import java.io.IOException;
 import java.util.Map;
 import java.util.Objects;
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.hadoop.hdds.utils.db.cache.CacheKey;
-import org.apache.hadoop.hdds.utils.db.cache.CacheValue;
 import org.apache.hadoop.ozone.audit.OMAction;
-import org.apache.hadoop.ozone.om.OMMetadataManager;
 import org.apache.hadoop.ozone.om.OMMetrics;
-import org.apache.hadoop.ozone.om.OzoneManager;
-import org.apache.hadoop.ozone.om.OzoneManagerUtils;
-import org.apache.hadoop.ozone.om.ResolvedBucket;
-import org.apache.hadoop.ozone.om.execution.flowcontrol.ExecutionContext;
 import org.apache.hadoop.ozone.om.helpers.KeyValueUtil;
-import org.apache.hadoop.ozone.om.helpers.OmBucketArgs;
-import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
-import org.apache.hadoop.ozone.om.request.OMClientRequest;
-import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
-import org.apache.hadoop.ozone.om.response.OMClientResponse;
-import org.apache.hadoop.ozone.om.response.bucket.OMBucketSetPropertyResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.BucketArgs;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PutBucketTaggingRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PutBucketTaggingResponse;
-import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
-import org.apache.hadoop.ozone.security.acl.OzoneObj;
-import org.apache.hadoop.util.Time;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Handles PutBucketTagging (S3 bucket tagging).
  */
-public class S3PutBucketTaggingRequest extends OMClientRequest {
-
-  private static final Logger LOG =
-      LoggerFactory.getLogger(S3PutBucketTaggingRequest.class);
+public class S3PutBucketTaggingRequest extends S3BucketTaggingRequestBase {
 
+  /**
+   * Creates a put-bucket-tagging request from the incoming OM RPC payload.
+   */
   public S3PutBucketTaggingRequest(OMRequest omRequest) {
     super(omRequest);
   }
 
+  /**
+   * Returns bucket args from the put-bucket-tagging sub-request.
+   */
   @Override
-  public OMRequest preExecute(OzoneManager ozoneManager)
-      throws IOException {
+  protected BucketArgs getRequestBucketArgs(OMRequest omRequest) {
     PutBucketTaggingRequest putBucketTaggingRequest =
-        getOmRequest().getPutBucketTaggingRequest();
-    Objects.requireNonNull(putBucketTaggingRequest, "putBucketTaggingRequest 
== null");
-
-    BucketArgs bucketArgs = putBucketTaggingRequest.getBucketArgs();
-    OmBucketArgs omBucketArgs = OmBucketArgs.getFromProtobuf(bucketArgs);
-    String volumeName = bucketArgs.getVolumeName();
-    String bucketName = bucketArgs.getBucketName();
-
-    ResolvedBucket resolvedBucket = ozoneManager.resolveBucketLink(
-        Pair.of(volumeName, bucketName), this);
+        omRequest.getPutBucketTaggingRequest();
+    Objects.requireNonNull(putBucketTaggingRequest,
+        "putBucketTaggingRequest == null");
+    return putBucketTaggingRequest.getBucketArgs();
+  }
 
-    if (ozoneManager.getAclsEnabled()) {
-      try {
-        checkAcls(ozoneManager, OzoneObj.ResourceType.BUCKET,
-            OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.WRITE,
-            resolvedBucket.realVolume(), resolvedBucket.realBucket(), null);
-      } catch (IOException ex) {
-        markForAudit(ozoneManager.getAuditLogger(), buildAuditMessage(
-            OMAction.PUT_BUCKET_TAGGING,
-            resolvedBucket.audit(omBucketArgs.toAuditMap()), ex,
-            getOmRequest().getUserInfo()));
-        throw ex;
-      }
-    }
+  /**
+   * Returns the modification time stamped during preExecute.
+   */
+  @Override
+  protected long getModificationTime(OMRequest omRequest) {
+    return omRequest.getPutBucketTaggingRequest().getModificationTime();
+  }
 
+  /**
+   * Rebuilds the OM request with resolved bucket args and modification time.
+   */
+  @Override
+  protected OMRequest buildUpdatedOMRequest(OMRequest baseRequest,
+      BucketArgs bucketArgs, long modificationTime) throws IOException {
+    PutBucketTaggingRequest putBucketTaggingRequest =
+        baseRequest.getPutBucketTaggingRequest();
     PutBucketTaggingRequest.Builder req = putBucketTaggingRequest.toBuilder();
-    req.setModificationTime(Time.now());
-    req.setBucketArgs(resolvedBucket.update(bucketArgs));
-    return getOmRequest().toBuilder()
+    req.setModificationTime(modificationTime);
+    req.setBucketArgs(bucketArgs);
+    return baseRequest.toBuilder()
         .setPutBucketTaggingRequest(req.build())
         .setUserInfo(getUserInfo())
         .build();
   }
 
+  /**
+   * Converts request tag list into the map persisted on bucket metadata.
+   */
   @Override
-  public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
-      ExecutionContext context) {
-    final long transactionLogIndex = context.getIndex();
-
-    PutBucketTaggingRequest putBucketTaggingRequest =
-        getOmRequest().getPutBucketTaggingRequest();
-    Objects.requireNonNull(putBucketTaggingRequest, "putBucketTaggingRequest 
== null");
-
-    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
-    OMMetrics omMetrics = ozoneManager.getMetrics();
-    omMetrics.incNumPutBucketTagging();
-
-    BucketArgs bucketArgs = putBucketTaggingRequest.getBucketArgs();
-    OmBucketArgs omBucketArgs = OmBucketArgs.getFromProtobuf(bucketArgs);
-
-    String volumeName = bucketArgs.getVolumeName();
-    String bucketName = bucketArgs.getBucketName();
-
-    OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(
-        getOmRequest());
-    OmBucketInfo omBucketInfo = null;
-
-    Exception exception = null;
-    boolean acquiredBucketLock = false;
-    boolean success = true;
-    OMClientResponse omClientResponse = null;
-    try {
-      mergeOmLockDetails(omMetadataManager.getLock().acquireWriteLock(
-          BUCKET_LOCK, volumeName, bucketName));
-      acquiredBucketLock = getOmLockDetails().isLockAcquired();
-
-      String bucketKey = omMetadataManager.getBucketKey(volumeName, 
bucketName);
-      OmBucketInfo dbBucketInfo = OzoneManagerUtils.getBucketInfo(
-          omMetadataManager, volumeName, bucketName);
-
-      Map<String, String> tags =
-          KeyValueUtil.getFromProtobuf(bucketArgs.getTagsList());
+  protected Map<String, String> getTagsToApply(BucketArgs bucketArgs) {
+    return KeyValueUtil.getFromProtobuf(bucketArgs.getTagsList());
+  }
 
-      omBucketInfo = dbBucketInfo.toBuilder()
-          .setTags(tags)
-          .setUpdateID(transactionLogIndex)
-          .setModificationTime(putBucketTaggingRequest.getModificationTime())
-          .build();
+  /**
+   * Sets the successful put-bucket-tagging response on the OM response.
+   */
+  @Override
+  protected void setSuccessResponse(OMResponse.Builder omResponse) {
+    omResponse.setPutBucketTaggingResponse(
+        PutBucketTaggingResponse.newBuilder().build());
+  }
 
-      omMetadataManager.getBucketTable().addCacheEntry(
-          new CacheKey<>(bucketKey),
-          CacheValue.get(transactionLogIndex, omBucketInfo));
+  /**
+   * Returns the audit action for put bucket tagging.
+   */
+  @Override
+  protected OMAction getAuditAction() {
+    return OMAction.PUT_BUCKET_TAGGING;
+  }
 
-      omResponse.setPutBucketTaggingResponse(
-          PutBucketTaggingResponse.newBuilder().build());
-      omClientResponse = new OMBucketSetPropertyResponse(
-          omResponse.build(), omBucketInfo);
-    } catch (IOException ex) {
-      success = false;
-      exception = ex;
-      omClientResponse = new OMBucketSetPropertyResponse(
-          createErrorOMResponse(omResponse, exception));
-    } finally {
-      if (acquiredBucketLock) {
-        mergeOmLockDetails(omMetadataManager.getLock()
-            .releaseWriteLock(BUCKET_LOCK, volumeName, bucketName));
-      }
-      if (omClientResponse != null) {
-        omClientResponse.setOmLockDetails(getOmLockDetails());
-      }
-    }
-    Map<String, String> auditMap = omBucketArgs.toAuditMap();
-    markForAudit(ozoneManager.getAuditLogger(), buildAuditMessage(
-        OMAction.PUT_BUCKET_TAGGING, auditMap, exception,
-        getOmRequest().getUserInfo()));
+  /**
+   * Increments the put-bucket-tagging request metric.
+   */
+  @Override
+  protected void incRequestMetric(OMMetrics omMetrics) {
+    omMetrics.incNumPutBucketTagging();
+  }
 
-    if (success) {
-      LOG.debug("Put bucket tagging for bucket:{} in volume:{}",
-          bucketName, volumeName);
-      return omClientResponse;
-    }
+  /**
+   * Increments the put-bucket-tagging failure metric.
+   */
+  @Override
+  protected void incRequestFailMetric(OMMetrics omMetrics) {
     omMetrics.incNumPutBucketTaggingFails();
-    LOG.error("Put bucket tagging failed for bucket:{} in volume:{}",
-        bucketName, volumeName, exception);
-    return omClientResponse;
+  }
+
+  /**
+   * Returns the operation label used in debug and error logs.
+   */
+  @Override
+  protected String getOperationName() {
+    return "Put";
   }
 }
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
index 17c65ce7862..8cc421c5c6e 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
@@ -879,4 +879,19 @@ public void deleteObjectTagging(String volumeName, String 
bucketName, String key
     getBucket(volumeName, bucketName).deleteObjectTagging(keyName);
   }
 
+  @Override
+  public Map<String, String> getBucketTagging(String volumeName, String 
bucketName) throws IOException {
+    return getBucket(volumeName, bucketName).getBucketTagging();
+  }
+
+  @Override
+  public void putBucketTagging(String volumeName, String bucketName, 
Map<String, String> tags)
+      throws IOException {
+    getBucket(volumeName, bucketName).putBucketTagging(tags);
+  }
+
+  @Override
+  public void deleteBucketTagging(String volumeName, String bucketName) throws 
IOException {
+    getBucket(volumeName, bucketName).deleteBucketTagging();
+  }
 }
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/OzoneBucketStub.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/OzoneBucketStub.java
index 2b6c5ab6a08..e9b1a15cf6f 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/OzoneBucketStub.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/OzoneBucketStub.java
@@ -78,6 +78,8 @@ public final class OzoneBucketStub extends OzoneBucket {
 
   private Map<String, MultipartInfoStub> keyToMultipartUpload = new 
HashMap<>();
 
+  private final Map<String, String> bucketTags = new HashMap<>();
+
   private Map<String, Map<Integer, Part>> partList = new HashMap<>();
 
   private ArrayList<OzoneAcl> aclList = new ArrayList<>();
@@ -765,6 +767,24 @@ public void deleteObjectTagging(String keyName) throws 
IOException {
     }
   }
 
+  @Override
+  public Map<String, String> getBucketTagging() throws IOException {
+    return Collections.unmodifiableMap(bucketTags);
+  }
+
+  @Override
+  public void putBucketTagging(Map<String, String> tags) throws IOException {
+    bucketTags.clear();
+    if (tags != null) {
+      bucketTags.putAll(tags);
+    }
+  }
+
+  @Override
+  public void deleteBucketTagging() throws IOException {
+    bucketTags.clear();
+  }
+
   /**
    * Class used to hold part information in a upload part request.
    */


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to