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

ivandika 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 0a8edfd515c HDDS-13678. Refactor presigned URL integration tests 
(#9037)
0a8edfd515c is described below

commit 0a8edfd515ca9e6e9e88ec2a76604b54d523b9d3
Author: Hsu Han Wen <[email protected]>
AuthorDate: Wed Sep 17 11:59:32 2025 +0800

    HDDS-13678. Refactor presigned URL integration tests (#9037)
---
 .../hadoop/ozone/s3/awssdk/S3SDKTestUtils.java     |  34 +
 .../ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java   | 545 ++++++-------
 .../ozone/s3/awssdk/v2/AbstractS3SDKV2Tests.java   | 865 +++++++++------------
 3 files changed, 646 insertions(+), 798 deletions(-)

diff --git 
a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/S3SDKTestUtils.java
 
b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/S3SDKTestUtils.java
index bb5ba27a28e..ec42a0d7b4f 100644
--- 
a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/S3SDKTestUtils.java
+++ 
b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/S3SDKTestUtils.java
@@ -20,10 +20,16 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.RandomAccessFile;
+import java.net.HttpURLConnection;
+import java.net.URL;
 import java.security.MessageDigest;
+import java.util.List;
+import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.RandomUtils;
 import org.apache.ozone.test.InputSubstream;
 
@@ -94,4 +100,32 @@ public static String extractUploadId(String xml) {
     }
     return null;
   }
+
+  /**
+   * Open an HttpURLConnection with the given parameters.
+   *
+   * @param url        The URL to connect to.
+   * @param httpMethod The HTTP method to use (e.g., "GET", "PUT", "POST", 
etc.).
+   * @param headers    A map of request headers to set. Can be null.
+   * @param body       The request body as a byte array. Can be null.
+   * @return An open HttpURLConnection.
+   * @throws IOException If an I/O error occurs.
+   */
+  public static HttpURLConnection openHttpURLConnection(URL url, String 
httpMethod, Map<String, List<String>> headers,
+                                                        byte[] body) throws 
IOException {
+    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+    connection.setRequestMethod(httpMethod);
+    if (headers != null) {
+      headers.forEach((key, values) -> values.forEach(value -> 
connection.addRequestProperty(key, value)));
+    }
+
+    if (body != null) {
+      connection.setDoOutput(true);
+      try (OutputStream os = connection.getOutputStream()) {
+        IOUtils.write(body, os);
+        os.flush();
+      }
+    }
+    return connection;
+  }
 }
diff --git 
a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java
 
b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java
index 54bdddf6e1c..3fe4f6ab5a1 100644
--- 
a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java
+++ 
b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java
@@ -77,7 +77,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.io.RandomAccessFile;
 import java.net.HttpURLConnection;
 import java.net.URL;
@@ -122,8 +121,11 @@
 import org.apache.hadoop.ozone.s3.util.S3Consts;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.ozone.test.OzoneTestBase;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
 import org.junit.jupiter.api.TestMethodOrder;
 import org.junit.jupiter.api.io.TempDir;
 
@@ -1059,196 +1061,159 @@ public void testQuotaExceeded() throws IOException {
     assertEquals("QuotaExceeded", ase.getErrorCode());
   }
 
-  @Test
-  public void testPresignedUrlGet() throws IOException {
-    final String bucketName = getBucketName();
-    final String keyName = getKeyName();
-    final String content = "bar";
-    s3Client.createBucket(bucketName);
+  @Nested
+  @TestInstance(TestInstance.Lifecycle.PER_CLASS)
+  class PresignedUrlTests {
+    private static final String BUCKET_NAME = "presigned-url-bucket";
+    private static final String CONTENT = "bar";
+    // Set the presigned URL to expire after one hour.
+    private final Date expiration = Date.from(Instant.now().plusMillis(1000 * 
60 * 60));
 
-    InputStream is = new 
ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
+    @BeforeAll
+    public void setup() {
+      s3Client.createBucket(BUCKET_NAME);
+    }
 
-    s3Client.putObject(bucketName, keyName, is, new ObjectMetadata());
+    @Test
+    public void testPresignedUrlGet() throws IOException {
+      final String keyName = getKeyName();
 
-    // Set the presigned URL to expire after one hour.
-    Date expiration = Date.from(Instant.now().plusMillis(1000 * 60 * 60));
-
-    // Generate the presigned URL
-    GeneratePresignedUrlRequest generatePresignedUrlRequest =
-        new GeneratePresignedUrlRequest(bucketName, keyName)
-            .withMethod(HttpMethod.GET)
-            .withExpiration(expiration);
-    generatePresignedUrlRequest.addRequestParameter("x-custom-parameter", 
"custom-value");
-    URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
-
-    // Download the object using HttpUrlConnection (since v1.1)
-    // Capture the response body to a byte array.
-    URL presignedUrl = new URL(url.toExternalForm());
-    HttpURLConnection connection = (HttpURLConnection) 
presignedUrl.openConnection();
-    connection.setRequestMethod("GET");
-    // Download the result of executing the request.
-    try (InputStream s3is = connection.getInputStream();
-         ByteArrayOutputStream bos = new ByteArrayOutputStream(
-             content.getBytes(StandardCharsets.UTF_8).length)) {
-      IOUtils.copy(s3is, bos);
-      assertEquals(content, bos.toString("UTF-8"));
-    }
-  }
+      InputStream is = new 
ByteArrayInputStream(CONTENT.getBytes(StandardCharsets.UTF_8));
 
-  @Test
-  public void testPresignedUrlHead() throws IOException {
-    final String bucketName = getBucketName();
-    final String keyName = getKeyName();
-    final String content = "bar";
-    s3Client.createBucket(bucketName);
+      s3Client.putObject(BUCKET_NAME, keyName, is, new ObjectMetadata());
 
-    InputStream is = new 
ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
-    s3Client.putObject(bucketName, keyName, is, new ObjectMetadata());
+      // Generate the presigned URL
+      GeneratePresignedUrlRequest generatePresignedUrlRequest =
+          new GeneratePresignedUrlRequest(BUCKET_NAME, 
keyName).withMethod(HttpMethod.GET).withExpiration(expiration);
+      generatePresignedUrlRequest.addRequestParameter("x-custom-parameter", 
"custom-value");
+      URL presignedUrl = 
s3Client.generatePresignedUrl(generatePresignedUrlRequest);
 
-    // Set the presigned URL to expire after one hour.
-    Date expiration = Date.from(Instant.now().plusMillis(1000 * 60 * 60));
-
-    // Test HeadObject presigned URL
-    GeneratePresignedUrlRequest generatePresignedUrlRequest =
-        new GeneratePresignedUrlRequest(bucketName, keyName)
-            .withMethod(HttpMethod.HEAD)
-            .withExpiration(expiration);
-    URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
-
-    URL presignedUrl = new URL(url.toExternalForm());
-    HttpURLConnection connection = null;
-    try {
-      connection = (HttpURLConnection) presignedUrl.openConnection();
-      connection.setRequestMethod("HEAD");
-
-      int responseCode = connection.getResponseCode();
-      assertEquals(200, responseCode, "HeadObject presigned URL should return 
200 OK");
-    } finally {
-      if (connection != null) {
-        connection.disconnect();
+      // Download the object using HttpUrlConnection (since v1.1)
+      // Capture the response body to a byte array.
+      HttpURLConnection connection = 
S3SDKTestUtils.openHttpURLConnection(presignedUrl, "GET", null, null);
+      // Download the result of executing the request.
+      try (InputStream s3is = connection.getInputStream();
+           ByteArrayOutputStream bos = new 
ByteArrayOutputStream(CONTENT.getBytes(StandardCharsets.UTF_8).length)) {
+        IOUtils.copy(s3is, bos);
+        assertEquals(CONTENT, bos.toString("UTF-8"));
       }
     }
 
-    // Test HeadBucket presigned URL
-    GeneratePresignedUrlRequest generateBucketPresignedUrlRequest =
-        new GeneratePresignedUrlRequest(bucketName, null)
-            .withMethod(HttpMethod.HEAD)
-            .withExpiration(expiration);
-    URL bucketUrl = 
s3Client.generatePresignedUrl(generateBucketPresignedUrlRequest);
-
-    URL presignedBucketUrl = new URL(bucketUrl.toExternalForm());
-    HttpURLConnection bucketConnection = null;
-    try {
-      bucketConnection = (HttpURLConnection) 
presignedBucketUrl.openConnection();
-      bucketConnection.setRequestMethod("HEAD");
-
-      int bucketResponseCode = bucketConnection.getResponseCode();
-      assertEquals(200, bucketResponseCode, "HeadBucket presigned URL should 
return 200 OK");
-    } finally {
-      if (bucketConnection != null) {
-        bucketConnection.disconnect();
+    @Test
+    public void testPresignedUrlHead() throws IOException {
+      final String keyName = getKeyName();
+
+      InputStream is = new 
ByteArrayInputStream(CONTENT.getBytes(StandardCharsets.UTF_8));
+      s3Client.putObject(BUCKET_NAME, keyName, is, new ObjectMetadata());
+
+      // Test HeadObject presigned URL
+      GeneratePresignedUrlRequest generatePresignedUrlRequest =
+          new GeneratePresignedUrlRequest(BUCKET_NAME, 
keyName).withMethod(HttpMethod.HEAD).withExpiration(expiration);
+      URL presignedUrl = 
s3Client.generatePresignedUrl(generatePresignedUrlRequest);
+
+      HttpURLConnection connection = null;
+      try {
+        connection = S3SDKTestUtils.openHttpURLConnection(presignedUrl, 
"HEAD", null, null);
+        int responseCode = connection.getResponseCode();
+        assertEquals(200, responseCode, "HeadObject presigned URL should 
return 200 OK");
+      } finally {
+        if (connection != null) {
+          connection.disconnect();
+        }
       }
-    }
-  }
-
-  @Test
-  public void testPresignedUrlPutObject() throws Exception {
-    final String bucketName = getBucketName();
-    final String keyName = getKeyName();
-    final String expectedContent = "bar";
-    s3Client.createBucket(bucketName);
 
-    // Set the presigned URL to expire after one hour.
-    Date expiration = Date.from(Instant.now().plusMillis(1000 * 60 * 60));
-
-    // Test PutObjectRequest presigned URL
-    GeneratePresignedUrlRequest generatePresignedUrlRequest =
-        new GeneratePresignedUrlRequest(bucketName, keyName)
-            .withMethod(HttpMethod.PUT)
-            .withExpiration(expiration);
-    URL presignedUrl = 
s3Client.generatePresignedUrl(generatePresignedUrlRequest);
-
-    HttpURLConnection connection = null;
-    try {
-      connection = (HttpURLConnection) presignedUrl.openConnection();
-      connection.setRequestMethod("PUT");
-      connection.setDoOutput(true);
-      try (OutputStream os = connection.getOutputStream()) {
-        os.write(expectedContent.getBytes(StandardCharsets.UTF_8));
-        os.flush();
+      // Test HeadBucket presigned URL
+      GeneratePresignedUrlRequest generateBucketPresignedUrlRequest =
+          new GeneratePresignedUrlRequest(BUCKET_NAME, 
null).withMethod(HttpMethod.HEAD).withExpiration(expiration);
+      URL presignedBucketUrl = 
s3Client.generatePresignedUrl(generateBucketPresignedUrlRequest);
+
+      HttpURLConnection bucketConnection = null;
+      try {
+        bucketConnection = 
S3SDKTestUtils.openHttpURLConnection(presignedBucketUrl, "HEAD", null, null);
+        int bucketResponseCode = bucketConnection.getResponseCode();
+        assertEquals(200, bucketResponseCode, "HeadBucket presigned URL should 
return 200 OK");
+      } finally {
+        if (bucketConnection != null) {
+          bucketConnection.disconnect();
+        }
       }
+    }
 
-      int responseCode = connection.getResponseCode();
-      assertEquals(200, responseCode, "PutObject presigned URL should return 
200 OK");
-      String actualContent;
-      S3Object s3Object = s3Client.getObject(bucketName, keyName);
-      try (S3ObjectInputStream inputStream = s3Object.getObjectContent()) {
-        actualContent = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
-      }
-      assertEquals(expectedContent, actualContent, "Downloaded content should 
match uploaded content");
-    } finally {
-      if (connection != null) {
-        connection.disconnect();
+    @Test
+    public void testPresignedUrlPutObject() throws Exception {
+      final String keyName = getKeyName();
+
+      // Test PutObjectRequest presigned URL
+      GeneratePresignedUrlRequest generatePresignedUrlRequest =
+          new GeneratePresignedUrlRequest(BUCKET_NAME, 
keyName).withMethod(HttpMethod.PUT).withExpiration(expiration);
+      URL presignedUrl = 
s3Client.generatePresignedUrl(generatePresignedUrlRequest);
+
+      HttpURLConnection connection = null;
+      try {
+        connection = S3SDKTestUtils.openHttpURLConnection(presignedUrl, "PUT",
+            null, CONTENT.getBytes(StandardCharsets.UTF_8));
+        int responseCode = connection.getResponseCode();
+        assertEquals(200, responseCode, "PutObject presigned URL should return 
200 OK");
+        String actualContent;
+        S3Object s3Object = s3Client.getObject(BUCKET_NAME, keyName);
+        try (S3ObjectInputStream inputStream = s3Object.getObjectContent()) {
+          actualContent = IOUtils.toString(inputStream, 
StandardCharsets.UTF_8);
+        }
+        assertEquals(CONTENT, actualContent, "Downloaded content should match 
uploaded content");
+      } finally {
+        if (connection != null) {
+          connection.disconnect();
+        }
       }
     }
-  }
 
-  @Test
-  public void testPresignedUrlMultipartUpload(@TempDir Path tempDir) throws 
Exception {
-    final String bucketName = getBucketName();
-    final String keyName = getKeyName();
-    final Map<String, String> userMetadata = new HashMap<>();
-    userMetadata.put("key1", "value1");
-    userMetadata.put("key2", "value2");
-    final Map<String, String> tags = new HashMap<>();
-    tags.put("tag1", "value1");
-    tags.put("tag2", "value2");
-
-    s3Client.createBucket(bucketName);
+    @Test
+    public void testPresignedUrlMultipartUpload(@TempDir Path tempDir) throws 
Exception {
+      final String keyName = getKeyName();
+      final Map<String, String> userMetadata = new HashMap<>();
+      userMetadata.put("key1", "value1");
+      userMetadata.put("key2", "value2");
+      final Map<String, String> tags = new HashMap<>();
+      tags.put("tag1", "value1");
+      tags.put("tag2", "value2");
 
-    File multipartUploadFile = 
Files.createFile(tempDir.resolve("multipartupload.txt")).toFile();
-    createFile(multipartUploadFile, (int) (10 * MB));
+      File multipartUploadFile = 
Files.createFile(tempDir.resolve("multipartupload.txt")).toFile();
+      createFile(multipartUploadFile, (int) (10 * MB));
 
-    // create MPU using presigned URL
-    GeneratePresignedUrlRequest initMPUPresignedUrlRequest =
-        createInitMPUPresignedUrlRequest(bucketName, keyName, userMetadata, 
tags);
+      // create MPU using presigned URL
+      GeneratePresignedUrlRequest initMPUPresignedUrlRequest =
+          createInitMPUPresignedUrlRequest(keyName, userMetadata, tags);
 
 
-    String uploadId = initMultipartUpload(initMPUPresignedUrlRequest);
+      String uploadId = initMultipartUpload(initMPUPresignedUrlRequest);
 
-    // upload parts using presigned URL
-    List<PartETag> completedParts = uploadParts(multipartUploadFile, 
bucketName, keyName, uploadId);
+      // upload parts using presigned URL
+      List<PartETag> completedParts = uploadParts(multipartUploadFile, 
keyName, uploadId);
 
-    // Complete multipart upload using presigned URL
-    completeMPU(bucketName, keyName, uploadId, completedParts);
+      // Complete multipart upload using presigned URL
+      completeMPU(keyName, uploadId, completedParts);
 
-    // Verify upload result
-    ObjectMetadata objectMeta = s3Client.getObjectMetadata(bucketName, 
keyName);
-    assertEquals(userMetadata, objectMeta.getUserMetadata());
+      // Verify upload result
+      ObjectMetadata objectMeta = s3Client.getObjectMetadata(BUCKET_NAME, 
keyName);
+      assertEquals(userMetadata, objectMeta.getUserMetadata());
 
-    // Verify content
-    S3Object s3Object = s3Client.getObject(bucketName, keyName);
-    assertEquals(tags.size(), s3Object.getTaggingCount());
-    String actualContent;
-    try (S3ObjectInputStream inputStream = s3Object.getObjectContent()) {
-      actualContent = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
+      // Verify content
+      S3Object s3Object = s3Client.getObject(BUCKET_NAME, keyName);
+      assertEquals(tags.size(), s3Object.getTaggingCount());
+      String actualContent;
+      try (S3ObjectInputStream inputStream = s3Object.getObjectContent()) {
+        actualContent = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
+      }
+      String expectedContent = new 
String(Files.readAllBytes(multipartUploadFile.toPath()), 
StandardCharsets.UTF_8);
+      assertEquals(expectedContent, actualContent, "Downloaded content should 
match uploaded content");
     }
-    String expectedContent = new 
String(Files.readAllBytes(multipartUploadFile.toPath()), 
StandardCharsets.UTF_8);
-    assertEquals(expectedContent, actualContent, "Downloaded content should 
match uploaded content");
-  }
 
-  private static void completeMPU(String bucketName, String keyName, String 
uploadId, List<PartETag> completedParts)
-      throws IOException {
-    GeneratePresignedUrlRequest request = new 
GeneratePresignedUrlRequest(bucketName, keyName)
-        .withMethod(HttpMethod.POST)
-        .withExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60));
-    request.addRequestParameter("uploadId", uploadId);
+    private void completeMPU(String keyName, String uploadId, List<PartETag> 
completedParts) throws IOException {
+      GeneratePresignedUrlRequest request =
+          new GeneratePresignedUrlRequest(BUCKET_NAME, 
keyName).withMethod(HttpMethod.POST).withExpiration(expiration);
+      request.addRequestParameter("uploadId", uploadId);
 
-    HttpURLConnection httpConnection = null;
-    try {
-      httpConnection = (HttpURLConnection) 
s3Client.generatePresignedUrl(request).openConnection();
-      httpConnection.setRequestMethod("POST");
-      httpConnection.setDoOutput(true);
+      URL presignedUrl = s3Client.generatePresignedUrl(request);
 
       // Generate completion XML payload
       StringBuilder completionXml = new StringBuilder();
@@ -1262,154 +1227,150 @@ private static void completeMPU(String bucketName, 
String keyName, String upload
       completionXml.append("</CompleteMultipartUpload>");
 
       byte[] completionPayloadBytes = 
completionXml.toString().getBytes(StandardCharsets.UTF_8);
-      try (OutputStream os = httpConnection.getOutputStream()) {
-        IOUtils.write(completionPayloadBytes, os);
-      }
 
-      int responseCode = httpConnection.getResponseCode();
-      assertEquals(200, responseCode, "Complete multipart upload should return 
200 OK");
-    } finally {
-      if (httpConnection != null) {
-        httpConnection.disconnect();
+      HttpURLConnection httpConnection = null;
+      try {
+        httpConnection = S3SDKTestUtils.openHttpURLConnection(presignedUrl, 
"POST", null, completionPayloadBytes);
+        int responseCode = httpConnection.getResponseCode();
+        assertEquals(200, responseCode, "Complete multipart upload should 
return 200 OK");
+      } finally {
+        if (httpConnection != null) {
+          httpConnection.disconnect();
+        }
       }
     }
-  }
 
-  private static List<PartETag> uploadParts(File multipartUploadFile, String 
bucketName, String keyName,
-                                             String uploadId) throws 
IOException {
-    List<PartETag> completedParts = new ArrayList<>();
-    ByteBuffer byteBuffer = ByteBuffer.allocate((int) (5 * MB));
-    long filePosition = 0;
-    long fileLength = multipartUploadFile.length();
-    int partNumber = 1;
-
-    try (RandomAccessFile file = new RandomAccessFile(multipartUploadFile, 
"r")) {
-      while (filePosition < fileLength) {
-        file.seek(filePosition);
-        long bytesRead = file.getChannel().read(byteBuffer);
-        byteBuffer.flip();
-
-        // generate presigned URL for each part
-        GeneratePresignedUrlRequest request = new 
GeneratePresignedUrlRequest(bucketName, keyName)
-            .withMethod(HttpMethod.PUT)
-            .withExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 
60));
-        request.addRequestParameter("partNumber", String.valueOf(partNumber));
-        request.addRequestParameter("uploadId", uploadId);
-
-        URL presignedUrl = s3Client.generatePresignedUrl(request);
-
-        // upload each part using presigned URL
-        HttpURLConnection connection = null;
-        try {
-          connection = (HttpURLConnection) presignedUrl.openConnection();
-          connection.setDoOutput(true);
-          connection.setRequestMethod("PUT");
-          connection.setRequestProperty("Content-Length", 
String.valueOf(byteBuffer.remaining()));
-
-          try (OutputStream os = connection.getOutputStream()) {
-            os.write(byteBuffer.array(), 0, byteBuffer.remaining());
-            os.flush();
+    private List<PartETag> uploadParts(File multipartUploadFile, String 
keyName, String uploadId) throws IOException {
+      List<PartETag> completedParts = new ArrayList<>();
+      ByteBuffer byteBuffer = ByteBuffer.allocate((int) (5 * MB));
+      long filePosition = 0;
+      long fileLength = multipartUploadFile.length();
+      int partNumber = 1;
+
+      try (RandomAccessFile file = new RandomAccessFile(multipartUploadFile, 
"r")) {
+        while (filePosition < fileLength) {
+          file.seek(filePosition);
+          long bytesRead = file.getChannel().read(byteBuffer);
+          byteBuffer.flip();
+
+          // generate presigned URL for each part
+          GeneratePresignedUrlRequest request =
+              new GeneratePresignedUrlRequest(BUCKET_NAME, 
keyName).withMethod(HttpMethod.PUT)
+                  .withExpiration(expiration);
+          request.addRequestParameter("partNumber", 
String.valueOf(partNumber));
+          request.addRequestParameter("uploadId", uploadId);
+
+          URL presignedUrl = s3Client.generatePresignedUrl(request);
+
+          // upload each part using presigned URL
+          HttpURLConnection connection = null;
+          try {
+            Map<String, List<String>> headers = new HashMap<>();
+            List<String> header = 
Collections.singletonList(String.valueOf(byteBuffer.remaining()));
+            headers.put("Content-Length", header);
+            byte[] body = new byte[byteBuffer.remaining()];
+            byteBuffer.get(body);
+
+            connection = S3SDKTestUtils.openHttpURLConnection(presignedUrl, 
"PUT", headers, body);
+            int responseCode = connection.getResponseCode();
+            assertEquals(200, responseCode, String.format("Upload part %d 
should return 200 OK", partNumber));
+
+            String etag = connection.getHeaderField("ETag");
+            PartETag partETag = new PartETag(partNumber, etag);
+            completedParts.add(partETag);
+          } finally {
+            if (connection != null) {
+              connection.disconnect();
+            }
           }
 
-          int responseCode = connection.getResponseCode();
-          assertEquals(200, responseCode, String.format("Upload part %d should 
return 200 OK", partNumber));
+          byteBuffer.clear();
+          filePosition += bytesRead;
+          partNumber++;
+        }
+      }
+      return completedParts;
+    }
 
-          String etag = connection.getHeaderField("ETag");
-          PartETag partETag = new PartETag(partNumber, etag);
-          completedParts.add(partETag);
-        } finally {
-          if (connection != null) {
-            connection.disconnect();
+    private String initMultipartUpload(GeneratePresignedUrlRequest request) 
throws IOException {
+      URL presignedUrl = s3Client.generatePresignedUrl(request);
+      String uploadId;
+      HttpURLConnection httpConnection = null;
+      try {
+        Map<String, String> customRequestHeaders = 
request.getCustomRequestHeaders();
+        Map<String, List<String>> headers = new HashMap<>();
+        if (customRequestHeaders != null) {
+          for (Map.Entry<String, String> entry : 
customRequestHeaders.entrySet()) {
+            headers.put(entry.getKey(), 
Collections.singletonList(entry.getValue()));
           }
         }
+        httpConnection = S3SDKTestUtils.openHttpURLConnection(presignedUrl, 
"POST", headers, null);
+        int initMPUConnectionResponseCode = httpConnection.getResponseCode();
+        assertEquals(200, initMPUConnectionResponseCode);
 
-        byteBuffer.clear();
-        filePosition += bytesRead;
-        partNumber++;
+        try (InputStream is = httpConnection.getInputStream()) {
+          String responseXml = IOUtils.toString(is, StandardCharsets.UTF_8);
+          uploadId = S3SDKTestUtils.extractUploadId(responseXml);
+        }
+      } finally {
+        if (httpConnection != null) {
+          httpConnection.disconnect();
+        }
       }
+      return uploadId;
     }
-    return completedParts;
-  }
 
-  private String initMultipartUpload(GeneratePresignedUrlRequest request) 
throws IOException {
-    URL presignedUrl = s3Client.generatePresignedUrl(request);
-    String uploadId;
-    HttpURLConnection httpConnection = null;
-    try {
-      httpConnection = (HttpURLConnection) presignedUrl.openConnection();
-      httpConnection.setRequestMethod("POST");
-      httpConnection.setDoOutput(true);
-      
request.getCustomRequestHeaders().forEach(httpConnection::setRequestProperty);
-
-      httpConnection.connect();
-      int initMPUConnectionResponseCode = httpConnection.getResponseCode();
-      assertEquals(200, initMPUConnectionResponseCode);
-      try (InputStream is = httpConnection.getInputStream()) {
-        String responseXml = IOUtils.toString(is, StandardCharsets.UTF_8);
-        uploadId = S3SDKTestUtils.extractUploadId(responseXml);
-      }
-    } finally {
-      if (httpConnection != null) {
-        httpConnection.disconnect();
+    private GeneratePresignedUrlRequest 
createInitMPUPresignedUrlRequest(String keyName,
+                                                                         
Map<String, String> userMetadata,
+                                                                         
Map<String, String> tags) throws Exception {
+      GeneratePresignedUrlRequest initMPUPresignUrlRequest =
+          new GeneratePresignedUrlRequest(BUCKET_NAME, 
keyName).withMethod(HttpMethod.POST).withExpiration(expiration);
+
+      userMetadata.forEach((k, v) -> {
+        
initMPUPresignUrlRequest.putCustomRequestHeader(CUSTOM_METADATA_HEADER_PREFIX + 
k, v);
+      });
+
+      StringBuilder tagValueBuilder = new StringBuilder();
+      for (Map.Entry<String, String> entry : tags.entrySet()) {
+        if (tagValueBuilder.length() > 0) {
+          tagValueBuilder.append('&');
+        }
+        
tagValueBuilder.append(entry.getKey()).append('=').append(URLEncoder.encode(entry.getValue(),
 "UTF-8"));
       }
+      initMPUPresignUrlRequest.putCustomRequestHeader(S3Consts.TAG_HEADER, 
tagValueBuilder.toString());
+      return initMPUPresignUrlRequest;
     }
-    return uploadId;
-  }
 
-  private GeneratePresignedUrlRequest createInitMPUPresignedUrlRequest(String 
bucketName, String keyName,
-                                                                       
Map<String, String> userMetadata,
-                                                                       
Map<String, String> tags) throws Exception {
-    GeneratePresignedUrlRequest initMPUPresignUrlRequest = new 
GeneratePresignedUrlRequest(bucketName, keyName)
-        .withMethod(HttpMethod.POST)
-        .withExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60));
-
-    userMetadata.forEach((k, v) -> {
-      
initMPUPresignUrlRequest.putCustomRequestHeader(CUSTOM_METADATA_HEADER_PREFIX + 
k, v);
-    });
-
-    StringBuilder tagValueBuilder = new StringBuilder();
-    for (Map.Entry<String, String> entry : tags.entrySet()) {
-      if (tagValueBuilder.length() > 0) {
-        tagValueBuilder.append('&');
+    @Test
+    public void testPresignedUrlDelete() throws IOException {
+      final String keyName = getKeyName();
+
+      try (InputStream is = new 
ByteArrayInputStream(CONTENT.getBytes(StandardCharsets.UTF_8))) {
+        s3Client.putObject(BUCKET_NAME, keyName, is, new ObjectMetadata());
       }
-      
tagValueBuilder.append(entry.getKey()).append('=').append(URLEncoder.encode(entry.getValue(),
 "UTF-8"));
-    }
-    initMPUPresignUrlRequest.putCustomRequestHeader(S3Consts.TAG_HEADER, 
tagValueBuilder.toString());
-    return initMPUPresignUrlRequest;
-  }
 
-  @Test
-  public void testPresignedUrlDelete() throws IOException {
-    final String bucketName = getBucketName();
-    final String keyName = getKeyName();
-    final String content = "bar";
+      // Generate the presigned URL for DELETE
+      GeneratePresignedUrlRequest generatePresignedUrlRequest =
+          new GeneratePresignedUrlRequest(BUCKET_NAME, 
keyName).withMethod(HttpMethod.DELETE)
+              .withExpiration(expiration);
+      URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
+
+      // Execute the DELETE request using HttpUrlConnection
+      HttpURLConnection connection = null;
+      try {
+        connection = S3SDKTestUtils.openHttpURLConnection(url, "DELETE", null, 
null);
+        int responseCode = connection.getResponseCode();
+        // Verify the response code is 204 (No Content)
+        assertEquals(HttpURLConnection.HTTP_NO_CONTENT, responseCode);
+      } finally {
+        if (connection != null) {
+          connection.disconnect();
+        }
+      }
 
-    s3Client.createBucket(bucketName);
-    try (InputStream is = new 
ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))) {
-      s3Client.putObject(bucketName, keyName, is, new ObjectMetadata());
+      // Verify the object is deleted
+      assertFalse(s3Client.doesObjectExist(BUCKET_NAME, keyName));
     }
-
-    // Set the presigned URL to expire after one hour.
-    Date expiration = Date.from(Instant.now().plusMillis(1000 * 60 * 60));
-
-    // Generate the presigned URL for DELETE
-    GeneratePresignedUrlRequest generatePresignedUrlRequest =
-        new GeneratePresignedUrlRequest(bucketName, keyName)
-            .withMethod(HttpMethod.DELETE)
-            .withExpiration(expiration);
-    URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
-
-    // Execute the DELETE request using HttpUrlConnection
-    URL presignedUrl = new URL(url.toExternalForm());
-    HttpURLConnection connection = (HttpURLConnection) 
presignedUrl.openConnection();
-    connection.setRequestMethod("DELETE");
-    int responseCode = connection.getResponseCode();
-
-    // Verify the response code is 204 (No Content)
-    assertEquals(HttpURLConnection.HTTP_NO_CONTENT, responseCode);
-
-    // Verify the object is deleted
-    assertFalse(s3Client.doesObjectExist(bucketName, keyName));
   }
 
   /**
diff --git 
a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v2/AbstractS3SDKV2Tests.java
 
b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v2/AbstractS3SDKV2Tests.java
index 31f58c6d9a2..79928c3264f 100644
--- 
a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v2/AbstractS3SDKV2Tests.java
+++ 
b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v2/AbstractS3SDKV2Tests.java
@@ -33,7 +33,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 import java.io.RandomAccessFile;
 import java.net.HttpURLConnection;
 import java.net.URL;
@@ -72,6 +71,7 @@
 import org.apache.hadoop.ozone.s3.endpoint.S3Owner;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.ozone.test.OzoneTestBase;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.MethodOrderer;
 import org.junit.jupiter.api.Nested;
@@ -456,26 +456,46 @@ public void testResumableDownloadWithEtagMismatch() 
throws Exception {
     }
   }
 
-  @Test
-  public void testPresignedUrlGet() throws Exception {
-    final String bucketName = getBucketName();
-    final String keyName = getKeyName();
-    final String content = "bar";
-    s3Client.createBucket(b -> b.bucket(bucketName));
+  @Nested
+  @TestInstance(TestInstance.Lifecycle.PER_CLASS)
+  class PresignedUrlTests {
+    private static final String CONTENT = "bar";
+    private static final String BUCKET_NAME = "presigned-url-bucket";
+    private final SdkHttpClient sdkHttpClient = ApacheHttpClient.create();
+    // The URL will expire in 10 minutes.
+    private final Duration duration = Duration.ofMinutes(10);
+    private S3Presigner presigner;
 
-    s3Client.putObject(b -> b
-            .bucket(bucketName)
-            .key(keyName),
-        RequestBody.fromString(content));
+    @BeforeAll
+    public void setup() {
+      s3Client.createBucket(b -> b.bucket(BUCKET_NAME));
+      presigner = S3Presigner.builder()
+          // TODO: Find a way to retrieve the path style configuration from 
S3Client instead
+          
.serviceConfiguration(S3Configuration.builder().pathStyleAccessEnabled(true).build())
+          
.endpointOverride(s3Client.serviceClientConfiguration().endpointOverride().get())
+          .region(s3Client.serviceClientConfiguration().region())
+          
.credentialsProvider(s3Client.serviceClientConfiguration().credentialsProvider()).build();
+    }
 
-    try (S3Presigner presigner = createS3Presigner()) {
-      GetObjectRequest objectRequest = GetObjectRequest.builder()
-          .bucket(bucketName)
-          .key(keyName)
-          .build();
+    @AfterAll
+    public void tearDown() {
+      presigner.close();
+      sdkHttpClient.close();
+    }
+
+    @Test
+    public void testPresignedUrlGet() throws Exception {
+      final String keyName = getKeyName();
+
+      s3Client.putObject(b -> b
+              .bucket(BUCKET_NAME)
+              .key(keyName),
+          RequestBody.fromString(CONTENT));
+
+      GetObjectRequest objectRequest = 
GetObjectRequest.builder().bucket(BUCKET_NAME).key(keyName).build();
 
       GetObjectPresignRequest presignRequest = 
GetObjectPresignRequest.builder()
-          .signatureDuration(Duration.ofMinutes(10))  // The URL will expire 
in 10 minutes.
+          .signatureDuration(duration)
           .getObjectRequest(objectRequest)
           .build();
 
@@ -484,66 +504,46 @@ public void testPresignedUrlGet() throws Exception {
       // Download the object using HttpUrlConnection (since v1.1)
       // Capture the response body to a byte array.
       URL presignedUrl = presignedRequest.url();
-      HttpURLConnection connection = (HttpURLConnection) 
presignedUrl.openConnection();
-      connection.setRequestMethod("GET");
+      HttpURLConnection connection = 
S3SDKTestUtils.openHttpURLConnection(presignedUrl, "GET", null, null);
       // Download the result of executing the request.
       try (InputStream s3is = connection.getInputStream();
-           ByteArrayOutputStream bos = new ByteArrayOutputStream(
-               content.getBytes(StandardCharsets.UTF_8).length)) {
+           ByteArrayOutputStream bos = new 
ByteArrayOutputStream(CONTENT.getBytes(StandardCharsets.UTF_8).length)) {
         IoUtils.copy(s3is, bos);
-        assertEquals(content, bos.toString("UTF-8"));
+        assertEquals(CONTENT, bos.toString("UTF-8"));
+      } finally {
+        connection.disconnect();
       }
 
       // Use the AWS SDK for Java SdkHttpClient class to do the download
-      SdkHttpRequest request = SdkHttpRequest.builder()
-          .method(SdkHttpMethod.GET)
-          .uri(presignedUrl.toURI())
-          .build();
+      SdkHttpRequest request = 
SdkHttpRequest.builder().method(SdkHttpMethod.GET).uri(presignedUrl.toURI()).build();
 
-      HttpExecuteRequest executeRequest = HttpExecuteRequest.builder()
-          .request(request)
-          .build();
+      HttpExecuteRequest executeRequest = 
HttpExecuteRequest.builder().request(request).build();
 
-      try (SdkHttpClient sdkHttpClient = ApacheHttpClient.create();
-           ByteArrayOutputStream bos = new ByteArrayOutputStream(
-               content.getBytes(StandardCharsets.UTF_8).length)) {
+      try (ByteArrayOutputStream bos = new 
ByteArrayOutputStream(CONTENT.getBytes(StandardCharsets.UTF_8).length)) {
         HttpExecuteResponse response = 
sdkHttpClient.prepareRequest(executeRequest).call();
-        assertTrue(response.responseBody().isPresent(), () -> "The presigned 
url download request " +
-            "should have a response body");
-        response.responseBody().ifPresent(
-            abortableInputStream -> {
-              try {
-                IoUtils.copy(abortableInputStream, bos);
-              } catch (IOException e) {
-                throw new RuntimeException(e);
-              }
-            });
-        assertEquals(content, bos.toString("UTF-8"));
+        assertTrue(response.responseBody().isPresent(),
+            () -> "The presigned url download request " + "should have a 
response body");
+        response.responseBody().ifPresent(abortableInputStream -> {
+          try {
+            IoUtils.copy(abortableInputStream, bos);
+          } catch (IOException e) {
+            throw new RuntimeException(e);
+          }
+        });
+        assertEquals(CONTENT, bos.toString("UTF-8"));
       }
     }
-  }
 
-  @Test
-  public void testPresignedUrlHead() throws Exception {
-    final String bucketName = getBucketName();
-    final String keyName = getKeyName();
-    final String content = "bar";
-    s3Client.createBucket(b -> b.bucket(bucketName));
-
-    s3Client.putObject(b -> b
-            .bucket(bucketName)
-            .key(keyName),
-        RequestBody.fromString(content));
+    @Test
+    public void testPresignedUrlHead() throws Exception {
+      final String keyName = getKeyName();
 
-    try (S3Presigner presigner = createS3Presigner()) {
+      s3Client.putObject(b -> b.bucket(BUCKET_NAME).key(keyName), 
RequestBody.fromString(CONTENT));
 
-      HeadObjectRequest objectRequest = HeadObjectRequest.builder()
-          .bucket(bucketName)
-          .key(keyName)
-          .build();
+      HeadObjectRequest objectRequest = 
HeadObjectRequest.builder().bucket(BUCKET_NAME).key(keyName).build();
 
       HeadObjectPresignRequest presignRequest = 
HeadObjectPresignRequest.builder()
-          .signatureDuration(Duration.ofMinutes(10))
+          .signatureDuration(duration)
           .headObjectRequest(objectRequest)
           .build();
 
@@ -552,40 +552,29 @@ public void testPresignedUrlHead() throws Exception {
       URL presignedUrl = presignedRequest.url();
       HttpURLConnection connection = null;
       try {
-        connection = (HttpURLConnection) presignedUrl.openConnection();
-        connection.setRequestMethod("HEAD");
-
+        connection = S3SDKTestUtils.openHttpURLConnection(presignedUrl, 
"HEAD", null, null);
         int responseCode = connection.getResponseCode();
         assertEquals(200, responseCode, "HeadObject presigned URL should 
return 200 OK");
-
-        // Use the AWS SDK for Java SdkHttpClient class to test the HEAD 
request
-        SdkHttpRequest request = SdkHttpRequest.builder()
-            .method(SdkHttpMethod.HEAD)
-            .uri(presignedUrl.toURI())
-            .build();
-
-        HttpExecuteRequest executeRequest = HttpExecuteRequest.builder()
-            .request(request)
-            .build();
-
-        try (SdkHttpClient sdkHttpClient = ApacheHttpClient.create()) {
-          HttpExecuteResponse response = 
sdkHttpClient.prepareRequest(executeRequest).call();
-          assertEquals(200, response.httpResponse().statusCode(),
-              "HeadObject presigned URL should return 200 OK via 
SdkHttpClient");
-        }
       } finally {
         if (connection != null) {
           connection.disconnect();
         }
       }
 
+      // Use the AWS SDK for Java SdkHttpClient class to test the HEAD request
+      SdkHttpRequest request = 
SdkHttpRequest.builder().method(SdkHttpMethod.HEAD).uri(presignedUrl.toURI()).build();
+
+      HttpExecuteRequest executeRequest = 
HttpExecuteRequest.builder().request(request).build();
+
+      HttpExecuteResponse response = 
sdkHttpClient.prepareRequest(executeRequest).call();
+      assertEquals(200, response.httpResponse().statusCode(),
+          "HeadObject presigned URL should return 200 OK via SdkHttpClient");
+
       // Test HeadBucket presigned URL
-      HeadBucketRequest bucketRequest = HeadBucketRequest.builder()
-          .bucket(bucketName)
-          .build();
+      HeadBucketRequest bucketRequest = 
HeadBucketRequest.builder().bucket(BUCKET_NAME).build();
 
       HeadBucketPresignRequest headBucketPresignRequest = 
HeadBucketPresignRequest.builder()
-          .signatureDuration(Duration.ofMinutes(10))
+          .signatureDuration(duration)
           .headBucketRequest(bucketRequest)
           .build();
 
@@ -594,50 +583,35 @@ public void testPresignedUrlHead() throws Exception {
       URL presignedBucketUrl = presignedBucketRequest.url();
       HttpURLConnection bucketConnection = null;
       try {
-        bucketConnection = (HttpURLConnection) 
presignedBucketUrl.openConnection();
-        bucketConnection.setRequestMethod("HEAD");
-
+        bucketConnection = 
S3SDKTestUtils.openHttpURLConnection(presignedBucketUrl, "HEAD", null, null);
         int bucketResponseCode = bucketConnection.getResponseCode();
         assertEquals(200, bucketResponseCode, "HeadBucket presigned URL should 
return 200 OK");
-
-        // Use the AWS SDK for Java SdkHttpClient class to test the HEAD 
request for bucket
-        SdkHttpRequest bucketSdkRequest = SdkHttpRequest.builder()
-            .method(SdkHttpMethod.HEAD)
-            .uri(presignedBucketUrl.toURI())
-            .build();
-
-        HttpExecuteRequest bucketExecuteRequest = HttpExecuteRequest.builder()
-            .request(bucketSdkRequest)
-            .build();
-
-        try (SdkHttpClient sdkHttpClient = ApacheHttpClient.create()) {
-          HttpExecuteResponse response = 
sdkHttpClient.prepareRequest(bucketExecuteRequest).call();
-          assertEquals(200, response.httpResponse().statusCode(),
-              "HeadBucket presigned URL should return 200 OK via 
SdkHttpClient");
-        }
       } finally {
         if (bucketConnection != null) {
           bucketConnection.disconnect();
         }
       }
-    }
-  }
 
-  @Test
-  public void testPresignedUrlPut() throws Exception {
-    final String bucketName = getBucketName();
-    final String keyName = getKeyName();
-    s3Client.createBucket(b -> b.bucket(bucketName));
+      // Use the AWS SDK for Java SdkHttpClient class to test the HEAD request 
for bucket
+      SdkHttpRequest bucketSdkRequest = SdkHttpRequest.builder()
+          .method(SdkHttpMethod.HEAD)
+          .uri(presignedBucketUrl.toURI())
+          .build();
+      HttpExecuteRequest bucketExecuteRequest = 
HttpExecuteRequest.builder().request(bucketSdkRequest).build();
 
-    try (S3Presigner presigner = createS3Presigner()) {
+      HttpExecuteResponse bucketResponse = 
sdkHttpClient.prepareRequest(bucketExecuteRequest).call();
+      assertEquals(200, bucketResponse.httpResponse().statusCode(),
+          "HeadBucket presigned URL should return 200 OK via SdkHttpClient");
+    }
 
-      PutObjectRequest objectRequest = PutObjectRequest.builder()
-          .bucket(bucketName)
-          .key(keyName)
-          .build();
+    @Test
+    public void testPresignedUrlPut() throws Exception {
+      final String keyName = getKeyName();
+
+      PutObjectRequest objectRequest = 
PutObjectRequest.builder().bucket(BUCKET_NAME).key(keyName).build();
 
       PutObjectPresignRequest presignRequest = 
PutObjectPresignRequest.builder()
-          .signatureDuration(Duration.ofMinutes(10))
+          .signatureDuration(duration)
           .putObjectRequest(objectRequest)
           .build();
 
@@ -645,460 +619,371 @@ public void testPresignedUrlPut() throws Exception {
 
       // use http url connection
       HttpURLConnection connection = null;
-      String expectedContent;
       String actualContent;
       try {
-        expectedContent = "This is a test content for presigned PUT URL.";
-        connection = (HttpURLConnection) 
presignedRequest.url().openConnection();
-        connection.setRequestMethod("PUT");
-        connection.setDoOutput(true);
-        try (OutputStream os = connection.getOutputStream()) {
-          os.write(expectedContent.getBytes(StandardCharsets.UTF_8));
-          os.flush();
-        }
-
+        connection = 
S3SDKTestUtils.openHttpURLConnection(presignedRequest.url(), "PUT",
+            presignedRequest.signedHeaders(), 
CONTENT.getBytes(StandardCharsets.UTF_8));
         int responseCode = connection.getResponseCode();
         assertEquals(200, responseCode, "PutObject presigned URL should return 
200 OK");
-
-        //verify the object was uploaded
-        ResponseInputStream<GetObjectResponse> object1 = s3Client.getObject(b1 
-> b1.bucket(bucketName).key(keyName));
-        actualContent = IoUtils.toUtf8String(object1);
-        assertEquals(expectedContent, actualContent);
-
-        // Use the AWS SDK for Java SdkHttpClient class to test the PUT request
-        expectedContent = "This content is for testing the SdkHttpClient PUT 
request.";
-        SdkHttpRequest request = SdkHttpRequest.builder()
-            .method(SdkHttpMethod.PUT)
-            .uri(presignedRequest.url().toURI())
-            .build();
-
-        byte[] bytes = expectedContent.getBytes(StandardCharsets.UTF_8);
-        HttpExecuteRequest executeRequest = HttpExecuteRequest.builder()
-            .request(request)
-            .contentStreamProvider(() -> new ByteArrayInputStream(bytes))
-            .build();
-
-        try (SdkHttpClient sdkHttpClient = ApacheHttpClient.create()) {
-          HttpExecuteResponse response = 
sdkHttpClient.prepareRequest(executeRequest).call();
-          assertEquals(200, response.httpResponse().statusCode(),
-              "PutObject presigned URL should return 200 OK via 
SdkHttpClient");
-        }
-
-        //verify the object was uploaded
-        ResponseInputStream<GetObjectResponse> object = s3Client.getObject(b 
-> b.bucket(bucketName).key(keyName));
-        actualContent = IoUtils.toUtf8String(object);
-        assertEquals(expectedContent, actualContent);
       } finally {
         if (connection != null) {
           connection.disconnect();
         }
       }
-    }
-  }
+      //verify the object was uploaded
+      ResponseInputStream<GetObjectResponse> object1 = s3Client.getObject(b1 
-> b1.bucket(BUCKET_NAME).key(keyName));
+      actualContent = IoUtils.toUtf8String(object1);
+      assertEquals(CONTENT, actualContent);
 
-  @Test
-  public void testPresignedUrlMultipartUpload(@TempDir Path tempDir) throws 
Exception {
-    final String bucketName = getBucketName();
-    final String keyName = getKeyName();
-    final Map<String, String> userMetadata = new HashMap<>();
-    userMetadata.put("key1", "value1");
-    userMetadata.put("key2", "value2");
+      // Use the AWS SDK for Java SdkHttpClient class to test the PUT request
+      SdkHttpRequest request = SdkHttpRequest.builder()
+          .method(SdkHttpMethod.PUT)
+          .uri(presignedRequest.url().toURI())
+          .build();
 
-    List<Tag> tags = Arrays.asList(
-        Tag.builder().key("tag1").value("value1").build(),
-        Tag.builder().key("tag2").value("value2").build()
-    );
+      byte[] bytes = CONTENT.getBytes(StandardCharsets.UTF_8);
+      HttpExecuteRequest executeRequest = HttpExecuteRequest.builder()
+          .request(request)
+          .contentStreamProvider(() -> new ByteArrayInputStream(bytes))
+          .build();
 
-    s3Client.createBucket(b -> b.bucket(bucketName));
+      HttpExecuteResponse response = 
sdkHttpClient.prepareRequest(executeRequest).call();
+      assertEquals(200, response.httpResponse().statusCode(),
+          "PutObject presigned URL should return 200 OK via SdkHttpClient");
 
-    File multipartUploadFile = 
Files.createFile(tempDir.resolve("multipartupload.txt")).toFile();
-    createFile(multipartUploadFile, (int) (10 * MB));
+      //verify the object was uploaded
+      ResponseInputStream<GetObjectResponse> object = s3Client.getObject(b -> 
b.bucket(BUCKET_NAME).key(keyName));
+      actualContent = IoUtils.toUtf8String(object);
+      assertEquals(CONTENT, actualContent);
+    }
+
+    @Test
+    public void testPresignedUrlMultipartUpload(@TempDir Path tempDir) throws 
Exception {
+      final String keyName = getKeyName();
+      final Map<String, String> userMetadata = new HashMap<>();
+      userMetadata.put("key1", "value1");
+      userMetadata.put("key2", "value2");
 
-    try (S3Presigner presigner = createS3Presigner()) {
+      List<Tag> tags = 
Arrays.asList(Tag.builder().key("tag1").value("value1").build(),
+          Tag.builder().key("tag2").value("value2").build());
+
+      File multipartUploadFile = 
Files.createFile(tempDir.resolve("multipartupload.txt")).toFile();
+      createFile(multipartUploadFile, (int) (10 * MB));
 
       // generate create MPU presigned URL
       CreateMultipartUploadRequest createRequest = 
CreateMultipartUploadRequest.builder()
-          .bucket(bucketName)
+          .bucket(BUCKET_NAME)
           .key(keyName)
           .metadata(userMetadata)
           .tagging(Tagging.builder().tagSet(tags).build())
           .build();
 
       CreateMultipartUploadPresignRequest createMPUPresignRequest = 
CreateMultipartUploadPresignRequest.builder()
-          .signatureDuration(Duration.ofMinutes(10))
+          .signatureDuration(duration)
           .createMultipartUploadRequest(createRequest)
           .build();
 
       PresignedCreateMultipartUploadRequest presignCreateMultipartUpload =
           presigner.presignCreateMultipartUpload(createMPUPresignRequest);
 
-      mpuWithHttpURLConnection(presignCreateMultipartUpload, 
multipartUploadFile, bucketName, keyName, presigner,
-          userMetadata, tags);
-      mpuWithSdkHttpClient(presignCreateMultipartUpload, multipartUploadFile, 
bucketName, keyName, presigner,
-          userMetadata, tags);
+      mpuWithHttpURLConnection(presignCreateMultipartUpload, 
multipartUploadFile, keyName, userMetadata, tags);
+      mpuWithSdkHttpClient(presignCreateMultipartUpload, multipartUploadFile, 
keyName, userMetadata, tags);
     }
-  }
 
-  private void mpuWithHttpURLConnection(PresignedCreateMultipartUploadRequest 
presignCreateMultipartUpload,
-                                        File multipartUploadFile, String 
bucketName, String keyName,
-                                        S3Presigner presigner, Map<String, 
String> userMetadata,
-                                        List<Tag> tags) throws IOException {
-    // create MPU using presigned URL
-    String uploadId;
-    HttpURLConnection createMultiPartUploadConnection = null;
-    try {
-      createMultiPartUploadConnection = 
openHttpUrlConnection(presignCreateMultipartUpload);
-      int createMultiPartUploadConnectionResponseCode = 
createMultiPartUploadConnection.getResponseCode();
-      assertEquals(200, createMultiPartUploadConnectionResponseCode,
-          "CreateMultipartUploadPresignRequest should return 200 OK");
-
-      try (InputStream is = createMultiPartUploadConnection.getInputStream()) {
-        String responseXml = IOUtils.toString(is, StandardCharsets.UTF_8);
-        uploadId = S3SDKTestUtils.extractUploadId(responseXml);
-      }
-    } finally {
-      if (createMultiPartUploadConnection != null) {
-        createMultiPartUploadConnection.disconnect();
+    private void 
mpuWithHttpURLConnection(PresignedCreateMultipartUploadRequest 
presignCreateMultipartUpload,
+                                          File multipartUploadFile, String 
keyName, Map<String, String> userMetadata,
+                                          List<Tag> tags) throws IOException {
+      // create MPU using presigned URL
+      String uploadId;
+      HttpURLConnection createMPUConnection = null;
+      try {
+        createMPUConnection = 
S3SDKTestUtils.openHttpURLConnection(presignCreateMultipartUpload.url(), "POST",
+            presignCreateMultipartUpload.signedHeaders(), null);
+        int createMultiPartUploadConnectionResponseCode = 
createMPUConnection.getResponseCode();
+        assertEquals(200, createMultiPartUploadConnectionResponseCode,
+            "CreateMultipartUploadPresignRequest should return 200 OK");
+
+        try (InputStream is = createMPUConnection.getInputStream()) {
+          String responseXml = IOUtils.toString(is, StandardCharsets.UTF_8);
+          uploadId = S3SDKTestUtils.extractUploadId(responseXml);
+        }
+      } finally {
+        if (createMPUConnection != null) {
+          createMPUConnection.disconnect();
+        }
       }
-    }
-
-    // Upload parts using presigned URL
-    List<CompletedPart> completedParts =
-        uploadPartWithHttpURLConnection(multipartUploadFile, bucketName, 
keyName, presigner, uploadId);
 
-    // complete MPU using presigned URL
-    CompleteMultipartUploadRequest completeRequest = 
CompleteMultipartUploadRequest.builder()
-        .bucket(bucketName)
-        .key(keyName)
-        .uploadId(uploadId)
-        
.multipartUpload(CompletedMultipartUpload.builder().parts(completedParts).build())
-        .build();
-    CompleteMultipartUploadPresignRequest 
completeMultipartUploadPresignRequest =
-        CompleteMultipartUploadPresignRequest.builder()
-            .signatureDuration(Duration.ofMinutes(10))
-            .completeMultipartUploadRequest(completeRequest)
-            .build();
+      // Upload parts using presigned URL
+      List<CompletedPart> completedParts = 
uploadPartWithHttpURLConnection(multipartUploadFile, keyName, uploadId);
 
-    PresignedCompleteMultipartUploadRequest 
presignedCompleteMultipartUploadRequest =
-        
presigner.presignCompleteMultipartUpload(completeMultipartUploadPresignRequest);
+      // complete MPU using presigned URL
+      CompleteMultipartUploadRequest completeRequest = 
CompleteMultipartUploadRequest.builder()
+          .bucket(BUCKET_NAME)
+          .key(keyName)
+          .uploadId(uploadId)
+          
.multipartUpload(CompletedMultipartUpload.builder().parts(completedParts).build())
+          .build();
+      CompleteMultipartUploadPresignRequest completeMPUPresignRequest = 
CompleteMultipartUploadPresignRequest.builder()
+          .signatureDuration(duration)
+          .completeMultipartUploadRequest(completeRequest)
+          .build();
 
-    completeMPUWithHttpUrlConnection(presignedCompleteMultipartUploadRequest, 
completedParts);
+      PresignedCompleteMultipartUploadRequest 
presignedCompleteMultipartUploadRequest =
+          presigner.presignCompleteMultipartUpload(completeMPUPresignRequest);
 
-    // verify upload result
-    HeadObjectResponse headObjectResponse = s3Client.headObject(b -> 
b.bucket(bucketName).key(keyName));
-    assertTrue(headObjectResponse.hasMetadata());
-    assertEquals(userMetadata, headObjectResponse.metadata());
-
-    ResponseInputStream<GetObjectResponse> object = s3Client.getObject(b -> 
b.bucket(bucketName).key(keyName));
-    assertEquals(tags.size(), object.response().tagCount());
-    String actualContent = IoUtils.toUtf8String(object);
-    String originalContent = new 
String(Files.readAllBytes(multipartUploadFile.toPath()), 
StandardCharsets.UTF_8);
-    assertEquals(originalContent, actualContent, "Uploaded file content should 
match original file content");
-  }
+      
completeMPUWithHttpUrlConnection(presignedCompleteMultipartUploadRequest, 
completedParts);
 
-  private List<CompletedPart> uploadPartWithHttpURLConnection(File 
multipartUploadFile, String bucketName,
-                                                              String keyName, 
S3Presigner presigner, String uploadId)
-      throws IOException {
-    List<CompletedPart> completedParts = new ArrayList<>();
-    int partNumber = 1;
-    ByteBuffer bb = ByteBuffer.allocate((int) (5 * MB));
+      // verify upload result
+      HeadObjectResponse headObjectResponse = s3Client.headObject(b -> 
b.bucket(BUCKET_NAME).key(keyName));
+      assertTrue(headObjectResponse.hasMetadata());
+      assertEquals(userMetadata, headObjectResponse.metadata());
 
-    try (RandomAccessFile file = new RandomAccessFile(multipartUploadFile, 
"r")) {
-      long fileSize = file.length();
-      long position = 0;
+      ResponseInputStream<GetObjectResponse> object = s3Client.getObject(b -> 
b.bucket(BUCKET_NAME).key(keyName));
+      assertEquals(tags.size(), object.response().tagCount());
+      String actualContent = IoUtils.toUtf8String(object);
+      String originalContent = new 
String(Files.readAllBytes(multipartUploadFile.toPath()), 
StandardCharsets.UTF_8);
+      assertEquals(originalContent, actualContent, "Uploaded file content 
should match original file content");
+    }
 
-      while (position < fileSize) {
-        file.seek(position);
-        long read = file.getChannel().read(bb);
+    private List<CompletedPart> uploadPartWithHttpURLConnection(File 
multipartUploadFile, String keyName,
+                                                                String 
uploadId) throws IOException {
+      List<CompletedPart> completedParts = new ArrayList<>();
+      int partNumber = 1;
+      ByteBuffer bb = ByteBuffer.allocate((int) (5 * MB));
 
-        bb.flip();
+      try (RandomAccessFile file = new RandomAccessFile(multipartUploadFile, 
"r")) {
+        long fileSize = file.length();
+        long position = 0;
 
-        // First create an UploadPartRequest
-        UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
-            .bucket(bucketName)
-            .key(keyName)
-            .uploadId(uploadId)
-            .partNumber(partNumber)
-            .contentLength((long) bb.remaining())
-            .build();
+        while (position < fileSize) {
+          file.seek(position);
+          long read = file.getChannel().read(bb);
 
-        // Generate presigned URL for each part
-        UploadPartPresignRequest presignRequest = 
UploadPartPresignRequest.builder()
-            .signatureDuration(Duration.ofMinutes(10))
-            .uploadPartRequest(uploadPartRequest)
-            .build();
+          bb.flip();
 
-        PresignedUploadPartRequest presignedRequest = 
presigner.presignUploadPart(presignRequest);
+          // First create an UploadPartRequest
+          UploadPartRequest request = UploadPartRequest.builder()
+              .bucket(BUCKET_NAME)
+              .key(keyName)
+              .uploadId(uploadId)
+              .partNumber(partNumber)
+              .contentLength((long) bb.remaining())
+              .build();
 
-        // use presigned URL to upload the part
-        HttpURLConnection connection = null;
-        try {
-          connection = (HttpURLConnection) 
presignedRequest.url().openConnection();
-          connection.setDoOutput(true);
-          connection.setRequestMethod("PUT");
+          // Generate presigned URL for each part
+          UploadPartPresignRequest presignRequest = 
UploadPartPresignRequest.builder()
+              .signatureDuration(duration)
+              .uploadPartRequest(request)
+              .build();
 
-          try (OutputStream os = connection.getOutputStream()) {
-            os.write(bb.array(), 0, bb.remaining());
-            os.flush();
+          PresignedUploadPartRequest presignedRequest = 
presigner.presignUploadPart(presignRequest);
+
+          // use presigned URL to upload the part
+          HttpURLConnection connection = null;
+          try {
+            byte[] body = new byte[bb.remaining()];
+            bb.get(body);
+            connection = 
S3SDKTestUtils.openHttpURLConnection(presignedRequest.url(), "PUT",
+                presignedRequest.signedHeaders(), body);
+
+            int responseCode = connection.getResponseCode();
+            assertEquals(200, responseCode, String.format("Upload part %d 
should return 200 OK", partNumber));
+
+            String etag = connection.getHeaderField("ETag");
+            CompletedPart part = 
CompletedPart.builder().partNumber(partNumber).eTag(etag).build();
+            completedParts.add(part);
+          } finally {
+            if (connection != null) {
+              connection.disconnect();
+            }
           }
 
-          int responseCode = connection.getResponseCode();
-          assertEquals(200, responseCode,
-              String.format("Upload part %d should return 200 OK", 
partNumber));
-
-          String etag = connection.getHeaderField("ETag");
-          CompletedPart part = CompletedPart.builder()
-              .partNumber(partNumber)
-              .eTag(etag)
-              .build();
-          completedParts.add(part);
-        } finally {
-          if (connection != null) {
-            connection.disconnect();
-          }
+          bb.clear();
+          position += read;
+          partNumber++;
         }
-
-        bb.clear();
-        position += read;
-        partNumber++;
       }
+      return completedParts;
     }
-    return completedParts;
-  }
 
-  private HttpURLConnection 
openHttpUrlConnection(PresignedCreateMultipartUploadRequest request) throws 
IOException {
-    HttpURLConnection connection = (HttpURLConnection) 
request.url().openConnection();
-    connection.setDoOutput(true);
-    connection.setRequestMethod("POST");
-    for (Map.Entry<String, List<String>> entry : 
request.signedHeaders().entrySet()) {
-      String key = entry.getKey();
-      for (String value : entry.getValue()) {
-        connection.setRequestProperty(key, value);
-      }
-    }
-    return connection;
-  }
+    private void 
completeMPUWithHttpUrlConnection(PresignedCompleteMultipartUploadRequest 
request,
+                                                  List<CompletedPart> 
completedParts) throws IOException {
+      HttpURLConnection connection = null;
+      try {
+        String xmlPayload = buildCompleteMultipartUploadXml(completedParts);
+        byte[] payloadBytes = xmlPayload.getBytes(StandardCharsets.UTF_8);
+        connection = S3SDKTestUtils.openHttpURLConnection(request.url(), 
"POST", request.signedHeaders(), payloadBytes);
 
-  private void 
completeMPUWithHttpUrlConnection(PresignedCompleteMultipartUploadRequest 
request,
-                                                List<CompletedPart> 
completedParts) throws IOException {
-    HttpURLConnection completeMultipartUploadConnection = null;
-    try {
-      completeMultipartUploadConnection = (HttpURLConnection) 
request.url().openConnection();
-      completeMultipartUploadConnection.setDoOutput(true);
-      completeMultipartUploadConnection.setRequestMethod("POST");
-
-      // copy headers
-      for (Map.Entry<String, List<String>> entry : 
request.signedHeaders().entrySet()) {
-        String key = entry.getKey();
-        for (String value : entry.getValue()) {
-          completeMultipartUploadConnection.setRequestProperty(key, value);
+        int responseCode = connection.getResponseCode();
+        assertEquals(200, responseCode, "CompleteMultipartUploadPresignRequest 
should return 200 OK");
+      } finally {
+        if (connection != null) {
+          connection.disconnect();
         }
       }
-
-      String xmlPayload = buildCompleteMultipartUploadXml(completedParts);
-      byte[] payloadBytes = xmlPayload.getBytes(StandardCharsets.UTF_8);
-      try (OutputStream os = 
completeMultipartUploadConnection.getOutputStream()) {
-        IOUtils.write(payloadBytes, os);
-        os.flush();
-      }
-
-      int completeMultipartUploadConnectionResponseCode = 
completeMultipartUploadConnection.getResponseCode();
-      assertEquals(200, completeMultipartUploadConnectionResponseCode,
-          "CompleteMultipartUploadPresignRequest should return 200 OK");
-    } finally {
-      if (completeMultipartUploadConnection != null) {
-        completeMultipartUploadConnection.disconnect();
-      }
     }
-  }
 
-  private void mpuWithSdkHttpClient(PresignedCreateMultipartUploadRequest 
presignCreateMultipartUpload,
-                                    File multipartUploadFile, String 
bucketName, String keyName,
-                                    S3Presigner presigner, Map<String, String> 
userMetadata, List<Tag> tags)
-      throws Exception {
-    // create MPU using presigned URL
-    String uploadId;
-    try (SdkHttpClient sdkHttpClient = ApacheHttpClient.create()) {
-      uploadId = createMPUWithSdkHttpClient(presignCreateMultipartUpload, 
sdkHttpClient);
+    private void mpuWithSdkHttpClient(PresignedCreateMultipartUploadRequest 
presignCreateMultipartUpload,
+                                      File multipartUploadFile, String 
keyName, Map<String, String> userMetadata,
+                                      List<Tag> tags) throws Exception {
+      // create MPU using presigned URL
+      String uploadId = 
createMPUWithSdkHttpClient(presignCreateMultipartUpload);
 
       // Upload parts using presigned URL
-      List<CompletedPart> completedParts =
-          uploadPartWithSdkHttpClient(multipartUploadFile, bucketName, 
keyName, presigner, uploadId, sdkHttpClient);
+      List<CompletedPart> completedParts = 
uploadPartWithSdkHttpClient(multipartUploadFile, keyName, uploadId);
 
       // complete MPU using presigned URL
-      completeMPUWithSdkHttpClient(bucketName, keyName, presigner, uploadId, 
completedParts, sdkHttpClient);
+      completeMPUWithSdkHttpClient(keyName, uploadId, completedParts);
 
       // verify upload result
-      HeadObjectResponse headObjectResponse = s3Client.headObject(b -> 
b.bucket(bucketName).key(keyName));
+      HeadObjectResponse headObjectResponse = s3Client.headObject(b -> 
b.bucket(BUCKET_NAME).key(keyName));
       assertTrue(headObjectResponse.hasMetadata());
       assertEquals(userMetadata, headObjectResponse.metadata());
 
-      ResponseInputStream<GetObjectResponse> object = s3Client.getObject(b -> 
b.bucket(bucketName).key(keyName));
+      ResponseInputStream<GetObjectResponse> object = s3Client.getObject(b -> 
b.bucket(BUCKET_NAME).key(keyName));
       assertEquals(tags.size(), object.response().tagCount());
       String actualContent = IoUtils.toUtf8String(object);
       String originalContent = new 
String(Files.readAllBytes(multipartUploadFile.toPath()), 
StandardCharsets.UTF_8);
       assertEquals(originalContent, actualContent, "Uploaded file content 
should match original file content");
     }
-  }
 
-  private void completeMPUWithSdkHttpClient(String bucketName, String keyName, 
S3Presigner presigner, String uploadId,
-                         List<CompletedPart> completedParts, SdkHttpClient 
sdkHttpClient) throws Exception {
-    CompleteMultipartUploadRequest completeRequest = 
CompleteMultipartUploadRequest.builder()
-        .bucket(bucketName)
-        .key(keyName)
-        .uploadId(uploadId)
-        
.multipartUpload(CompletedMultipartUpload.builder().parts(completedParts).build())
-        .build();
+    private void completeMPUWithSdkHttpClient(String keyName, String uploadId, 
List<CompletedPart> completedParts)
+        throws Exception {
+      CompleteMultipartUploadRequest request = 
CompleteMultipartUploadRequest.builder()
+          .bucket(BUCKET_NAME)
+          .key(keyName)
+          .uploadId(uploadId)
+          
.multipartUpload(CompletedMultipartUpload.builder().parts(completedParts).build())
+          .build();
 
-    CompleteMultipartUploadPresignRequest 
completeMultipartUploadPresignRequest =
-        CompleteMultipartUploadPresignRequest.builder()
-            .signatureDuration(Duration.ofMinutes(10))
-            .completeMultipartUploadRequest(completeRequest)
-            .build();
+      CompleteMultipartUploadPresignRequest presignRequest = 
CompleteMultipartUploadPresignRequest.builder()
+          .signatureDuration(duration)
+          .completeMultipartUploadRequest(request)
+          .build();
 
-    PresignedCompleteMultipartUploadRequest 
presignedCompleteMultipartUploadRequest =
-        
presigner.presignCompleteMultipartUpload(completeMultipartUploadPresignRequest);
+      PresignedCompleteMultipartUploadRequest 
presignedCompleteMultipartUploadRequest =
+          presigner.presignCompleteMultipartUpload(presignRequest);
 
-    String xmlPayload = buildCompleteMultipartUploadXml(completedParts);
-    byte[] payloadBytes = xmlPayload.getBytes(StandardCharsets.UTF_8);
+      String xmlPayload = buildCompleteMultipartUploadXml(completedParts);
+      byte[] payloadBytes = xmlPayload.getBytes(StandardCharsets.UTF_8);
 
-    SdkHttpRequest completeMultipartUploadRequest = SdkHttpRequest.builder()
-        .method(SdkHttpMethod.POST)
-        .uri(presignedCompleteMultipartUploadRequest.url().toURI())
-        .build();
+      SdkHttpRequest sdkHttpRequest = SdkHttpRequest.builder()
+          .method(SdkHttpMethod.POST)
+          .uri(presignedCompleteMultipartUploadRequest.url().toURI())
+          .build();
 
-    HttpExecuteRequest completeMultipartUploadExecuteRequest = 
HttpExecuteRequest.builder()
-        .request(completeMultipartUploadRequest)
-        .contentStreamProvider(() -> new ByteArrayInputStream(payloadBytes))
-        .build();
+      HttpExecuteRequest httpExecuteRequest = HttpExecuteRequest.builder()
+          .request(sdkHttpRequest)
+          .contentStreamProvider(() -> new ByteArrayInputStream(payloadBytes))
+          .build();
 
-    HttpExecuteResponse completeMultipartUploadResponse =
-        
sdkHttpClient.prepareRequest(completeMultipartUploadExecuteRequest).call();
-    assertEquals(200, 
completeMultipartUploadResponse.httpResponse().statusCode(),
-        "CompleteMultipartUploadPresignRequest should return 200 OK");
-  }
+      HttpExecuteResponse response = 
sdkHttpClient.prepareRequest(httpExecuteRequest).call();
+      assertEquals(200, response.httpResponse().statusCode(),
+          "CompleteMultipartUploadPresignRequest should return 200 OK");
+    }
 
-  private List<CompletedPart> uploadPartWithSdkHttpClient(File 
multipartUploadFile, String bucketName, String keyName,
-                                                       S3Presigner presigner, 
String uploadId,
-                                                       SdkHttpClient 
httpClient) throws Exception {
-    List<CompletedPart> completedParts = new ArrayList<>();
-    int partNumber = 1;
-    ByteBuffer bb = ByteBuffer.allocate((int) (5 * MB));
+    private List<CompletedPart> uploadPartWithSdkHttpClient(File 
multipartUploadFile, String keyName, String uploadId)
+        throws Exception {
+      List<CompletedPart> completedParts = new ArrayList<>();
+      int partNumber = 1;
+      ByteBuffer bb = ByteBuffer.allocate((int) (5 * MB));
 
-    try (RandomAccessFile file = new RandomAccessFile(multipartUploadFile, 
"r")) {
-      long fileSize = file.length();
-      long position = 0;
+      try (RandomAccessFile file = new RandomAccessFile(multipartUploadFile, 
"r")) {
+        long fileSize = file.length();
+        long position = 0;
 
-      while (position < fileSize) {
-        file.seek(position);
-        long read = file.getChannel().read(bb);
+        while (position < fileSize) {
+          file.seek(position);
+          long read = file.getChannel().read(bb);
 
-        bb.flip();
+          bb.flip();
 
-        // Generate presigned URL for each part
-        UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
-            .bucket(bucketName)
-            .key(keyName)
-            .uploadId(uploadId)
-            .partNumber(partNumber)
-            .contentLength((long) bb.remaining())
-            .build();
+          // Generate presigned URL for each part
+          UploadPartRequest request = UploadPartRequest.builder()
+              .bucket(BUCKET_NAME)
+              .key(keyName)
+              .uploadId(uploadId)
+              .partNumber(partNumber)
+              .contentLength((long) bb.remaining())
+              .build();
 
-        UploadPartPresignRequest presignRequest = 
UploadPartPresignRequest.builder()
-            .signatureDuration(Duration.ofMinutes(10))
-            .uploadPartRequest(uploadPartRequest)
-            .build();
+          UploadPartPresignRequest presignRequest = 
UploadPartPresignRequest.builder()
+              .signatureDuration(duration)
+              .uploadPartRequest(request)
+              .build();
 
-        PresignedUploadPartRequest presignedRequest = 
presigner.presignUploadPart(presignRequest);
+          PresignedUploadPartRequest presignedRequest = 
presigner.presignUploadPart(presignRequest);
 
-        // upload each part using presigned URL
-        SdkHttpRequest uploadPartSdkRequest = SdkHttpRequest.builder()
-            .method(SdkHttpMethod.PUT)
-            .uri(presignedRequest.url().toURI())
-            .build();
+          // upload each part using presigned URL
+          SdkHttpRequest uploadPartSdkRequest = SdkHttpRequest.builder()
+              .method(SdkHttpMethod.PUT)
+              .uri(presignedRequest.url().toURI())
+              .build();
 
-        byte[] bytes = new byte[bb.remaining()];
-        bb.get(bytes);
+          byte[] bytes = new byte[bb.remaining()];
+          bb.get(bytes);
 
-        HttpExecuteRequest uploadPartExecuteRequest = 
HttpExecuteRequest.builder()
-            .request(uploadPartSdkRequest)
-            .contentStreamProvider(() -> new ByteArrayInputStream(bytes))
-            .build();
+          HttpExecuteRequest executeRequest = HttpExecuteRequest.builder()
+              .request(uploadPartSdkRequest)
+              .contentStreamProvider(() -> new ByteArrayInputStream(bytes))
+              .build();
 
-        HttpExecuteResponse uploadPartResponse = 
httpClient.prepareRequest(uploadPartExecuteRequest).call();
+          HttpExecuteResponse response = 
sdkHttpClient.prepareRequest(executeRequest).call();
 
-        String etag = uploadPartResponse.httpResponse()
-            .firstMatchingHeader("ETag")
-            .orElseThrow(() -> new RuntimeException("ETag missing in 
response"));
+          String etag = response.httpResponse().firstMatchingHeader("ETag")
+              .orElseThrow(() -> new RuntimeException("ETag missing in 
response"));
 
-        CompletedPart part = CompletedPart.builder()
-            .partNumber(partNumber)
-            .eTag(etag)
-            .build();
-        completedParts.add(part);
+          CompletedPart part = 
CompletedPart.builder().partNumber(partNumber).eTag(etag).build();
+          completedParts.add(part);
 
-        bb.clear();
-        position += read;
-        partNumber++;
+          bb.clear();
+          position += read;
+          partNumber++;
+        }
       }
+      return completedParts;
     }
-    return completedParts;
-  }
-
-  private String 
createMPUWithSdkHttpClient(PresignedCreateMultipartUploadRequest request,
-                                  SdkHttpClient httpClient) throws Exception {
-    String uploadId;
-    SdkHttpRequest createMultipartUploadRequest = SdkHttpRequest.builder()
-        .method(SdkHttpMethod.POST)
-        .uri(request.url().toURI())
-        .headers(request.signedHeaders())
-        .build();
 
-    HttpExecuteRequest createMultipartUploadExecuteRequest = 
HttpExecuteRequest.builder()
-        .request(createMultipartUploadRequest)
-        .build();
+    private String 
createMPUWithSdkHttpClient(PresignedCreateMultipartUploadRequest request) 
throws Exception {
+      String uploadId;
+      SdkHttpRequest sdkHttpRequest = SdkHttpRequest.builder()
+          .method(SdkHttpMethod.POST)
+          .uri(request.url().toURI())
+          .headers(request.signedHeaders())
+          .build();
 
-    HttpExecuteResponse createMultipartUploadResponse =
-        httpClient.prepareRequest(createMultipartUploadExecuteRequest).call();
+      HttpExecuteRequest httpExecuteRequest = HttpExecuteRequest.builder()
+          .request(sdkHttpRequest)
+          .build();
 
-    try (InputStream is = createMultipartUploadResponse.responseBody().get()) {
-      String responseXml = IOUtils.toString(is, StandardCharsets.UTF_8);
-      uploadId = S3SDKTestUtils.extractUploadId(responseXml);
+      HttpExecuteResponse response = 
sdkHttpClient.prepareRequest(httpExecuteRequest).call();
+      try (InputStream is = response.responseBody().get()) {
+        String responseXml = IOUtils.toString(is, StandardCharsets.UTF_8);
+        uploadId = S3SDKTestUtils.extractUploadId(responseXml);
+      }
+      return uploadId;
     }
-    return uploadId;
-  }
 
-  private String buildCompleteMultipartUploadXml(List<CompletedPart> parts) {
-    StringBuilder xml = new StringBuilder();
-    xml.append("<CompleteMultipartUpload>\n");
-    for (CompletedPart part : parts) {
-      xml.append("  <Part>\n");
-      xml.append("    
<PartNumber>").append(part.partNumber()).append("</PartNumber>\n");
-      xml.append("    <ETag>").append(part.eTag()).append("</ETag>\n");
-      xml.append("  </Part>\n");
+    private String buildCompleteMultipartUploadXml(List<CompletedPart> parts) {
+      StringBuilder xml = new StringBuilder();
+      xml.append("<CompleteMultipartUpload>\n");
+      for (CompletedPart part : parts) {
+        xml.append("  <Part>\n");
+        xml.append("    
<PartNumber>").append(part.partNumber()).append("</PartNumber>\n");
+        xml.append("    <ETag>").append(part.eTag()).append("</ETag>\n");
+        xml.append("  </Part>\n");
+      }
+      xml.append("</CompleteMultipartUpload>");
+      return xml.toString();
     }
-    xml.append("</CompleteMultipartUpload>");
-    return xml.toString();
-  }
 
-  @Test
-  public void testPresignedUrlDelete() throws Exception {
-    final String bucketName = getBucketName();
-    final String keyName = getKeyName();
-    final String content = "bar";
-    s3Client.createBucket(b -> b.bucket(bucketName));
-
-    s3Client.putObject(b -> b
-            .bucket(bucketName)
-            .key(keyName),
-        RequestBody.fromString(content));
+    @Test
+    public void testPresignedUrlDelete() throws Exception {
+      final String keyName = getKeyName();
 
-    try (S3Presigner presigner = createS3Presigner()) {
+      s3Client.putObject(b -> b.bucket(BUCKET_NAME).key(keyName), 
RequestBody.fromString(CONTENT));
 
-      DeleteObjectRequest objectRequest = DeleteObjectRequest.builder()
-          .bucket(bucketName)
-          .key(keyName)
-          .build();
+      DeleteObjectRequest objectRequest = 
DeleteObjectRequest.builder().bucket(BUCKET_NAME).key(keyName).build();
 
       DeleteObjectPresignRequest presignRequest = 
DeleteObjectPresignRequest.builder()
           .signatureDuration(Duration.ofMinutes(10))
@@ -1110,69 +995,37 @@ public void testPresignedUrlDelete() throws Exception {
       // use http url connection
       HttpURLConnection connection = null;
       try {
-        connection = (HttpURLConnection) 
presignedRequest.url().openConnection();
-        connection.setRequestMethod("DELETE");
-
+        connection = 
S3SDKTestUtils.openHttpURLConnection(presignedRequest.url(), "DELETE", null, 
null);
         int responseCode = connection.getResponseCode();
         assertEquals(204, responseCode, "DeleteObject presigned URL should 
return 204 No Content");
 
         //verify the object was deleted
-        assertThrows(NoSuchKeyException.class, () -> s3Client.getObject(b -> 
b.bucket(bucketName).key(keyName)));
+        assertThrows(NoSuchKeyException.class, () -> s3Client.getObject(b -> 
b.bucket(BUCKET_NAME).key(keyName)));
       } finally {
         if (connection != null) {
           connection.disconnect();
         }
       }
-    }
 
-    // use SdkHttpClient
-    s3Client.putObject(b -> b
-            .bucket(bucketName)
-            .key(keyName),
-        RequestBody.fromString(content));
-
-    try (S3Presigner presigner = createS3Presigner();
-         SdkHttpClient sdkHttpClient = ApacheHttpClient.create()) {
-
-      DeleteObjectRequest objectRequest = DeleteObjectRequest.builder()
-          .bucket(bucketName)
-          .key(keyName)
-          .build();
-
-      DeleteObjectPresignRequest presignRequest = 
DeleteObjectPresignRequest.builder()
-          .signatureDuration(Duration.ofMinutes(10))
-          .deleteObjectRequest(objectRequest)
-          .build();
-
-      PresignedDeleteObjectRequest presignedRequest = 
presigner.presignDeleteObject(presignRequest);
+      // use SdkHttpClient
+      s3Client.putObject(b -> b.bucket(BUCKET_NAME).key(keyName), 
RequestBody.fromString(CONTENT));
 
       SdkHttpRequest request = SdkHttpRequest.builder()
           .method(SdkHttpMethod.DELETE)
           .uri(presignedRequest.url().toURI())
           .build();
 
-      HttpExecuteRequest executeRequest = HttpExecuteRequest.builder()
-          .request(request)
-          .build();
+      HttpExecuteRequest executeRequest = 
HttpExecuteRequest.builder().request(request).build();
 
       HttpExecuteResponse response = 
sdkHttpClient.prepareRequest(executeRequest).call();
       assertEquals(204, response.httpResponse().statusCode(),
           "DeleteObject presigned URL should return 204 No Content via 
SdkHttpClient");
 
       //verify the object was deleted
-      assertThrows(NoSuchKeyException.class, () -> s3Client.getObject(b -> 
b.bucket(bucketName).key(keyName)));
+      assertThrows(NoSuchKeyException.class, () -> s3Client.getObject(b -> 
b.bucket(BUCKET_NAME).key(keyName)));
     }
   }
 
-  private S3Presigner createS3Presigner() {
-    return S3Presigner.builder()
-        // TODO: Find a way to retrieve the path style configuration from 
S3Client instead
-        
.serviceConfiguration(S3Configuration.builder().pathStyleAccessEnabled(true).build())
-        
.endpointOverride(s3Client.serviceClientConfiguration().endpointOverride().get())
-        .region(s3Client.serviceClientConfiguration().region())
-        
.credentialsProvider(s3Client.serviceClientConfiguration().credentialsProvider()).build();
-  }
-
   /**
    * Tests the functionality to create a snapshot of an Ozone bucket and then 
read files
    * from the snapshot directory using the S3 SDK.


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

Reply via email to