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 92fdf29 ATLAS-3872 Restrict typedef creation when a child type
attribute conflicts with parent type attribute of same name
92fdf29 is described below
commit 92fdf298b5cfeb8e3d4b265085f9783af9d79cf6
Author: Mandar Ambawane <[email protected]>
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);