From 7384220905e0bd3d271fc6a03100e92b442f9946 Mon Sep 17 00:00:00 2001 From: Siyao Meng <50227127+smengcl@users.noreply.github.com> Date: Wed, 7 Oct 2026 10:33:08 -0700 Subject: [PATCH] HDDS-16757. RenameKeys overwrites an existing destination key and still reports the pair as not renamed Co-Authored-By: Claude Opus 5.5 --- .../om/request/key/OMKeysRenameRequest.java | 1 + .../request/key/TestOMKeysRenameRequest.java | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysRenameRequest.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysRenameRequest.java index 3da0849f44f4..12e6ec5a312a 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysRenameRequest.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeysRenameRequest.java @@ -177,6 +177,7 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, Execut .build()); LOG.error("Received a request name of new key {} already exists", toKeyName); + continue; } // fromKeyName should exist diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeysRenameRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeysRenameRequest.java index 8eca1660da43..d1de04440381 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeysRenameRequest.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeysRenameRequest.java @@ -18,6 +18,7 @@ package org.apache.hadoop.ozone.om.request.key; import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor.THREE; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -25,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.UUID; import org.apache.hadoop.hdds.client.RatisReplicationConfig; @@ -110,6 +112,38 @@ public void testKeysRenameRequestFail() throws Exception { assertEquals("testKey", unRenamedKeys.getFromKeyName()); } + @Test + public void testKeysRenameRequestToExistingKey() throws Exception { + OMRequestTestUtils.addVolumeAndBucketToDB(volumeName, bucketName, omMetadataManager); + + String fromKeyName = parentDir.concat("/fromKey"); + String toKeyName = parentDir.concat("/toKey"); + OmKeyInfo fromKeyInfo = OMRequestTestUtils.addKeyToTableCache(volumeName, bucketName, fromKeyName, + RatisReplicationConfig.getInstance(THREE), omMetadataManager); + OmKeyInfo toKeyInfo = OMRequestTestUtils.addKeyToTableCache(volumeName, bucketName, toKeyName, + RatisReplicationConfig.getInstance(THREE), omMetadataManager); + + RenameKeysMap renameKey = RenameKeysMap.newBuilder().setFromKeyName(fromKeyName).setToKeyName(toKeyName).build(); + // fromKey does not exist either, the pair should still be reported only once. + RenameKeysMap missingRenameKey = + RenameKeysMap.newBuilder().setFromKeyName("testKey").setToKeyName(toKeyName).build(); + OMRequest omRequest = createRenameKeyRequest(Arrays.asList(renameKey, missingRenameKey)); + + OMClientResponse omKeysRenameResponse = + new OMKeysRenameRequest(omRequest, getBucketLayout()).validateAndUpdateCache(ozoneManager, 100L); + + assertThat(omKeysRenameResponse.getOMResponse().getStatus()) + .isEqualTo(OzoneManagerProtocolProtos.Status.PARTIAL_RENAME); + assertThat(omKeysRenameResponse.getOMResponse().getRenameKeysResponse().getUnRenamedKeysList()) + .containsExactly(renameKey, missingRenameKey); + + // The existing toKey must not be overwritten, and fromKey must stay. + assertThat(omMetadataManager.getKeyTable(getBucketLayout()) + .get(omMetadataManager.getOzoneKey(volumeName, bucketName, fromKeyName))).isEqualTo(fromKeyInfo); + assertThat(omMetadataManager.getKeyTable(getBucketLayout()) + .get(omMetadataManager.getOzoneKey(volumeName, bucketName, toKeyName))).isEqualTo(toKeyInfo); + } + /** * Create OMRequest which encapsulates RenameKeyRequest. * @@ -144,6 +178,10 @@ private OMRequest createRenameKeyRequest(Boolean isIllegal) throws Exception { renameKeyList.add(renameKey.build()); } + return createRenameKeyRequest(renameKeyList); + } + + private OMRequest createRenameKeyRequest(List renameKeyList) { RenameKeysArgs.Builder renameKeyArgs = RenameKeysArgs.newBuilder() .setVolumeName(volumeName) .setBucketName(bucketName)