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

adoroszlai 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 021042e7fa7 HDDS-14685. Create context for BucketOperationHandler 
(#9798)
021042e7fa7 is described below

commit 021042e7fa7a9c05a7dee65c91c9c763b12c4664
Author: Doroszlai, Attila <[email protected]>
AuthorDate: Sun Feb 22 09:11:06 2026 +0100

    HDDS-14685. Create context for BucketOperationHandler (#9798)
---
 .../hadoop/ozone/s3/endpoint/BucketAclHandler.java | 37 +++++-----
 .../ozone/s3/endpoint/BucketCrudHandler.java       | 33 +++++----
 .../hadoop/ozone/s3/endpoint/BucketEndpoint.java   | 20 ++++--
 .../ozone/s3/endpoint/BucketOperationHandler.java  |  9 +--
 .../hadoop/ozone/s3/endpoint/ObjectEndpoint.java   | 48 +------------
 .../hadoop/ozone/s3/endpoint/S3RequestContext.java | 78 ++++++++++++++++++++++
 .../ozone/s3/endpoint/TestBucketAclHandler.java    | 46 +++++++------
 7 files changed, 156 insertions(+), 115 deletions(-)

diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketAclHandler.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketAclHandler.java
index 66e122f0ed8..1ac30f49797 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketAclHandler.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketAclHandler.java
@@ -45,7 +45,6 @@
 import org.apache.hadoop.ozone.s3.exception.S3ErrorTable;
 import org.apache.hadoop.ozone.s3.util.S3Consts.QueryParams;
 import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
-import org.apache.hadoop.util.Time;
 import org.apache.http.HttpStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -57,7 +56,7 @@
  * This handler extends EndpointBase to inherit all required functionality
  * (configuration, headers, request context, audit logging, metrics, etc.).
  */
-public class BucketAclHandler extends EndpointBase implements 
BucketOperationHandler {
+public class BucketAclHandler extends BucketOperationHandler {
 
   private static final Logger LOG = 
LoggerFactory.getLogger(BucketAclHandler.class);
 
@@ -75,15 +74,14 @@ private boolean shouldHandle() {
    * see: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAcl.html
    */
   @Override
-  public Response handleGetRequest(String bucketName)
+  Response handleGetRequest(S3RequestContext context, String bucketName)
       throws IOException, OS3Exception {
 
     if (!shouldHandle()) {
       return null;  // Not responsible for this request
     }
 
-    long startNanos = Time.monotonicNowNanos();
-    S3GAction s3GAction = S3GAction.GET_ACL;
+    context.setAction(S3GAction.GET_ACL);
 
     try {
       OzoneBucket bucket = getBucket(bucketName);
@@ -107,12 +105,12 @@ public Response handleGetRequest(String bucketName)
       result.setAclList(
           new S3BucketAcl.AccessControlList(grantList));
 
-      getMetrics().updateGetAclSuccessStats(startNanos);
-      auditReadSuccess(s3GAction);
+      getMetrics().updateGetAclSuccessStats(context.getStartNanos());
+      auditReadSuccess(context.getAction());
       return Response.ok(result, MediaType.APPLICATION_XML_TYPE).build();
     } catch (OMException ex) {
-      getMetrics().updateGetAclFailureStats(startNanos);
-      auditReadFailure(s3GAction, ex);
+      getMetrics().updateGetAclFailureStats(context.getStartNanos());
+      auditReadFailure(context.getAction(), ex);
       if (ex.getResult() == ResultCodes.BUCKET_NOT_FOUND) {
         throw newError(S3ErrorTable.NO_SUCH_BUCKET, bucketName, ex);
       } else if (isAccessDenied(ex)) {
@@ -121,8 +119,8 @@ public Response handleGetRequest(String bucketName)
         throw newError(S3ErrorTable.INTERNAL_ERROR, bucketName, ex);
       }
     } catch (OS3Exception ex) {
-      getMetrics().updateGetAclFailureStats(startNanos);
-      auditReadFailure(s3GAction, ex);
+      getMetrics().updateGetAclFailureStats(context.getStartNanos());
+      auditReadFailure(context.getAction(), ex);
       throw ex;
     }
   }
@@ -133,15 +131,14 @@ public Response handleGetRequest(String bucketName)
    * see: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAcl.html
    */
   @Override
-  public Response handlePutRequest(String bucketName, InputStream body)
+  Response handlePutRequest(S3RequestContext context, String bucketName, 
InputStream body)
       throws IOException, OS3Exception {
 
     if (!shouldHandle()) {
       return null;  // Not responsible for this request
     }
 
-    long startNanos = Time.monotonicNowNanos();
-    S3GAction s3GAction = S3GAction.PUT_ACL;
+    context.setAction(S3GAction.PUT_ACL);
 
     String grantReads = getHeaders().getHeaderString(S3Acl.GRANT_READ);
     String grantWrites = getHeaders().getHeaderString(S3Acl.GRANT_WRITE);
@@ -226,13 +223,13 @@ public Response handlePutRequest(String bucketName, 
InputStream body)
         volume.addAcl(acl);
       }
 
-      getMetrics().updatePutAclSuccessStats(startNanos);
-      auditWriteSuccess(s3GAction);
+      getMetrics().updatePutAclSuccessStats(context.getStartNanos());
+      auditWriteSuccess(context.getAction());
       return Response.status(HttpStatus.SC_OK).build();
 
     } catch (OMException exception) {
-      getMetrics().updatePutAclFailureStats(startNanos);
-      auditWriteFailure(s3GAction, exception);
+      getMetrics().updatePutAclFailureStats(context.getStartNanos());
+      auditWriteFailure(context.getAction(), exception);
       if (exception.getResult() == ResultCodes.BUCKET_NOT_FOUND) {
         throw newError(S3ErrorTable.NO_SUCH_BUCKET, bucketName, exception);
       } else if (isAccessDenied(exception)) {
@@ -240,8 +237,8 @@ public Response handlePutRequest(String bucketName, 
InputStream body)
       }
       throw exception;
     } catch (OS3Exception ex) {
-      getMetrics().updatePutAclFailureStats(startNanos);
-      auditWriteFailure(s3GAction, ex);
+      getMetrics().updatePutAclFailureStats(context.getStartNanos());
+      auditWriteFailure(context.getAction(), ex);
       throw ex;
     }
   }
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketCrudHandler.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketCrudHandler.java
index 69ce57eff04..982838d0dd0 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketCrudHandler.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketCrudHandler.java
@@ -28,7 +28,6 @@
 import org.apache.hadoop.ozone.s3.exception.OS3Exception;
 import org.apache.hadoop.ozone.s3.exception.S3ErrorTable;
 import org.apache.hadoop.ozone.s3.util.S3Consts.QueryParams;
-import org.apache.hadoop.util.Time;
 import org.apache.http.HttpStatus;
 
 /**
@@ -43,7 +42,7 @@
  * This handler extends EndpointBase to inherit all required functionality
  * (configuration, headers, request context, audit logging, metrics, etc.).
  */
-public class BucketCrudHandler extends EndpointBase implements 
BucketOperationHandler {
+public class BucketCrudHandler extends BucketOperationHandler {
 
   /**
    * Handle only plain PUT bucket (create bucket), not subresources.
@@ -58,31 +57,30 @@ && queryParams().get(QueryParams.UPLOADS) == null
    * Handle PUT /{bucket} for bucket creation.
    */
   @Override
-  public Response handlePutRequest(String bucketName, InputStream body)
+  Response handlePutRequest(S3RequestContext context, String bucketName, 
InputStream body)
       throws IOException, OS3Exception {
 
     if (!shouldHandle()) {
       return null;
     }
 
-    long startNanos = Time.monotonicNowNanos();
-    S3GAction s3GAction = S3GAction.CREATE_BUCKET;
+    context.setAction(S3GAction.CREATE_BUCKET);
 
     try {
       String location = createS3Bucket(bucketName);
-      auditWriteSuccess(s3GAction);
-      getMetrics().updateCreateBucketSuccessStats(startNanos);
+      auditWriteSuccess(context.getAction());
+      getMetrics().updateCreateBucketSuccessStats(context.getStartNanos());
       return Response.status(HttpStatus.SC_OK).header("Location", location)
           .build();
     } catch (OMException exception) {
-      auditWriteFailure(s3GAction, exception);
-      getMetrics().updateCreateBucketFailureStats(startNanos);
+      auditWriteFailure(context.getAction(), exception);
+      getMetrics().updateCreateBucketFailureStats(context.getStartNanos());
       if (exception.getResult() == 
OMException.ResultCodes.INVALID_BUCKET_NAME) {
         throw newError(S3ErrorTable.INVALID_BUCKET_NAME, bucketName, 
exception);
       }
       throw exception;
     } catch (Exception ex) {
-      auditWriteFailure(s3GAction, ex);
+      auditWriteFailure(context.getAction(), ex);
       throw ex;
     }
   }
@@ -91,15 +89,14 @@ public Response handlePutRequest(String bucketName, 
InputStream body)
    * Handle DELETE /{bucket} for bucket deletion.
    */
   @Override
-  public Response handleDeleteRequest(String bucketName)
+  Response handleDeleteRequest(S3RequestContext context, String bucketName)
       throws IOException, OS3Exception {
 
     if (!shouldHandle()) {
       return null;
     }
 
-    long startNanos = Time.monotonicNowNanos();
-    S3GAction s3GAction = S3GAction.DELETE_BUCKET;
+    context.setAction(S3GAction.DELETE_BUCKET);
 
     try {
       if (S3Owner.hasBucketOwnershipVerificationConditions(getHeaders())) {
@@ -108,8 +105,8 @@ public Response handleDeleteRequest(String bucketName)
       }
       deleteS3Bucket(bucketName);
     } catch (OMException ex) {
-      auditWriteFailure(s3GAction, ex);
-      getMetrics().updateDeleteBucketFailureStats(startNanos);
+      auditWriteFailure(context.getAction(), ex);
+      getMetrics().updateDeleteBucketFailureStats(context.getStartNanos());
       if (ex.getResult() == OMException.ResultCodes.BUCKET_NOT_EMPTY) {
         throw newError(S3ErrorTable.BUCKET_NOT_EMPTY, bucketName, ex);
       } else if (ex.getResult() == OMException.ResultCodes.BUCKET_NOT_FOUND) {
@@ -120,12 +117,12 @@ public Response handleDeleteRequest(String bucketName)
         throw ex;
       }
     } catch (Exception ex) {
-      auditWriteFailure(s3GAction, ex);
+      auditWriteFailure(context.getAction(), ex);
       throw ex;
     }
 
-    auditWriteSuccess(s3GAction);
-    getMetrics().updateDeleteBucketSuccessStats(startNanos);
+    auditWriteSuccess(context.getAction());
+    getMetrics().updateDeleteBucketSuccessStats(context.getStartNanos());
     return Response
         .status(HttpStatus.SC_NO_CONTENT)
         .build();
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
index d49e0a97275..18ba9f34934 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java
@@ -97,13 +97,15 @@ public class BucketEndpoint extends EndpointBase {
   public Response get(
       @PathParam(BUCKET) String bucketName
   ) throws OS3Exception, IOException {
-    long startNanos = Time.monotonicNowNanos();
-    S3GAction s3GAction = S3GAction.GET_BUCKET;
-    PerformanceStringBuilder perf = new PerformanceStringBuilder();
+    S3RequestContext context = new S3RequestContext(this, 
S3GAction.GET_BUCKET);
+
+    long startNanos = context.getStartNanos();
+    S3GAction s3GAction = context.getAction();
+    PerformanceStringBuilder perf = context.getPerf();
 
     // Chain of responsibility: let each handler try to handle the request
     for (BucketOperationHandler handler : handlers) {
-      Response response = handler.handleGetRequest(bucketName);
+      Response response = handler.handleGetRequest(context, bucketName);
       if (response != null) {
         return response;  // Handler handled the request
       }
@@ -299,9 +301,11 @@ public Response put(
       InputStream body
   ) throws IOException, OS3Exception {
 
+    S3RequestContext context = new S3RequestContext(this, 
S3GAction.CREATE_BUCKET);
+
     // Chain of responsibility: let each handler try to handle the request
     for (BucketOperationHandler handler : handlers) {
-      Response response = handler.handlePutRequest(bucketName, body);
+      Response response = handler.handlePutRequest(context, bucketName, body);
       if (response != null) {
         return response;  // Handler handled the request
       }
@@ -400,8 +404,10 @@ public Response head(@PathParam(BUCKET) String bucketName)
   @DELETE
   public Response delete(@PathParam(BUCKET) String bucketName)
       throws IOException, OS3Exception {
+    S3RequestContext context = new S3RequestContext(this, 
S3GAction.DELETE_BUCKET);
+
     for (BucketOperationHandler handler : handlers) {
-      Response response = handler.handleDeleteRequest(bucketName);
+      Response response = handler.handleDeleteRequest(context, bucketName);
       if (response != null) {
         return response;
       }
@@ -507,7 +513,7 @@ protected void init() {
     addHandler(new BucketCrudHandler());
   }
 
-  private <T extends EndpointBase & BucketOperationHandler> void addHandler(T 
handler) {
+  private void addHandler(BucketOperationHandler handler) {
     copyDependenciesTo(handler);
     handlers.add(handler);
   }
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketOperationHandler.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketOperationHandler.java
index 026c1cc22a8..0991c083f79 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketOperationHandler.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketOperationHandler.java
@@ -30,7 +30,7 @@
  * Implementations should extend EndpointBase to inherit all required 
functionality
  * (configuration, headers, request context, audit logging, metrics, etc.).
  */
-public interface BucketOperationHandler {
+abstract class BucketOperationHandler extends EndpointBase {
 
   /**
    * Handle the bucket PUT operation if this handler is responsible for it.
@@ -43,7 +43,7 @@ public interface BucketOperationHandler {
    * @throws IOException if an I/O error occurs
    * @throws OS3Exception if an S3-specific error occurs
    */
-  default Response handlePutRequest(String bucketName, InputStream body)
+  Response handlePutRequest(S3RequestContext context, String bucketName, 
InputStream body)
       throws IOException, OS3Exception {
     return null;
   }
@@ -53,17 +53,18 @@ default Response handlePutRequest(String bucketName, 
InputStream body)
    * The handler inspects the request (query parameters, headers, etc.) to 
determine
    * if it should handle the request.
    *
+   * @param context
    * @param bucketName the name of the bucket
    * @return Response if this handler handles the request, null otherwise
    * @throws IOException if an I/O error occurs
    * @throws OS3Exception if an S3-specific error occurs
    */
-  default Response handleGetRequest(String bucketName)
+  Response handleGetRequest(S3RequestContext context, String bucketName)
       throws IOException, OS3Exception {
     return null;
   }
 
-  default Response handleDeleteRequest(String bucketName)
+  Response handleDeleteRequest(S3RequestContext context, String bucketName)
       throws IOException, OS3Exception {
     return null;
   }
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
index f56828f5364..b18cf35d0d3 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java
@@ -47,7 +47,6 @@
 import static org.apache.hadoop.ozone.s3.util.S3Utils.wrapInQuotes;
 
 import com.google.common.collect.ImmutableMap;
-import jakarta.annotation.Nullable;
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -656,7 +655,7 @@ public Response delete(
   Response handleDeleteRequest(ObjectRequestContext context, String keyPath)
       throws IOException, OS3Exception {
 
-    final long startNanos = context.startNanos;
+    final long startNanos = context.getStartNanos();
 
     try {
       OzoneVolume volume = context.getVolume();
@@ -1130,41 +1129,20 @@ private CopyObjectResponse copyObject(OzoneVolume 
volume,
   }
   
   /** Request context shared among {@code ObjectOperationHandler}s. */
-  final class ObjectRequestContext {
+  final class ObjectRequestContext extends S3RequestContext {
     private final String bucketName;
-    private final long startNanos;
-    private final PerformanceStringBuilder perf;
-    private S3GAction action;
-    private OzoneVolume volume;
     private OzoneBucket bucket;
 
     /** @param action best guess on action based on request method, may be 
refined later by handlers */
     ObjectRequestContext(S3GAction action, String bucketName) {
-      this.action = action;
+      super(ObjectEndpoint.this, action);
       this.bucketName = bucketName;
-      this.startNanos = Time.monotonicNowNanos();
-      this.perf = new PerformanceStringBuilder();
-    }
-
-    long getStartNanos() {
-      return startNanos;
-    }
-
-    PerformanceStringBuilder getPerf() {
-      return perf;
     }
 
     String getBucketName() {
       return bucketName;
     }
 
-    OzoneVolume getVolume() throws IOException {
-      if (volume == null) {
-        volume = ObjectEndpoint.this.getVolume();
-      }
-      return volume;
-    }
-
     OzoneBucket getBucket() throws IOException {
       if (bucket == null) {
         bucket = getVolume().getBucket(bucketName);
@@ -1172,25 +1150,5 @@ OzoneBucket getBucket() throws IOException {
       return bucket;
     }
 
-    S3GAction getAction() {
-      return action;
-    }
-
-    void setAction(S3GAction action) {
-      this.action = action;
-    }
-
-    /**
-     * This method should be called by each handler with the {@code S3GAction} 
decided based on request parameters,
-     * {@code null} if it does not handle the request.  {@code action} is 
stored, if not null, for use in audit logging.
-     * @param a action as determined by handler
-     * @return true if handler should ignore the request (i.e. if {@code null} 
is passed) */
-    boolean ignore(@Nullable S3GAction a) {
-      final boolean ignore = a == null;
-      if (!ignore) {
-        setAction(a);
-      }
-      return ignore;
-    }
   }
 }
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/S3RequestContext.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/S3RequestContext.java
new file mode 100644
index 00000000000..4130feaf6fd
--- /dev/null
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/S3RequestContext.java
@@ -0,0 +1,78 @@
+/*
+ * 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.s3.endpoint;
+
+import jakarta.annotation.Nullable;
+import java.io.IOException;
+import org.apache.hadoop.ozone.audit.AuditLogger.PerformanceStringBuilder;
+import org.apache.hadoop.ozone.audit.S3GAction;
+import org.apache.hadoop.ozone.client.OzoneVolume;
+import org.apache.hadoop.util.Time;
+
+class S3RequestContext {
+  private final long startNanos;
+  private final PerformanceStringBuilder perf;
+  private final EndpointBase endpoint;
+  private S3GAction action;
+  private OzoneVolume volume;
+
+  S3RequestContext(EndpointBase endpoint, S3GAction action) {
+    this.endpoint = endpoint;
+    this.startNanos = Time.monotonicNowNanos();
+    this.perf = new PerformanceStringBuilder();
+    this.action = action;
+  }
+
+  long getStartNanos() {
+    return startNanos;
+  }
+
+  PerformanceStringBuilder getPerf() {
+    return perf;
+  }
+
+  OzoneVolume getVolume() throws IOException {
+    if (volume == null) {
+      volume = endpoint.getVolume();
+    }
+    return volume;
+  }
+
+  S3GAction getAction() {
+    return action;
+  }
+
+  void setAction(S3GAction action) {
+    this.action = action;
+  }
+
+  /**
+   * This method should be called by each handler with the {@code S3GAction} 
decided based on request parameters,
+   * {@code null} if it does not handle the request.  {@code action} is 
stored, if not null, for use in audit logging.
+   *
+   * @param a action as determined by handler
+   * @return true if handler should ignore the request (i.e. if {@code null} 
is passed)
+   */
+  boolean ignore(@Nullable S3GAction a) {
+    final boolean ignore = a == null;
+    if (!ignore) {
+      setAction(a);
+    }
+    return ignore;
+  }
+}
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestBucketAclHandler.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestBucketAclHandler.java
index 7e442ea6703..1982fdb362e 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestBucketAclHandler.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestBucketAclHandler.java
@@ -89,7 +89,7 @@ public void testHandlePutRequestWithAclQueryParam() throws 
Exception {
     when(headers.getHeaderString(S3Acl.GRANT_READ))
         .thenReturn("id=\"testuser\"");
 
-    assertNotNull(aclHandler.handlePutRequest(BUCKET_NAME, null),
+    assertNotNull(aclHandler.handlePutRequest(mockContext(), BUCKET_NAME, 
null),
         "Handler should handle request with ?acl param");
   }
 
@@ -100,7 +100,7 @@ public void testHandlePutRequestWithoutAclQueryParam() 
throws Exception {
     when(headers.getHeaderString(S3Acl.GRANT_READ))
         .thenReturn("id=\"testuser\"");
 
-    Response response = aclHandler.handlePutRequest(BUCKET_NAME, null);
+    Response response = aclHandler.handlePutRequest(mockContext(), 
BUCKET_NAME, null);
 
     assertNull(response, "Handler should return null without ?acl param");
   }
@@ -121,7 +121,7 @@ public void testHandlePutRequestWithGrantHeaders(String 
headerName) throws Excep
     when(headers.getHeaderString(headerName))
         .thenReturn("id=\"testuser\"");
 
-    assertSucceeds(() -> aclHandler.handlePutRequest(BUCKET_NAME, null));
+    assertSucceeds(() -> aclHandler.handlePutRequest(mockContext(), 
BUCKET_NAME, null));
   }
 
   @Test
@@ -131,7 +131,7 @@ public void testHandlePutRequestWithMultipleHeaders() 
throws Exception {
     when(headers.getHeaderString(S3Acl.GRANT_WRITE))
         .thenReturn("id=\"testuser2\"");
 
-    assertSucceeds(() -> aclHandler.handlePutRequest(BUCKET_NAME, null));
+    assertSucceeds(() -> aclHandler.handlePutRequest(mockContext(), 
BUCKET_NAME, null));
   }
 
   @Test
@@ -140,7 +140,7 @@ public void 
testHandlePutRequestWithUnsupportedGranteeType() {
         .thenReturn("uri=\"http://example.com\"";);
 
     assertErrorResponse(NOT_IMPLEMENTED,
-        () -> aclHandler.handlePutRequest(BUCKET_NAME, null));
+        () -> aclHandler.handlePutRequest(mockContext(), BUCKET_NAME, null));
   }
 
   @Test
@@ -149,7 +149,7 @@ public void testHandlePutRequestWithEmailAddressType() {
         .thenReturn("emailAddress=\"[email protected]\"");
 
     assertErrorResponse(NOT_IMPLEMENTED,
-        () -> aclHandler.handlePutRequest(BUCKET_NAME, null));
+        () -> aclHandler.handlePutRequest(mockContext(), BUCKET_NAME, null));
   }
 
   @Test
@@ -158,7 +158,7 @@ public void testHandlePutRequestBucketNotFound() {
         .thenReturn("id=\"testuser\"");
 
     assertThrows(OS3Exception.class,
-        () -> aclHandler.handlePutRequest("nonexistent-bucket", null),
+        () -> aclHandler.handlePutRequest(mockContext(), "nonexistent-bucket", 
null),
         "Should throw OS3Exception for non-existent bucket");
   }
 
@@ -184,7 +184,7 @@ public void testHandlePutRequestWithBody() throws Exception 
{
     InputStream body = new ByteArrayInputStream(
         aclXml.getBytes(StandardCharsets.UTF_8));
 
-    assertSucceeds(() -> aclHandler.handlePutRequest(BUCKET_NAME, body));
+    assertSucceeds(() -> aclHandler.handlePutRequest(mockContext(), 
BUCKET_NAME, body));
   }
 
   @Test
@@ -193,7 +193,7 @@ public void testHandlePutRequestWithInvalidHeaderFormat() {
         .thenReturn("invalid-format");
 
     assertThrows(OS3Exception.class,
-        () -> aclHandler.handlePutRequest(BUCKET_NAME, null),
+        () -> aclHandler.handlePutRequest(mockContext(), BUCKET_NAME, null),
         "Should throw OS3Exception for invalid header format");
   }
 
@@ -202,7 +202,7 @@ public void testHandlePutRequestWithMultipleGrantees() 
throws Exception {
     when(headers.getHeaderString(S3Acl.GRANT_READ))
         .thenReturn("id=\"user1\",id=\"user2\"");
 
-    assertSucceeds(() -> aclHandler.handlePutRequest(BUCKET_NAME, null));
+    assertSucceeds(() -> aclHandler.handlePutRequest(mockContext(), 
BUCKET_NAME, null));
   }
 
   @Test
@@ -213,7 +213,7 @@ public void testPutAclReplacesExistingAcls() throws 
Exception {
     when(headers.getHeaderString(S3Acl.GRANT_WRITE))
         .thenReturn(null);
 
-    aclHandler.handlePutRequest(BUCKET_NAME, null);
+    aclHandler.handlePutRequest(mockContext(), BUCKET_NAME, null);
 
     // Replace with new ACL
     when(headers.getHeaderString(S3Acl.GRANT_READ))
@@ -221,7 +221,7 @@ public void testPutAclReplacesExistingAcls() throws 
Exception {
     when(headers.getHeaderString(S3Acl.GRANT_WRITE))
         .thenReturn("id=\"user2\"");
 
-    assertSucceeds(() -> aclHandler.handlePutRequest(BUCKET_NAME, null));
+    assertSucceeds(() -> aclHandler.handlePutRequest(mockContext(), 
BUCKET_NAME, null));
   }
 
   @Test
@@ -233,7 +233,7 @@ public void testAuditLoggingOnBucketNotFound() throws 
Exception {
 
     // This should throw exception for non-existent bucket
     assertThrows(OS3Exception.class,
-        () -> spyHandler.handlePutRequest("nonexistent-bucket", null));
+        () -> spyHandler.handlePutRequest(mockContext(), "nonexistent-bucket", 
null));
 
     // Verify that auditWriteFailure was called with PUT_ACL action
     verify(spyHandler, times(1)).auditWriteFailure(
@@ -250,7 +250,7 @@ public void testAuditLoggingOnInvalidArgument() throws 
Exception {
         .thenReturn("invalid-format");
 
     assertThrows(OS3Exception.class,
-        () -> spyHandler.handlePutRequest(BUCKET_NAME, null));
+        () -> spyHandler.handlePutRequest(mockContext(), BUCKET_NAME, null));
 
     // Verify that auditWriteFailure was called with PUT_ACL action
     verify(spyHandler, times(1)).auditWriteFailure(
@@ -265,19 +265,19 @@ public void testHandleGetRequestWithoutAclQueryParam() 
throws Exception {
     // Remove "acl" query parameter - handler should not handle request
     aclHandler.queryParamsForTest().unset("acl");
 
-    assertNull(aclHandler.handleGetRequest(BUCKET_NAME),
+    assertNull(aclHandler.handleGetRequest(mockContext(), BUCKET_NAME),
         "Handler should return null without ?acl param");
   }
 
   @Test
   public void testHandleGetRequestSucceeds() throws Exception {
-    assertSucceeds(() -> aclHandler.handleGetRequest(BUCKET_NAME));
+    assertSucceeds(() -> aclHandler.handleGetRequest(mockContext(), 
BUCKET_NAME));
   }
 
   @Test
   public void testHandleGetRequestBucketNotFound() {
     assertThrows(OS3Exception.class,
-        () -> aclHandler.handleGetRequest("nonexistent-bucket"),
+        () -> aclHandler.handleGetRequest(mockContext(), "nonexistent-bucket"),
         "Should throw OS3Exception for non-existent bucket");
   }
 
@@ -286,10 +286,10 @@ public void 
testHandleGetRequestReturnsCorrectAclStructure() throws Exception {
     // First set some ACL
     when(headers.getHeaderString(S3Acl.GRANT_READ))
         .thenReturn("id=\"testuser\"");
-    aclHandler.handlePutRequest(BUCKET_NAME, null);
+    aclHandler.handlePutRequest(mockContext(), BUCKET_NAME, null);
 
     // Now get ACL
-    Response response = aclHandler.handleGetRequest(BUCKET_NAME);
+    Response response = aclHandler.handleGetRequest(mockContext(), 
BUCKET_NAME);
 
     assertNotNull(response);
     S3BucketAcl result = assertInstanceOf(S3BucketAcl.class, 
response.getEntity());
@@ -302,7 +302,7 @@ public void 
testHandleGetRequestReturnsCorrectAclStructure() throws Exception {
   public void testAuditLoggingOnGetSuccess() throws Exception {
     BucketAclHandler spyHandler = spy(aclHandler);
 
-    Response response = spyHandler.handleGetRequest(BUCKET_NAME);
+    Response response = spyHandler.handleGetRequest(mockContext(), 
BUCKET_NAME);
 
     assertNotNull(response);
     // Verify that auditReadSuccess was called with GET_ACL action
@@ -315,11 +315,15 @@ public void testAuditLoggingOnGetBucketNotFound() throws 
Exception {
 
     // This should throw exception for non-existent bucket
     assertThrows(OS3Exception.class,
-        () -> spyHandler.handleGetRequest("nonexistent-bucket"));
+        () -> spyHandler.handleGetRequest(mockContext(), 
"nonexistent-bucket"));
 
     // Verify that auditReadFailure was called with GET_ACL action
     verify(spyHandler, times(1)).auditReadFailure(
         eq(S3GAction.GET_ACL),
         any(OS3Exception.class));
   }
+
+  private static S3RequestContext mockContext() {
+    return new S3RequestContext(mock(BucketEndpoint.class), null);
+  }
 }


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

Reply via email to