@@ -1665,4 +1665,122 @@ public void testGetOmContainersDeletedInSCMPrevContainerParam()
1665
1665
assertEquals (1 , containerDiscrepancyInfoList .size ());
1666
1666
assertEquals (2 , containerDiscrepancyInfoList .get (0 ).getContainerID ());
1667
1667
}
1668
+
1669
+ /**
1670
+ * Helper method that creates duplicate FSO file keys – two keys having the same file
1671
+ * name but under different directories. It creates the necessary volume, bucket, and
1672
+ * directory entries, and then writes two keys using writeKeyToOm.
1673
+ */
1674
+ private void setUpDuplicateFSOFileKeys () throws IOException {
1675
+ // Ensure the volume exists.
1676
+ String volumeKey = reconOMMetadataManager .getVolumeKey (VOLUME_NAME );
1677
+ OmVolumeArgs volArgs = OmVolumeArgs .newBuilder ()
1678
+ .setVolume (VOLUME_NAME )
1679
+ .setAdminName ("TestUser" )
1680
+ .setOwnerName ("TestUser" )
1681
+ .setObjectID (VOL_OBJECT_ID )
1682
+ .build ();
1683
+ reconOMMetadataManager .getVolumeTable ().put (volumeKey , volArgs );
1684
+
1685
+ // Ensure the bucket exists.
1686
+ OmBucketInfo bucketInfo = OmBucketInfo .newBuilder ()
1687
+ .setVolumeName (VOLUME_NAME )
1688
+ .setBucketName (BUCKET_NAME )
1689
+ .setBucketLayout (BucketLayout .FILE_SYSTEM_OPTIMIZED )
1690
+ .setObjectID (BUCKET_OBJECT_ID )
1691
+ .build ();
1692
+ String bucketKey = reconOMMetadataManager .getBucketKey (VOLUME_NAME , BUCKET_NAME );
1693
+ reconOMMetadataManager .getBucketTable ().put (bucketKey , bucketInfo );
1694
+
1695
+ // Create two directories: "dirA" and "dirB" with unique object IDs.
1696
+ // For a top-level directory in a bucket, the parent's object id is the bucket's id.
1697
+ OmDirectoryInfo dirA = OmDirectoryInfo .newBuilder ()
1698
+ .setName ("dirA" )
1699
+ .setParentObjectID (BUCKET_OBJECT_ID )
1700
+ .setUpdateID (1L )
1701
+ .setObjectID (5L ) // Unique object id for dirA.
1702
+ .build ();
1703
+ OmDirectoryInfo dirB = OmDirectoryInfo .newBuilder ()
1704
+ .setName ("dirB" )
1705
+ .setParentObjectID (BUCKET_OBJECT_ID )
1706
+ .setUpdateID (1L )
1707
+ .setObjectID (6L ) // Unique object id for dirB.
1708
+ .build ();
1709
+ // Build DB directory keys. (The third parameter is used to form a unique key.)
1710
+ String dirKeyA = reconOMMetadataManager .getOzonePathKey (VOL_OBJECT_ID , BUCKET_OBJECT_ID , 5L , "dirA" );
1711
+ String dirKeyB = reconOMMetadataManager .getOzonePathKey (VOL_OBJECT_ID , BUCKET_OBJECT_ID , 6L , "dirB" );
1712
+ reconOMMetadataManager .getDirectoryTable ().put (dirKeyA , dirA );
1713
+ reconOMMetadataManager .getDirectoryTable ().put (dirKeyB , dirB );
1714
+
1715
+ // Use a common OmKeyLocationInfoGroup.
1716
+ OmKeyLocationInfoGroup locationInfoGroup = getLocationInfoGroup1 ();
1717
+
1718
+ // Write two FSO keys with the same file name ("dupFile") but in different directories.
1719
+ // The file name stored in OM is the full path (e.g., "dirA/dupFile" vs. "dirB/dupFile").
1720
+ writeKeyToOm (reconOMMetadataManager ,
1721
+ "dupFileKey1" , // internal key name for the first key
1722
+ BUCKET_NAME ,
1723
+ VOLUME_NAME ,
1724
+ "dupFileKey1" , // full file path for the first key
1725
+ 100L , // object id (example)
1726
+ 5L , // parent's object id for dirA (same as dirA's object id)
1727
+ BUCKET_OBJECT_ID ,
1728
+ VOL_OBJECT_ID ,
1729
+ Collections .singletonList (locationInfoGroup ),
1730
+ BucketLayout .FILE_SYSTEM_OPTIMIZED ,
1731
+ KEY_ONE_SIZE );
1732
+
1733
+ writeKeyToOm (reconOMMetadataManager ,
1734
+ "dupFileKey1" , // internal key name for the second key
1735
+ BUCKET_NAME ,
1736
+ VOLUME_NAME ,
1737
+ "dupFileKey1" , // full file path for the second key
1738
+ 100L ,
1739
+ 6L , // parent's object id for dirB
1740
+ BUCKET_OBJECT_ID ,
1741
+ VOL_OBJECT_ID ,
1742
+ Collections .singletonList (locationInfoGroup ),
1743
+ BucketLayout .FILE_SYSTEM_OPTIMIZED ,
1744
+ KEY_ONE_SIZE );
1745
+ }
1746
+
1747
+ /**
1748
+ * Test method that sets up two duplicate FSO file keys (same file name but in different directories)
1749
+ * and then verifies that the ContainerEndpoint returns two distinct key records.
1750
+ */
1751
+ @ Test
1752
+ public void testDuplicateFSOKeysForContainerEndpoint () throws IOException {
1753
+ // Set up duplicate FSO file keys.
1754
+ setUpDuplicateFSOFileKeys ();
1755
+ NSSummaryTaskWithFSO nSSummaryTaskWithFso =
1756
+ new NSSummaryTaskWithFSO (reconNamespaceSummaryManager ,
1757
+ reconOMMetadataManager , 10 );
1758
+ nSSummaryTaskWithFso .reprocessWithFSO (reconOMMetadataManager );
1759
+ // Reprocess the container key mappings so that the new keys are loaded.
1760
+ reprocessContainerKeyMapper ();
1761
+
1762
+ // Assume that FSO keys are mapped to container ID 20L (as in previous tests for FSO).
1763
+ Response response = containerEndpoint .getKeysForContainer (20L , -1 , "" );
1764
+ KeysResponse keysResponse = (KeysResponse ) response .getEntity ();
1765
+ Collection <KeyMetadata > keyMetadataList = keysResponse .getKeys ();
1766
+
1767
+ // We expect two distinct keys.
1768
+ assertEquals (2 , keysResponse .getTotalCount ());
1769
+ assertEquals (2 , keyMetadataList .size ());
1770
+
1771
+ for (KeyMetadata km : keyMetadataList ) {
1772
+ String completePath = km .getCompletePath ();
1773
+ assertNotNull (completePath );
1774
+ // Verify that the complete path reflects either directory "dirA" or "dirB"
1775
+ if (completePath .contains ("dirA" )) {
1776
+ assertEquals (VOLUME_NAME + "/" + BUCKET_NAME + "/dirA/dupFileKey1" , completePath );
1777
+ } else if (completePath .contains ("dirB" )) {
1778
+ assertEquals (VOLUME_NAME + "/" + BUCKET_NAME + "/dirB/dupFileKey1" , completePath );
1779
+ } else {
1780
+ throw new AssertionError ("Unexpected complete path: " + completePath );
1781
+ }
1782
+ }
1783
+ }
1784
+
1785
+
1668
1786
}
0 commit comments