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 f7bfdf19b63 HDDS-16659. Reuse destination OzoneBucket in streaming S3 
CopyObject (#11383)
f7bfdf19b63 is described below

commit f7bfdf19b630814fca448565ef374283045c011f
Author: KUAN-HAO HUANG <[email protected]>
AuthorDate: Fri Oct 2 21:29:07 2026 +0800

    HDDS-16659. Reuse destination OzoneBucket in streaming S3 CopyObject 
(#11383)
    
    Generated-by: Codex (GPT-6)
---
 .../hadoop/ozone/s3/endpoint/ObjectEndpoint.java     | 13 +++++++------
 .../hadoop/ozone/s3/endpoint/TestObjectPut.java      | 20 ++++++++++++++++++++
 2 files changed, 27 insertions(+), 6 deletions(-)

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 430300163c5..e911b07eee1 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
@@ -238,7 +238,7 @@ Response handlePutRequest(ObjectRequestContext context, 
String keyPath, InputStr
         //Copy object, as copy source available.
         context.setAction(S3GAction.COPY_OBJECT);
         CopyObjectResponse copyObjectResponse = copyObject(volume,
-            bucketName, keyPath, replicationConfig, perf);
+            bucket, keyPath, replicationConfig, perf);
         return Response.status(Status.OK).entity(copyObjectResponse).header(
             "Connection", "close").build();
       }
@@ -1136,7 +1136,7 @@ uploadID, getChunkSize(), multiDigestInputStream, perf, 
getHeaders(),
    */
   @SuppressWarnings("checkstyle:ParameterNumber")
   CopyResult copy(OzoneVolume volume, DigestInputStream src, String 
reusedETag, long srcKeyLen,
-      String destKey, String destBucket,
+      String destKey, OzoneBucket destBucket,
       ReplicationConfig replication,
       Map<String, String> metadata,
       PerformanceStringBuilder perf, long startNanos,
@@ -1151,7 +1151,7 @@ CopyResult copy(OzoneVolume volume, DigestInputStream 
src, String reusedETag, lo
         srcKeyLen > getDatastreamMinLength()) {
       perf.appendStreamMode();
       final CopyResult copyResult = ObjectEndpointStreaming
-          .copyKeyWithStream(volume.getBucket(destBucket), destKey, srcKeyLen,
+          .copyKeyWithStream(destBucket, destKey, srcKeyLen,
               getChunkSize(), replication, metadata, src, reusedETag, perf, 
startNanos, tags,
               writeConditions);
       eTag = copyResult.getETag();
@@ -1160,7 +1160,7 @@ srcKeyLen > getDatastreamMinLength()) {
     } else {
       final long expectedLength = srcKeyLen;
       final OzoneOutputStream destStream = openKeyForPut(
-          volume.getName(), destBucket, destKey, expectedLength,
+          volume.getName(), destBucket.getName(), destKey, expectedLength,
           replication, metadata, tags, writeConditions, false);
       try (S3ObjectWriteGuard dest = new S3ObjectWriteGuard(destStream, 
expectedLength, destKey)) {
         long metadataLatencyNs =
@@ -1179,9 +1179,10 @@ srcKeyLen > getDatastreamMinLength()) {
   }
 
   private CopyObjectResponse copyObject(OzoneVolume volume,
-      String destBucket, String destkey, ReplicationConfig replicationConfig,
+      OzoneBucket destinationBucket, String destkey, ReplicationConfig 
replicationConfig,
       PerformanceStringBuilder perf)
       throws OS3Exception, IOException {
+    String destBucket = destinationBucket.getName();
     String copyHeader = getHeaders().getHeaderString(COPY_SOURCE_HEADER);
     String storageType = getHeaders().getHeaderString(STORAGE_CLASS_HEADER);
     boolean storageTypeDefault = StringUtils.isEmpty(storageType);
@@ -1294,7 +1295,7 @@ private CopyObjectResponse copyObject(OzoneVolume volume,
           sourceDigestInputStream.on(false);
         }
         final CopyResult copyResult = runWithS3ActionString("PutObject", () ->
-            copy(volume, sourceDigestInputStream, reusedETag, sourceKeyLen, 
destkey, destBucket,
+            copy(volume, sourceDigestInputStream, reusedETag, sourceKeyLen, 
destkey, destinationBucket,
               replicationConfig, customMetadata, perf, startNanos, tags, 
writeConditions));
 
         getMetrics().updateCopyObjectSuccessStats(startNanos);
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectPut.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectPut.java
index 4ac538a4a7d..8e48c6ca1f9 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectPut.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestObjectPut.java
@@ -59,6 +59,7 @@
 import static org.mockito.Mockito.CALLS_REAL_METHODS;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.mockStatic;
@@ -737,6 +738,25 @@ public void 
testCopyObjectMessageDigestResetDuringException() throws Exception {
     }
   }
 
+  @Test
+  void testStreamingCopyReusesDestinationBucket() throws Exception {
+    assertSucceeds(() -> putObject(CONTENT));
+    objectEndpoint.init();
+    OzoneVolume volume = spy(objectEndpoint.getVolume());
+    doReturn(volume).when(objectEndpoint).getVolume();
+    doReturn(true).when(objectEndpoint).isDatastreamEnabled();
+    doReturn(0L).when(objectEndpoint).getDatastreamMinLength();
+    when(headers.getHeaderString(COPY_SOURCE_HEADER)).thenReturn(BUCKET_NAME + 
"/" + urlEncode(KEY_NAME));
+
+    try (Response response = put(objectEndpoint, DEST_BUCKET_NAME, DEST_KEY, 
CONTENT)) {
+      assertThat(response.getStatus()).isEqualTo(HttpStatus.SC_OK);
+      assertThat(((CopyObjectResponse) 
response.getEntity()).getETag()).isEqualTo("\"" + contentMd5Hex() + "\"");
+    }
+    assertKeyContent(destBucket, DEST_KEY, CONTENT);
+    
assertThat(destBucket.getKey(DEST_KEY).getMetadata().get(OzoneConsts.ETAG)).isEqualTo(contentMd5Hex());
+    verify(volume).getBucket(DEST_BUCKET_NAME);
+  }
+
   @Test
   void testCopyObjectReusesSourceETagWithoutRehashing() throws Exception {
     assertSucceeds(() -> putObject(CONTENT));


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

Reply via email to