This is an automated email from the ASF dual-hosted git repository.
sshenoy 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 86c433919e HDDS-11187. Fix Event Handling in Recon OMDBUpdatesHandler
to Prevent ClassCastException. (#6950)
86c433919e is described below
commit 86c433919ea8252763a534bb0bf17f5b4c57b86f
Author: Arafat2198 <[email protected]>
AuthorDate: Mon Jul 22 14:14:06 2024 +0530
HDDS-11187. Fix Event Handling in Recon OMDBUpdatesHandler to Prevent
ClassCastException. (#6950)
---
.../ozone/recon/tasks/OMDBUpdatesHandler.java | 11 ++--
.../ozone/recon/tasks/TestOMDBUpdatesHandler.java | 67 ++++++++++++++++++++++
2 files changed, 74 insertions(+), 4 deletions(-)
diff --git
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/tasks/OMDBUpdatesHandler.java
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/tasks/OMDBUpdatesHandler.java
index cfaf4bb60a..41e6bf962a 100644
---
a/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/tasks/OMDBUpdatesHandler.java
+++
b/hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/tasks/OMDBUpdatesHandler.java
@@ -48,8 +48,7 @@ public class OMDBUpdatesHandler extends
ManagedWriteBatch.Handler {
private Map<Integer, String> tablesNames;
private OMMetadataManager omMetadataManager;
private List<OMDBUpdateEvent> omdbUpdateEvents = new ArrayList<>();
- private Map<Object, OMDBUpdateEvent> omdbLatestUpdateEvents
- = new HashMap<>();
+ private Map<String, Map<Object, OMDBUpdateEvent>> omdbLatestUpdateEvents =
new HashMap<>();
private OMDBDefinition omdbDefinition;
private OmUpdateEventValidator omUpdateEventValidator;
@@ -112,6 +111,10 @@ public class OMDBUpdatesHandler extends
ManagedWriteBatch.Handler {
final Object key = cf.getKeyCodec().fromPersistedFormat(keyBytes);
builder.setKey(key);
+ // Initialize table-specific event map if it does not exist
+ omdbLatestUpdateEvents.putIfAbsent(tableName, new HashMap<>());
+ Map<Object, OMDBUpdateEvent> tableEventsMap =
omdbLatestUpdateEvents.get(tableName);
+
// Handle the event based on its type:
// - PUT with a new key: Insert the new value.
// - PUT with an existing key: Update the existing value.
@@ -120,7 +123,7 @@ public class OMDBUpdatesHandler extends
ManagedWriteBatch.Handler {
// necessary.
Table table = omMetadataManager.getTable(tableName);
- OMDBUpdateEvent latestEvent = omdbLatestUpdateEvents.get(key);
+ OMDBUpdateEvent latestEvent = tableEventsMap.get(key);
Object oldValue;
if (latestEvent != null) {
oldValue = latestEvent.getValue();
@@ -184,7 +187,7 @@ public class OMDBUpdatesHandler extends
ManagedWriteBatch.Handler {
"action = %s", tableName, action));
}
omdbUpdateEvents.add(event);
- omdbLatestUpdateEvents.put(key, event);
+ tableEventsMap.put(key, event);
} else {
// Log and ignore events if key or value types are undetermined.
if (LOG.isWarnEnabled()) {
diff --git
a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/tasks/TestOMDBUpdatesHandler.java
b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/tasks/TestOMDBUpdatesHandler.java
index 9676af0157..3831f03bfd 100644
---
a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/tasks/TestOMDBUpdatesHandler.java
+++
b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/tasks/TestOMDBUpdatesHandler.java
@@ -42,6 +42,8 @@ import org.apache.hadoop.io.Text;
import org.apache.hadoop.ozone.om.OMMetadataManager;
import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
import org.apache.hadoop.ozone.om.codec.OMDBDefinition;
+import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.OmDirectoryInfo;
import org.apache.hadoop.ozone.om.helpers.BucketLayout;
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
@@ -286,6 +288,71 @@ public class TestOMDBUpdatesHandler {
((OmKeyInfo)keyPut2.getOldValue()).getKeyName());
}
+ /**
+ * Test to verify that events with duplicate keys in different tables
+ * (FileTable and DirectoryTable) are handled correctly without causing
+ * ClassCastException or event conflicts.
+ *
+ * This test simulates creating a file, deleting the file, and then creating
+ * a directory with the same name under the same parent ID in different
tables.
+ * It ensures that the events are correctly processed and stored in the
+ * `omdbLatestUpdateEvents` map without causing any type mismatches or
+ * exceptions.
+ *
+ * @throws Exception if any error occurs during the test execution.
+ */
+ @Test
+ public void testEventsHavingDuplicateRocksDBKey() throws Exception {
+ // Step 1: Create a file with the name "sameName" in the fileTable
+ OmKeyInfo fileKeyInfo = getOmKeyInfo("sampleVol", "bucketOne", "sameName");
+
omMetadataManager.getFileTable().put("/sampleVol/bucketOne/parentId/sameName",
fileKeyInfo);
+
+ // Step 2: Delete the file by adding its information to the deletedTable
+ RepeatedOmKeyInfo repeatedKeyInfo = new RepeatedOmKeyInfo(fileKeyInfo);
+
omMetadataManager.getDeletedTable().put("/sampleVol/bucketOne/parentId/sameName",
repeatedKeyInfo);
+
+ // Step 3: Create a directory with the same name "sameName" in the
directoryTable
+ OmDirectoryInfo dirInfo = OmDirectoryInfo.newBuilder()
+ .setName("sameName")
+ .setParentObjectID(fileKeyInfo.getParentObjectID())
+ .setObjectID(fileKeyInfo.getObjectID())
+ .setCreationTime(System.currentTimeMillis())
+ .setModificationTime(System.currentTimeMillis())
+ .build();
+
omMetadataManager.getDirectoryTable().put("/sampleVol/bucketOne/parentId/sameName",
dirInfo);
+
+ // Capture the events from the OM Metadata Manager
+ List<byte[]> writeBatches = getBytesFromOmMetaManager(0);
+ OMDBUpdatesHandler omdbUpdatesHandler = captureEvents(writeBatches);
+
+ // Retrieve the captured events and assert the correct number of events
+ List<OMDBUpdateEvent> events = omdbUpdatesHandler.getEvents();
+ // Verify no events were discarded
+ assertEquals(3, events.size());
+
+ // Validate the file creation event
+ OMDBUpdateEvent filePutEvent = events.get(0);
+ assertEquals(PUT, filePutEvent.getAction());
+ assertEquals("/sampleVol/bucketOne/parentId/sameName",
filePutEvent.getKey());
+ assertEquals("sameName", ((OmKeyInfo)
filePutEvent.getValue()).getKeyName());
+ assertNull(filePutEvent.getOldValue());
+
+ // Validate the file deletion event
+ OMDBUpdateEvent fileDeleteEvent = events.get(1);
+ assertEquals(PUT, fileDeleteEvent.getAction());
+ assertEquals("/sampleVol/bucketOne/parentId/sameName",
fileDeleteEvent.getKey());
+ assertEquals("sameName",
+ ((RepeatedOmKeyInfo)
fileDeleteEvent.getValue()).getOmKeyInfoList().get(0).getKeyName());
+
+ // Validate the directory creation event
+ OMDBUpdateEvent dirPutEvent = events.get(2);
+ assertEquals(PUT, dirPutEvent.getAction());
+ assertEquals("/sampleVol/bucketOne/parentId/sameName",
dirPutEvent.getKey());
+ assertEquals("sameName", ((OmDirectoryInfo)
dirPutEvent.getValue()).getName());
+ // There will be no old value as the key was not present in the
directoryTable before
+ assertNull(dirPutEvent.getOldValue());
+ }
+
@Test
public void testGetKeyType() throws IOException {
final String keyTable = omMetadataManager
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]