blob: 31bfb2cf95d0a41ee4ebf789c5558fa39c60ba08 [file] [log] [blame]
/**
* 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.IStruct;
import org.apache.atlas.typesystem.ITypedStruct;
import org.apache.atlas.typesystem.Struct;
import org.apache.atlas.typesystem.TypesDef;
import org.apache.atlas.typesystem.types.utils.TypesUtil;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.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 HierarchicalTypeTest<TraitType> {
@BeforeMethod
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 available 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 AtlasException {
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", ImmutableSet.<String>of("A"),
createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE));
HierarchicalTypeDefinition C =
createTraitTypeDef("C", ImmutableSet.<String>of("A"), createOptionalAttrDef("c", DataTypes.BYTE_TYPE));
HierarchicalTypeDefinition D = createTraitTypeDef("D", ImmutableSet.<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 AtlasException {
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", ImmutableSet.<String>of("A"),
createOptionalAttrDef("b", DataTypes.BOOLEAN_TYPE));
HierarchicalTypeDefinition C = createTraitTypeDef("C", ImmutableSet.<String>of("A"),
createOptionalAttrDef("c", DataTypes.BYTE_TYPE));
HierarchicalTypeDefinition D = createTraitTypeDef("D", ImmutableSet.<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" +
"}");
}
@Override
protected HierarchicalTypeDefinition<TraitType> getTypeDefinition(String name, AttributeDefinition... attributes) {
return new HierarchicalTypeDefinition(TraitType.class, name, null, null, attributes);
}
@Override
protected HierarchicalTypeDefinition<TraitType> getTypeDefinition(String name, ImmutableSet<String> superTypes,
AttributeDefinition... attributes) {
return new HierarchicalTypeDefinition(TraitType.class, name, null, superTypes, attributes);
}
@Override
protected TypesDef getTypesDef(StructTypeDefinition typeDefinition) {
return TypesUtil.getTypesDef(ImmutableList.<EnumTypeDefinition>of(), ImmutableList.<StructTypeDefinition>of(),
ImmutableList.of((HierarchicalTypeDefinition<TraitType>) typeDefinition),
ImmutableList.<HierarchicalTypeDefinition<ClassType>>of());
}
@Override
protected TypesDef getTypesDef(HierarchicalTypeDefinition<TraitType>... typeDefinitions) {
return TypesUtil.getTypesDef(ImmutableList.<EnumTypeDefinition>of(), ImmutableList.<StructTypeDefinition>of(),
ImmutableList.copyOf(typeDefinitions), ImmutableList.<HierarchicalTypeDefinition<ClassType>>of());
}
}