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 2021/04/20 15:08:15 UTC

[atlas] branch branch-2.0 updated: ATLAS-3872 Restrict typedef creation when a child type attribute conflicts with parent type attribute of same name

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 eaef904  ATLAS-3872 Restrict typedef creation when a child type attribute conflicts with parent type attribute of same name
eaef904 is described below

commit eaef904d52e2c67352e125b6d0cb7ba0ac40171a
Author: Mandar Ambawane <ma...@freestoneinfotech.com>
AuthorDate: Thu Apr 8 18:21:59 2021 +0530

    ATLAS-3872 Restrict typedef creation when a child type attribute conflicts with parent type attribute of same name
    
    Signed-off-by: Pinal <pinal-shah>
---
 .../main/java/org/apache/atlas/AtlasErrorCode.java |   1 +
 .../apache/atlas/type/AtlasClassificationType.java |   1 +
 .../org/apache/atlas/type/AtlasEntityType.java     |   1 +
 .../org/apache/atlas/type/AtlasStructType.java     |  12 ++++++++++++
 .../test/java/org/apache/atlas/TestUtilsV2.java    |   6 ++----
 .../java/org/apache/atlas/model/ModelTestUtil.java |  21 +++++++++++++++++++++
 repository/src/test/resources/logging-v1-full.zip  | Bin 4853 -> 5106 bytes
 repository/src/test/resources/sales-v1-full.zip    | Bin 10799 -> 11339 bytes
 .../src/test/resources/salesNewTypeAttrs-next.zip  | Bin 2947 -> 3172 bytes
 .../src/test/resources/salesNewTypeAttrs.zip       | Bin 2918 -> 3140 bytes
 .../java/org/apache/atlas/examples/QuickStart.java |   2 +-
 .../org/apache/atlas/examples/QuickStartV2.java    |   5 -----
 .../atlas/web/integration/BaseResourceIT.java      |   3 +--
 .../web/integration/TypedefsJerseyResourceIT.java  |   4 ++--
 .../web/integration/TypesJerseyResourceIT.java     |   4 ++--
 15 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
index 773fae2..5ef62d3 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -172,6 +172,7 @@ public enum AtlasErrorCode {
     ATTRIBUTE_NAME_INVALID_CHARS(400, "ATLAS-400-00-09A", "{0}: invalid name. Attribute names must begin with a letter followed by a sequence of letters, numbers, or '_' characters"),
     NO_DATA_FOUND(400, "ATLAS-400-00-09B", "No data found in the uploaded file"),
     NOT_VALID_FILE(400, "ATLAS-400-00-09C", "Invalid {0} file"),
+    ATTRIBUTE_NAME_ALREADY_EXISTS_IN_PARENT_TYPE(400, "ATLAS-400-00-09D", "Invalid attribute name: {0}.{1}. Attribute already exists in parent type: {2}"),
     UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to perform {1}"),
 
     // All Not found enums go here
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 22259bc..5b86b80 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java
@@ -130,6 +130,7 @@ public class AtlasClassificationType extends AtlasStructType {
     @Override
     void resolveReferencesPhase2(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
         super.resolveReferencesPhase2(typeRegistry);
+        ensureNoAttributeOverride(superTypes);
 
         for (AtlasClassificationType superType : superTypes) {
             superType.addSubType(this);
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
index bfd5e98..ded6d63 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
@@ -212,6 +212,7 @@ public class AtlasEntityType extends AtlasStructType {
     @Override
     void resolveReferencesPhase2(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
         super.resolveReferencesPhase2(typeRegistry);
+        ensureNoAttributeOverride(superTypes);
 
         for (AtlasEntityType superType : superTypes) {
             superType.addSubType(this);
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
index d89aca2..21ce236 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
@@ -21,6 +21,8 @@ import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasStruct;
+import org.apache.atlas.model.typedef.AtlasClassificationDef;
+import org.apache.atlas.model.typedef.AtlasEntityDef;
 import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
@@ -718,6 +720,16 @@ public class AtlasStructType extends AtlasType {
         return ret;
     }
 
+    protected void ensureNoAttributeOverride(List<? extends AtlasStructType> superTypes) throws AtlasBaseException {
+        for (AtlasStructType superType : superTypes) {
+            for (AtlasAttributeDef attributeDef : this.structDef.getAttributeDefs()) {
+                if (superType.getAllAttributes().containsKey(attributeDef.getName())) {
+                    throw new AtlasBaseException(AtlasErrorCode.ATTRIBUTE_NAME_ALREADY_EXISTS_IN_PARENT_TYPE, getStructDef().getName(), attributeDef.getName(), superType.getStructDef().getName());
+                }
+            }
+        }
+    }
+
     public static class AtlasAttribute {
         public static final Object VERTEX_PROPERTY_PREFIX_STRING_INDEX_TYPE = "__s_";
         private final AtlasStructType          definedInType;
diff --git a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
index d9e2d19..f0ec675 100755
--- a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
+++ b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
@@ -969,8 +969,7 @@ public final class TestUtilsV2 {
                         createRequiredAttrDef("tag", "string"));
 
         AtlasClassificationDef fetlClassificationTypeDefinition =
-                AtlasTypeUtil.createTraitTypeDef("fetl" + CLASSIFICATION, "fetl" + CLASSIFICATION + _description, Collections.singleton(CLASSIFICATION),
-                        createRequiredAttrDef("tag", "string"));
+                AtlasTypeUtil.createTraitTypeDef("fetl" + CLASSIFICATION, "fetl" + CLASSIFICATION + _description, Collections.singleton(CLASSIFICATION));
 
         AtlasClassificationDef phiTypeDefinition = AtlasTypeUtil.createTraitTypeDef(PHI, PHI + _description, Collections.<String>emptySet(),
                                                                                     createRequiredAttrDef("stringAttr", "string"),
@@ -1450,8 +1449,7 @@ public final class TestUtilsV2 {
                         createRequiredAttrDef("level", "int"));
 
         AtlasClassificationDef janitorSecurityClearanceTypeDef =
-                AtlasTypeUtil.createTraitTypeDef("JanitorClearance", "JanitorClearance_description", Collections.singleton("SecurityClearance1"),
-                        createRequiredAttrDef("level", "int"));
+                AtlasTypeUtil.createTraitTypeDef("JanitorClearance", "JanitorClearance_description", Collections.singleton("SecurityClearance1"));
 
         List<AtlasClassificationDef> ret = Arrays.asList(securityClearanceTypeDef, janitorSecurityClearanceTypeDef);
 
diff --git a/intg/src/test/java/org/apache/atlas/model/ModelTestUtil.java b/intg/src/test/java/org/apache/atlas/model/ModelTestUtil.java
index 5df9525..549512e 100644
--- a/intg/src/test/java/org/apache/atlas/model/ModelTestUtil.java
+++ b/intg/src/test/java/org/apache/atlas/model/ModelTestUtil.java
@@ -29,6 +29,7 @@ import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasStructType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.type.AtlasTypeRegistry.AtlasTransientTypeRegistry;
+import org.apache.commons.collections.CollectionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,6 +37,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_BUILTIN_TYPES;
 import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_PRIMITIVE_TYPES;
@@ -228,8 +230,13 @@ public final class  ModelTestUtil {
         ret.setDescription(ret.getName());
         ret.setAttributeDefs(newAttributeDefsWithAllBuiltInTypes(PREFIX_ATTRIBUTE_NAME));
 
+        List<AtlasAttributeDef> currentTypeAttrDefs = ret.getAttributeDefs();
+
         if (superTypes != null) {
             for (AtlasEntityDef superType : superTypes) {
+                List<AtlasAttributeDef> superTypeAttrDefs = superType.getAttributeDefs();
+                removeAttributeIfExistedInSuperType(currentTypeAttrDefs, superTypeAttrDefs);
+
                 ret.addSuperType(superType.getName());
             }
         }
@@ -284,8 +291,13 @@ public final class  ModelTestUtil {
         ret.setDescription(ret.getName());
         ret.setAttributeDefs(newAttributeDefsWithAllBuiltInTypes(PREFIX_ATTRIBUTE_NAME));
 
+        List<AtlasAttributeDef> currentTypeAttrDefs = ret.getAttributeDefs();
+
         if (superTypes != null) {
             for (AtlasClassificationDef superType : superTypes) {
+                List<AtlasAttributeDef> superTypeAttrDefs = superType.getAttributeDefs();
+                removeAttributeIfExistedInSuperType(currentTypeAttrDefs, superTypeAttrDefs);
+
                 ret.addSuperType(superType.getName());
             }
         }
@@ -514,4 +526,13 @@ public final class  ModelTestUtil {
     private static String getRandomBuiltInType() {
         return ATLAS_BUILTIN_TYPES[ThreadLocalRandom.current().nextInt(0, ATLAS_BUILTIN_TYPES.length)];
     }
+
+    private static void removeAttributeIfExistedInSuperType(List<AtlasAttributeDef> currentTypeAttrDefs, List<AtlasAttributeDef> superTypeAttrDefs) {
+        if (CollectionUtils.isNotEmpty(superTypeAttrDefs)) {
+            List<String> superTypeAttrNames = superTypeAttrDefs.stream()
+                    .map(superTypeObj -> superTypeObj.getName()).collect(Collectors.toList());
+
+            currentTypeAttrDefs.removeIf(obj -> superTypeAttrNames.contains(obj.getName()));
+        }
+    }
 }
diff --git a/repository/src/test/resources/logging-v1-full.zip b/repository/src/test/resources/logging-v1-full.zip
index 69c54ee..dc983ca 100644
Binary files a/repository/src/test/resources/logging-v1-full.zip and b/repository/src/test/resources/logging-v1-full.zip differ
diff --git a/repository/src/test/resources/sales-v1-full.zip b/repository/src/test/resources/sales-v1-full.zip
index 07afbf6..296e11e 100644
Binary files a/repository/src/test/resources/sales-v1-full.zip and b/repository/src/test/resources/sales-v1-full.zip differ
diff --git a/repository/src/test/resources/salesNewTypeAttrs-next.zip b/repository/src/test/resources/salesNewTypeAttrs-next.zip
index e4c8505..c04b86c 100644
Binary files a/repository/src/test/resources/salesNewTypeAttrs-next.zip and b/repository/src/test/resources/salesNewTypeAttrs-next.zip differ
diff --git a/repository/src/test/resources/salesNewTypeAttrs.zip b/repository/src/test/resources/salesNewTypeAttrs.zip
index a4467e6..6f11b00 100644
Binary files a/repository/src/test/resources/salesNewTypeAttrs.zip and b/repository/src/test/resources/salesNewTypeAttrs.zip differ
diff --git a/webapp/src/main/java/org/apache/atlas/examples/QuickStart.java b/webapp/src/main/java/org/apache/atlas/examples/QuickStart.java
index 82a9f5c..fcf5bd4 100755
--- a/webapp/src/main/java/org/apache/atlas/examples/QuickStart.java
+++ b/webapp/src/main/java/org/apache/atlas/examples/QuickStart.java
@@ -169,7 +169,7 @@ public class QuickStart {
                 .createClassTypeDef(TABLE_TYPE, TABLE_TYPE, Collections.singleton("DataSet"),
                         new AttributeDefinition(DB_ATTRIBUTE, DATABASE_TYPE, Multiplicity.REQUIRED, false, null),
                         new AttributeDefinition("sd", STORAGE_DESC_TYPE, Multiplicity.REQUIRED, true, null),
-                        attrDef("owner", AtlasBaseTypeDef.ATLAS_TYPE_STRING), attrDef("createTime", AtlasBaseTypeDef.ATLAS_TYPE_LONG),
+                        attrDef("createTime", AtlasBaseTypeDef.ATLAS_TYPE_LONG),
                         attrDef("lastAccessTime", AtlasBaseTypeDef.ATLAS_TYPE_LONG), attrDef("retention", AtlasBaseTypeDef.ATLAS_TYPE_LONG),
                         attrDef("viewOriginalText", AtlasBaseTypeDef.ATLAS_TYPE_STRING),
                         attrDef("viewExpandedText", AtlasBaseTypeDef.ATLAS_TYPE_STRING), attrDef("tableType", AtlasBaseTypeDef.ATLAS_TYPE_STRING),
diff --git a/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java b/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java
index d5cf9b7..bc3efbe 100755
--- a/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java
+++ b/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java
@@ -231,15 +231,11 @@ public class QuickStartV2 {
     AtlasTypesDef createTypeDefinitions() {
         // Entity-Definitions
         AtlasEntityDef dbTypeDef      = createClassTypeDef(DATABASE_TYPE, DATABASE_TYPE, VERSION_1, Collections.singleton("DataSet"),
-                                                            createUniqueRequiredAttrDef("name", "string"),
-                                                            createOptionalAttrDef("description", "string"),
                                                             createOptionalAttrDef("locationUri", "string"),
-                                                            createOptionalAttrDef("owner", "string"),
                                                             createOptionalAttrDef("createTime", "long"));
 
         AtlasEntityDef tableTypeDef   = createClassTypeDef(TABLE_TYPE, TABLE_TYPE, VERSION_1, Collections.singleton("DataSet"),
                                                             new HashMap<String, String>() {{ put("schemaElementsAttribute", "columns"); }} ,
-                                                            createOptionalAttrDef("owner", "string"),
                                                             createOptionalAttrDef("createTime", "long"),
                                                             createOptionalAttrDef("lastAccessTime", "long"),
                                                             createOptionalAttrDef("retention", "long"),
@@ -250,7 +246,6 @@ public class QuickStartV2 {
 
         AtlasEntityDef colTypeDef     = createClassTypeDef(COLUMN_TYPE, COLUMN_TYPE, VERSION_1, Collections.singleton("DataSet"),
                                                             new HashMap<String, String>() {{ put("schemaAttributes", "[\"name\", \"description\", \"owner\", \"type\", \"comment\", \"position\"]"); }},
-                                                            createOptionalAttrDef("name", "string"),
                                                             createOptionalAttrDef("dataType", "string"),
                                                             createOptionalAttrDef("comment", "string"));
 
diff --git a/webapp/src/test/java/org/apache/atlas/web/integration/BaseResourceIT.java b/webapp/src/test/java/org/apache/atlas/web/integration/BaseResourceIT.java
index 6db6b58..50f93d9 100755
--- a/webapp/src/test/java/org/apache/atlas/web/integration/BaseResourceIT.java
+++ b/webapp/src/test/java/org/apache/atlas/web/integration/BaseResourceIT.java
@@ -354,7 +354,7 @@ public abstract class BaseResourceIT {
 
         ClassTypeDefinition tblClsDef = TypesUtil
                 .createClassTypeDef(HIVE_TABLE_TYPE, null, Collections.singleton("DataSet"),
-                        attrDef("owner", AtlasBaseTypeDef.ATLAS_TYPE_STRING), attrDef("createTime", AtlasBaseTypeDef.ATLAS_TYPE_LONG),
+                        attrDef("createTime", AtlasBaseTypeDef.ATLAS_TYPE_LONG),
                         attrDef("lastAccessTime", AtlasBaseTypeDef.ATLAS_TYPE_DATE),
                         attrDef("temporary", AtlasBaseTypeDef.ATLAS_TYPE_BOOLEAN),
                         new AttributeDefinition("db", DATABASE_TYPE, Multiplicity.OPTIONAL, true, "tables"),
@@ -435,7 +435,6 @@ public abstract class BaseResourceIT {
         AtlasEntityDef tblClsDef = AtlasTypeUtil
                 .createClassTypeDef(HIVE_TABLE_TYPE_V2,
                         Collections.singleton("DataSet"),
-                        AtlasTypeUtil.createOptionalAttrDef("owner", "string"),
                         AtlasTypeUtil.createOptionalAttrDef("createTime", "long"),
                         AtlasTypeUtil.createOptionalAttrDef("lastAccessTime", "date"),
                         AtlasTypeUtil.createOptionalAttrDef("temporary", "boolean"),
diff --git a/webapp/src/test/java/org/apache/atlas/web/integration/TypedefsJerseyResourceIT.java b/webapp/src/test/java/org/apache/atlas/web/integration/TypedefsJerseyResourceIT.java
index 0cd707f..9506c62 100644
--- a/webapp/src/test/java/org/apache/atlas/web/integration/TypedefsJerseyResourceIT.java
+++ b/webapp/src/test/java/org/apache/atlas/web/integration/TypedefsJerseyResourceIT.java
@@ -339,9 +339,9 @@ public class TypedefsJerseyResourceIT extends BaseResourceIT {
     public void testListTypesByFilter() throws Exception {
         AtlasAttributeDef attr = AtlasTypeUtil.createOptionalAttrDef("attr", "string");
         AtlasEntityDef classDefA = AtlasTypeUtil.createClassTypeDef("A" + randomString(), Collections.<String>emptySet(), attr);
-        AtlasEntityDef classDefA1 = AtlasTypeUtil.createClassTypeDef("A1" + randomString(), Collections.singleton(classDefA.getName()), attr);
+        AtlasEntityDef classDefA1 = AtlasTypeUtil.createClassTypeDef("A1" + randomString(), Collections.singleton(classDefA.getName()));
         AtlasEntityDef classDefB = AtlasTypeUtil.createClassTypeDef("B" + randomString(), Collections.<String>emptySet(), attr);
-        AtlasEntityDef classDefC = AtlasTypeUtil.createClassTypeDef("C" + randomString(), new HashSet<>(Arrays.asList(classDefB.getName(), classDefA.getName())), attr);
+        AtlasEntityDef classDefC = AtlasTypeUtil.createClassTypeDef("C" + randomString(), new HashSet<>(Arrays.asList(classDefB.getName(), classDefA.getName())));
 
         AtlasTypesDef atlasTypesDef = new AtlasTypesDef();
         atlasTypesDef.getEntityDefs().add(classDefA);
diff --git a/webapp/src/test/java/org/apache/atlas/web/integration/TypesJerseyResourceIT.java b/webapp/src/test/java/org/apache/atlas/web/integration/TypesJerseyResourceIT.java
index 7c820e7..6a0bbec 100755
--- a/webapp/src/test/java/org/apache/atlas/web/integration/TypesJerseyResourceIT.java
+++ b/webapp/src/test/java/org/apache/atlas/web/integration/TypesJerseyResourceIT.java
@@ -216,7 +216,7 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
         TypesDef typesDef = new TypesDef(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.singletonList(classTypeDef));
         String a = createType(AtlasType.toV1Json(typesDef)).get(0);
 
-        classTypeDef = TypesUtil.createClassTypeDef("A1" + randomString(), null, Collections.singleton(a), attr);
+        classTypeDef = TypesUtil.createClassTypeDef("A1" + randomString(), null, Collections.singleton(a));
         typesDef = new TypesDef(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.singletonList(classTypeDef));
         String a1 = createType(AtlasType.toV1Json(typesDef)).get(0);
 
@@ -224,7 +224,7 @@ public class TypesJerseyResourceIT extends BaseResourceIT {
         typesDef = new TypesDef(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.singletonList(classTypeDef));
         String b = createType(AtlasType.toV1Json(typesDef)).get(0);
 
-        classTypeDef = TypesUtil.createClassTypeDef("C" + randomString(), null, new HashSet<>(Arrays.asList(a, b)), attr);
+        classTypeDef = TypesUtil.createClassTypeDef("C" + randomString(), null, new HashSet<>(Arrays.asList(a, b)));
         typesDef = new TypesDef(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.singletonList(classTypeDef));
         String c = createType(AtlasType.toV1Json(typesDef)).get(0);