This is an automated email from the ASF dual-hosted git repository.

mandarambawane pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/master by this push:
     new df293c4bd ATLAS-5034: Entities not created in Atlas when hive table 
created on top a OFS/O3FS bucket/volume (#372)
df293c4bd is described below

commit df293c4bd1b8d25b9a9e7b32533364cfc9f7f0ce
Author: Aditya Gupta <aditya.gu...@freestoneinfotech.com>
AuthorDate: Mon Jun 16 16:14:47 2025 +0530

    ATLAS-5034: Entities not created in Atlas when hive table created on top a 
OFS/O3FS bucket/volume (#372)
---
 .../apache/atlas/utils/AtlasPathExtractorUtil.java | 269 +++++++++++++++------
 .../atlas/utils/AtlasPathExtractorUtilTest.java    |  81 +++++--
 2 files changed, 258 insertions(+), 92 deletions(-)

diff --git 
a/common/src/main/java/org/apache/atlas/utils/AtlasPathExtractorUtil.java 
b/common/src/main/java/org/apache/atlas/utils/AtlasPathExtractorUtil.java
index a60da1ec5..06558737f 100644
--- a/common/src/main/java/org/apache/atlas/utils/AtlasPathExtractorUtil.java
+++ b/common/src/main/java/org/apache/atlas/utils/AtlasPathExtractorUtil.java
@@ -29,7 +29,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.net.URI;
-import java.util.Arrays;
+import java.util.Optional;
 
 public class AtlasPathExtractorUtil {
     // Common
@@ -90,6 +90,10 @@ public class AtlasPathExtractorUtil {
     }
 
     public static AtlasEntityWithExtInfo getPathEntity(Path path, 
PathExtractorContext context) {
+        if (StringUtils.isEmpty(path.toString())) {
+            throw new IllegalArgumentException("Invalid Input: Path is Null");
+        }
+
         AtlasEntityWithExtInfo entityWithExtInfo = new 
AtlasEntityWithExtInfo();
         String                 strPath           = path.toString();
         AtlasEntity            ret;
@@ -344,111 +348,232 @@ public class AtlasPathExtractorUtil {
         return ret;
     }
 
-    private static AtlasEntity addOzonePathEntity(Path path, 
AtlasEntityExtInfo extInfo, PathExtractorContext context) {
-        String strPath = path.toString();
+    /**
+     * Returns O3FS Authority i.e. "bucket-volume-Ozone_Service_Id"
+     * Example: query: 'o3fs://buck1.vol1.ozone1747118357/key1' - 
O3FS_Authority: buck1.vol1.ozone1747118357
+     */
+    private static String o3fsAuthorityExtractor(String path) {
+        return Optional.ofNullable(path)
+                .filter(p -> p.startsWith(OZONE_3_SCHEME))
+                .map(p -> p.substring(OZONE_3_SCHEME.length()).split("/", 2))
+                .filter(parts -> parts.length > 0)
+                .map(parts -> parts[0])
+                .orElse("");
+    }
 
-        LOG.debug("==> addOzonePathEntity(strPath={})", strPath);
+    /**
+     * Returns O3FS Keys defined in the path.
+     * Example: query: 'o3fs://buck1.vol1.ozone1747118357/key1' -> Keys: key1
+     * Example: query: 'o3fs://buck1.vol1.ozone1747118357/key1/key2' -> Keys: 
[key1, key2]
+     */
+    private static String[] o3fsKeyExtractor(String path) {
+        return Optional.ofNullable(path)
+                .filter(p -> p.startsWith(OZONE_3_SCHEME))
+                .map(p -> p.substring(OZONE_3_SCHEME.length()).split("/", 2))
+                .filter(parts -> parts.length == 2)
+                .map(parts -> parts[1].split("/"))
+                .orElse(new String[] {""});
+    }
 
-        String      metadataNamespace = context.getMetadataNamespace();
-        String      ozoneScheme       = path.toUri().getScheme();
-        String      pathQualifiedName = strPath + QNAME_SEP_METADATA_NAMESPACE 
+ metadataNamespace;
-        AtlasEntity ret               = context.getEntity(pathQualifiedName);
+    /**
+     * Returns Count of O3FS paths - [bucket + volume + keys].
+     * Example: query: 'o3fs://buck1.vol1.ozone1747118357/key1': length = 1 
(bucket) + 1 (volume) + 1 (key) = 3
+     * Example: query: 'o3fs://buck1.vol1.ozone1747118357/key1/key2': length = 
1 (bucket) + 1 (volume) + 2 (key segments) = 4
+     *
+     * O3FS_AUTHORITY_WITH_KEYS: "buck1.vol1.ozone1747118357/key1/key2"
+     * Authority_And_Keys: [buck1.vol1.ozone1747118357, key1/key2]
+     * O3fs_Authority: "buck1.vol1.ozone1747118357"
+     * keyPath: "key1/key2"
+     */
+    private static int getO3fsPathLength(String path) {
+        if (!path.startsWith(OZONE_3_SCHEME)) {
+            return 0;
+        }
+        String o3fsAuthorityWithKeys = path.substring(OZONE_3_SCHEME.length());
+        String[] authorityAndKeys = o3fsAuthorityWithKeys.split("/", 2);
+        String o3fsAuthority = authorityAndKeys[0];
+        String keyPath = authorityAndKeys.length > 1 ? 
authorityAndKeys[1].trim() : "";
+
+        // Count bucket and volume from authority
+        String[] bucketAndVolume = o3fsAuthority.split("\\.");
+        int length = 0;
+        if (bucketAndVolume.length >= 1) {
+            length++;  // bucket
+        }
+        if (bucketAndVolume.length >= 2) {
+            length++;  // volume
+        }
 
-        if (ret == null) {
-            //create ozone volume entity
-            String      volumeName          = getOzoneVolumeName(path);
-            String      volumeQualifiedName = ozoneScheme + SCHEME_SEPARATOR + 
volumeName + QNAME_SEP_METADATA_NAMESPACE + metadataNamespace;
-            AtlasEntity volumeEntity        = 
context.getEntity(volumeQualifiedName);
+        // Count key segments if present
+        if (!keyPath.isEmpty()) {
+            String[] keys = keyPath.split("/");
+            length += keys.length;
+        }
 
-            if (volumeEntity == null) {
-                volumeEntity = new AtlasEntity(OZONE_VOLUME);
+        return length;
+    }
 
-                volumeEntity.setAttribute(ATTRIBUTE_QUALIFIED_NAME, 
volumeQualifiedName);
-                volumeEntity.setAttribute(ATTRIBUTE_NAME, volumeName);
+    /**
+     * Creates Ozone Entity for different Ozone Type Names: OZONE_BUCKET, 
OZONE_VOLUME, OZONE_KEY and sets relationshipAttribute between them
+     */
+    private static AtlasEntity createOzoneEntity(PathExtractorContext context, 
String typeName, String name, String qualifiedName, AtlasRelatedObjectId 
relationship) {
+        AtlasEntity ozoneEntity = context.getEntity(qualifiedName);
 
-                LOG.debug("adding entity: typeName={}, qualifiedName={}", 
volumeEntity.getTypeName(), 
volumeEntity.getAttribute(ATTRIBUTE_QUALIFIED_NAME));
+        if (ozoneEntity == null) {
+            ozoneEntity = new AtlasEntity(typeName);
+            ozoneEntity.setAttribute(ATTRIBUTE_QUALIFIED_NAME, qualifiedName);
+            ozoneEntity.setAttribute(ATTRIBUTE_NAME, name);
 
-                context.putEntity(volumeQualifiedName, volumeEntity);
+            if (relationship != null) {
+                String relationshipAttribute = typeName.equals(OZONE_BUCKET) ? 
ATTRIBUTE_VOLUME : ATTRIBUTE_PARENT;
+                ozoneEntity.setRelationshipAttribute(relationshipAttribute, 
relationship);
             }
 
-            extInfo.addReferredEntity(volumeEntity);
+            context.putEntity(qualifiedName, ozoneEntity);
+            LOG.info("Added entity: typeName={}, qualifiedName={}", typeName, 
qualifiedName);
+        }
 
-            //create ozone bucket entity
-            String      bucketName          = getOzoneBucketName(path);
-            String      bucketQualifiedName = ozoneScheme + SCHEME_SEPARATOR + 
volumeName + QNAME_SEP_ENTITY_NAME + bucketName + QNAME_SEP_METADATA_NAMESPACE 
+ metadataNamespace;
-            AtlasEntity bucketEntity        = 
context.getEntity(bucketQualifiedName);
+        return ozoneEntity;
+    }
 
-            if (bucketEntity == null) {
-                bucketEntity = new AtlasEntity(OZONE_BUCKET);
+    /**
+     * Adds Ozone Path Entity for Scheme: OZONE_SCHEME
+     */
+    private static AtlasEntity addOfsPathEntity(Path path, AtlasEntityExtInfo 
extInfo, PathExtractorContext context) {
+        String metadataNamespace = context.getMetadataNamespace();
+        String ozoneScheme = path.toUri().getScheme();
+        String ofsVolumeName = getOzoneVolumeName(path);
+        String ofsVolumeQualifiedName = OZONE_SCHEME + ofsVolumeName + 
QNAME_SEP_METADATA_NAMESPACE + metadataNamespace;
+
+        String ofsDirPath = path.toUri().getPath();
+        if (StringUtils.isEmpty(ofsDirPath)) {
+            ofsDirPath = Path.SEPARATOR;
+        }
 
-                bucketEntity.setAttribute(ATTRIBUTE_QUALIFIED_NAME, 
bucketQualifiedName);
-                bucketEntity.setAttribute(ATTRIBUTE_NAME, bucketName);
-                bucketEntity.setRelationshipAttribute(ATTRIBUTE_VOLUME, 
AtlasTypeUtil.getAtlasRelatedObjectId(volumeEntity, 
RELATIONSHIP_OZONE_VOLUME_BUCKET));
+        String[] ofsPath = ofsDirPath.split(Path.SEPARATOR);
+        if (ofsPath.length < 2) {
+            return null;
+        }
 
-                LOG.debug("adding entity: typeName={}, qualifiedName={}", 
bucketEntity.getTypeName(), 
bucketEntity.getAttribute(ATTRIBUTE_QUALIFIED_NAME));
+        AtlasEntity volumeEntity = createOzoneEntity(context, OZONE_VOLUME, 
ofsVolumeName, ofsVolumeQualifiedName, null);
+        extInfo.addReferredEntity(volumeEntity);
 
-                context.putEntity(bucketQualifiedName, bucketEntity);
-            }
+        if (ofsPath.length == 2) {
+            return volumeEntity;
+        }
 
-            extInfo.addReferredEntity(bucketEntity);
+        String ofsBucketName = ofsPath[2];
+        String ofsBucketQualifiedName = OZONE_SCHEME + ofsVolumeName + 
QNAME_SEP_ENTITY_NAME + ofsBucketName + QNAME_SEP_METADATA_NAMESPACE + 
metadataNamespace;
+        AtlasEntity bucketEntity = createOzoneEntity(context, OZONE_BUCKET, 
ofsBucketName, ofsBucketQualifiedName,
+                AtlasTypeUtil.getAtlasRelatedObjectId(volumeEntity, 
RELATIONSHIP_OZONE_VOLUME_BUCKET));
+        extInfo.addReferredEntity(bucketEntity);
 
-            AtlasRelatedObjectId parentObjId = 
AtlasTypeUtil.getAtlasRelatedObjectId(bucketEntity, 
RELATIONSHIP_OZONE_PARENT_CHILDREN);
-            String               parentPath  = Path.SEPARATOR;
-            String               dirPath     = path.toUri().getPath();
+        if (ofsPath.length == 3) {
+            return bucketEntity;
+        }
 
-            if (StringUtils.isEmpty(dirPath)) {
-                dirPath = Path.SEPARATOR;
-            }
+        AtlasEntity currentOfsKeyEntity = null;
+        StringBuilder keyPathBuilder = new StringBuilder();
+        String keyQNamePrefix = ozoneScheme + SCHEME_SEPARATOR + 
path.toUri().getAuthority();
 
-            String keyQNamePrefix = ozoneScheme + SCHEME_SEPARATOR + 
path.toUri().getAuthority();
-            String[] subDirNames   = dirPath.split(Path.SEPARATOR);
-            String[] subDirNameArr = subDirNames;
+        AtlasEntity parentEntityForOfsKey = bucketEntity;
 
-            if (ozoneScheme.equals(OZONE_SCHEME_NAME)) {
-                subDirNames = Arrays.stream(subDirNameArr, 3, 
subDirNameArr.length).toArray(String[]::new);
+        for (int i = 3; i < ofsPath.length; i++) {
+            String ofsKeyName = ofsPath[i];
+            if (StringUtils.isEmpty(ofsKeyName)) {
+                continue;
             }
 
-            boolean volumeBucketAdded = false;
+            keyPathBuilder.append(Path.SEPARATOR).append(ofsKeyName);
 
-            for (String subDirName : subDirNames) {
-                if (StringUtils.isEmpty(subDirName)) {
-                    continue;
-                }
+            String ofsKeyQualifiedName = keyQNamePrefix
+                    + Path.SEPARATOR + ofsVolumeName
+                    + Path.SEPARATOR + ofsBucketName
+                    + keyPathBuilder
+                    + QNAME_SEP_METADATA_NAMESPACE + metadataNamespace;
 
-                String subDirPath;
+            currentOfsKeyEntity = createOzoneEntity(context, OZONE_KEY, 
ofsKeyName, ofsKeyQualifiedName,
+                    
AtlasTypeUtil.getAtlasRelatedObjectId(parentEntityForOfsKey, 
RELATIONSHIP_OZONE_PARENT_CHILDREN));
 
-                if (ozoneScheme.equals(OZONE_SCHEME_NAME) && 
!volumeBucketAdded) {
-                    subDirPath        = "%s%s" + Path.SEPARATOR + "%s" + 
Path.SEPARATOR + "%s";
-                    subDirPath        = String.format(subDirPath, parentPath, 
subDirNameArr[1], subDirNameArr[2], subDirName);
-                    volumeBucketAdded = true;
-                } else {
-                    subDirPath = parentPath + subDirName;
-                }
+            parentEntityForOfsKey = currentOfsKeyEntity;
+            AtlasTypeUtil.getAtlasRelatedObjectId(parentEntityForOfsKey, 
RELATIONSHIP_OZONE_PARENT_CHILDREN);
+        }
 
-                String subDirQualifiedName = keyQNamePrefix + subDirPath + 
QNAME_SEP_METADATA_NAMESPACE + metadataNamespace;
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== addOzonePathEntity(strPath={})", path.toString());
+        }
 
-                ret = context.getEntity(subDirQualifiedName);
+        return currentOfsKeyEntity;
+    }
 
-                if (ret == null) {
-                    ret = new AtlasEntity(OZONE_KEY);
+    /**
+     * Adds Ozone Path Entity for Scheme: OZONE_3_SCHEME
+     */
+    private static AtlasEntity addO3fsPathEntity(Path path, AtlasEntityExtInfo 
extInfo, PathExtractorContext context) {
+        String[] o3fsKeys = o3fsKeyExtractor(path.toString());
+        int o3fsPathLength = getO3fsPathLength(path.toString());
+        String metadataNamespace = context.getMetadataNamespace();
+        String ozoneScheme = path.toUri().getScheme();
+        String o3fsBucketName = getOzoneBucketName(path);
+        String o3fsVolumeName = getOzoneVolumeName(path);
+        String o3fsVolumeQualifiedName = ozoneScheme + SCHEME_SEPARATOR + 
o3fsVolumeName + QNAME_SEP_METADATA_NAMESPACE + metadataNamespace;
+
+        AtlasEntity volumeEntity = createOzoneEntity(context, OZONE_VOLUME, 
o3fsVolumeName, o3fsVolumeQualifiedName, null);
+        extInfo.addReferredEntity(volumeEntity);
+
+        String bucketQualifiedName = ozoneScheme + SCHEME_SEPARATOR + 
o3fsVolumeName + QNAME_SEP_ENTITY_NAME + o3fsBucketName + 
QNAME_SEP_METADATA_NAMESPACE + metadataNamespace;
+        AtlasEntity bucketEntity = createOzoneEntity(context, OZONE_BUCKET, 
o3fsBucketName, bucketQualifiedName,
+                AtlasTypeUtil.getAtlasRelatedObjectId(volumeEntity, 
RELATIONSHIP_OZONE_VOLUME_BUCKET));
+        extInfo.addReferredEntity(bucketEntity);
+
+        if (o3fsPathLength < 1) {
+            return null;
+        }
 
-                    ret.setRelationshipAttribute(ATTRIBUTE_PARENT, 
parentObjId);
-                    ret.setAttribute(ATTRIBUTE_QUALIFIED_NAME, 
subDirQualifiedName);
-                    ret.setAttribute(ATTRIBUTE_NAME, subDirName);
+        if (o3fsPathLength == 1) {
+            return volumeEntity;
+        }
+        if (o3fsPathLength == 2) {
+            return bucketEntity;
+        }
 
-                    LOG.debug("adding entity: typeName={}, qualifiedName={}", 
ret.getTypeName(), ret.getAttribute(ATTRIBUTE_QUALIFIED_NAME));
+        AtlasEntity currentO3fsKeyEntity = null;
+        AtlasEntity parentEntityForO3fsKey = bucketEntity;
+        StringBuilder keyPathBuilder = new StringBuilder();
+        String authority = o3fsAuthorityExtractor(path.toString());
 
-                    context.putEntity(subDirQualifiedName, ret);
-                }
+        for (String o3fsKeyName : o3fsKeys) {
+            keyPathBuilder.append(Path.SEPARATOR).append(o3fsKeyName);
 
-                parentObjId = AtlasTypeUtil.getAtlasRelatedObjectId(ret, 
RELATIONSHIP_OZONE_PARENT_CHILDREN);
-                parentPath  = subDirPath + Path.SEPARATOR;
-            }
+            String o3fsKeyQualifiedName = ozoneScheme + SCHEME_SEPARATOR + 
authority + keyPathBuilder + QNAME_SEP_METADATA_NAMESPACE + metadataNamespace;
+
+            currentO3fsKeyEntity = createOzoneEntity(context, OZONE_KEY, 
o3fsKeyName, o3fsKeyQualifiedName,
+                    
AtlasTypeUtil.getAtlasRelatedObjectId(parentEntityForO3fsKey, 
RELATIONSHIP_OZONE_PARENT_CHILDREN));
+
+            parentEntityForO3fsKey = currentO3fsKeyEntity;
+            AtlasTypeUtil.getAtlasRelatedObjectId(parentEntityForO3fsKey, 
RELATIONSHIP_OZONE_PARENT_CHILDREN);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== addOzonePathEntity(strPath={})", path.toString());
         }
 
-        LOG.debug("<== addOzonePathEntity(strPath={})", strPath);
+        return currentO3fsKeyEntity;
+    }
 
-        return ret;
+    /**
+     * Adds Ozone Path Entity: OZONE_3_SCHEME | OZONE_3_SCHEME
+     */
+    private static AtlasEntity addOzonePathEntity(Path path, 
AtlasEntityExtInfo extInfo, PathExtractorContext context) {
+        String strPath = path.toString();
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> addOzonePathEntity(strPath={})", strPath);
+        }
+
+        return strPath.startsWith(OZONE_3_SCHEME)
+                ? addO3fsPathEntity(path, extInfo, context)
+                : addOfsPathEntity(path, extInfo, context);
     }
 
     private static AtlasEntity addGCSPathEntity(Path path, AtlasEntityExtInfo 
extInfo, PathExtractorContext context) {
diff --git 
a/common/src/test/java/org/apache/atlas/utils/AtlasPathExtractorUtilTest.java 
b/common/src/test/java/org/apache/atlas/utils/AtlasPathExtractorUtilTest.java
index 6b95fd30c..83c84d785 100644
--- 
a/common/src/test/java/org/apache/atlas/utils/AtlasPathExtractorUtilTest.java
+++ 
b/common/src/test/java/org/apache/atlas/utils/AtlasPathExtractorUtilTest.java
@@ -28,6 +28,7 @@ import org.testng.annotations.Test;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -88,22 +89,32 @@ public class AtlasPathExtractorUtilTest {
 
     @Test(dataProvider = "ozonePathProvider")
     public void testGetPathEntityOzone3Path(OzoneKeyValidator validator) {
-        String scheme    = validator.scheme;
+        String scheme = validator.scheme;
         String ozonePath = scheme + validator.location;
 
         PathExtractorContext extractorContext = new 
PathExtractorContext(METADATA_NAMESPACE);
-        Path                 path             = new Path(ozonePath);
+        Path path = new Path(ozonePath);
 
         AtlasEntityWithExtInfo entityWithExtInfo = 
AtlasPathExtractorUtil.getPathEntity(path, extractorContext);
-        AtlasEntity            entity            = 
entityWithExtInfo.getEntity();
+        AtlasEntity entity = entityWithExtInfo.getEntity();
 
         assertNotNull(entity);
         verifyOzoneKeyEntity(entity, validator);
 
-        assertEquals(entityWithExtInfo.getReferredEntities().size(), 2);
+        if (entity.getTypeName() == OZONE_KEY) {
+            verifyReferredAndKnownEntities(entityWithExtInfo, 
extractorContext, validator, validator.knownEntitiesCountTillKey, 2);
+        } else if (entity.getTypeName() == OZONE_BUCKET) {
+            verifyReferredAndKnownEntities(entityWithExtInfo, 
extractorContext, validator, validator.knownEntitiesCountTillBucket, 2);
+        } else if (entity.getTypeName() == OZONE_VOLUME) {
+            verifyReferredAndKnownEntities(entityWithExtInfo, 
extractorContext, validator, validator.knownEntitiesCountTillVolume, 1);
+        }
+    }
+
+    private void verifyReferredAndKnownEntities(AtlasEntityWithExtInfo 
entityWithExtInfo, PathExtractorContext extractorContext, OzoneKeyValidator 
validator, int knownEntitiesCountTillVolume, int referredEntitiesSize) {
+        assertEquals(entityWithExtInfo.getReferredEntities().size(), 
referredEntitiesSize);
         verifyOzoneEntities(entityWithExtInfo.getReferredEntities(), 
validator);
 
-        assertEquals(extractorContext.getKnownEntities().size(), 
validator.knownEntitiesCount);
+        assertEquals(extractorContext.getKnownEntities().size(), 
knownEntitiesCountTillVolume);
         verifyOzoneEntities(extractorContext.getKnownEntities(), validator);
     }
 
@@ -271,20 +282,40 @@ public class AtlasPathExtractorUtilTest {
                         "quarter_one", "ozone1/volume1/bucket1/quarter_one",
                         "sales", "ozone1/volume1/bucket1/quarter_one/sales")},
 
+                {new OzoneKeyValidator(OZONE_SCHEME, 
"ozone1745922163/volume1/bucket1/mykey1/key.text",
+                        "mykey1", "ozone1745922163/volume1/bucket1/mykey1",
+                        "key.text", 
"ozone1745922163/volume1/bucket1/mykey1/key.text")},
+
+                {new OzoneKeyValidator(OZONE_SCHEME, "ozone1/volume1/bucket1",
+                        "bucket1", "volume1.bucket1")},
+
+                {new OzoneKeyValidator(OZONE_SCHEME, "ozone1/volume1",
+                        "volume1", "volume1")},
+
                 {new OzoneKeyValidator(OZONE_3_SCHEME, 
"bucket1.volume1.ozone1/files/file.txt",
                         "files", "bucket1.volume1.ozone1/files",
-                        "file.txt", "bucket1.volume1.ozone1/files/file.txt")},
+                        "file.txt", "bucket1.volume1.ozone1/files/file.txt") },
 
                 {new OzoneKeyValidator(OZONE_3_SCHEME, 
"bucket1.volume1.ozone1/file21.txt",
-                        "file21.txt", "bucket1.volume1.ozone1/file21.txt")},
+                        "file21.txt", "bucket1.volume1.ozone1/file21.txt") },
 
                 {new OzoneKeyValidator(OZONE_3_SCHEME, 
"bucket1.volume1.ozone1/quarter_one/sales",
                         "quarter_one", "bucket1.volume1.ozone1/quarter_one",
-                        "sales", "bucket1.volume1.ozone1/quarter_one/sales")},
+                        "sales", "bucket1.volume1.ozone1/quarter_one/sales") },
 
                 {new OzoneKeyValidator(OZONE_3_SCHEME, 
"bucket1.volume1.ozone1/quarter_one/sales/",
                         "quarter_one", "bucket1.volume1.ozone1/quarter_one",
-                        "sales", "bucket1.volume1.ozone1/quarter_one/sales")},
+                        "sales", "bucket1.volume1.ozone1/quarter_one/sales") },
+
+                {new OzoneKeyValidator(OZONE_3_SCHEME, 
"bucket1.volume1.ozone1/",
+                        "bucket1", "volume1.bucket1")},
+
+                {new OzoneKeyValidator(OZONE_3_SCHEME, 
"bucket1.volume1.ozone1/key1/key1.txt/",
+                        "key1", "bucket1.volume1.ozone1/key1",
+                        "key1.txt", "bucket1.volume1.ozone1/key1/key1.txt") },
+
+                {new OzoneKeyValidator(OZONE_3_SCHEME, "bucket1.volume1/key1/",
+                        "key1", "bucket1.volume1/key1") },
         };
     }
 
@@ -309,8 +340,16 @@ public class AtlasPathExtractorUtilTest {
     }
 
     private void verifyOzoneKeyEntity(AtlasEntity entity, OzoneKeyValidator 
validator) {
-        assertEquals(entity.getTypeName(), OZONE_KEY);
-        assertTrue(validator.validateNameQName(entity));
+        if (Objects.equals(entity.getTypeName(), OZONE_KEY)) {
+            assertEquals(entity.getTypeName(), OZONE_KEY);
+            assertTrue(validator.validateNameQName(entity));
+        } else if (Objects.equals(entity.getTypeName(), OZONE_BUCKET)) {
+            assertEquals(entity.getTypeName(), OZONE_BUCKET);
+            assertTrue(validator.validateNameQName(entity));
+        } else if (Objects.equals(entity.getTypeName(), OZONE_VOLUME)) {
+            assertEquals(entity.getTypeName(), OZONE_VOLUME);
+            assertTrue(validator.validateNameQName(entity));
+        }
     }
 
     private void verifyHDFSEntity(AtlasEntity entity, boolean toLowerCase) {
@@ -476,25 +515,27 @@ public class AtlasPathExtractorUtilTest {
     private static class OzoneKeyValidator {
         private final String              scheme;
         private final String              location;
-        private final int                 knownEntitiesCount;
+        private final int knownEntitiesCountTillKey;
+        private final int knownEntitiesCountTillBucket;
+        private final int knownEntitiesCountTillVolume;
         private final Map<String, String> nameQNamePairs;
 
         public OzoneKeyValidator(String scheme, String location, String... 
pairs) {
             this.scheme             = scheme;
             this.location           = location;
             this.nameQNamePairs     = getPairMap(scheme, pairs);
-            this.knownEntitiesCount = nameQNamePairs.size() + 2;
-        }
+            this.knownEntitiesCountTillKey    = nameQNamePairs.size() + 2;
+            this.knownEntitiesCountTillBucket = nameQNamePairs.size() + 1;
+            this.knownEntitiesCountTillVolume = nameQNamePairs.size();        }
 
         public boolean validateNameQName(AtlasEntity entity) {
-            String name = (String) entity.getAttribute(ATTRIBUTE_NAME);
-
-            if (this.nameQNamePairs.containsKey(name)) {
-                String qName = (String) 
entity.getAttribute(ATTRIBUTE_QUALIFIED_NAME);
+            String qName = (String) 
entity.getAttribute(ATTRIBUTE_QUALIFIED_NAME);
 
-                return qName.equals(this.nameQNamePairs.get(name));
+            for (Map.Entry<String, String> nameQName : 
nameQNamePairs.entrySet()) {
+                if (qName.equals(nameQName.getValue())) {
+                    return true;
+                }
             }
-
             return false;
         }
 

Reply via email to