diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java index a5aa58a1ba4..43eb1a1b412 100644 --- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java +++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java @@ -184,6 +184,7 @@ public enum AtlasErrorCode { BLANK_VALUE_ATTRIBUTE(400, "ATLAS-400-00-105", "Value Attribute can't be empty!"), INVALID_RELATIONSHIP_LABEL(400, "ATLAS-400-00-106", "Invalid relationship label {0}. The referenced entity type {1} could not be resolved from the type registry."), NON_INDEXABLE_BM_DELETE_NOT_ALLOWED(400, "ATLAS-400-00-107", "Deletion not allowed for non-indexable Business Metadata ''{0}'' without force=true. Non-indexable attributes cannot be validated efficiently for references; use force=true to skip validation and delete (warning: orphaned references may remain)."), + CLASSIFICATIONDEF_SUBTYPES_NOT_ALLOWED(400, "ATLAS-400-00-107", "ClassificationDef {0}: subTypes is a derived field and cannot be specified during create/update. To establish a parent-child relationship, set superTypes on the child classification instead."), UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to perform {1}"), diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java index 0913466c909..225dcb34fc5 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java @@ -423,6 +423,7 @@ public AtlasTypesDef createTypesDef(AtlasTypesDef typesDef) throws AtlasBaseExce } AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit(); + validateClassificationDefsHaveNoSubTypes(typesDef); tryTypeCreation(typesDef, ttr); AtlasTypesDef ret = addToGraphStore(typesDef, ttr); @@ -460,7 +461,7 @@ public AtlasTypesDef updateTypesDef(AtlasTypesDef typesDef) throws AtlasBaseExce } AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit(); - + validateClassificationDefsHaveNoSubTypes(typesDef); // Translate any NOT FOUND errors to BAD REQUEST try { ttr.updateTypes(typesDef); @@ -493,6 +494,17 @@ public AtlasTypesDef updateTypesDef(AtlasTypesDef typesDef) throws AtlasBaseExce return ret; } + private void validateClassificationDefsHaveNoSubTypes(AtlasTypesDef typesDef) throws AtlasBaseException { + if (CollectionUtils.isNotEmpty(typesDef.getClassificationDefs())) { + for (AtlasClassificationDef classificationDef : typesDef.getClassificationDefs()) { + if (CollectionUtils.isNotEmpty(classificationDef.getSubTypes())) { + LOG.info("ClassificationDef {}: subTypes is a derived field and cannot be specified during create/update. To establish a parent-child relationship, set superTypes on the child instead.", classificationDef.getName()); + throw new AtlasBaseException(AtlasErrorCode.CLASSIFICATIONDEF_SUBTYPES_NOT_ALLOWED, classificationDef.getName()); + } + } + } + } + @Override @GraphTransaction public AtlasTypesDef createUpdateTypesDef(AtlasTypesDef typesDef) throws AtlasBaseException { diff --git a/repository/src/test/resources/tag-prop-2.zip b/repository/src/test/resources/tag-prop-2.zip index f9657706a48..580ca8dc6be 100644 Binary files a/repository/src/test/resources/tag-prop-2.zip and b/repository/src/test/resources/tag-prop-2.zip differ