/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.atlas.typesystem.types; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import org.apache.atlas.AtlasException; import org.apache.atlas.typesystem.exception.TypeExistsException; import org.apache.atlas.typesystem.types.utils.TypesUtil; import org.apache.commons.lang3.RandomStringUtils; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import scala.actors.threadpool.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import static org.apache.atlas.typesystem.types.utils.TypesUtil.createClassTypeDef; import static org.apache.atlas.typesystem.types.utils.TypesUtil.createOptionalAttrDef; import static org.apache.atlas.typesystem.types.utils.TypesUtil.createRequiredAttrDef; import static org.apache.atlas.typesystem.types.utils.TypesUtil.createStructTypeDef; import static org.apache.atlas.typesystem.types.utils.TypesUtil.createTraitTypeDef; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; public class TypeSystemTest extends BaseTest { public static final long TEST_DATE_IN_LONG = 1418265358440L; public static final String TEST_DATE_STRING = "2014-12-11T02:35:58.440Z"; @BeforeClass public void setUp() throws Exception { super.setup(); } @AfterMethod public void tearDown() throws Exception { getTypeSystem().reset(); } @Test public void testGetTypeNames() throws Exception { getTypeSystem().defineEnumType("enum_test", new EnumValue("0", 0), new EnumValue("1", 1), new EnumValue("2", 2), new EnumValue("3", 3)); assertTrue(getTypeSystem().getTypeNames().contains("enum_test")); } @Test public void testGetTypeDescription() throws Exception { String typeName = "enum_type"; String description = "_description"; String typeDescription = typeName + description; getTypeSystem().defineEnumType(typeName, typeDescription, new EnumValue("0", 0), new EnumValue("1", 1), new EnumValue("2", 2), new EnumValue("3", 3)); assertTrue(getTypeSystem().getTypeNames().contains(typeName)); IDataType type = getTypeSystem().getDataType(EnumType.class, typeName); Assert.assertNotNull(type); Assert.assertEquals(type.getDescription(), typeDescription); typeName = "trait_type"; typeDescription = typeName + description; HierarchicalTypeDefinition<TraitType> trait = TypesUtil .createTraitTypeDef(typeName, typeDescription, ImmutableSet.<String>of(), TypesUtil.createRequiredAttrDef("type", DataTypes.STRING_TYPE)); getTypeSystem().defineTraitType(trait); assertTrue(getTypeSystem().getTypeNames().contains(typeName)); type = getTypeSystem().getDataType(TraitType.class, typeName); Assert.assertNotNull(type); Assert.assertEquals(type.getDescription(), typeDescription); typeName = "class_type"; typeDescription = typeName + description; HierarchicalTypeDefinition<ClassType> classType = TypesUtil .createClassTypeDef(typeName, typeDescription, ImmutableSet.<String>of(), TypesUtil.createRequiredAttrDef("type", DataTypes.STRING_TYPE)); getTypeSystem().defineClassType(classType); assertTrue(getTypeSystem().getTypeNames().contains(typeName)); type = getTypeSystem().getDataType(ClassType.class, typeName); Assert.assertNotNull(type); Assert.assertEquals(type.getDescription(), typeDescription); typeName = "struct_type"; typeDescription = typeName + description; getTypeSystem().defineStructType(typeName, typeDescription, true, createRequiredAttrDef("a", DataTypes.INT_TYPE)); assertTrue(getTypeSystem().getTypeNames().contains(typeName)); type = getTypeSystem().getDataType(StructType.class, typeName); Assert.assertNotNull(type); Assert.assertEquals(type.getDescription(), typeDescription); } @Test public void testIsRegistered() throws Exception { getTypeSystem().defineEnumType("enum_test", new EnumValue("0", 0), new EnumValue("1", 1), new EnumValue("2", 2), new EnumValue("3", 3)); assertTrue(getTypeSystem().isRegistered("enum_test")); } @Test public void testGetTraitsNames() throws Exception { HierarchicalTypeDefinition<TraitType> classificationTraitDefinition = TypesUtil .createTraitTypeDef("Classification", ImmutableSet.<String>of(), TypesUtil.createRequiredAttrDef("tag", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<TraitType> piiTrait = TypesUtil.createTraitTypeDef("PII", ImmutableSet.<String>of()); HierarchicalTypeDefinition<TraitType> phiTrait = TypesUtil.createTraitTypeDef("PHI", ImmutableSet.<String>of()); HierarchicalTypeDefinition<TraitType> pciTrait = TypesUtil.createTraitTypeDef("PCI", ImmutableSet.<String>of()); HierarchicalTypeDefinition<TraitType> soxTrait = TypesUtil.createTraitTypeDef("SOX", ImmutableSet.<String>of()); HierarchicalTypeDefinition<TraitType> secTrait = TypesUtil.createTraitTypeDef("SEC", ImmutableSet.<String>of()); HierarchicalTypeDefinition<TraitType> financeTrait = TypesUtil.createTraitTypeDef("Finance", ImmutableSet.<String>of()); getTypeSystem().defineTypes(ImmutableList.<EnumTypeDefinition>of(), ImmutableList.<StructTypeDefinition>of(), ImmutableList.of(classificationTraitDefinition, piiTrait, phiTrait, pciTrait, soxTrait, secTrait, financeTrait), ImmutableList.<HierarchicalTypeDefinition<ClassType>>of()); final ImmutableList<String> traitsNames = getTypeSystem().getTypeNamesByCategory(DataTypes.TypeCategory.TRAIT); Assert.assertEquals(traitsNames.size(), 7); List traits = Arrays.asList(new String[]{"Classification", "PII", "PHI", "PCI", "SOX", "SEC", "Finance",}); Assert.assertFalse(Collections.disjoint(traitsNames, traits)); } private String random() { return RandomStringUtils.random(10); } @Test public void testUTFNames() throws Exception { TypeSystem ts = getTypeSystem(); String enumType = random(); EnumTypeDefinition orgLevelEnum = new EnumTypeDefinition(enumType, new EnumValue(random(), 1), new EnumValue(random(), 2)); String structName = random(); String attrType = random(); StructTypeDefinition structType = createStructTypeDef(structName, createRequiredAttrDef(attrType, DataTypes.STRING_TYPE)); String className = random(); HierarchicalTypeDefinition<ClassType> classType = createClassTypeDef(className, ImmutableSet.<String>of(), createRequiredAttrDef(attrType, DataTypes.STRING_TYPE)); String traitName = random(); HierarchicalTypeDefinition<TraitType> traitType = createTraitTypeDef(traitName, ImmutableSet.<String>of(), createRequiredAttrDef(attrType, DataTypes.INT_TYPE)); ts.defineTypes(ImmutableList.of(orgLevelEnum), ImmutableList.of(structType), ImmutableList.of(traitType), ImmutableList.of(classType)); } @Test public void testTypeCategory() throws AtlasException { TypeSystem ts = getTypeSystem(); ts.reset(); StructTypeDefinition struct_A = createStructTypeDef("struct_A", createRequiredAttrDef("s_A", DataTypes.STRING_TYPE)); StructTypeDefinition struct_B = createStructTypeDef("struct_B", createRequiredAttrDef("s_B", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<TraitType> trait_A = createTraitTypeDef("trait_A", null, createRequiredAttrDef("t_A", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<TraitType> trait_B = createTraitTypeDef("trait_B", ImmutableSet.of("trait_A"), createRequiredAttrDef("t_B", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<TraitType> trait_C = createTraitTypeDef("trait_C", ImmutableSet.of("trait_A"), createRequiredAttrDef("t_C", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<TraitType> trait_D = createTraitTypeDef("trait_D", ImmutableSet.of("trait_B", "trait_C"), createRequiredAttrDef("t_D", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<ClassType> class_A = createClassTypeDef("class_A", null, createRequiredAttrDef("c_A", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<ClassType> class_B = createClassTypeDef("class_B", ImmutableSet.of("class_A"), createRequiredAttrDef("c_B", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<ClassType> class_C = createClassTypeDef("class_C", ImmutableSet.of("class_B"), createRequiredAttrDef("c_C", DataTypes.STRING_TYPE)); ts.defineTypes(ImmutableList.<EnumTypeDefinition>of(), ImmutableList.of(struct_A, struct_B), ImmutableList.of(trait_A, trait_B, trait_C, trait_D), ImmutableList.of(class_A, class_B, class_C)); final ImmutableList<String> structNames = ts.getTypeNamesByCategory(DataTypes.TypeCategory.STRUCT); final ImmutableList<String> traitNames = ts.getTypeNamesByCategory(DataTypes.TypeCategory.TRAIT); final ImmutableList<String> classNames = ts.getTypeNamesByCategory(DataTypes.TypeCategory.CLASS); Assert.assertEquals(structNames.size(), 2); Assert.assertEquals(traitNames.size(), 4); Assert.assertEquals(classNames.size(), 3); } @Test public void testTypeNamesAreNotDuplicated() throws Exception { TypeSystem typeSystem = getTypeSystem(); ImmutableList<String> traitNames = typeSystem.getTypeNamesByCategory(DataTypes.TypeCategory.TRAIT); int numTraits = traitNames.size(); HashMap<String, IDataType> typesAdded = new HashMap<>(); String traitName = "dup_type_test" + random(); TraitType traitType = new TraitType(typeSystem, traitName, null, null, 0); typesAdded.put(traitName, traitType); typeSystem.commitTypes(typesAdded); traitNames = typeSystem.getTypeNamesByCategory(DataTypes.TypeCategory.TRAIT); Assert.assertEquals(traitNames.size(), numTraits+1); // add again with another trait this time traitName = "dup_type_test" + random(); TraitType traitTypeNew = new TraitType(typeSystem, traitName, null, null, 0); typesAdded.put(traitName, traitTypeNew); typeSystem.commitTypes(typesAdded); traitNames = typeSystem.getTypeNamesByCategory(DataTypes.TypeCategory.TRAIT); Assert.assertEquals(traitNames.size(), numTraits+2); } @Test public void testHierarchy() throws Exception { HierarchicalTypeDefinition<ClassType> testObjectDef = TypesUtil.createClassTypeDef("TestObject", ImmutableSet.<String>of(), createOptionalAttrDef("name", DataTypes.STRING_TYPE), createOptionalAttrDef("description", DataTypes.STRING_TYPE), createOptionalAttrDef("topAttribute", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<ClassType> testDataSetDef = TypesUtil.createClassTypeDef("TestDataSet", ImmutableSet.of("TestObject")); HierarchicalTypeDefinition<ClassType> testColumnDef = TypesUtil.createClassTypeDef("TestColumn", ImmutableSet.of("TestObject"), createRequiredAttrDef("name", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<ClassType> testRelationalDataSetDef = TypesUtil.createClassTypeDef("TestRelationalDataSet", ImmutableSet.of("TestDataSet"), new AttributeDefinition("columns", DataTypes.arrayTypeName("TestColumn"), Multiplicity.OPTIONAL, true, null)); HierarchicalTypeDefinition<ClassType> testTableDef = TypesUtil.createClassTypeDef("TestTable", ImmutableSet.of("TestRelationalDataSet"), createOptionalAttrDef("schema", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<ClassType> testDataFileDef = TypesUtil.createClassTypeDef("TestDataFile", ImmutableSet.of("TestRelationalDataSet"), createOptionalAttrDef("urlString", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<ClassType> testDocumentDef = TypesUtil.createClassTypeDef("TestDocument", ImmutableSet.of("TestDataSet"), createOptionalAttrDef("urlString", DataTypes.STRING_TYPE), createOptionalAttrDef("encoding", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<ClassType> testAnnotationDef =TypesUtil.createClassTypeDef("TestAnnotation", ImmutableSet.<String>of(), createOptionalAttrDef("inheritedAttribute", DataTypes.STRING_TYPE)); HierarchicalTypeDefinition<ClassType> myNewAnnotationDef = TypesUtil.createClassTypeDef("MyNewAnnotation", ImmutableSet.of("TestAnnotation"), createRequiredAttrDef("myNewAnnotationAttribute", DataTypes.STRING_TYPE)); getTypeSystem().defineTypes(ImmutableList.<EnumTypeDefinition>of(), ImmutableList.<StructTypeDefinition>of(), ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(), ImmutableList.of(testObjectDef, testDataSetDef, testColumnDef, testRelationalDataSetDef, testTableDef, testDataFileDef, testDocumentDef, testAnnotationDef, myNewAnnotationDef)); // Verify that field mappings for MyNewAnnotation contains the attribute inherited from the TestAnnotation superclass. // Prior to fix for ATLAS-573, the inherited attribute was missing. ClassType dataType = getTypeSystem().getDataType(ClassType.class, "MyNewAnnotation"); Assert.assertTrue(dataType.fieldMapping.fields.containsKey("inheritedAttribute")); } @Test public void testRedefineExistingType() throws Exception { TypeSystem typeSystem = getTypeSystem(); HierarchicalTypeDefinition<TraitType> trait = TypesUtil .createTraitTypeDef(random(), "description", ImmutableSet.<String>of(), TypesUtil.createRequiredAttrDef("type", DataTypes.STRING_TYPE)); typeSystem.defineTraitType(trait); try { typeSystem.defineTraitType(trait); fail("Expected TypeExistsException"); } catch(TypeExistsException e) { //expected } } @Test public void testDuplicateNewTypenames() throws Exception { TypeSystem typeSystem = getTypeSystem(); HierarchicalTypeDefinition<TraitType> trait1 = TypesUtil .createTraitTypeDef(random(), "description", ImmutableSet.<String>of(), TypesUtil.createRequiredAttrDef("type", DataTypes.STRING_TYPE)); // create another trait with the same name HierarchicalTypeDefinition<TraitType> trait2 = TypesUtil .createTraitTypeDef(trait1.typeName, "description", ImmutableSet.<String>of(), TypesUtil.createRequiredAttrDef("type", DataTypes.STRING_TYPE)); try { typeSystem.defineTypes(ImmutableList.<EnumTypeDefinition>of(), ImmutableList.<StructTypeDefinition>of(), ImmutableList.of(trait1, trait2), ImmutableList.<HierarchicalTypeDefinition<ClassType>>of()); } catch(AtlasException e) { fail("Exception unexpected"); } } @Test(expectedExceptions = ValueConversionException.class) public void testConvertInvalidDate() throws Exception { DataTypes.DATE_TYPE.convert("", Multiplicity.OPTIONAL); } @Test() public void testConvertValidDate() throws Exception { Date date = DataTypes.DATE_TYPE.convert(TEST_DATE_STRING, Multiplicity.OPTIONAL); Assert.assertEquals(date, new Date(TEST_DATE_IN_LONG)); StringBuilder buf = new StringBuilder(); DataTypes.DATE_TYPE.output(new Date(TEST_DATE_IN_LONG), buf, "", new HashSet<Date>()); Assert.assertEquals(buf.toString(), TEST_DATE_STRING); } }