You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by pi...@apache.org on 2022/10/11 05:45:52 UTC

[atlas] branch branch-2.0 updated: ATLAS-4668 : When classification is created with multiple super types having same attributes , Atlas doesn't throw an exception

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

pinal pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new 06dca9584 ATLAS-4668 : When classification is created with multiple super types having same attributes , Atlas doesn't throw an exception
06dca9584 is described below

commit 06dca95849f72d31c85eb9a517f08f9336e3a74e
Author: Mandar Ambawane <ma...@freestoneinfotech.com>
AuthorDate: Thu Oct 6 11:45:45 2022 +0530

    ATLAS-4668 : When classification is created with multiple super types having same attributes , Atlas doesn't throw an exception
    
    Signed-off-by: Pinal Shah <pi...@freestoneinfotech.com>
    (cherry picked from commit 956f1728bab8b8224554cb76a8810e2f3816662f)
---
 .../apache/atlas/type/AtlasClassificationType.java | 17 ++++--
 .../apache/atlas/type/TestAtlasTypeRegistry.java   | 65 ++++++++++++++++++++++
 2 files changed, 78 insertions(+), 4 deletions(-)

diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java b/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java
index 5b86b808b..17422cf95 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java
@@ -523,8 +523,9 @@ public class AtlasClassificationType extends AtlasStructType {
                                       Set<String>                    allSuperTypeNames,
                                       Map<String, AtlasAttribute>    allAttributes) throws AtlasBaseException {
         List<String> visitedTypes = new ArrayList<>();
+        Map<String, String> attributeToClassificationNameMap = new HashMap<>();
 
-        collectTypeHierarchyInfo(typeRegistry, allSuperTypeNames, allAttributes, visitedTypes);
+        collectTypeHierarchyInfo(typeRegistry, allSuperTypeNames, allAttributes, attributeToClassificationNameMap, visitedTypes);
     }
 
     /*
@@ -534,6 +535,7 @@ public class AtlasClassificationType extends AtlasStructType {
     private void collectTypeHierarchyInfo(AtlasTypeRegistry              typeRegistry,
                                           Set<String>                    allSuperTypeNames,
                                           Map<String, AtlasAttribute>    allAttributes,
+                                          Map<String, String> attributeToClassificationNameMap,
                                           List<String>                   visitedTypes) throws AtlasBaseException {
         if (visitedTypes.contains(classificationDef.getName())) {
             throw new AtlasBaseException(AtlasErrorCode.CIRCULAR_REFERENCE, classificationDef.getName(),
@@ -546,7 +548,7 @@ public class AtlasClassificationType extends AtlasStructType {
                 AtlasClassificationType superType = typeRegistry.getClassificationTypeByName(superTypeName);
 
                 if (superType != null) {
-                    superType.collectTypeHierarchyInfo(typeRegistry, allSuperTypeNames, allAttributes, visitedTypes);
+                    superType.collectTypeHierarchyInfo(typeRegistry, allSuperTypeNames, allAttributes, attributeToClassificationNameMap, visitedTypes);
                 }
             }
             visitedTypes.remove(classificationDef.getName());
@@ -556,8 +558,15 @@ public class AtlasClassificationType extends AtlasStructType {
 
         if (CollectionUtils.isNotEmpty(classificationDef.getAttributeDefs())) {
             for (AtlasAttributeDef attributeDef : classificationDef.getAttributeDefs()) {
-                AtlasType type = typeRegistry.getType(attributeDef.getTypeName());
-                allAttributes.put(attributeDef.getName(), new AtlasAttribute(this, attributeDef, type));
+                AtlasType type          = typeRegistry.getType(attributeDef.getTypeName());
+                String attributeName    = attributeDef.getName();
+
+                if (attributeToClassificationNameMap.containsKey(attributeName) && !attributeToClassificationNameMap.get(attributeName).equals(classificationDef.getName())) {
+                    throw new AtlasBaseException(AtlasErrorCode.ATTRIBUTE_NAME_ALREADY_EXISTS_IN_ANOTHER_PARENT_TYPE, classificationDef.getName(), attributeName, attributeToClassificationNameMap.get(attributeName));
+                }
+
+                allAttributes.put(attributeName, new AtlasAttribute(this, attributeDef, type));
+                attributeToClassificationNameMap.put(attributeName, classificationDef.getName());
             }
         }
     }
diff --git a/intg/src/test/java/org/apache/atlas/type/TestAtlasTypeRegistry.java b/intg/src/test/java/org/apache/atlas/type/TestAtlasTypeRegistry.java
index 85d041bdb..fa5ec4f4f 100644
--- a/intg/src/test/java/org/apache/atlas/type/TestAtlasTypeRegistry.java
+++ b/intg/src/test/java/org/apache/atlas/type/TestAtlasTypeRegistry.java
@@ -18,6 +18,7 @@
 package org.apache.atlas.type;
 
 
+import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.typedef.*;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
@@ -659,6 +660,70 @@ public class TestAtlasTypeRegistry {
         validateAllSubTypes(typeRegistry, "L1", new HashSet<String>());
     }
 
+    @Test
+    public void testRegistryValiditySuperTypesUpdateWithExistingAttributeForClassification() throws AtlasBaseException {
+        AtlasClassificationDef class0 = new AtlasClassificationDef("class0");
+        AtlasClassificationDef class1 = new AtlasClassificationDef("class1");
+        AtlasClassificationDef class2 = new AtlasClassificationDef("class2");
+
+        class1.addSuperType(class0.getName());
+
+        class0.addAttribute(new AtlasAttributeDef("attr1", AtlasBaseTypeDef.ATLAS_TYPE_INT));
+        class1.addAttribute(new AtlasAttributeDef("attr2", AtlasBaseTypeDef.ATLAS_TYPE_INT));
+        class2.addAttribute(new AtlasAttributeDef("attr1", AtlasBaseTypeDef.ATLAS_TYPE_INT));
+
+        AtlasTypesDef typesDef = new AtlasTypesDef();
+
+        typesDef.getClassificationDefs().add(class0);
+        typesDef.getClassificationDefs().add(class1);
+        typesDef.getClassificationDefs().add(class2);
+
+        AtlasTypeRegistry          typeRegistry = new AtlasTypeRegistry();
+        AtlasTransientTypeRegistry ttr          = null;
+        boolean                    commit       = false;
+        String                     failureMsg   = null;
+
+        try {
+            ttr = typeRegistry.lockTypeRegistryForUpdate();
+
+            ttr.addTypes(typesDef);
+
+            commit = true;
+        } catch (AtlasBaseException excp) {
+            failureMsg = excp.getMessage();
+        } finally {
+            typeRegistry.releaseTypeRegistryForUpdate(ttr, commit);
+        }
+        assertNull(failureMsg);
+
+        validateAllSuperTypes(typeRegistry, "class1", new HashSet<>(Arrays.asList("class0")));
+        validateAllSubTypes(typeRegistry, "class1", new HashSet<String>());
+
+        //Add class2 as supertype for class1
+        class1.addSuperType(class2.getName());
+
+        AtlasErrorCode atlasErrorCode = null;
+        try {
+            commit = false;
+
+            ttr = typeRegistry.lockTypeRegistryForUpdate();
+
+            ttr.updateTypes(typesDef);
+
+            commit = true;
+        } catch (AtlasBaseException excp) {
+            failureMsg = excp.getMessage();
+            atlasErrorCode = excp.getAtlasErrorCode();
+        } finally {
+            typeRegistry.releaseTypeRegistryForUpdate(ttr, commit);
+        }
+        assertNotNull(failureMsg);
+        assertEquals(atlasErrorCode, AtlasErrorCode.ATTRIBUTE_NAME_ALREADY_EXISTS_IN_ANOTHER_PARENT_TYPE);
+
+        validateAllSuperTypes(typeRegistry, "class1", new HashSet<>(Arrays.asList("class0")));
+        validateAllSubTypes(typeRegistry, "class1", new HashSet<String>());
+    }
+
     private boolean addType(AtlasTypeRegistry typeRegistry, AtlasBaseTypeDef typeDef) {
         boolean                    ret = false;
         AtlasTransientTypeRegistry ttr = null;