Repository: incubator-atlas Updated Branches: refs/heads/master 03857baa6 -> 407ff00c1
ATLAS-1408: added validation to prevent creating types with . (dot) in name (ashutoshm via mneethiraj) Signed-off-by: Madhan Neethiraj <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/407ff00c Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/407ff00c Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/407ff00c Branch: refs/heads/master Commit: 407ff00c1b51cf164dffc356526e8966acee5dc8 Parents: 03857ba Author: ashutoshm <[email protected]> Authored: Thu Jan 5 11:50:59 2017 -0800 Committer: Madhan Neethiraj <[email protected]> Committed: Thu Jan 5 13:02:48 2017 -0800 ---------------------------------------------------------------------- .../java/org/apache/atlas/AtlasErrorCode.java | 1 + .../org/apache/atlas/type/AtlasTypeUtil.java | 21 ++++++++++++++ release-log.txt | 1 + .../graph/v1/AtlasClassificationDefStoreV1.java | 9 ++++++ .../store/graph/v1/AtlasEntityDefStoreV1.java | 9 ++++++ .../store/graph/v1/AtlasEnumDefStoreV1.java | 9 ++++++ .../store/graph/v1/AtlasStructDefStoreV1.java | 8 ++++++ .../atlas/services/DefaultMetadataService.java | 30 ++++++++++++++++++-- .../service/DefaultMetadataServiceTest.java | 18 +++++++++++- 9 files changed, 103 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/407ff00c/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java index 4060b85..f026ec6 100644 --- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java +++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java @@ -51,6 +51,7 @@ public enum AtlasErrorCode { PATCH_NOT_APPLICABLE_FOR_TYPE(400, "ATLAS40022E", "{0} - invalid patch for type {1}"), PATCH_FOR_UNKNOWN_TYPE(400, "ATLAS40023E", "{0} - patch references unknown type {1}"), PATCH_INVALID_DATA(400, "ATLAS40024E", "{0} - patch data is invalid for type {1}"), + TYPE_NAME_INVALID_FORMAT(400, "ATLAS40025E", "{0}: invalid name for {1}. Only alphanumeric and '_' are allowed."), // All Not found enums go here TYPE_NAME_NOT_FOUND(404, "ATLAS4041E", "Given typename {0} was invalid"), http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/407ff00c/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java b/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java index b0a4e07..19553bf 100644 --- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java +++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java @@ -19,6 +19,8 @@ package org.apache.atlas.type; import com.google.common.collect.ImmutableSet; +import org.apache.atlas.AtlasErrorCode; +import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.typedef.AtlasBaseTypeDef; import org.apache.atlas.model.typedef.AtlasClassificationDef; import org.apache.atlas.model.typedef.AtlasEntityDef; @@ -40,6 +42,8 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_ARRAY_PREFIX; import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_ARRAY_SUFFIX; @@ -52,6 +56,9 @@ import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_MAP_SUF */ public class AtlasTypeUtil { private static final Set<String> ATLAS_BUILTIN_TYPENAMES = new HashSet<>(); + private static final String NAME_REGEX = "[a-zA-z][a-zA-Z0-9_ ]*"; + private static final Pattern NAME_PATTERN = Pattern.compile(NAME_REGEX); + static { Collections.addAll(ATLAS_BUILTIN_TYPENAMES, AtlasBaseTypeDef.ATLAS_BUILTIN_TYPES); @@ -80,6 +87,20 @@ public class AtlasTypeUtil { } + public static boolean isValidTypeName(String typeName) { + Matcher m = NAME_PATTERN.matcher(typeName); + + return m.matches(); + } + + public static void validateType(AtlasBaseTypeDef typeDef) throws AtlasBaseException { + String typeName = typeDef.getName(); + + if (!isValidTypeName(typeName)) { + throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID_FORMAT, typeName, typeDef.getCategory().name()); + } + } + public static String getStringValue(Map map, Object key) { Object ret = map != null ? map.get(key) : null; http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/407ff00c/release-log.txt ---------------------------------------------------------------------- diff --git a/release-log.txt b/release-log.txt index a2a2b45..8887247 100644 --- a/release-log.txt +++ b/release-log.txt @@ -9,6 +9,7 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai) ALL CHANGES: +ATLAS-1408 added validation to prevent creating types with . (dot) in name (ashutoshm via mneethiraj) ATLAS-1277 Add feather use 'order by ' in the DSL search (zhangqiang2 via sumasai) ATLAS-1379 Avoid object query overhead when report query selects class type alias (guptaneeru via dkantor) ATLAS-1419 update entity-update API impl to preserve value of entity attribute when no value is provided http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/407ff00c/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasClassificationDefStoreV1.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasClassificationDefStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasClassificationDefStoreV1.java index 936dd4f..f9c17fd 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasClassificationDefStoreV1.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasClassificationDefStoreV1.java @@ -30,6 +30,7 @@ import org.apache.atlas.repository.util.FilterUtil; import org.apache.atlas.type.AtlasClassificationType; import org.apache.atlas.type.AtlasType; import org.apache.atlas.type.AtlasTypeRegistry; +import org.apache.atlas.type.AtlasTypeUtil; import org.apache.atlas.typesystem.types.DataTypes.TypeCategory; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; @@ -56,6 +57,8 @@ public class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1 imple LOG.debug("==> AtlasClassificationDefStoreV1.preCreate({})", classificationDef); } + AtlasTypeUtil.validateType(classificationDef); + AtlasType type = typeRegistry.getType(classificationDef.getName()); if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.CLASSIFICATION) { @@ -174,6 +177,8 @@ public class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1 imple LOG.debug("==> AtlasClassificationDefStoreV1.update({})", classifiDef); } + AtlasTypeUtil.validateType(classifiDef); + AtlasClassificationDef ret = StringUtils.isNotBlank(classifiDef.getGuid()) ? updateByGuid(classifiDef.getGuid(), classifiDef) : updateByName(classifiDef.getName(), classifiDef); @@ -191,6 +196,8 @@ public class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1 imple LOG.debug("==> AtlasClassificationDefStoreV1.updateByName({}, {})", name, classificationDef); } + AtlasTypeUtil.validateType(classificationDef); + AtlasType type = typeRegistry.getType(classificationDef.getName()); if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.CLASSIFICATION) { @@ -221,6 +228,8 @@ public class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1 imple LOG.debug("==> AtlasClassificationDefStoreV1.updateByGuid({})", guid); } + AtlasTypeUtil.validateType(classificationDef); + AtlasType type = typeRegistry.getTypeByGuid(guid); if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.CLASSIFICATION) { http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/407ff00c/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityDefStoreV1.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityDefStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityDefStoreV1.java index c7f6cdf..32a6d83 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityDefStoreV1.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityDefStoreV1.java @@ -29,6 +29,7 @@ import org.apache.atlas.repository.util.FilterUtil; import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasType; import org.apache.atlas.type.AtlasTypeRegistry; +import org.apache.atlas.type.AtlasTypeUtil; import org.apache.atlas.typesystem.types.DataTypes.TypeCategory; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; @@ -55,6 +56,8 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At LOG.debug("==> AtlasEntityDefStoreV1.preCreate({})", entityDef); } + AtlasTypeUtil.validateType(entityDef); + AtlasType type = typeRegistry.getType(entityDef.getName()); if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.ENTITY) { @@ -173,6 +176,8 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At LOG.debug("==> AtlasEntityDefStoreV1.update({})", entityDef); } + AtlasTypeUtil.validateType(entityDef); + AtlasEntityDef ret = StringUtils.isNotBlank(entityDef.getGuid()) ? updateByGuid(entityDef.getGuid(), entityDef) : updateByName(entityDef.getName(), entityDef); @@ -189,6 +194,8 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At LOG.debug("==> AtlasEntityDefStoreV1.updateByName({}, {})", name, entityDef); } + AtlasTypeUtil.validateType(entityDef); + AtlasType type = typeRegistry.getType(entityDef.getName()); if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.ENTITY) { @@ -219,6 +226,8 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At LOG.debug("==> AtlasEntityDefStoreV1.updateByGuid({})", guid); } + AtlasTypeUtil.validateType(entityDef); + AtlasType type = typeRegistry.getTypeByGuid(guid); if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.ENTITY) { http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/407ff00c/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEnumDefStoreV1.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEnumDefStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEnumDefStoreV1.java index 97542d5..fccbeba 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEnumDefStoreV1.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEnumDefStoreV1.java @@ -28,6 +28,7 @@ import org.apache.atlas.repository.graphdb.AtlasVertex; import org.apache.atlas.repository.store.graph.AtlasEnumDefStore; import org.apache.atlas.repository.util.FilterUtil; import org.apache.atlas.type.AtlasTypeRegistry; +import org.apache.atlas.type.AtlasTypeUtil; import org.apache.atlas.typesystem.types.DataTypes.TypeCategory; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -54,6 +55,8 @@ public class AtlasEnumDefStoreV1 extends AtlasAbstractDefStoreV1 implements Atla LOG.debug("==> AtlasEnumDefStoreV1.create({})", enumDef); } + AtlasTypeUtil.validateType(enumDef); + AtlasVertex vertex = typeDefStore.findTypeVertexByName(enumDef.getName()); if (vertex != null) { @@ -143,6 +146,8 @@ public class AtlasEnumDefStoreV1 extends AtlasAbstractDefStoreV1 implements Atla LOG.debug("==> AtlasEnumDefStoreV1.update({})", enumDef); } + AtlasTypeUtil.validateType(enumDef); + AtlasEnumDef ret = StringUtils.isNotBlank(enumDef.getGuid()) ? updateByGuid(enumDef.getGuid(), enumDef) : updateByName(enumDef.getName(), enumDef); @@ -159,6 +164,8 @@ public class AtlasEnumDefStoreV1 extends AtlasAbstractDefStoreV1 implements Atla LOG.debug("==> AtlasEnumDefStoreV1.updateByName({}, {})", name, enumDef); } + AtlasTypeUtil.validateType(enumDef); + AtlasVertex vertex = typeDefStore.findTypeVertexByNameAndCategory(name, TypeCategory.ENUM); if (vertex == null) { @@ -184,6 +191,8 @@ public class AtlasEnumDefStoreV1 extends AtlasAbstractDefStoreV1 implements Atla LOG.debug("==> AtlasEnumDefStoreV1.updateByGuid({})", guid); } + AtlasTypeUtil.validateType(enumDef); + AtlasVertex vertex = typeDefStore.findTypeVertexByGuidAndCategory(guid, TypeCategory.ENUM); if (vertex == null) { http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/407ff00c/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java index ee36182..e780dc1 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java @@ -67,6 +67,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At LOG.debug("==> AtlasStructDefStoreV1.preCreate({})", structDef); } + AtlasTypeUtil.validateType(structDef); + AtlasType type = typeRegistry.getType(structDef.getName()); if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.STRUCT) { @@ -184,6 +186,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At LOG.debug("==> AtlasStructDefStoreV1.update({})", structDef); } + AtlasTypeUtil.validateType(structDef); + AtlasStructDef ret = StringUtils.isNotBlank(structDef.getGuid()) ? updateByGuid(structDef.getGuid(), structDef) : updateByName(structDef.getName(), structDef); @@ -200,6 +204,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At LOG.debug("==> AtlasStructDefStoreV1.updateByName({}, {})", name, structDef); } + AtlasTypeUtil.validateType(structDef); + AtlasType type = typeRegistry.getType(structDef.getName()); if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.STRUCT) { @@ -230,6 +236,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At LOG.debug("==> AtlasStructDefStoreV1.updateByGuid({})", guid); } + AtlasTypeUtil.validateType(structDef); + AtlasType type = typeRegistry.getTypeByGuid(guid); if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.STRUCT) { http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/407ff00c/repository/src/main/java/org/apache/atlas/services/DefaultMetadataService.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/services/DefaultMetadataService.java b/repository/src/main/java/org/apache/atlas/services/DefaultMetadataService.java index a58bd75..edd12ab 100755 --- a/repository/src/main/java/org/apache/atlas/services/DefaultMetadataService.java +++ b/repository/src/main/java/org/apache/atlas/services/DefaultMetadataService.java @@ -40,6 +40,7 @@ import org.apache.atlas.repository.RepositoryException; import org.apache.atlas.repository.audit.EntityAuditRepository; import org.apache.atlas.repository.graph.GraphHelper; import org.apache.atlas.repository.typestore.ITypeStore; +import org.apache.atlas.type.AtlasTypeUtil; import org.apache.atlas.typesystem.IStruct; import org.apache.atlas.typesystem.ITypedReferenceableInstance; import org.apache.atlas.typesystem.ITypedStruct; @@ -55,8 +56,11 @@ import org.apache.atlas.typesystem.persistence.ReferenceableInstance; import org.apache.atlas.typesystem.types.AttributeInfo; import org.apache.atlas.typesystem.types.ClassType; import org.apache.atlas.typesystem.types.DataTypes; +import org.apache.atlas.typesystem.types.EnumTypeDefinition; +import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition; import org.apache.atlas.typesystem.types.IDataType; import org.apache.atlas.typesystem.types.Multiplicity; +import org.apache.atlas.typesystem.types.StructTypeDefinition; import org.apache.atlas.typesystem.types.TraitType; import org.apache.atlas.typesystem.types.TypeSystem; import org.apache.atlas.typesystem.types.cache.TypeCache; @@ -213,14 +217,36 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang return createOrUpdateTypes(typeDefinition, true); } - private TypesDef validateTypeDefinition(String typeDefinition) { + private TypesDef validateTypeDefinition(String typeDefinition) throws AtlasException { try { TypesDef typesDef = TypesSerialization.fromJson(typeDefinition); if (typesDef.isEmpty()) { throw new IllegalArgumentException("Invalid type definition"); } + + for (HierarchicalTypeDefinition<ClassType> t : typesDef.classTypesAsJavaList()) { + if (!AtlasTypeUtil.isValidTypeName(t.typeName)) + throw new AtlasException("Only characters, numbers and '_' are allowed in class names. " + t.toString()); + } + + for (StructTypeDefinition t : typesDef.structTypesAsJavaList()) { + if (!AtlasTypeUtil.isValidTypeName(t.typeName)) + throw new AtlasException("Only characters, numbers and '_' are allowed in struct names. " + t.toString()); + } + + for (EnumTypeDefinition t : typesDef.enumTypesAsJavaList()) { + if (!AtlasTypeUtil.isValidTypeName(t.name)) + throw new AtlasException("Only characters, numbers and '_' are allowed in enum names. " + t.toString()); + } + + for (HierarchicalTypeDefinition<TraitType> t : typesDef.traitTypesAsJavaList()) { + if (!AtlasTypeUtil.isValidTypeName(t.typeName)) + throw new AtlasException("Only characters, numbers and '_' are allowed in trait names. " + t.toString()); + } + return typesDef; - } catch (Exception e) { + } + catch (Exception e) { LOG.error("Unable to deserialize json={}", typeDefinition, e); throw new IllegalArgumentException("Unable to deserialize json " + typeDefinition, e); } http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/407ff00c/repository/src/test/java/org/apache/atlas/service/DefaultMetadataServiceTest.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/service/DefaultMetadataServiceTest.java b/repository/src/test/java/org/apache/atlas/service/DefaultMetadataServiceTest.java index a0ca7b7..4b500ff 100644 --- a/repository/src/test/java/org/apache/atlas/service/DefaultMetadataServiceTest.java +++ b/repository/src/test/java/org/apache/atlas/service/DefaultMetadataServiceTest.java @@ -202,7 +202,7 @@ public class DefaultMetadataServiceTest { String arrayAttrName = randomStrWithReservedChars(); String mapAttrName = randomStrWithReservedChars(); HierarchicalTypeDefinition<ClassType> typeDefinition = - createClassTypeDef(randomStrWithReservedChars(), ImmutableSet.<String>of(), + createClassTypeDef("test_type_"+ RandomStringUtils.randomAlphanumeric(10), ImmutableSet.<String>of(), createOptionalAttrDef(strAttrName, DataTypes.STRING_TYPE), new AttributeDefinition(arrayAttrName, DataTypes.arrayTypeName(DataTypes.STRING_TYPE.getName()), Multiplicity.OPTIONAL, false, null), @@ -1145,6 +1145,22 @@ public class DefaultMetadataServiceTest { } @Test + public void testTypeWithDotsCreationShouldNotBeCreated() throws AtlasException, JSONException { + String typeName = "test_.v1_type_"+ RandomStringUtils.randomAlphanumeric(10); + HierarchicalTypeDefinition<ClassType> typeDef = TypesUtil.createClassTypeDef( + typeName, ImmutableSet.<String>of(), + TypesUtil.createUniqueRequiredAttrDef("test_type_attribute", DataTypes.STRING_TYPE)); + TypesDef typesDef = new TypesDef(typeDef, false); + + try { + metadataService.createType(TypesSerialization.toJson(typesDef)); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + //expected + } + } + + @Test public void testAuditEventsInvalidParams() throws Exception { //entity id can't be null try {
