ATLAS-1863: added support for default value for attributes
Signed-off-by: Madhan Neethiraj <madhan@apache.org>
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 @@
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 @@
setValuesMaxCount(valuesMaxCount);
setIsUnique(isUnique);
setIsIndexable(isIndexable);
+ setDefaultValue(defaultValue);
setConstraints(constraints);
}
@@ -303,6 +311,7 @@
setValuesMaxCount(other.getValuesMaxCount());
setIsUnique(other.getIsUnique());
setIsIndexable(other.getIsIndexable());
+ setDefaultValue(other.getDefaultValue());
setConstraints(other.getConstraints());
}
}
@@ -365,6 +374,14 @@
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 @@
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 @@
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
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 @@
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<>();
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 @@
}
@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) {
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 @@
return null;
}
+ if (obj instanceof String) {
+ obj = AtlasType.fromJson(obj.toString(), Map.class);
+ }
+
if (obj instanceof Map) {
Map<Object, Object> ret = new HashMap<>();
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 @@
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 @@
if (attribute != null) {
AtlasType dataType = attribute.getAttributeType();
- ret = dataType.createDefaultValue();
+ ret = dataType.createDefaultValue(attributeDef.getDefaultValue());
}
}
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 @@
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);
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.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 @@
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));
}
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 @@
};
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),
};
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 @@
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 @@
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));
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.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 @@
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();
+ }
}
}
}
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.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 @@
private AtlasEntitiesWithExtInfo deptEntity;
private AtlasEntityWithExtInfo dbEntity;
private AtlasEntityWithExtInfo tblEntity;
+ private AtlasEntityWithExtInfo primitiveEntity;
AtlasEntityChangeNotifier mockChangeNotifier = mock(AtlasEntityChangeNotifier.class);
@Inject
@@ -130,6 +132,14 @@
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 @@
}
@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);