ATLAS-1863: added support for default value for attributes Signed-off-by: Madhan Neethiraj <[email protected]>
Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/d9f62cb5 Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/d9f62cb5 Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/d9f62cb5 Branch: refs/heads/feature-odf Commit: d9f62cb5a97d033448567688bd21e7a4ea25d65a Parents: 1de6016 Author: rdsolani <[email protected]> Authored: Thu Jun 15 19:32:37 2017 +0530 Committer: Madhan Neethiraj <[email protected]> Committed: Fri Jun 16 08:14:14 2017 -0700 ---------------------------------------------------------------------- .../atlas/model/typedef/AtlasStructDef.java | 23 ++++++++- .../org/apache/atlas/type/AtlasArrayType.java | 4 ++ .../org/apache/atlas/type/AtlasEntityType.java | 8 +++ .../org/apache/atlas/type/AtlasMapType.java | 4 ++ .../org/apache/atlas/type/AtlasStructType.java | 11 +++- .../java/org/apache/atlas/type/AtlasType.java | 4 ++ .../test/java/org/apache/atlas/TestUtilsV2.java | 53 ++++++++++++++++++++ .../apache/atlas/type/TestAtlasArrayType.java | 2 +- .../store/graph/v1/AtlasStructDefStoreV1.java | 2 + .../store/graph/v1/EntityGraphMapper.java | 13 +++-- .../store/graph/v1/AtlasEntityStoreV1Test.java | 43 ++++++++++++++++ 11 files changed, 158 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java index aee4907..3a5c43a 100644 --- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java +++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java @@ -271,16 +271,23 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable { private int valuesMaxCount; private boolean isUnique; private boolean isIndexable; + private String defaultValue; + private List<AtlasConstraintDef> constraints; public AtlasAttributeDef() { this(null, null); } public AtlasAttributeDef(String name, String typeName) { this(name, typeName, false, Cardinality.SINGLE, COUNT_NOT_SET, COUNT_NOT_SET, false, false, null); + + } + public AtlasAttributeDef(String name, String typeName, boolean isOptional, Cardinality cardinality, + int valuesMinCount, int valuesMaxCount, boolean isUnique, boolean isIndexable, List<AtlasConstraintDef> constraints) { + this(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, null, constraints); } public AtlasAttributeDef(String name, String typeName, boolean isOptional, Cardinality cardinality, - int valuesMinCount, int valuesMaxCount, boolean isUnique, boolean isIndexable, + int valuesMinCount, int valuesMaxCount, boolean isUnique, boolean isIndexable, String defaultValue, List<AtlasConstraintDef> constraints) { setName(name); setTypeName(typeName); @@ -290,6 +297,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable { setValuesMaxCount(valuesMaxCount); setIsUnique(isUnique); setIsIndexable(isIndexable); + setDefaultValue(defaultValue); setConstraints(constraints); } @@ -303,6 +311,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable { setValuesMaxCount(other.getValuesMaxCount()); setIsUnique(other.getIsUnique()); setIsIndexable(other.getIsIndexable()); + setDefaultValue(other.getDefaultValue()); setConstraints(other.getConstraints()); } } @@ -365,6 +374,14 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable { return isIndexable; } + public String getDefaultValue(){ + return defaultValue; + } + + public void setDefaultValue(String defaultValue){ + this.defaultValue = defaultValue; + } + public void setIsIndexable(boolean idexable) { isIndexable = idexable; } @@ -409,6 +426,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable { sb.append(", valuesMaxCount=").append(valuesMaxCount); sb.append(", isUnique=").append(isUnique); sb.append(", isIndexable=").append(isIndexable); + sb.append(", defaultValue=").append(defaultValue); sb.append(", constraints=["); if (CollectionUtils.isNotEmpty(constraints)) { int i = 0; @@ -439,12 +457,13 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable { Objects.equals(name, that.name) && Objects.equals(typeName, that.typeName) && cardinality == that.cardinality && + Objects.equals(defaultValue, that.defaultValue) && Objects.equals(constraints, that.constraints); } @Override public int hashCode() { - return Objects.hash(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, constraints); + return Objects.hash(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, defaultValue, constraints); } @Override http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/main/java/org/apache/atlas/type/AtlasArrayType.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasArrayType.java b/intg/src/main/java/org/apache/atlas/type/AtlasArrayType.java index 2d386f1..de3394f 100644 --- a/intg/src/main/java/org/apache/atlas/type/AtlasArrayType.java +++ b/intg/src/main/java/org/apache/atlas/type/AtlasArrayType.java @@ -201,6 +201,10 @@ public class AtlasArrayType extends AtlasType { return null; } + if (obj instanceof String){ + obj = AtlasType.fromJson(obj.toString(), List.class); + } + if (obj instanceof List || obj instanceof Set) { List<Object> ret = new ArrayList<>(); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java index 6516d48..0ff1582 100644 --- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java +++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java @@ -146,6 +146,14 @@ public class AtlasEntityType extends AtlasStructType { } @Override + public AtlasEntity createDefaultValue(Object defaultValue){ + AtlasEntity ret = new AtlasEntity(entityDef.getName()); + + populateDefaultValues(ret); + + return ret; + } + @Override public boolean isValidValue(Object obj) { if (obj != null) { for (AtlasEntityType superType : superTypes) { http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/main/java/org/apache/atlas/type/AtlasMapType.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasMapType.java b/intg/src/main/java/org/apache/atlas/type/AtlasMapType.java index 385a9ae..90c898a 100644 --- a/intg/src/main/java/org/apache/atlas/type/AtlasMapType.java +++ b/intg/src/main/java/org/apache/atlas/type/AtlasMapType.java @@ -148,6 +148,10 @@ public class AtlasMapType extends AtlasType { return null; } + if (obj instanceof String) { + obj = AtlasType.fromJson(obj.toString(), Map.class); + } + if (obj instanceof Map) { Map<Object, Object> ret = new HashMap<>(); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java index 0eeaf9c..c2e0be5 100644 --- a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java +++ b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java @@ -186,6 +186,15 @@ public class AtlasStructType extends AtlasType { return ret; } + @Override + public Object createDefaultValue(Object defaultValue) { + AtlasStruct ret = new AtlasStruct(structDef.getName()); + + populateDefaultValues(ret); + + return ret; + } + public Map<String, AtlasAttribute> getAllAttributes() { return allAttributes; } @@ -480,7 +489,7 @@ public class AtlasStructType extends AtlasType { if (attribute != null) { AtlasType dataType = attribute.getAttributeType(); - ret = dataType.createDefaultValue(); + ret = dataType.createDefaultValue(attributeDef.getDefaultValue()); } } http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/main/java/org/apache/atlas/type/AtlasType.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasType.java b/intg/src/main/java/org/apache/atlas/type/AtlasType.java index 28d0a07..f05cfd6 100644 --- a/intg/src/main/java/org/apache/atlas/type/AtlasType.java +++ b/intg/src/main/java/org/apache/atlas/type/AtlasType.java @@ -66,6 +66,10 @@ public abstract class AtlasType { return createDefaultValue(); } + public Object createDefaultValue(Object val){ + return val == null ? createDefaultValue() : getNormalizedValue(val); + } + public abstract boolean isValidValue(Object obj); public abstract Object getNormalizedValue(Object obj); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/test/java/org/apache/atlas/TestUtilsV2.java ---------------------------------------------------------------------- diff --git a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java index 2a6ea92..9774583 100755 --- a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java +++ b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java @@ -35,6 +35,7 @@ import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef; import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality; import org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef; import org.apache.atlas.model.typedef.AtlasTypesDef; +import org.apache.atlas.type.AtlasStructType; import org.apache.atlas.type.AtlasTypeUtil; import org.apache.commons.lang.RandomStringUtils; @@ -877,6 +878,58 @@ public final class TestUtilsV2 { return ret; } + public static AtlasEntityWithExtInfo createprimitiveEntityV2() { + + AtlasEntity defaultprimitive = new AtlasEntity(createPrimitiveEntityDef()); + defaultprimitive.setAttribute("name", "testname"); + defaultprimitive.setAttribute("description","test"); + defaultprimitive.setAttribute("check","check"); + + AtlasEntityWithExtInfo ret = new AtlasEntityWithExtInfo(defaultprimitive); + + return ret; + + } + + + public static AtlasEntityDef createPrimitiveEntityDef() { + + AtlasEntityDef newtestEntityDef = new AtlasEntityDef("newtest"); + AtlasAttributeDef attrName = new AtlasAttributeDef("name", AtlasBaseTypeDef.ATLAS_TYPE_STRING); + + AtlasAttributeDef attrDescription = new AtlasAttributeDef("description", AtlasBaseTypeDef.ATLAS_TYPE_STRING); + attrDescription.setIsOptional(false); + + AtlasAttributeDef attrcheck = new AtlasAttributeDef("check", AtlasBaseTypeDef.ATLAS_TYPE_STRING); + attrcheck.setIsOptional(true); + + AtlasAttributeDef attrSourceCode = new AtlasAttributeDef("sourcecode", AtlasBaseTypeDef.ATLAS_TYPE_STRING); + attrSourceCode.setDefaultValue("Hello World"); + attrSourceCode.setIsOptional(true); + + AtlasAttributeDef attrCost = new AtlasAttributeDef("Cost", AtlasBaseTypeDef.ATLAS_TYPE_INT); + attrCost.setIsOptional(true); + attrCost.setDefaultValue("30"); + + AtlasAttributeDef attrDiskUsage = new AtlasAttributeDef("diskUsage", AtlasBaseTypeDef.ATLAS_TYPE_FLOAT); + attrDiskUsage.setIsOptional(true); + attrDiskUsage.setDefaultValue("70.50"); + + AtlasAttributeDef attrisStoreUse = new AtlasAttributeDef("isstoreUse", AtlasBaseTypeDef.ATLAS_TYPE_BOOLEAN); + attrisStoreUse.setIsOptional(true); + attrisStoreUse.setDefaultValue("true"); + + newtestEntityDef.addAttribute(attrName); + newtestEntityDef.addAttribute(attrDescription); + newtestEntityDef.addAttribute(attrcheck); + newtestEntityDef.addAttribute(attrSourceCode); + newtestEntityDef.addAttribute(attrCost); + newtestEntityDef.addAttribute(attrDiskUsage); + newtestEntityDef.addAttribute(attrisStoreUse); + + return newtestEntityDef; + } + public static AtlasEntity createColumnEntity(AtlasEntity tableEntity) { return createColumnEntity(tableEntity, "col" + seq.addAndGet(1)); } http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/test/java/org/apache/atlas/type/TestAtlasArrayType.java ---------------------------------------------------------------------- diff --git a/intg/src/test/java/org/apache/atlas/type/TestAtlasArrayType.java b/intg/src/test/java/org/apache/atlas/type/TestAtlasArrayType.java index e882473..f123b3c 100644 --- a/intg/src/test/java/org/apache/atlas/type/TestAtlasArrayType.java +++ b/intg/src/test/java/org/apache/atlas/type/TestAtlasArrayType.java @@ -59,7 +59,7 @@ public class TestAtlasArrayType { }; invalidValues = new Object[] { - new String[] { "1", "abcd", "3", "xyz", "5" }, "1", Byte.valueOf((byte)1), Short.valueOf((short)1), + Byte.valueOf((byte)1), Short.valueOf((short)1), Integer.valueOf(1), Long.valueOf(1L), Float.valueOf(1), Double.valueOf(1), BigInteger.valueOf(1), BigDecimal.valueOf(1), }; http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java index 1c6cfc7..62729e7 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java @@ -511,6 +511,7 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At attribInfo.put("isIndexable", attributeDef.getIsIndexable()); attribInfo.put("isComposite", attribute.isOwnedRef()); attribInfo.put("reverseAttributeName", attribute.getInverseRefAttributeName()); + attribInfo.put("defaultValue", attributeDef.getDefaultValue()); final int lower; final int upper; @@ -549,6 +550,7 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At ret.setTypeName((String) attribInfo.get("dataType")); ret.setIsUnique((Boolean) attribInfo.get("isUnique")); ret.setIsIndexable((Boolean) attribInfo.get("isIndexable")); + ret.setDefaultValue((String) attribInfo.get("defaultValue")); if ((Boolean)attribInfo.get("isComposite")) { ret.addConstraint(new AtlasConstraintDef(AtlasConstraintDef.CONSTRAINT_TYPE_OWNED_REF)); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java index 80cd1ee..ebf6a20 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java @@ -33,7 +33,6 @@ import org.apache.atlas.model.instance.EntityMutations.EntityOperation; import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef; import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.RepositoryException; -import org.apache.atlas.repository.graph.AtlasGraphProvider; import org.apache.atlas.repository.graph.GraphHelper; import org.apache.atlas.repository.graphdb.AtlasEdge; import org.apache.atlas.repository.graphdb.AtlasGraph; @@ -259,13 +258,17 @@ public class EntityGraphMapper { private void mapAttribute(AtlasAttribute attribute, Object attrValue, AtlasVertex vertex, EntityOperation op, EntityMutationContext context) throws AtlasBaseException { if (attrValue == null) { + AtlasAttributeDef attributeDef = attribute.getAttributeDef(); AtlasType attrType = attribute.getAttributeType(); - if (attrType.getTypeCategory() == TypeCategory.PRIMITIVE) { - if (attribute.getAttributeDef().getIsOptional()) { - attrValue = attrType.createOptionalDefaultValue(); + if (attributeDef.getDefaultValue() != null) { + attrValue = attrType.createDefaultValue(attributeDef.getDefaultValue()); } else { - attrValue = attrType.createDefaultValue(); + if (attribute.getAttributeDef().getIsOptional()) { + attrValue = attrType.createOptionalDefaultValue(); + } else { + attrValue = attrType.createDefaultValue(); + } } } } http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java index 44067b9..2ac0fc6 100644 --- a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java +++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java @@ -77,6 +77,7 @@ import static org.apache.atlas.TestUtils.COLUMNS_ATTR_NAME; import static org.apache.atlas.TestUtils.COLUMN_TYPE; import static org.apache.atlas.TestUtils.NAME; import static org.apache.atlas.TestUtils.randomString; +import static org.apache.atlas.TestUtilsV2.STORAGE_DESC_TYPE; import static org.apache.atlas.TestUtilsV2.TABLE_TYPE; import static org.mockito.Mockito.mock; import static org.testng.Assert.assertEquals; @@ -104,6 +105,7 @@ public class AtlasEntityStoreV1Test { private AtlasEntitiesWithExtInfo deptEntity; private AtlasEntityWithExtInfo dbEntity; private AtlasEntityWithExtInfo tblEntity; + private AtlasEntityWithExtInfo primitiveEntity; AtlasEntityChangeNotifier mockChangeNotifier = mock(AtlasEntityChangeNotifier.class); @Inject @@ -130,6 +132,14 @@ public class AtlasEntityStoreV1Test { deptEntity = TestUtilsV2.createDeptEg2(); dbEntity = TestUtilsV2.createDBEntityV2(); tblEntity = TestUtilsV2.createTableEntityV2(dbEntity.getEntity()); + + AtlasTypesDef typesDef11 = new AtlasTypesDef(); + List primitiveEntityDef = new ArrayList<AtlasEntityDef>(); + primitiveEntityDef.add(TestUtilsV2.createPrimitiveEntityDef()); + typesDef11.setEntityDefs(primitiveEntityDef); + typeDefStore.createTypesDef( typesDef11 ); + + primitiveEntity = TestUtilsV2.createprimitiveEntityV2(); } @AfterClass @@ -144,6 +154,39 @@ public class AtlasEntityStoreV1Test { } @Test + public void testDefaultValueForPrimitiveTypes() throws Exception { + + init(); + + EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(primitiveEntity), false); + List<AtlasEntityHeader> entitiesCreatedResponse = response.getEntitiesByOperation(EntityOperation.CREATE); + final Map<EntityOperation, List<AtlasEntityHeader>> entitiesMutated = response.getMutatedEntities(); + List<AtlasEntityHeader> entitiesCreatedwithdefault = entitiesMutated.get(EntityOperation.CREATE); + + AtlasEntity entityCreated = getEntityFromStore(entitiesCreatedResponse.get(0)); + + + Map attributesMap = entityCreated.getAttributes(); + String description = (String) attributesMap.get("description"); + String check = (String) attributesMap.get("check"); + String sourceCode = (String) attributesMap.get("sourcecode"); + float diskUsage = (float) attributesMap.get("diskUsage"); + boolean isstoreUse = (boolean) attributesMap.get("isstoreUse"); + int cost = (int)attributesMap.get("Cost"); + + + assertEquals(description,"test"); + assertEquals(check,"check"); + + //defaultValue + assertEquals(diskUsage,70.5f); + assertEquals(isstoreUse,true); + assertEquals(sourceCode,"Hello World"); + assertEquals(cost,30); + } + + + @Test public void testCreate() throws Exception { init(); EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(deptEntity), false);
