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]