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

pinal 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 956f1728b ATLAS-4668 : When classification is created with multiple 
super types having same attributes , Atlas doesn't throw an exception
956f1728b is described below

commit 956f1728bab8b8224554cb76a8810e2f3816662f
Author: Mandar Ambawane <[email protected]>
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 <[email protected]>
---
 .../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;

Reply via email to