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); } 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..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 @@ -1036,6 +1036,31 @@ public void testCopyBlobUpdateMetadata() { assertTrue(storage.delete(gen1.getBlobId())); } + @Test + public void testCopyBlob_targetBlobInfo_doesNotInheritMetadata() { + BlobId source = BlobId.of(bucket.getName(), generator.randomObjectName() + "-source"); + Blob remoteSourceBlob = + storage.create( + BlobInfo.newBuilder(source).setMetadata(ImmutableMap.of("k", "v")).build(), + BLOB_BYTE_CONTENT); + assertNotNull(remoteSourceBlob); + BlobInfo target = BlobInfo.newBuilder(bucket, generator.randomObjectName() + "-target").build(); + CopyRequest req = + CopyRequest.newBuilder() + .setSource(source) + .setTarget(target, BlobTargetOption.doesNotExist()) + .build(); + + CopyWriter copyWriter = storage.copy(req); + Blob copied = copyWriter.getResult(); + + assertTrue(copyWriter.isDone()); + assertThat(copied.getMetadata()).isAnyOf(null, ImmutableMap.of()); + + assertTrue(remoteSourceBlob.delete()); + assertTrue(storage.delete(copied.getBlobId())); + } + @Test public void testCopyBlobFail() {