http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/main/scala/org/apache/hadoop/metadata/typesystem/json/TypesSerialization.scala ---------------------------------------------------------------------- diff --git a/typesystem/src/main/scala/org/apache/hadoop/metadata/typesystem/json/TypesSerialization.scala b/typesystem/src/main/scala/org/apache/hadoop/metadata/typesystem/json/TypesSerialization.scala deleted file mode 100755 index ae803c6..0000000 --- a/typesystem/src/main/scala/org/apache/hadoop/metadata/typesystem/json/TypesSerialization.scala +++ /dev/null @@ -1,244 +0,0 @@ -/* - * 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.hadoop.metadata.typesystem.json - -import java.text.SimpleDateFormat - -import com.google.common.collect.ImmutableList -import org.apache.hadoop.metadata.typesystem.TypesDef -import org.apache.hadoop.metadata.typesystem.types.DataTypes.{ArrayType, MapType, TypeCategory} -import org.apache.hadoop.metadata.typesystem.types._ -import org.apache.hadoop.metadata.MetadataException -import org.json4s.JsonAST.JString -import org.json4s._ -import org.json4s.native.Serialization._ - - -/** - * Module for serializing to/from Json. - * - * @example {{{ - * val j = TypesSerialization.toJson(typeSystem, "Employee", "Person", "Department", "SecurityClearance") - * - * val typesDef = TypesSerialization.fromJson(jsonStr) - * typesDef.enumTypes.foreach( typeSystem.defineEnumType(_)) - - typeSystem.defineTypes(ImmutableList.copyOf(typesDef.structTypes.toArray), - ImmutableList.copyOf(typesDef.traitTypes.toArray), - ImmutableList.copyOf(typesDef.classTypes.toArray) - ) - * }}} - * - * @todo doesn't traverse includes directives. Includes are parsed into - * [[org.apache.hadoop.metadata.tools.thrift.IncludeDef IncludeDef]] structures - * but are not traversed. - * @todo mixing in [[scala.util.parsing.combinator.PackratParsers PackratParsers]] is a placeholder. Need to - * change specific grammar rules to `lazy val` and `Parser[Elem]` to `PackratParser[Elem]`. Will do based on - * performance analysis. - * @todo Error reporting - */ -object TypesSerialization { - - def toJsonValue(typ: IDataType[_])(implicit formats: Formats): JValue = { - typ.getTypeCategory match { - case TypeCategory.CLASS => { - Extraction.decompose(convertClassTypeToHierarchicalTypeDefintion(typ.asInstanceOf[ClassType])) - } - case TypeCategory.STRUCT => { - Extraction.decompose(convertStructTypeToStructDef(typ.asInstanceOf[StructType])) - } - case TypeCategory.TRAIT => { - Extraction.decompose(convertTraitTypeToHierarchicalTypeDefintion(typ.asInstanceOf[TraitType])) - } - case TypeCategory.ENUM => { - Extraction.decompose(convertEnumTypeToEnumTypeDef(typ.asInstanceOf[EnumType])) - } - case _ => JString(s"${typ.getName}") - } - } - - def toJson(ts: TypeSystem, typName: String): String = { - toJson(ts, List(typName): _*) - } - - def toJson(ts: TypeSystem, typNames: String*): String = { - toJson(ts, (typ: IDataType[_]) => typNames.contains(typ.getName)) - } - - import scala.collection.JavaConversions._ - - def toJson(ts: TypeSystem, typNames: java.util.List[String]): String = { - toJson(ts, typNames.toIndexedSeq: _*) - } - - val _formats = new DefaultFormats { - override val dateFormatter = TypeSystem.getInstance().getDateFormat.asInstanceOf[SimpleDateFormat] - override val typeHints = NoTypeHints - } - - def toJson(ts: TypeSystem, export: IDataType[_] => Boolean): String = { - implicit val formats = _formats + new MultiplicitySerializer - - val typsDef = convertToTypesDef(ts, export) - - writePretty(typsDef) - } - - def fromJson(jsonStr: String): TypesDef = { - implicit val formats = _formats + new MultiplicitySerializer - - read[TypesDef](jsonStr) - } - - def toJson(typesDef : TypesDef) : String = { - implicit val formats = _formats + new MultiplicitySerializer - writePretty(typesDef) - - } - - def toJson(enumTypeDefinition: EnumTypeDefinition) : String = { - toJson(new TypesDef(enumTypeDefinition)) - } - - def toJson(structTypeDefinition: StructTypeDefinition) : String = { - toJson(new TypesDef(structTypeDefinition)) - } - - def toJson(typDef: HierarchicalTypeDefinition[_], isTrait : Boolean) : String = { - toJson(new TypesDef(typDef, isTrait)) - } - - private def convertAttributeInfoToAttributeDef(aInfo: AttributeInfo) = { - new AttributeDefinition(aInfo.name, aInfo.dataType().getName, aInfo.multiplicity, - aInfo.isComposite, aInfo.isUnique, aInfo.isIndexable, aInfo.reverseAttributeName) - } - - private def convertEnumTypeToEnumTypeDef(et: EnumType) = { - val eVals: Seq[EnumValue] = et.valueMap.values().toSeq - new EnumTypeDefinition(et.name, eVals: _*) - } - - private def convertStructTypeToStructDef(st: StructType): StructTypeDefinition = { - - val aDefs: Iterable[AttributeDefinition] = - st.fieldMapping.fields.values().map(convertAttributeInfoToAttributeDef(_)) - new StructTypeDefinition(st.name, aDefs.toArray) - } - - private def convertTraitTypeToHierarchicalTypeDefintion(tt: TraitType): HierarchicalTypeDefinition[TraitType] = { - - val aDefs: Iterable[AttributeDefinition] = - tt.immediateAttrs.map(convertAttributeInfoToAttributeDef(_)) - new HierarchicalTypeDefinition[TraitType](classOf[TraitType], tt.name, tt.superTypes, aDefs.toArray) - } - - private def convertClassTypeToHierarchicalTypeDefintion(tt: ClassType): HierarchicalTypeDefinition[ClassType] = { - - val aDefs: Iterable[AttributeDefinition] = - tt.immediateAttrs.map(convertAttributeInfoToAttributeDef(_)) - new HierarchicalTypeDefinition[ClassType](classOf[ClassType], tt.name, tt.superTypes, aDefs.toArray) - } - - def convertToTypesDef(ts: TypeSystem, export: IDataType[_] => Boolean): TypesDef = { - - var enumTypes: Seq[EnumTypeDefinition] = Nil - var structTypes: Seq[StructTypeDefinition] = Nil - var traitTypes: Seq[HierarchicalTypeDefinition[TraitType]] = Nil - var classTypes: Seq[HierarchicalTypeDefinition[ClassType]] = Nil - - def toTyp(nm: String) = ts.getDataType(classOf[IDataType[_]], nm) - - val typs: Iterable[IDataType[_]] = ts.getTypeNames.map(toTyp(_)).filter { (typ: IDataType[_]) => - !(ts.getCoreTypes.contains(typ.getName)) && export(typ) - } - - typs.foreach { - case typ: ArrayType => () - case typ: MapType => () - case typ: EnumType => enumTypes = enumTypes :+ convertEnumTypeToEnumTypeDef(typ) - case typ: StructType => structTypes = structTypes :+ convertStructTypeToStructDef(typ) - case typ: TraitType => traitTypes = traitTypes :+ convertTraitTypeToHierarchicalTypeDefintion(typ) - case typ: ClassType => classTypes = classTypes :+ convertClassTypeToHierarchicalTypeDefintion(typ) - } - - TypesDef(enumTypes, structTypes, traitTypes, classTypes) - } - -} - -class MultiplicitySerializer extends CustomSerializer[Multiplicity](format => ( { - case JString(m) => m match { - case "optional" => Multiplicity.OPTIONAL - case "required" => Multiplicity.REQUIRED - case "collection" => Multiplicity.COLLECTION - case "set" => Multiplicity.SET - } -}, { - case m: Multiplicity => JString(m match { - case Multiplicity.OPTIONAL => "optional" - case Multiplicity.REQUIRED => "required" - case Multiplicity.COLLECTION => "collection" - case Multiplicity.SET => "set" - } - - ) -} - )) - -trait TypeHelpers { - def requiredAttr(name: String, dataType: IDataType[_]) = - new AttributeDefinition(name, dataType.getName, Multiplicity.REQUIRED, false, null) - - def optionalAttr(name: String, dataTypeName: String) = - new AttributeDefinition(name, dataTypeName, Multiplicity.OPTIONAL, false, null) - - - def optionalAttr(name: String, dataType: IDataType[_]) = - new AttributeDefinition(name, dataType.getName, Multiplicity.OPTIONAL, false, null) - - def structDef(name: String, attrs: AttributeDefinition*) = { - new StructTypeDefinition(name, attrs.toArray) - } - - def defineTraits(ts: TypeSystem, tDefs: HierarchicalTypeDefinition[TraitType]*) = { - ts.defineTraitTypes(tDefs: _*) - } - - def createTraitTypeDef(name: String, superTypes: Seq[String], attrDefs: AttributeDefinition*): - HierarchicalTypeDefinition[TraitType] = { - val sts = ImmutableList.copyOf(superTypes.toArray) - return new HierarchicalTypeDefinition[TraitType](classOf[TraitType], name, - sts, attrDefs.toArray) - } - - def createClassTypeDef(name: String, superTypes: Seq[String], attrDefs: AttributeDefinition*): - HierarchicalTypeDefinition[ClassType] = { - val sts = ImmutableList.copyOf(superTypes.toArray) - return new HierarchicalTypeDefinition[ClassType](classOf[ClassType], name, - sts, attrDefs.toArray) - } - - @throws(classOf[MetadataException]) - def defineClassType(ts: TypeSystem, classDef: HierarchicalTypeDefinition[ClassType]): ClassType = { - ts.defineTypes(ImmutableList.of[StructTypeDefinition], - ImmutableList.of[HierarchicalTypeDefinition[TraitType]], - ImmutableList.of[HierarchicalTypeDefinition[ClassType]](classDef)) - return ts.getDataType(classOf[ClassType], classDef.typeName) - } -}
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/test/java/org/apache/atlas/typesystem/json/SerializationJavaTest.java ---------------------------------------------------------------------- diff --git a/typesystem/src/test/java/org/apache/atlas/typesystem/json/SerializationJavaTest.java b/typesystem/src/test/java/org/apache/atlas/typesystem/json/SerializationJavaTest.java new file mode 100755 index 0000000..dde66f8 --- /dev/null +++ b/typesystem/src/test/java/org/apache/atlas/typesystem/json/SerializationJavaTest.java @@ -0,0 +1,177 @@ +/** + * 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.json; + +import com.google.common.collect.ImmutableList; +import org.apache.atlas.MetadataException; +import org.apache.atlas.typesystem.ITypedInstance; +import org.apache.atlas.typesystem.ITypedReferenceableInstance; +import org.apache.atlas.typesystem.Referenceable; +import org.apache.atlas.typesystem.Struct; +import org.apache.atlas.typesystem.types.AttributeDefinition; +import org.apache.atlas.typesystem.types.BaseTest; +import org.apache.atlas.typesystem.types.ClassType; +import org.apache.atlas.typesystem.types.DataTypes; +import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition; +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.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import static org.apache.atlas.typesystem.types.utils.TypesUtil.createClassTypeDef; +import static org.apache.atlas.typesystem.types.utils.TypesUtil.createRequiredAttrDef; +import static org.apache.atlas.typesystem.types.utils.TypesUtil.createTraitTypeDef; + +public class SerializationJavaTest extends BaseTest { + + + @Before + public void setup() throws Exception { + super.setup(); + } + + /* + * Class Hierarchy is: + * Department(name : String, employees : Array[Person]) + * Person(name : String, department : Department, manager : Manager) + * Manager(subordinates : Array[Person]) extends Person + * + * Persons can have SecurityClearance(level : Int) clearance. + */ + @Test + public void test1() throws MetadataException { + + TypeSystem ts = getTypeSystem(); + + HierarchicalTypeDefinition<ClassType> deptTypeDef = createClassTypeDef("Department", + ImmutableList.<String>of(), + createRequiredAttrDef("name", DataTypes.STRING_TYPE), + new AttributeDefinition("employees", + String.format("array<%s>", "Person"), Multiplicity.COLLECTION, true, + "department") + ); + HierarchicalTypeDefinition<ClassType> personTypeDef = createClassTypeDef("Person", + ImmutableList.<String>of(), + createRequiredAttrDef("name", DataTypes.STRING_TYPE), + new AttributeDefinition("department", + "Department", Multiplicity.REQUIRED, false, "employees"), + new AttributeDefinition("manager", + "Manager", Multiplicity.OPTIONAL, false, "subordinates") + ); + HierarchicalTypeDefinition<ClassType> managerTypeDef = createClassTypeDef("Manager", + ImmutableList.<String>of("Person"), + new AttributeDefinition("subordinates", + String.format("array<%s>", "Person"), Multiplicity.COLLECTION, false, + "manager") + ); + + HierarchicalTypeDefinition<TraitType> securityClearanceTypeDef = createTraitTypeDef( + "SecurityClearance", + ImmutableList.<String>of(), + createRequiredAttrDef("level", DataTypes.INT_TYPE) + ); + + ts.defineTypes(ImmutableList.<StructTypeDefinition>of(), + ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(securityClearanceTypeDef), + ImmutableList.<HierarchicalTypeDefinition<ClassType>>of(deptTypeDef, personTypeDef, + managerTypeDef)); + + Referenceable hrDept = new Referenceable("Department"); + Referenceable john = new Referenceable("Person"); + Referenceable jane = new Referenceable("Manager", "SecurityClearance"); + + hrDept.set("name", "hr"); + john.set("name", "John"); + john.set("department", hrDept); + jane.set("name", "Jane"); + jane.set("department", hrDept); + + john.set("manager", jane); + + hrDept.set("employees", ImmutableList.<Referenceable>of(john, jane)); + + jane.set("subordinates", ImmutableList.<Referenceable>of(john)); + + jane.getTrait("SecurityClearance").set("level", 1); + + ClassType deptType = ts.getDataType(ClassType.class, "Department"); + ITypedReferenceableInstance hrDept2 = deptType.convert(hrDept, Multiplicity.REQUIRED); + + String hrDeptStr = hrDept2.toString(); + + Assert.assertEquals(hrDeptStr, "{\n" + + "\tid : (type: Department, id: <unassigned>)\n" + + "\tname : \thr\n" + + "\temployees : \t[{\n" + + "\tid : (type: Person, id: <unassigned>)\n" + + "\tname : \tJohn\n" + + "\tdepartment : (type: Department, id: <unassigned>)\n" + + "\tmanager : (type: Manager, id: <unassigned>)\n" + + "}, {\n" + + "\tid : (type: Manager, id: <unassigned>)\n" + + "\tsubordinates : \t[{\n" + + "\tid : (type: Person, id: <unassigned>)\n" + + "\tname : \tJohn\n" + + "\tdepartment : (type: Department, id: <unassigned>)\n" + + "\tmanager : (type: Manager, id: <unassigned>)\n" + + "}]\n" + + "\tname : \tJane\n" + + "\tdepartment : (type: Department, id: <unassigned>)\n" + + "\tmanager : <null>\n" + + "\n" + + "\tSecurityClearance : \t{\n" + + "\t\tlevel : \t\t1\n" + + "\t}}]\n" + + "}"); + + String jsonStr = Serialization$.MODULE$.toJson(hrDept2); + //System.out.println(jsonStr); + + hrDept2 = Serialization$.MODULE$.fromJson(jsonStr); + Assert.assertEquals(hrDept2.toString(), hrDeptStr); + + } + + @Test + public void testTrait() throws MetadataException { + + TypeSystem ts = getTypeSystem(); + HierarchicalTypeDefinition<TraitType> securityClearanceTypeDef = createTraitTypeDef( + "SecurityClearance2", + ImmutableList.<String>of(), + createRequiredAttrDef("level", DataTypes.INT_TYPE) + ); + + ts.defineTypes(ImmutableList.<StructTypeDefinition>of(), + ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(securityClearanceTypeDef), + ImmutableList.<HierarchicalTypeDefinition<ClassType>>of()); + + + Struct s = new Struct("SecurityClearance2"); + s.set("level", 1); + TraitType tType = ts.getDataType(TraitType.class, "SecurityClearance2"); + ITypedInstance t = tType.convert(s, Multiplicity.REQUIRED); + String jsonStr = Serialization$.MODULE$.toJson(t); + ITypedInstance t2 = Serialization$.MODULE$.traitFromJson(jsonStr); + Assert.assertEquals(t.toString(), t2.toString()); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/test/java/org/apache/atlas/typesystem/types/BaseTest.java ---------------------------------------------------------------------- diff --git a/typesystem/src/test/java/org/apache/atlas/typesystem/types/BaseTest.java b/typesystem/src/test/java/org/apache/atlas/typesystem/types/BaseTest.java new file mode 100755 index 0000000..f5c6f7f --- /dev/null +++ b/typesystem/src/test/java/org/apache/atlas/typesystem/types/BaseTest.java @@ -0,0 +1,193 @@ +/** + * 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.Lists; +import com.google.common.collect.Maps; +import org.apache.atlas.MetadataException; +import org.apache.atlas.typesystem.Referenceable; +import org.apache.atlas.typesystem.Struct; +import org.apache.atlas.typesystem.types.utils.TypesUtil; +import org.junit.Before; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; +import java.util.Map; + +public abstract class BaseTest { + + public static final String STRUCT_TYPE_1 = "t1"; + public static final String STRUCT_TYPE_2 = "t2"; + public static final String TEST_DATE = "2014-12-11T02:35:58.440Z"; + public static final long TEST_DATE_IN_LONG=1418265358440L; + + public static Struct createStruct() throws MetadataException { + StructType structType = TypeSystem.getInstance().getDataType( + StructType.class, STRUCT_TYPE_1); + Struct s = new Struct(structType.getName()); + s.set("a", 1); + s.set("b", true); + s.set("c", (byte) 1); + s.set("d", (short) 2); + s.set("e", 1); + s.set("f", 1); + s.set("g", 1L); + s.set("h", 1.0f); + s.set("i", 1.0); + s.set("j", BigInteger.valueOf(1L)); + s.set("k", new BigDecimal(1)); + s.set("l", new Date(1418265358440L)); + s.set("m", Lists.asList(1, new Integer[]{1})); + s.set("n", Lists.asList(BigDecimal.valueOf(1.1), + new BigDecimal[]{BigDecimal.valueOf(1.1)})); + Map<String, Double> hm = Maps.newHashMap(); + hm.put("a", 1.0); + hm.put("b", 2.0); + s.set("o", hm); + return s; + } + + protected final TypeSystem getTypeSystem() { + return TypeSystem.getInstance(); + } + + @Before + public void setup() throws Exception { + TypeSystem ts = TypeSystem.getInstance(); + ts.reset(); + + StructType structType = ts.defineStructType(STRUCT_TYPE_1, + true, + TypesUtil.createRequiredAttrDef("a", DataTypes.INT_TYPE), + TypesUtil.createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE), + TypesUtil.createOptionalAttrDef("c", DataTypes.BYTE_TYPE), + TypesUtil.createOptionalAttrDef("d", DataTypes.SHORT_TYPE), + TypesUtil.createOptionalAttrDef("e", DataTypes.INT_TYPE), + TypesUtil.createOptionalAttrDef("f", DataTypes.INT_TYPE), + TypesUtil.createOptionalAttrDef("g", DataTypes.LONG_TYPE), + TypesUtil.createOptionalAttrDef("h", DataTypes.FLOAT_TYPE), + TypesUtil.createOptionalAttrDef("i", DataTypes.DOUBLE_TYPE), + TypesUtil.createOptionalAttrDef("j", DataTypes.BIGINTEGER_TYPE), + TypesUtil.createOptionalAttrDef("k", DataTypes.BIGDECIMAL_TYPE), + TypesUtil.createOptionalAttrDef("l", DataTypes.DATE_TYPE), + TypesUtil.createOptionalAttrDef("m", ts.defineArrayType(DataTypes.INT_TYPE)), + TypesUtil.createOptionalAttrDef("n", ts.defineArrayType(DataTypes.BIGDECIMAL_TYPE)), + TypesUtil.createOptionalAttrDef("o", + ts.defineMapType(DataTypes.STRING_TYPE, DataTypes.DOUBLE_TYPE))); + System.out.println("defined structType = " + structType); + + StructType recursiveStructType = ts.defineStructType(STRUCT_TYPE_2, + true, + TypesUtil.createRequiredAttrDef("a", DataTypes.INT_TYPE), + TypesUtil.createOptionalAttrDef("s", STRUCT_TYPE_2)); + System.out.println("defined recursiveStructType = " + recursiveStructType); + } + + protected Map<String, IDataType> defineTraits(HierarchicalTypeDefinition... tDefs) + throws MetadataException { + + return getTypeSystem().defineTraitTypes(tDefs); + } + + protected Map<String, IDataType> defineClasses( + HierarchicalTypeDefinition<ClassType>... classDefs) throws MetadataException { + return getTypeSystem().defineClassTypes(classDefs); + } + + /* + * Class Hierarchy is: + * Department(name : String, employees : Array[Person]) + * Person(name : String, department : Department, manager : Manager) + * Manager(subordinates : Array[Person]) extends Person + * + * Persons can have SecurityClearance(level : Int) clearance. + */ + protected void defineDeptEmployeeTypes(TypeSystem ts) throws MetadataException { + + HierarchicalTypeDefinition<ClassType> deptTypeDef = TypesUtil + .createClassTypeDef("Department", + ImmutableList.<String>of(), + TypesUtil.createRequiredAttrDef("name", DataTypes.STRING_TYPE), + new AttributeDefinition("employees", + String.format("array<%s>", "Person"), Multiplicity.COLLECTION, true, + "department") + ); + HierarchicalTypeDefinition<ClassType> personTypeDef = TypesUtil.createClassTypeDef("Person", + ImmutableList.<String>of(), + TypesUtil.createRequiredAttrDef("name", DataTypes.STRING_TYPE), + new AttributeDefinition("department", + "Department", Multiplicity.REQUIRED, false, "employees"), + new AttributeDefinition("manager", + "Manager", Multiplicity.OPTIONAL, false, "subordinates") + ); + HierarchicalTypeDefinition<ClassType> managerTypeDef = + TypesUtil.createClassTypeDef("Manager", + ImmutableList.of("Person"), + new AttributeDefinition("subordinates", + String.format("array<%s>", "Person"), + Multiplicity.COLLECTION, false, "manager") + ); + + HierarchicalTypeDefinition<TraitType> securityClearanceTypeDef = + TypesUtil.createTraitTypeDef( + "SecurityClearance", + ImmutableList.<String>of(), + TypesUtil.createRequiredAttrDef("level", DataTypes.INT_TYPE) + ); + + ts.defineTypes(ImmutableList.<StructTypeDefinition>of(), + ImmutableList.of(securityClearanceTypeDef), + ImmutableList.of(deptTypeDef, personTypeDef, + managerTypeDef)); + + ImmutableList.of( + ts.getDataType(HierarchicalType.class, "SecurityClearance"), + ts.getDataType(ClassType.class, "Department"), + ts.getDataType(ClassType.class, "Person"), + ts.getDataType(ClassType.class, "Manager") + ); + } + + protected Referenceable createDeptEg1(TypeSystem ts) throws MetadataException { + Referenceable hrDept = new Referenceable("Department"); + Referenceable john = new Referenceable("Person"); + Referenceable jane = new Referenceable("Manager", "SecurityClearance"); + + hrDept.set("name", "hr"); + john.set("name", "John"); + john.set("department", hrDept); + jane.set("name", "Jane"); + jane.set("department", hrDept); + + john.set("manager", jane); + + hrDept.set("employees", ImmutableList.of(john, jane)); + + jane.set("subordinates", ImmutableList.of(john)); + + jane.getTrait("SecurityClearance").set("level", 1); + + ClassType deptType = ts.getDataType(ClassType.class, "Department"); + deptType.convert(hrDept, Multiplicity.REQUIRED); + + return hrDept; + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/test/java/org/apache/atlas/typesystem/types/ClassTest.java ---------------------------------------------------------------------- diff --git a/typesystem/src/test/java/org/apache/atlas/typesystem/types/ClassTest.java b/typesystem/src/test/java/org/apache/atlas/typesystem/types/ClassTest.java new file mode 100755 index 0000000..c7bb448 --- /dev/null +++ b/typesystem/src/test/java/org/apache/atlas/typesystem/types/ClassTest.java @@ -0,0 +1,72 @@ +/** + * 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 org.apache.atlas.MetadataException; +import org.apache.atlas.typesystem.ITypedReferenceableInstance; +import org.apache.atlas.typesystem.Referenceable; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ClassTest extends BaseTest { + + @Before + public void setup() throws Exception { + super.setup(); + } + + @Test + public void test1() throws MetadataException { + + TypeSystem ts = getTypeSystem(); + + defineDeptEmployeeTypes(ts); + Referenceable hrDept = createDeptEg1(ts); + ClassType deptType = ts.getDataType(ClassType.class, "Department"); + ITypedReferenceableInstance hrDept2 = deptType.convert(hrDept, Multiplicity.REQUIRED); + + + Assert.assertEquals(hrDept2.toString(), "{\n" + + "\tid : (type: Department, id: <unassigned>)\n" + + "\tname : \thr\n" + + "\temployees : \t[{\n" + + "\tid : (type: Person, id: <unassigned>)\n" + + "\tname : \tJohn\n" + + "\tdepartment : (type: Department, id: <unassigned>)\n" + + "\tmanager : (type: Manager, id: <unassigned>)\n" + + "}, {\n" + + "\tid : (type: Manager, id: <unassigned>)\n" + + "\tsubordinates : \t[{\n" + + "\tid : (type: Person, id: <unassigned>)\n" + + "\tname : \tJohn\n" + + "\tdepartment : (type: Department, id: <unassigned>)\n" + + "\tmanager : (type: Manager, id: <unassigned>)\n" + + "}]\n" + + "\tname : \tJane\n" + + "\tdepartment : (type: Department, id: <unassigned>)\n" + + "\tmanager : <null>\n" + + "\n" + + "\tSecurityClearance : \t{\n" + + "\t\tlevel : \t\t1\n" + + "\t}}]\n" + + "}"); + + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/test/java/org/apache/atlas/typesystem/types/EnumTest.java ---------------------------------------------------------------------- diff --git a/typesystem/src/test/java/org/apache/atlas/typesystem/types/EnumTest.java b/typesystem/src/test/java/org/apache/atlas/typesystem/types/EnumTest.java new file mode 100755 index 0000000..4677d07 --- /dev/null +++ b/typesystem/src/test/java/org/apache/atlas/typesystem/types/EnumTest.java @@ -0,0 +1,221 @@ +/** + * 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.Lists; +import com.google.common.collect.Maps; +import org.apache.atlas.MetadataException; +import org.apache.atlas.typesystem.IReferenceableInstance; +import org.apache.atlas.typesystem.ITypedReferenceableInstance; +import org.apache.atlas.typesystem.ITypedStruct; +import org.apache.atlas.typesystem.Referenceable; +import org.apache.atlas.typesystem.Struct; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; +import java.util.Map; + +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; + +public class EnumTest extends BaseTest { + + @Before + public void setup() throws Exception { + super.setup(); + } + + void defineEnums(TypeSystem ts) throws MetadataException { + ts.defineEnumType("HiveObjectType", + new EnumValue("GLOBAL", 1), + new EnumValue("DATABASE", 2), + new EnumValue("TABLE", 3), + new EnumValue("PARTITION", 4), + new EnumValue("COLUMN", 5)); + + ts.defineEnumType("PrincipalType", + new EnumValue("USER", 1), + new EnumValue("ROLE", 2), + new EnumValue("GROUP", 3)); + + ts.defineEnumType("TxnState", + new EnumValue("COMMITTED", 1), + new EnumValue("ABORTED", 2), + new EnumValue("OPEN", 3)); + + ts.defineEnumType("LockLevel", + new EnumValue("DB", 1), + new EnumValue("TABLE", 2), + new EnumValue("PARTITION", 3)); + + } + + protected void fillStruct(Struct s) throws MetadataException { + s.set("a", 1); + s.set("b", true); + s.set("c", (byte) 1); + s.set("d", (short) 2); + s.set("e", 1); + s.set("f", 1); + s.set("g", 1L); + s.set("h", 1.0f); + s.set("i", 1.0); + s.set("j", BigInteger.valueOf(1L)); + s.set("k", new BigDecimal(1)); + s.set("l", new Date(1418265358440L)); + s.set("m", Lists.asList(1, new Integer[]{1})); + s.set("n", + Lists.asList(BigDecimal.valueOf(1.1), new BigDecimal[]{BigDecimal.valueOf(1.1)})); + Map<String, Double> hm = Maps.newHashMap(); + hm.put("a", 1.0); + hm.put("b", 2.0); + s.set("o", hm); + s.set("enum1", "GLOBAL"); + s.set("enum2", 1); + s.set("enum3", "COMMITTED"); + s.set("enum4", 3); + } + + protected Struct createStructWithEnum(String typeName) throws MetadataException { + Struct s = new Struct(typeName); + fillStruct(s); + return s; + } + + protected Referenceable createInstanceWithEnum(String typeName) throws MetadataException { + Referenceable r = new Referenceable(typeName); + fillStruct(r); + return r; + } + + protected ClassType defineClassTypeWithEnum(TypeSystem ts) throws MetadataException { + return ts.defineClassType(createClassTypeDef("t4", + ImmutableList.<String>of(), + createRequiredAttrDef("a", DataTypes.INT_TYPE), + createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE), + createOptionalAttrDef("c", DataTypes.BYTE_TYPE), + createOptionalAttrDef("d", DataTypes.SHORT_TYPE), + createOptionalAttrDef("enum1", ts.getDataType(EnumType.class, "HiveObjectType")), + createOptionalAttrDef("e", DataTypes.INT_TYPE), + createOptionalAttrDef("f", DataTypes.INT_TYPE), + createOptionalAttrDef("g", DataTypes.LONG_TYPE), + createOptionalAttrDef("enum2", ts.getDataType(EnumType.class, "PrincipalType")), + createOptionalAttrDef("h", DataTypes.FLOAT_TYPE), + createOptionalAttrDef("i", DataTypes.DOUBLE_TYPE), + createOptionalAttrDef("j", DataTypes.BIGINTEGER_TYPE), + createOptionalAttrDef("k", DataTypes.BIGDECIMAL_TYPE), + createOptionalAttrDef("enum3", ts.getDataType(EnumType.class, "TxnState")), + createOptionalAttrDef("l", DataTypes.DATE_TYPE), + createOptionalAttrDef("m", ts.defineArrayType(DataTypes.INT_TYPE)), + createOptionalAttrDef("n", ts.defineArrayType(DataTypes.BIGDECIMAL_TYPE)), + createOptionalAttrDef("o", + ts.defineMapType(DataTypes.STRING_TYPE, DataTypes.DOUBLE_TYPE)), + createOptionalAttrDef("enum4", ts.getDataType(EnumType.class, "LockLevel")))); + } + + @Test + public void testStruct() throws MetadataException { + TypeSystem ts = getTypeSystem(); + defineEnums(ts); + StructType structType = ts.defineStructType("t3", + true, + createRequiredAttrDef("a", DataTypes.INT_TYPE), + createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE), + createOptionalAttrDef("c", DataTypes.BYTE_TYPE), + createOptionalAttrDef("d", DataTypes.SHORT_TYPE), + createOptionalAttrDef("enum1", ts.getDataType(EnumType.class, "HiveObjectType")), + createOptionalAttrDef("e", DataTypes.INT_TYPE), + createOptionalAttrDef("f", DataTypes.INT_TYPE), + createOptionalAttrDef("g", DataTypes.LONG_TYPE), + createOptionalAttrDef("enum2", ts.getDataType(EnumType.class, "PrincipalType")), + createOptionalAttrDef("h", DataTypes.FLOAT_TYPE), + createOptionalAttrDef("i", DataTypes.DOUBLE_TYPE), + createOptionalAttrDef("j", DataTypes.BIGINTEGER_TYPE), + createOptionalAttrDef("k", DataTypes.BIGDECIMAL_TYPE), + createOptionalAttrDef("enum3", ts.getDataType(EnumType.class, "TxnState")), + createOptionalAttrDef("l", DataTypes.DATE_TYPE), + createOptionalAttrDef("m", ts.defineArrayType(DataTypes.INT_TYPE)), + createOptionalAttrDef("n", ts.defineArrayType(DataTypes.BIGDECIMAL_TYPE)), + createOptionalAttrDef("o", + ts.defineMapType(DataTypes.STRING_TYPE, DataTypes.DOUBLE_TYPE)), + createOptionalAttrDef("enum4", ts.getDataType(EnumType.class, "LockLevel"))); + + Struct s = createStructWithEnum("t3"); + ITypedStruct typedS = structType.convert(s, Multiplicity.REQUIRED); + Assert.assertEquals(typedS.toString(), "{\n" + + "\ta : \t1\n" + + "\tb : \ttrue\n" + + "\tc : \t1\n" + + "\td : \t2\n" + + "\tenum1 : \tGLOBAL\n" + + "\te : \t1\n" + + "\tf : \t1\n" + + "\tg : \t1\n" + + "\tenum2 : \tUSER\n" + + "\th : \t1.0\n" + + "\ti : \t1.0\n" + + "\tj : \t1\n" + + "\tk : \t1\n" + + "\tenum3 : \tCOMMITTED\n" + + "\tl : \t" + TEST_DATE + "\n" + + "\tm : \t[1, 1]\n" + + "\tn : \t[1.1, 1.1]\n" + + "\to : \t{b=2.0, a=1.0}\n" + + "\tenum4 : \tPARTITION\n" + + "}"); + } + + @Test + public void testClass() throws MetadataException { + TypeSystem ts = getTypeSystem(); + defineEnums(ts); + ClassType clsType = defineClassTypeWithEnum(ts); + + IReferenceableInstance r = createInstanceWithEnum("t4"); + ITypedReferenceableInstance typedR = clsType.convert(r, Multiplicity.REQUIRED); + Assert.assertEquals(typedR.toString(), "{\n" + + "\tid : (type: t4, id: <unassigned>)\n" + + "\ta : \t1\n" + + "\tb : \ttrue\n" + + "\tc : \t1\n" + + "\td : \t2\n" + + "\tenum1 : \tGLOBAL\n" + + "\te : \t1\n" + + "\tf : \t1\n" + + "\tg : \t1\n" + + "\tenum2 : \tUSER\n" + + "\th : \t1.0\n" + + "\ti : \t1.0\n" + + "\tj : \t1\n" + + "\tk : \t1\n" + + "\tenum3 : \tCOMMITTED\n" + + "\tl : \t" + TEST_DATE + "\n" + + "\tm : \t[1, 1]\n" + + "\tn : \t[1.1, 1.1]\n" + + "\to : \t{b=2.0, a=1.0}\n" + + "\tenum4 : \tPARTITION\n" + + "}"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/test/java/org/apache/atlas/typesystem/types/StructTest.java ---------------------------------------------------------------------- diff --git a/typesystem/src/test/java/org/apache/atlas/typesystem/types/StructTest.java b/typesystem/src/test/java/org/apache/atlas/typesystem/types/StructTest.java new file mode 100755 index 0000000..e063bed --- /dev/null +++ b/typesystem/src/test/java/org/apache/atlas/typesystem/types/StructTest.java @@ -0,0 +1,82 @@ +/** + * 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 org.apache.atlas.MetadataException; +import org.apache.atlas.typesystem.ITypedStruct; +import org.apache.atlas.typesystem.Struct; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class StructTest extends BaseTest { + + StructType structType; + StructType recursiveStructType; + + @Before + public void setup() throws Exception { + super.setup(); + structType = getTypeSystem().getDataType(StructType.class, STRUCT_TYPE_1); + recursiveStructType = getTypeSystem() + .getDataType(StructType.class, STRUCT_TYPE_2); + } + + @Test + public void test1() throws MetadataException { + Struct s = createStruct(); + ITypedStruct ts = structType.convert(s, Multiplicity.REQUIRED); + Assert.assertEquals(ts.toString(), "{\n" + + "\ta : \t1\n" + + "\tb : \ttrue\n" + + "\tc : \t1\n" + + "\td : \t2\n" + + "\te : \t1\n" + + "\tf : \t1\n" + + "\tg : \t1\n" + + "\th : \t1.0\n" + + "\ti : \t1.0\n" + + "\tj : \t1\n" + + "\tk : \t1\n" + + "\tl : \t" + TEST_DATE + "\n" + + "\tm : \t[1, 1]\n" + + "\tn : \t[1.1, 1.1]\n" + + "\to : \t{b=2.0, a=1.0}\n" + + "}"); + } + + @Test + public void testRecursive() throws MetadataException { + Struct s1 = new Struct(recursiveStructType.getName()); + s1.set("a", 1); + Struct s2 = new Struct(recursiveStructType.getName()); + s2.set("a", 1); + s2.set("s", s1); + ITypedStruct ts = recursiveStructType.convert(s2, Multiplicity.REQUIRED); + Assert.assertEquals(ts.toString(), "{\n" + + "\ta : \t1\n" + + "\ts : \t{\n" + + "\t\ta : \t\t1\n" + + "\t\ts : <null>\n" + + "\n" + + "\t}\n" + + "}"); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/test/java/org/apache/atlas/typesystem/types/TraitTest.java ---------------------------------------------------------------------- diff --git a/typesystem/src/test/java/org/apache/atlas/typesystem/types/TraitTest.java b/typesystem/src/test/java/org/apache/atlas/typesystem/types/TraitTest.java new file mode 100755 index 0000000..31a1128 --- /dev/null +++ b/typesystem/src/test/java/org/apache/atlas/typesystem/types/TraitTest.java @@ -0,0 +1,224 @@ +/** + * 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 org.apache.atlas.MetadataException; +import org.apache.atlas.typesystem.IStruct; +import org.apache.atlas.typesystem.ITypedStruct; +import org.apache.atlas.typesystem.Struct; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +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.createTraitTypeDef; + +public class TraitTest extends BaseTest { + + + @Before + public void setup() throws Exception { + super.setup(); + } + + /* + * Type Hierarchy is: + * A(a,b,c,d) + * B(b) extends A + * C(c) extends A + * D(d) extends B,C + * + * - There are a total of 11 fields in an instance of D + * - an attribute that is hidden by a SubType can referenced by prefixing it with the + * complete Path. + * For e.g. the 'b' attribute in A (that is a superType for B) is hidden the 'b' attribute + * in B. + * So it is availabel by the name 'A.B.D.b' + * + * - Another way to set attributes is to cast. Casting a 'D' instance of 'B' makes the 'A.B.D + * .b' attribute + * available as 'A.B.b'. Casting one more time to an 'A' makes the 'A.B.b' attribute + * available as 'b'. + */ + @Test + public void test1() throws MetadataException { + HierarchicalTypeDefinition A = createTraitTypeDef("A", null, + createRequiredAttrDef("a", DataTypes.INT_TYPE), + createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE), + createOptionalAttrDef("c", DataTypes.BYTE_TYPE), + createOptionalAttrDef("d", DataTypes.SHORT_TYPE)); + HierarchicalTypeDefinition B = createTraitTypeDef("B", ImmutableList.<String>of("A"), + createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE)); + HierarchicalTypeDefinition C = createTraitTypeDef("C", ImmutableList.<String>of("A"), + createOptionalAttrDef("c", DataTypes.BYTE_TYPE)); + HierarchicalTypeDefinition D = createTraitTypeDef("D", ImmutableList.<String>of("B", "C"), + createOptionalAttrDef("d", DataTypes.SHORT_TYPE)); + + defineTraits(A, B, C, D); + + TraitType DType = (TraitType) getTypeSystem().getDataType(TraitType.class, "D"); + +// for(String aName : DType.fieldMapping().fields.keySet()) { +// System.out.println(String.format("nameToQualifiedName.put(\"%s\", \"%s\");", aName, DType.getQualifiedName(aName))); +// } + + Map<String,String> nameToQualifiedName = new HashMap(); + { + nameToQualifiedName.put("d", "D.d"); + nameToQualifiedName.put("b", "B.b"); + nameToQualifiedName.put("c", "C.c"); + nameToQualifiedName.put("a", "A.a"); + nameToQualifiedName.put("A.B.D.b", "A.B.D.b"); + nameToQualifiedName.put("A.B.D.c", "A.B.D.c"); + nameToQualifiedName.put("A.B.D.d", "A.B.D.d"); + nameToQualifiedName.put("A.C.D.a", "A.C.D.a"); + nameToQualifiedName.put("A.C.D.b", "A.C.D.b"); + nameToQualifiedName.put("A.C.D.c", "A.C.D.c"); + nameToQualifiedName.put("A.C.D.d", "A.C.D.d"); + } + + Struct s1 = new Struct("D"); + s1.set("d", 1); + s1.set("c", 1); + s1.set("b", true); + s1.set("a", 1); + s1.set("A.B.D.b", true); + s1.set("A.B.D.c", 2); + s1.set("A.B.D.d", 2); + + s1.set("A.C.D.a", 3); + s1.set("A.C.D.b", false); + s1.set("A.C.D.c", 3); + s1.set("A.C.D.d", 3); + + + ITypedStruct ts = DType.convert(s1, Multiplicity.REQUIRED); + Assert.assertEquals(ts.toString(), "{\n" + + "\td : \t1\n" + + "\tb : \ttrue\n" + + "\tc : \t1\n" + + "\ta : \t1\n" + + "\tA.B.D.b : \ttrue\n" + + "\tA.B.D.c : \t2\n" + + "\tA.B.D.d : \t2\n" + + "\tA.C.D.a : \t3\n" + + "\tA.C.D.b : \tfalse\n" + + "\tA.C.D.c : \t3\n" + + "\tA.C.D.d : \t3\n" + + "}"); + + /* + * cast to B and set the 'b' attribute on A. + */ + TraitType BType = (TraitType) getTypeSystem().getDataType(TraitType.class, "B"); + IStruct s2 = DType.castAs(ts, "B"); + s2.set("A.B.b", false); + + Assert.assertEquals(ts.toString(), "{\n" + + "\td : \t1\n" + + "\tb : \ttrue\n" + + "\tc : \t1\n" + + "\ta : \t1\n" + + "\tA.B.D.b : \tfalse\n" + + "\tA.B.D.c : \t2\n" + + "\tA.B.D.d : \t2\n" + + "\tA.C.D.a : \t3\n" + + "\tA.C.D.b : \tfalse\n" + + "\tA.C.D.c : \t3\n" + + "\tA.C.D.d : \t3\n" + + "}"); + + /* + * cast again to A and set the 'b' attribute on A. + */ + TraitType AType = (TraitType) getTypeSystem().getDataType(TraitType.class, "A"); + IStruct s3 = BType.castAs(s2, "A"); + s3.set("b", true); + Assert.assertEquals(ts.toString(), "{\n" + + "\td : \t1\n" + + "\tb : \ttrue\n" + + "\tc : \t1\n" + + "\ta : \t1\n" + + "\tA.B.D.b : \ttrue\n" + + "\tA.B.D.c : \t2\n" + + "\tA.B.D.d : \t2\n" + + "\tA.C.D.a : \t3\n" + + "\tA.C.D.b : \tfalse\n" + + "\tA.C.D.c : \t3\n" + + "\tA.C.D.d : \t3\n" + + "}"); + } + + @Test + public void testRandomOrder() throws MetadataException { + HierarchicalTypeDefinition A = createTraitTypeDef("A", null, + createRequiredAttrDef("a", DataTypes.INT_TYPE), + createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE), + createOptionalAttrDef("c", DataTypes.BYTE_TYPE), + createOptionalAttrDef("d", DataTypes.SHORT_TYPE)); + HierarchicalTypeDefinition B = createTraitTypeDef("B", ImmutableList.<String>of("A"), + createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE)); + HierarchicalTypeDefinition C = createTraitTypeDef("C", ImmutableList.<String>of("A"), + createOptionalAttrDef("c", DataTypes.BYTE_TYPE)); + HierarchicalTypeDefinition D = createTraitTypeDef("D", ImmutableList.<String>of("B", "C"), + createOptionalAttrDef("d", DataTypes.SHORT_TYPE)); + + defineTraits(B, D, A, C); + + TraitType DType = (TraitType) getTypeSystem().getDataType(TraitType.class, "D"); + + Struct s1 = new Struct("D"); + s1.set("d", 1); + s1.set("c", 1); + s1.set("b", true); + s1.set("a", 1); + s1.set("A.B.D.b", true); + s1.set("A.B.D.c", 2); + s1.set("A.B.D.d", 2); + + s1.set("A.C.D.a", 3); + s1.set("A.C.D.b", false); + s1.set("A.C.D.c", 3); + s1.set("A.C.D.d", 3); + + + ITypedStruct ts = DType.convert(s1, Multiplicity.REQUIRED); + Assert.assertEquals(ts.toString(), "{\n" + + "\td : \t1\n" + + "\tb : \ttrue\n" + + "\tc : \t1\n" + + "\ta : \t1\n" + + "\tA.B.D.b : \ttrue\n" + + "\tA.B.D.c : \t2\n" + + "\tA.B.D.d : \t2\n" + + "\tA.C.D.a : \t3\n" + + "\tA.C.D.b : \tfalse\n" + + "\tA.C.D.c : \t3\n" + + "\tA.C.D.d : \t3\n" + + "}"); + + } + +} + http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeInheritanceTest.java ---------------------------------------------------------------------- diff --git a/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeInheritanceTest.java b/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeInheritanceTest.java new file mode 100644 index 0000000..8829862 --- /dev/null +++ b/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeInheritanceTest.java @@ -0,0 +1,256 @@ +/** + * 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 org.apache.atlas.MetadataException; +import org.apache.atlas.typesystem.IStruct; +import org.apache.atlas.typesystem.ITypedInstance; +import org.apache.atlas.typesystem.ITypedStruct; +import org.apache.atlas.typesystem.Struct; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +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.createTraitTypeDef; + +/** + * Unit tests for type inheritance. + */ +public class TypeInheritanceTest extends BaseTest { + + @BeforeMethod + public void setup() throws Exception { + TypeSystem.getInstance().reset(); + super.setup(); + } + + /* + * Type Hierarchy is: + * A(a) + * B(b) extends A + */ + @Test + public void testSimpleInheritance() throws MetadataException { + HierarchicalTypeDefinition A = createClassTypeDef("A", null, + createRequiredAttrDef("a", DataTypes.INT_TYPE)); + + HierarchicalTypeDefinition B = createClassTypeDef("B", ImmutableList.of("A"), + createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE)); + + defineClasses(A, B); + + ClassType BType = getTypeSystem().getDataType(ClassType.class, "B"); + + Struct s1 = new Struct("B"); + s1.set("b", true); + s1.set("a", 1); + + ITypedInstance ts = BType.convert(s1, Multiplicity.REQUIRED); + Assert.assertEquals(ts.toString(), "{\n" + + "\tid : (type: B, id: <unassigned>)\n" + + "\tb : \ttrue\n" + + "\ta : \t1\n" + + "}"); + } + + /* + * Type Hierarchy is: + * A(a, b) + * B(b) extends A + */ + @Test + public void testSimpleInheritanceWithOverrides() throws MetadataException { + HierarchicalTypeDefinition A = createClassTypeDef("A", null, + createRequiredAttrDef("a", DataTypes.INT_TYPE), + createRequiredAttrDef("b", DataTypes.BOOLEAN_TYPE)); + + HierarchicalTypeDefinition B = createClassTypeDef("B", ImmutableList.of("A"), + createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE)); + + defineClasses(A, B); + + ClassType BType = getTypeSystem().getDataType(ClassType.class, "B"); + + Struct s1 = new Struct("B"); + s1.set("b", true); + s1.set("a", 1); + s1.set("A.B.b", false); + + ITypedInstance ts = BType.convert(s1, Multiplicity.REQUIRED); + Assert.assertEquals(ts.toString(), "{\n" + + "\tid : (type: B, id: <unassigned>)\n" + + "\tb : \ttrue\n" + + "\ta : \t1\n" + + "\tA.B.b : \tfalse\n" + + "}"); + } + + /* + * Type Hierarchy is: + * A(a) + * B(b) extends A + * C(c) extends B + * D(d) extends C + */ + @Test + public void testMultiLevelInheritance() throws MetadataException { + HierarchicalTypeDefinition A = createClassTypeDef("A", null, + createRequiredAttrDef("a", DataTypes.INT_TYPE)); + + HierarchicalTypeDefinition B = createClassTypeDef("B", ImmutableList.of("A"), + createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE)); + + HierarchicalTypeDefinition C = createClassTypeDef("C", ImmutableList.of("B"), + createOptionalAttrDef("c", DataTypes.BYTE_TYPE)); + + HierarchicalTypeDefinition D = createClassTypeDef("D", ImmutableList.of("C"), + createOptionalAttrDef("d", DataTypes.SHORT_TYPE)); + + defineClasses(A, B, C, D); + + ClassType DType = getTypeSystem().getDataType(ClassType.class, "D"); + + Struct s1 = new Struct("D"); + s1.set("d", 1); + s1.set("c", 1); + s1.set("b", true); + s1.set("a", 1); + + ITypedInstance ts = DType.convert(s1, Multiplicity.REQUIRED); + Assert.assertEquals(ts.toString(), "{\n" + + "\tid : (type: D, id: <unassigned>)\n" + + "\td : \t1\n" + + "\tc : \t1\n" + + "\tb : \ttrue\n" + + "\ta : \t1\n" + + "}"); + } + + /* + * Type Hierarchy is: + * A(a,b,c,d) + * B(b) extends A + * C(c) extends A + * D(d) extends B,C + * + * - There are a total of 11 fields in an instance of D + * - an attribute that is hidden by a SubType can referenced by prefixing it with the + * complete Path. + * For e.g. the 'b' attribute in A (that is a superType for B) is hidden the 'b' attribute + * in B. + * So it is availabel by the name 'A.B.D.b' + * + * - Another way to set attributes is to cast. Casting a 'D' instance of 'B' makes the 'A.B.D + * .b' attribute + * available as 'A.B.b'. Casting one more time to an 'A' makes the 'A.B.b' attribute + * available as 'b'. + */ + @Test + public void testDiamondInheritance() throws MetadataException { + HierarchicalTypeDefinition A = createTraitTypeDef("A", null, + createRequiredAttrDef("a", DataTypes.INT_TYPE), + createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE), + createOptionalAttrDef("c", DataTypes.BYTE_TYPE), + createOptionalAttrDef("d", DataTypes.SHORT_TYPE)); + HierarchicalTypeDefinition B = createTraitTypeDef("B", ImmutableList.of("A"), + createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE)); + HierarchicalTypeDefinition C = createTraitTypeDef("C", ImmutableList.of("A"), + createOptionalAttrDef("c", DataTypes.BYTE_TYPE)); + HierarchicalTypeDefinition D = createTraitTypeDef("D", ImmutableList.of("B", "C"), + createOptionalAttrDef("d", DataTypes.SHORT_TYPE)); + + defineTraits(A, B, C, D); + + TraitType DType = getTypeSystem().getDataType(TraitType.class, "D"); + + Struct s1 = new Struct("D"); + s1.set("d", 1); + s1.set("c", 1); + s1.set("b", true); + s1.set("a", 1); + s1.set("A.B.D.b", true); + s1.set("A.B.D.c", 2); + s1.set("A.B.D.d", 2); + + s1.set("A.C.D.a", 3); + s1.set("A.C.D.b", false); + s1.set("A.C.D.c", 3); + s1.set("A.C.D.d", 3); + + + ITypedStruct ts = DType.convert(s1, Multiplicity.REQUIRED); + Assert.assertEquals(ts.toString(), "{\n" + + "\td : \t1\n" + + "\tb : \ttrue\n" + + "\tc : \t1\n" + + "\ta : \t1\n" + + "\tA.B.D.b : \ttrue\n" + + "\tA.B.D.c : \t2\n" + + "\tA.B.D.d : \t2\n" + + "\tA.C.D.a : \t3\n" + + "\tA.C.D.b : \tfalse\n" + + "\tA.C.D.c : \t3\n" + + "\tA.C.D.d : \t3\n" + + "}"); + + /* + * cast to B and set the 'b' attribute on A. + */ + TraitType BType = getTypeSystem().getDataType(TraitType.class, "B"); + IStruct s2 = DType.castAs(ts, "B"); + s2.set("A.B.b", false); + + Assert.assertEquals(ts.toString(), "{\n" + + "\td : \t1\n" + + "\tb : \ttrue\n" + + "\tc : \t1\n" + + "\ta : \t1\n" + + "\tA.B.D.b : \tfalse\n" + + "\tA.B.D.c : \t2\n" + + "\tA.B.D.d : \t2\n" + + "\tA.C.D.a : \t3\n" + + "\tA.C.D.b : \tfalse\n" + + "\tA.C.D.c : \t3\n" + + "\tA.C.D.d : \t3\n" + + "}"); + + /* + * cast again to A and set the 'b' attribute on A. + */ + IStruct s3 = BType.castAs(s2, "A"); + s3.set("b", true); + Assert.assertEquals(ts.toString(), "{\n" + + "\td : \t1\n" + + "\tb : \ttrue\n" + + "\tc : \t1\n" + + "\ta : \t1\n" + + "\tA.B.D.b : \ttrue\n" + + "\tA.B.D.c : \t2\n" + + "\tA.B.D.d : \t2\n" + + "\tA.C.D.a : \t3\n" + + "\tA.C.D.b : \tfalse\n" + + "\tA.C.D.c : \t3\n" + + "\tA.C.D.d : \t3\n" + + "}"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeSystemTest.java ---------------------------------------------------------------------- diff --git a/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeSystemTest.java b/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeSystemTest.java new file mode 100755 index 0000000..4f43ad0 --- /dev/null +++ b/typesystem/src/test/java/org/apache/atlas/typesystem/types/TypeSystemTest.java @@ -0,0 +1,139 @@ +/** + * 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 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.List; + +import static org.apache.atlas.typesystem.types.utils.TypesUtil.createClassTypeDef; +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; + +public class TypeSystemTest extends BaseTest { + + @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)); + Assert.assertTrue(getTypeSystem().getTypeNames().contains("enum_test")); + } + + @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)); + Assert.assertTrue(getTypeSystem().isRegistered("enum_test")); + } + + @Test + public void testGetTraitsNames() throws Exception { + HierarchicalTypeDefinition<TraitType> classificationTraitDefinition = + TypesUtil.createTraitTypeDef("Classification", + ImmutableList.<String>of(), + TypesUtil.createRequiredAttrDef("tag", DataTypes.STRING_TYPE)); + HierarchicalTypeDefinition<TraitType> piiTrait = + TypesUtil.createTraitTypeDef("PII", ImmutableList.<String>of()); + HierarchicalTypeDefinition<TraitType> phiTrait = + TypesUtil.createTraitTypeDef("PHI", ImmutableList.<String>of()); + HierarchicalTypeDefinition<TraitType> pciTrait = + TypesUtil.createTraitTypeDef("PCI", ImmutableList.<String>of()); + HierarchicalTypeDefinition<TraitType> soxTrait = + TypesUtil.createTraitTypeDef("SOX", ImmutableList.<String>of()); + HierarchicalTypeDefinition<TraitType> secTrait = + TypesUtil.createTraitTypeDef("SEC", ImmutableList.<String>of()); + HierarchicalTypeDefinition<TraitType> financeTrait = + TypesUtil.createTraitTypeDef("Finance", ImmutableList.<String>of()); + + getTypeSystem().defineTypes( + 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)); + ts.defineEnumType(orgLevelEnum); + + String structName = random(); + String attrType = random(); + StructTypeDefinition structType = createStructTypeDef(structName, + createRequiredAttrDef(attrType, DataTypes.STRING_TYPE)); + + String className = random(); + HierarchicalTypeDefinition<ClassType> classType = + createClassTypeDef(className, ImmutableList.<String>of(), + createRequiredAttrDef(attrType, DataTypes.STRING_TYPE)); + + String traitName = random(); + HierarchicalTypeDefinition<TraitType> traitType = createTraitTypeDef(traitName, + ImmutableList.<String>of(), createRequiredAttrDef(attrType, DataTypes.INT_TYPE)); + + ts.defineTypes(ImmutableList.of(structType), ImmutableList.of(traitType), ImmutableList.of(classType)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/test/java/org/apache/atlas/typesystem/types/ValidationTest.java ---------------------------------------------------------------------- diff --git a/typesystem/src/test/java/org/apache/atlas/typesystem/types/ValidationTest.java b/typesystem/src/test/java/org/apache/atlas/typesystem/types/ValidationTest.java new file mode 100644 index 0000000..29638de --- /dev/null +++ b/typesystem/src/test/java/org/apache/atlas/typesystem/types/ValidationTest.java @@ -0,0 +1,102 @@ +/* + * 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 org.apache.atlas.typesystem.types.utils.TypesUtil; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class ValidationTest { + @DataProvider(name = "attributeData") + private Object[][] createAttributeData() { + return new String[][]{ + {null, "type"}, {"", "type"}, {"name", null}, {"name", ""}}; + } + + @Test (dataProvider = "attributeData", expectedExceptions = {IllegalArgumentException.class}) + public void testAttributes(String name, String type) { + TypesUtil.createRequiredAttrDef(name, type); + } + + @DataProvider(name = "enumValueData") + private Object[][] createEnumValueData() { + return new String[][]{{null}, {""}}; + } + + @Test (dataProvider = "enumValueData", expectedExceptions = {IllegalArgumentException.class}) + public void testEnumValue(String name) { + new EnumValue(name, 1); + } + + @DataProvider(name = "enumTypeData") + private Object[][] createEnumTypeData() { + EnumValue value = new EnumValue("name", 1); + return new Object[][]{{null, value}, {"", value}, {"name"}}; + } + + @Test (dataProvider = "enumTypeData", expectedExceptions = {IllegalArgumentException.class}) + public void testEnumType(String name, EnumValue... values) { + new EnumTypeDefinition(name, values); + } + + @DataProvider(name = "structTypeData") + private Object[][] createStructTypeData() { + AttributeDefinition value = TypesUtil.createRequiredAttrDef("name", "type"); + return new Object[][]{{null, value}, {"", value}, {"name"}}; + } + + @Test (dataProvider = "structTypeData", expectedExceptions = {IllegalArgumentException.class}) + public void testStructType(String name, AttributeDefinition... values) { + new StructTypeDefinition(name, values); + } + + @DataProvider(name = "classTypeData") + private Object[][] createClassTypeData() { + return new Object[][]{{null}, {""}}; + } + + @Test (dataProvider = "classTypeData", expectedExceptions = {IllegalArgumentException.class}) + public void testClassType(String name) { + AttributeDefinition value = TypesUtil.createRequiredAttrDef("name", "type");; + TypesUtil.createClassTypeDef(name, ImmutableList.of("super"), value); + } + + @Test (dataProvider = "classTypeData", expectedExceptions = {IllegalArgumentException.class}) + public void testTraitType(String name) { + AttributeDefinition value = TypesUtil.createRequiredAttrDef("name", "type");; + TypesUtil.createTraitTypeDef(name, ImmutableList.of("super"), value); + } + + @Test + public void testValidTypes() { + AttributeDefinition attribute = TypesUtil.createRequiredAttrDef("name", "type"); + + //class with no attributes + TypesUtil.createClassTypeDef("name", ImmutableList.of("super")); + + //class with no super types + TypesUtil.createClassTypeDef("name", ImmutableList.<String>of(), attribute); + + //trait with no attributes + TypesUtil.createTraitTypeDef("name", ImmutableList.of("super")); + + //trait with no super types + TypesUtil.createTraitTypeDef("name", ImmutableList.<String>of(), attribute); + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/test/java/org/apache/hadoop/metadata/typesystem/json/SerializationJavaTest.java ---------------------------------------------------------------------- diff --git a/typesystem/src/test/java/org/apache/hadoop/metadata/typesystem/json/SerializationJavaTest.java b/typesystem/src/test/java/org/apache/hadoop/metadata/typesystem/json/SerializationJavaTest.java deleted file mode 100755 index c2ef616..0000000 --- a/typesystem/src/test/java/org/apache/hadoop/metadata/typesystem/json/SerializationJavaTest.java +++ /dev/null @@ -1,177 +0,0 @@ -/** - * 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.hadoop.metadata.typesystem.json; - -import com.google.common.collect.ImmutableList; -import org.apache.hadoop.metadata.MetadataException; -import org.apache.hadoop.metadata.typesystem.ITypedInstance; -import org.apache.hadoop.metadata.typesystem.ITypedReferenceableInstance; -import org.apache.hadoop.metadata.typesystem.Referenceable; -import org.apache.hadoop.metadata.typesystem.Struct; -import org.apache.hadoop.metadata.typesystem.types.AttributeDefinition; -import org.apache.hadoop.metadata.typesystem.types.BaseTest; -import org.apache.hadoop.metadata.typesystem.types.ClassType; -import org.apache.hadoop.metadata.typesystem.types.DataTypes; -import org.apache.hadoop.metadata.typesystem.types.HierarchicalTypeDefinition; -import org.apache.hadoop.metadata.typesystem.types.Multiplicity; -import org.apache.hadoop.metadata.typesystem.types.StructTypeDefinition; -import org.apache.hadoop.metadata.typesystem.types.TraitType; -import org.apache.hadoop.metadata.typesystem.types.TypeSystem; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import static org.apache.hadoop.metadata.typesystem.types.utils.TypesUtil.createClassTypeDef; -import static org.apache.hadoop.metadata.typesystem.types.utils.TypesUtil.createRequiredAttrDef; -import static org.apache.hadoop.metadata.typesystem.types.utils.TypesUtil.createTraitTypeDef; - -public class SerializationJavaTest extends BaseTest { - - - @Before - public void setup() throws Exception { - super.setup(); - } - - /* - * Class Hierarchy is: - * Department(name : String, employees : Array[Person]) - * Person(name : String, department : Department, manager : Manager) - * Manager(subordinates : Array[Person]) extends Person - * - * Persons can have SecurityClearance(level : Int) clearance. - */ - @Test - public void test1() throws MetadataException { - - TypeSystem ts = getTypeSystem(); - - HierarchicalTypeDefinition<ClassType> deptTypeDef = createClassTypeDef("Department", - ImmutableList.<String>of(), - createRequiredAttrDef("name", DataTypes.STRING_TYPE), - new AttributeDefinition("employees", - String.format("array<%s>", "Person"), Multiplicity.COLLECTION, true, - "department") - ); - HierarchicalTypeDefinition<ClassType> personTypeDef = createClassTypeDef("Person", - ImmutableList.<String>of(), - createRequiredAttrDef("name", DataTypes.STRING_TYPE), - new AttributeDefinition("department", - "Department", Multiplicity.REQUIRED, false, "employees"), - new AttributeDefinition("manager", - "Manager", Multiplicity.OPTIONAL, false, "subordinates") - ); - HierarchicalTypeDefinition<ClassType> managerTypeDef = createClassTypeDef("Manager", - ImmutableList.<String>of("Person"), - new AttributeDefinition("subordinates", - String.format("array<%s>", "Person"), Multiplicity.COLLECTION, false, - "manager") - ); - - HierarchicalTypeDefinition<TraitType> securityClearanceTypeDef = createTraitTypeDef( - "SecurityClearance", - ImmutableList.<String>of(), - createRequiredAttrDef("level", DataTypes.INT_TYPE) - ); - - ts.defineTypes(ImmutableList.<StructTypeDefinition>of(), - ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(securityClearanceTypeDef), - ImmutableList.<HierarchicalTypeDefinition<ClassType>>of(deptTypeDef, personTypeDef, - managerTypeDef)); - - Referenceable hrDept = new Referenceable("Department"); - Referenceable john = new Referenceable("Person"); - Referenceable jane = new Referenceable("Manager", "SecurityClearance"); - - hrDept.set("name", "hr"); - john.set("name", "John"); - john.set("department", hrDept); - jane.set("name", "Jane"); - jane.set("department", hrDept); - - john.set("manager", jane); - - hrDept.set("employees", ImmutableList.<Referenceable>of(john, jane)); - - jane.set("subordinates", ImmutableList.<Referenceable>of(john)); - - jane.getTrait("SecurityClearance").set("level", 1); - - ClassType deptType = ts.getDataType(ClassType.class, "Department"); - ITypedReferenceableInstance hrDept2 = deptType.convert(hrDept, Multiplicity.REQUIRED); - - String hrDeptStr = hrDept2.toString(); - - Assert.assertEquals(hrDeptStr, "{\n" + - "\tid : (type: Department, id: <unassigned>)\n" + - "\tname : \thr\n" + - "\temployees : \t[{\n" + - "\tid : (type: Person, id: <unassigned>)\n" + - "\tname : \tJohn\n" + - "\tdepartment : (type: Department, id: <unassigned>)\n" + - "\tmanager : (type: Manager, id: <unassigned>)\n" + - "}, {\n" + - "\tid : (type: Manager, id: <unassigned>)\n" + - "\tsubordinates : \t[{\n" + - "\tid : (type: Person, id: <unassigned>)\n" + - "\tname : \tJohn\n" + - "\tdepartment : (type: Department, id: <unassigned>)\n" + - "\tmanager : (type: Manager, id: <unassigned>)\n" + - "}]\n" + - "\tname : \tJane\n" + - "\tdepartment : (type: Department, id: <unassigned>)\n" + - "\tmanager : <null>\n" + - "\n" + - "\tSecurityClearance : \t{\n" + - "\t\tlevel : \t\t1\n" + - "\t}}]\n" + - "}"); - - String jsonStr = Serialization$.MODULE$.toJson(hrDept2); - //System.out.println(jsonStr); - - hrDept2 = Serialization$.MODULE$.fromJson(jsonStr); - Assert.assertEquals(hrDept2.toString(), hrDeptStr); - - } - - @Test - public void testTrait() throws MetadataException { - - TypeSystem ts = getTypeSystem(); - HierarchicalTypeDefinition<TraitType> securityClearanceTypeDef = createTraitTypeDef( - "SecurityClearance2", - ImmutableList.<String>of(), - createRequiredAttrDef("level", DataTypes.INT_TYPE) - ); - - ts.defineTypes(ImmutableList.<StructTypeDefinition>of(), - ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(securityClearanceTypeDef), - ImmutableList.<HierarchicalTypeDefinition<ClassType>>of()); - - - Struct s = new Struct("SecurityClearance2"); - s.set("level", 1); - TraitType tType = ts.getDataType(TraitType.class, "SecurityClearance2"); - ITypedInstance t = tType.convert(s, Multiplicity.REQUIRED); - String jsonStr = Serialization$.MODULE$.toJson(t); - ITypedInstance t2 = Serialization$.MODULE$.traitFromJson(jsonStr); - Assert.assertEquals(t.toString(), t2.toString()); - } -} \ No newline at end of file
