Commit e92502dd by ashutoshm Committed by Madhan Neethiraj

ATLAS-1434: Updated typename validation to allow "." for classifications

parent d8db4310
......@@ -56,9 +56,13 @@ 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 String NAME_REGEX = "[a-zA-Z][a-zA-Z0-9_ ]*";
private static final String TRAIT_NAME_REGEX = "[a-zA-Z][a-zA-Z0-9_ .]*";
private static final Pattern NAME_PATTERN = Pattern.compile(NAME_REGEX);
private static final Pattern TRAIT_NAME_PATTERN = Pattern.compile(TRAIT_NAME_REGEX);
private static final String InvalidTypeNameErrorMessage = "Only characters, numbers and '_' are allowed in names.";
private static final String InvalidTraitTypeNameErrorMessage = "Only characters, numbers, '.' and '_' are allowed in names.";
static {
Collections.addAll(ATLAS_BUILTIN_TYPENAMES, AtlasBaseTypeDef.ATLAS_BUILTIN_TYPES);
......@@ -93,6 +97,20 @@ public class AtlasTypeUtil {
return m.matches();
}
public static String getInvalidTypeNameErrorMessage() {
return InvalidTypeNameErrorMessage;
}
public static boolean isValidTraitTypeName(String typeName) {
Matcher m = TRAIT_NAME_PATTERN.matcher(typeName);
return m.matches();
}
public static String getInvalidTraitTypeNameErrorMessage() {
return InvalidTraitTypeNameErrorMessage;
}
public static void validateType(AtlasBaseTypeDef typeDef) throws AtlasBaseException {
String typeName = typeDef.getName();
......
......@@ -71,6 +71,7 @@ import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
......@@ -88,6 +89,9 @@ import javax.inject.Singleton;
*/
@Singleton
public class DefaultMetadataService implements MetadataService, ActiveStateChangeHandler, TypeDefChangeListener {
private enum OperationType {
CREATE, UPDATE, DELETE
};
private static final Logger LOG = LoggerFactory.getLogger(DefaultMetadataService.class);
private final short maxAuditResults;
......@@ -177,12 +181,12 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
*/
@Override
public JSONObject createType(String typeDefinition) throws AtlasException {
return createOrUpdateTypes(typeDefinition, false);
return createOrUpdateTypes(OperationType.CREATE, typeDefinition, false);
}
private JSONObject createOrUpdateTypes(String typeDefinition, boolean isUpdate) throws AtlasException {
private JSONObject createOrUpdateTypes(OperationType opType, String typeDefinition, boolean isUpdate) throws AtlasException {
typeDefinition = ParamChecker.notEmpty(typeDefinition, "type definition");
TypesDef typesDef = validateTypeDefinition(typeDefinition);
TypesDef typesDef = validateTypeDefinition(opType, typeDefinition);
try {
......@@ -214,10 +218,12 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
@Override
public JSONObject updateType(String typeDefinition) throws AtlasException {
return createOrUpdateTypes(typeDefinition, true);
return createOrUpdateTypes(OperationType.UPDATE, typeDefinition, true);
}
private TypesDef validateTypeDefinition(String typeDefinition) throws AtlasException {
private TypesDef validateTypeDefinition(OperationType opType, String typeDefinition) throws AtlasException {
final String exceptionErrorMessageFormat = "%s for '%s' failed: %s";
try {
TypesDef typesDef = TypesSerialization.fromJson(typeDefinition);
if (typesDef.isEmpty()) {
......@@ -226,22 +232,26 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
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());
throw new AtlasException(
String.format(exceptionErrorMessageFormat, opType.toString(), t.typeName, AtlasTypeUtil.getInvalidTypeNameErrorMessage()));
}
for (StructTypeDefinition t : typesDef.structTypesAsJavaList()) {
if (!AtlasTypeUtil.isValidTypeName(t.typeName))
throw new AtlasException("Only characters, numbers and '_' are allowed in struct names. " + t.toString());
throw new AtlasException(
String.format(exceptionErrorMessageFormat, opType.toString(), t.typeName, AtlasTypeUtil.getInvalidTypeNameErrorMessage()));
}
for (EnumTypeDefinition t : typesDef.enumTypesAsJavaList()) {
if (!AtlasTypeUtil.isValidTypeName(t.name))
throw new AtlasException("Only characters, numbers and '_' are allowed in enum names. " + t.toString());
throw new AtlasException(
String.format(exceptionErrorMessageFormat, opType.toString(), t.name, AtlasTypeUtil.getInvalidTypeNameErrorMessage()));
}
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());
if (!AtlasTypeUtil.isValidTraitTypeName(t.typeName))
throw new AtlasException(
String.format(exceptionErrorMessageFormat, opType.toString(), t.typeName, AtlasTypeUtil.getInvalidTraitTypeNameErrorMessage()));
}
return typesDef;
......
......@@ -39,6 +39,7 @@ import org.apache.atlas.repository.audit.HBaseTestUtils;
import org.apache.atlas.repository.graph.AtlasGraphProvider;
import org.apache.atlas.services.DefaultMetadataService;
import org.apache.atlas.services.MetadataService;
import org.apache.atlas.type.AtlasTypeUtil;
import org.apache.atlas.typesystem.IReferenceableInstance;
import org.apache.atlas.typesystem.IStruct;
import org.apache.atlas.typesystem.ITypedReferenceableInstance;
......@@ -1146,7 +1147,7 @@ public class DefaultMetadataServiceTest {
@Test
public void testTypeWithDotsCreationShouldNotBeCreated() throws AtlasException, JSONException {
String typeName = "test_.v1_type_"+ RandomStringUtils.randomAlphanumeric(10);
String typeName = "test_.v1_type_XXXX";
HierarchicalTypeDefinition<ClassType> typeDef = TypesUtil.createClassTypeDef(
typeName, ImmutableSet.<String>of(),
TypesUtil.createUniqueRequiredAttrDef("test_type_attribute", DataTypes.STRING_TYPE));
......@@ -1156,7 +1157,7 @@ public class DefaultMetadataServiceTest {
metadataService.createType(TypesSerialization.toJson(typesDef));
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
//expected
assertTrue (e.getCause().getMessage().contains(AtlasTypeUtil.getInvalidTypeNameErrorMessage()), e.getCause().getMessage());
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment