From 31a2cc2730500bf4a63da18ec82a32212183e002 Mon Sep 17 00:00:00 2001 From: Dhriti Chopra Date: Tue, 27 Oct 2026 08:41:26 +0000 Subject: [PATCH 1/3] fix(storage): send destination on gRPC copy when target BlobInfo is provided --- .../main/java/com/google/cloud/storage/GrpcStorageImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java-storage/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageImpl.java b/java-storage/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageImpl.java index 120b7a269724..4f33b7c6c3f1 100644 --- a/java-storage/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageImpl.java +++ b/java-storage/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageImpl.java @@ -692,7 +692,9 @@ public CopyWriter copy(CopyRequest copyRequest) { // only set the destination if it is not equal to the default instance // otherwise we will clobber default values populated in the gcs server side for the object // metadata - if (!cleanedDst.equals(Object.getDefaultInstance())) { + // If the caller provided a BlobInfo target (overrideInfo), always send the destination so the + // server does not fall back to copying the source object's metadata. + if (copyRequest.overrideInfo() || !cleanedDst.equals(Object.getDefaultInstance())) { b.setDestination(cleanedDst); } From 219c78806d8b248f28572eb22fcbe146244f35f7 Mon Sep 17 00:00:00 2001 From: Dhriti Chopra Date: Tue, 27 Oct 2026 11:03:34 +0000 Subject: [PATCH 2/3] test(storage): verify copy with target BlobInfo does not inherit source metadata --- .../google/cloud/storage/it/ITObjectTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/java-storage/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java b/java-storage/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java index f186afd077b6..3636b1f25d79 100644 --- a/java-storage/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java +++ b/java-storage/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java @@ -1036,6 +1036,31 @@ public void testCopyBlobUpdateMetadata() { assertTrue(storage.delete(gen1.getBlobId())); } + @Test + public void testCopyBlob_targetBlobInfo_doesNotInheritMetadata() { + String sourceBlobName = generator.randomObjectName() + "-source"; + BlobId source = BlobId.of(bucket.getName(), sourceBlobName); + ImmutableMap metadata = ImmutableMap.of("k", "v"); + Blob remoteSourceBlob = + storage.create( + BlobInfo.newBuilder(source).setMetadata(metadata).build(), BLOB_BYTE_CONTENT); + assertNotNull(remoteSourceBlob); + String targetBlobName = generator.randomObjectName() + "-target"; + CopyRequest req = + CopyRequest.newBuilder() + .setSource(source) + .setTarget( + BlobInfo.newBuilder(bucket, targetBlobName).build(), + BlobTargetOption.doesNotExist()) + .build(); + CopyWriter copyWriter = storage.copy(req); + Blob gen1 = copyWriter.getResult(); + assertThat(gen1.getMetadata()).isAnyOf(null, ImmutableMap.of()); + assertTrue(copyWriter.isDone()); + assertTrue(remoteSourceBlob.delete()); + assertTrue(storage.delete(gen1.getBlobId())); + } + @Test public void testCopyBlobFail() { From 164e2292c214c7e17aefdbde1f1d58a796332771 Mon Sep 17 00:00:00 2001 From: Dhriti Chopra Date: Tue, 27 Oct 2026 11:07:49 +0000 Subject: [PATCH 3/3] test(storage): restructure copy metadata test --- .../google/cloud/storage/it/ITObjectTest.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/java-storage/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java b/java-storage/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java index 3636b1f25d79..510fa890bf9e 100644 --- a/java-storage/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java +++ b/java-storage/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java @@ -1038,27 +1038,27 @@ public void testCopyBlobUpdateMetadata() { @Test public void testCopyBlob_targetBlobInfo_doesNotInheritMetadata() { - String sourceBlobName = generator.randomObjectName() + "-source"; - BlobId source = BlobId.of(bucket.getName(), sourceBlobName); - ImmutableMap metadata = ImmutableMap.of("k", "v"); + BlobId source = BlobId.of(bucket.getName(), generator.randomObjectName() + "-source"); Blob remoteSourceBlob = storage.create( - BlobInfo.newBuilder(source).setMetadata(metadata).build(), BLOB_BYTE_CONTENT); + BlobInfo.newBuilder(source).setMetadata(ImmutableMap.of("k", "v")).build(), + BLOB_BYTE_CONTENT); assertNotNull(remoteSourceBlob); - String targetBlobName = generator.randomObjectName() + "-target"; + BlobInfo target = BlobInfo.newBuilder(bucket, generator.randomObjectName() + "-target").build(); CopyRequest req = CopyRequest.newBuilder() .setSource(source) - .setTarget( - BlobInfo.newBuilder(bucket, targetBlobName).build(), - BlobTargetOption.doesNotExist()) + .setTarget(target, BlobTargetOption.doesNotExist()) .build(); + CopyWriter copyWriter = storage.copy(req); - Blob gen1 = copyWriter.getResult(); - assertThat(gen1.getMetadata()).isAnyOf(null, ImmutableMap.of()); + Blob copied = copyWriter.getResult(); + assertTrue(copyWriter.isDone()); + assertThat(copied.getMetadata()).isAnyOf(null, ImmutableMap.of()); + assertTrue(remoteSourceBlob.delete()); - assertTrue(storage.delete(gen1.getBlobId())); + assertTrue(storage.delete(copied.getBlobId())); } @Test