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;