Commit 48477e20 by Madhan Neethiraj

ATLAS-1526: removed foreignKey/mappedFromRef constraints and brought back

legacy flags isComposite/reverseAttributeName using constraints ownedRef/inverseRef(attribute=attr1)
parent 5f508c97
......@@ -215,12 +215,9 @@
"name": "sd",
"typeName": "hive_storagedesc",
"cardinality": "SINGLE",
"constraintDefs": [
"constraints": [
{
"type": "mappedFromRef",
"params": {
"refAttribute": "table"
}
"type": "ownedRef"
}
],
"isIndexable": false,
......@@ -231,7 +228,11 @@
"name": "partitionKeys",
"typeName": "array<hive_column>",
"cardinality": "SINGLE",
"constraintDefs": [],
"constraints": [
{
"type": "ownedRef"
}
],
"isIndexable": false,
"isOptional": true,
"isUnique": false
......@@ -248,7 +249,11 @@
"name": "columns",
"typeName": "array<hive_column>",
"cardinality": "SINGLE",
"constraintDefs": [],
"constraints": [
{
"type": "ownedRef"
}
],
"isIndexable": false,
"isOptional": true,
"isUnique": false
......@@ -306,11 +311,11 @@
"name": "table",
"typeName": "hive_table",
"cardinality": "SINGLE",
"constraintDefs": [
"constraints": [
{
"type": "foreignKey",
"type": "inverseRef",
"params": {
"onDelete": "cascade"
"attribute": "sd"
}
}
],
......@@ -469,11 +474,11 @@
"name": "table",
"typeName": "hive_table",
"cardinality": "SINGLE",
"constraintDefs": [
"constraints": [
{
"type": "foreignKey",
"type": "inverseRef",
"params": {
"onDelete": "cascade"
"attribute": "columns"
}
}
],
......
......@@ -17,7 +17,20 @@
"isIndexable": false,
"isOptional": false,
"isUnique": false
},
{
"name": "column_families",
"typeName": "array<hbase_column_family>",
"cardinality": "SINGLE",
"constraints": [
{
"type": "ownedRef"
}
],
"isIndexable": false,
"isOptional": true,
"isUnique": false
},
]
},
{
......@@ -33,14 +46,27 @@
"isIndexable": false,
"isOptional": false,
"isUnique": false,
"constraintDefs": [
"constraints": [
{
"type": "foreignKey",
"type": "inverseRef",
"params": {
"onDelete": "cascade"
"attribute": "column_families"
}
}
]
},
{
"name": "columns",
"typeName": "array<hbase_column>",
"cardinality": "SINGLE",
"constraints": [
{
"type": "ownedRef"
}
],
"isIndexable": false,
"isOptional": true,
"isUnique": false
}
],
"typeVersion": "1.0"
......@@ -58,11 +84,11 @@
"isIndexable": false,
"isOptional": false,
"isUnique": false,
"constraintDefs": [
"constraints": [
{
"type": "foreignKey",
"type": "inverseRef",
"params": {
"onDelete": "cascade"
"attribute": "columns"
}
}
]
......
......@@ -54,7 +54,7 @@
"name": "nodes",
"typeName": "array<storm_node>",
"cardinality": "LIST",
"constraintDefs": [],
"constraints": [],
"isIndexable": false,
"isOptional": false,
"isUnique": false
......
......@@ -55,6 +55,10 @@ public enum AtlasErrorCode {
TYPE_NAME_INVALID_FORMAT(400, "ATLAS40025E", "{0}: invalid name for {1}. Names must consist of a letter followed by a sequence of letter, number, or '_' characters"),
INVALID_PARAMETERS(400, "ATLAS40025E", "invalid parameters: {0}"),
CLASSIFICATION_ALREADY_ASSOCIATED(400, "ATLAS40026E", "instance {0} already is associated with classification {1}"),
CONSTRAINT_INVERSE_REF_ATTRIBUTE_INVALID_TYPE(400, "ATLAS40027E", "{0}.{1}: invalid {2} constraint. Attribute {3} is not an entity type"),
CONSTRAINT_INVERSE_REF_INVERSE_ATTRIBUTE_NON_EXISTING(400, "ATLAS40028E", "{0}.{1}: invalid {2} constraint. Inverse attribute {3}.{4} does not exist"),
CONSTRAINT_INVERSE_REF_INVERSE_ATTRIBUTE_INVALID_TYPE(400, "ATLAS40029E", "{0}.{1}: invalid {2} constraint. Inverse attribute {3}.{4} is not an entity type"),
CONSTRAINT_OWNED_REF_ATTRIBUTE_INVALID_TYPE(400, "ATLAS40030E", "{0}.{1}: invalid {2} constraint. Attribute {3} is not an entity type"),
// All Not found enums go here
TYPE_NAME_NOT_FOUND(404, "ATLAS4041E", "Given typename {0} was invalid"),
......
......@@ -42,6 +42,8 @@ import org.apache.hadoop.util.StringUtils;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonSerialize;
......@@ -269,7 +271,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
private int valuesMaxCount;
private boolean isUnique;
private boolean isIndexable;
private List<AtlasConstraintDef> constraintDefs;
private List<AtlasConstraintDef> constraints;
public AtlasAttributeDef() { this(null, null); }
......@@ -279,7 +281,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
public AtlasAttributeDef(String name, String typeName, boolean isOptional, Cardinality cardinality,
int valuesMinCount, int valuesMaxCount, boolean isUnique, boolean isIndexable,
List<AtlasConstraintDef> constraintDefs) {
List<AtlasConstraintDef> constraints) {
setName(name);
setTypeName(typeName);
setIsOptional(isOptional);
......@@ -288,7 +290,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
setValuesMaxCount(valuesMaxCount);
setIsUnique(isUnique);
setIsIndexable(isIndexable);
setConstraintDefs(constraintDefs);
setConstraints(constraints);
}
public AtlasAttributeDef(AtlasAttributeDef other) {
......@@ -301,7 +303,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
setValuesMaxCount(other.getValuesMaxCount());
setIsUnique(other.getIsUnique());
setIsIndexable(other.getIsIndexable());
setConstraintDefs(other.getConstraintDefs());
setConstraints(other.getConstraints());
}
}
......@@ -367,33 +369,34 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
isIndexable = idexable;
}
public List<AtlasConstraintDef> getConstraintDefs() { return constraintDefs; }
public List<AtlasConstraintDef> getConstraints() { return constraints; }
public void setConstraintDefs(List<AtlasConstraintDef> constraintDefs) {
if (this.constraintDefs != null && this.constraintDefs == constraintDefs) {
public void setConstraints(List<AtlasConstraintDef> constraints) {
if (this.constraints != null && this.constraints == constraints) {
return;
}
if (CollectionUtils.isEmpty(constraintDefs)) {
this.constraintDefs = null;
if (CollectionUtils.isEmpty(constraints)) {
this.constraints = null;
} else {
this.constraintDefs = new ArrayList<>(constraintDefs);
this.constraints = new ArrayList<>(constraints);
}
}
public void addConstraint(AtlasConstraintDef constraintDef) {
List<AtlasConstraintDef> cDefs = constraintDefs;
List<AtlasConstraintDef> cDefs = constraints;
if (cDefs == null) {
cDefs = new ArrayList<>();
this.constraints = cDefs;
} else {
cDefs = new ArrayList<>(cDefs);
}
cDefs.add(constraintDef);
this.constraintDefs = cDefs;
}
public StringBuilder toString(StringBuilder sb) {
if (sb == null) {
sb = new StringBuilder();
......@@ -408,10 +411,10 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
sb.append(", valuesMaxCount=").append(valuesMaxCount);
sb.append(", isUnique=").append(isUnique);
sb.append(", isIndexable=").append(isIndexable);
sb.append(", constraintDefs=[");
if (CollectionUtils.isNotEmpty(constraintDefs)) {
sb.append(", constraints=[");
if (CollectionUtils.isNotEmpty(constraints)) {
int i = 0;
for (AtlasConstraintDef constraintDef : constraintDefs) {
for (AtlasConstraintDef constraintDef : constraints) {
constraintDef.toString(sb);
if (i > 0) {
sb.append(", ");
......@@ -438,12 +441,12 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
Objects.equals(name, that.name) &&
Objects.equals(typeName, that.typeName) &&
cardinality == that.cardinality &&
Objects.equals(constraintDefs, that.constraintDefs);
Objects.equals(constraints, that.constraints);
}
@Override
public int hashCode() {
return Objects.hash(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, constraintDefs);
return Objects.hash(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, constraints);
}
@Override
......@@ -465,11 +468,9 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
public static class AtlasConstraintDef implements Serializable {
private static final long serialVersionUID = 1L;
public static final String CONSTRAINT_TYPE_FOREIGN_KEY = "foreignKey";
public static final String CONSTRAINT_TYPE_MAPPED_FROM_REF = "mappedFromRef";
public static final String CONSTRAINT_PARAM_REF_ATTRIBUTE = "refAttribute";
public static final String CONSTRAINT_PARAM_ON_DELETE = "onDelete";
public static final String CONSTRAINT_PARAM_VAL_CASCADE = "cascade";
public static final String CONSTRAINT_TYPE_OWNED_REF = "ownedRef";
public static final String CONSTRAINT_TYPE_INVERSE_REF = "inverseRef";
public static final String CONSTRAINT_PARAM_ATTRIBUTE = "attribute";
private String type; // foreignKey/mappedFromRef/valueInRange
private Map<String, Object> params; // onDelete=cascade/refAttribute=attr2/min=0,max=23
......@@ -515,6 +516,18 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
this.params = params;
}
@JsonIgnore
public boolean isConstraintType(String name) {
return StringUtils.equalsIgnoreCase(name, this.type);
}
@JsonIgnore
public Object getParam(String name) {
Map<String, Object> params = this.params;
return params != null ? params.get(name) : null;
}
public StringBuilder toString(StringBuilder sb) {
if (sb == null) {
sb = new StringBuilder();
......
......@@ -87,12 +87,6 @@ public final class TestUtilsV2 {
AtlasAttributeDef.Cardinality.SINGLE, 0, 1, false, false,
new ArrayList<AtlasConstraintDef>()));
deptTypeDef.getAttribute("employees").addConstraint(
new AtlasConstraintDef(
AtlasConstraintDef.CONSTRAINT_TYPE_MAPPED_FROM_REF, new HashMap<String, Object>() {{
put(AtlasConstraintDef.CONSTRAINT_PARAM_REF_ATTRIBUTE, "department");
}}));
AtlasEntityDef personTypeDef = AtlasTypeUtil.createClassTypeDef("Person", "Person"+_description, ImmutableSet.<String>of(),
AtlasTypeUtil.createUniqueRequiredAttrDef("name", "string"),
AtlasTypeUtil.createOptionalAttrDef("address", "Address"),
......@@ -126,8 +120,8 @@ public final class TestUtilsV2 {
employeeTypeDef.getAttribute("department").addConstraint(
new AtlasConstraintDef(
AtlasConstraintDef.CONSTRAINT_TYPE_FOREIGN_KEY, new HashMap<String, Object>() {{
put(AtlasConstraintDef.CONSTRAINT_PARAM_ON_DELETE, AtlasConstraintDef.CONSTRAINT_PARAM_VAL_CASCADE);
AtlasConstraintDef.CONSTRAINT_TYPE_INVERSE_REF, new HashMap<String, Object>() {{
put(AtlasConstraintDef.CONSTRAINT_PARAM_ATTRIBUTE, "employees");
}}));
AtlasEntityDef managerTypeDef = AtlasTypeUtil.createClassTypeDef("Manager", "Manager"+_description, ImmutableSet.of("Employee"),
......@@ -480,8 +474,8 @@ public final class TestUtilsV2 {
false, false,
new ArrayList<AtlasStructDef.AtlasConstraintDef>() {{
add(new AtlasStructDef.AtlasConstraintDef(
AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_FOREIGN_KEY, new HashMap<String, Object>() {{
put(AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_ON_DELETE, AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_VAL_CASCADE);
AtlasConstraintDef.CONSTRAINT_TYPE_INVERSE_REF, new HashMap<String, Object>() {{
put(AtlasConstraintDef.CONSTRAINT_PARAM_ATTRIBUTE, "columns");
}}));
}})
);
......@@ -583,11 +577,7 @@ public final class TestUtilsV2 {
AtlasAttributeDef.Cardinality.SINGLE, 0, 1,
false, false,
new ArrayList<AtlasStructDef.AtlasConstraintDef>() {{
add(new AtlasStructDef.AtlasConstraintDef(
AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_MAPPED_FROM_REF,
new HashMap<String, Object>() {{
put(AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_REF_ATTRIBUTE, "table");
}}));
add(new AtlasStructDef.AtlasConstraintDef(AtlasConstraintDef.CONSTRAINT_TYPE_OWNED_REF));
}}),
// array of structs
new AtlasAttributeDef("partitions", String.format("array<%s>", "partition_struct_type"),
......
......@@ -52,11 +52,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_ON_DELETE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_VAL_CASCADE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_FOREIGN_KEY;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_MAPPED_FROM_REF;
/**
* StructDef store in v1 format.
*/
......@@ -503,18 +498,14 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
@VisibleForTesting
public static String toJsonFromAttribute(AtlasAttribute attribute) {
AtlasAttributeDef attributeDef = attribute.getAttributeDef();
boolean isComposite = attribute.legacyIsComposite();
String reverseAttribName = attribute.legacyReverseAttribute();
Map<String, Object> attribInfo = new HashMap<>();
attribInfo.put("name", attributeDef.getName());
attribInfo.put("dataType", attributeDef.getTypeName());
attribInfo.put("isUnique", attributeDef.getIsUnique());
attribInfo.put("isIndexable", attributeDef.getIsIndexable());
attribInfo.put("isComposite", isComposite);
attribInfo.put("reverseAttributeName", reverseAttribName);
attribInfo.put("isForeignKeyWithOnDeleteCascade", attribute.isForeignKeyWithOnDeleteCascade());
attribInfo.put("isComposite", attribute.isOwnedRef());
attribInfo.put("reverseAttributeName", attribute.getInverseRefAttribute());
final int lower;
final int upper;
......@@ -554,111 +545,16 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
ret.setIsUnique((Boolean) attribInfo.get("isUnique"));
ret.setIsIndexable((Boolean) attribInfo.get("isIndexable"));
String attrTypeName = ret.getTypeName();
if (AtlasTypeUtil.isArrayType(attrTypeName)) {
Set<String> typeNames = AtlasTypeUtil.getReferencedTypeNames(attrTypeName);
if (typeNames.size() > 0) {
attrTypeName = typeNames.iterator().next();
}
}
if (!AtlasTypeUtil.isBuiltInType(attrTypeName)) {
AtlasVertex attributeType = typeDefStore.findTypeVertexByName(attrTypeName);
/* determine constraints to add to this attribute
- add mappedFromRef if attribute-type has an attribute that refers to this attribute via reverseAttributeName
example: hive_table.sd referenced from hive_storagedesc.table with reverseAttributeName=sd
- add foreignKey(onDelete=cascade) if attribute-type has an attribute that refers to this struct with isComposite=true
example: hive_storagedesc referenced from hive_table.sd with isComposite=true
example: hive_column referenced from hive_table.columns with isComposite=true
*/
if (attributeType != null && typeDefStore.isTypeVertex(attributeType, TypeCategory.CLASS)) {
boolean attributeTypeHasIsCompositeRef = false;
String attributeTypeRevAttribRefFrom = null;
List<String> attrNames = attributeType.getProperty(AtlasGraphUtilsV1.getTypeDefPropertyKey(attrTypeName), List.class);
if (CollectionUtils.isNotEmpty(attrNames)) {
for (String attrName : attrNames) {
String attribJson = attributeType.getProperty(
AtlasGraphUtilsV1.getTypeDefPropertyKey(attrTypeName, attrName), String.class);
if (StringUtils.isBlank(attribJson)) {
continue;
}
Map refAttrInfo = AtlasType.fromJson(attribJson, Map.class);
if (refAttrInfo == null) {
continue;
}
String refAttribType = (String) refAttrInfo.get("dataType");
if (AtlasTypeUtil.isArrayType(refAttribType)) {
Set<String> typeNames = AtlasTypeUtil.getReferencedTypeNames(refAttribType);
if (typeNames.size() > 0) {
refAttribType = typeNames.iterator().next();
}
}
if (!StringUtils.equals(refAttribType, structDef.getName())) {
continue;
if ((Boolean)attribInfo.get("isComposite")) {
ret.addConstraint(new AtlasConstraintDef(AtlasConstraintDef.CONSTRAINT_TYPE_OWNED_REF));
}
if (StringUtils.isBlank(attributeTypeRevAttribRefFrom)) {
String refAttribRevAttribName = (String) refAttrInfo.get("reverseAttributeName");
if (StringUtils.equals(refAttribRevAttribName, ret.getName())) {
attributeTypeRevAttribRefFrom = (String) refAttrInfo.get("name");
}
}
if (!attributeTypeHasIsCompositeRef) {
Object val = refAttrInfo.get("isComposite");
if (val instanceof Boolean) {
attributeTypeHasIsCompositeRef = (Boolean) val;
} if (val != null) {
attributeTypeHasIsCompositeRef = Boolean.parseBoolean(val.toString());
}
}
if (StringUtils.isNotBlank(attributeTypeRevAttribRefFrom) && attributeTypeHasIsCompositeRef) {
break;
}
}
}
boolean isForeignKeyWithOnDeleteCascade = attributeTypeHasIsCompositeRef;
if (!isForeignKeyWithOnDeleteCascade) {
Object val = attribInfo.get("isForeignKeyWithOnDeleteCascade");
if (val instanceof Boolean) {
isForeignKeyWithOnDeleteCascade = (Boolean) val;
} else if (val != null) {
isForeignKeyWithOnDeleteCascade = Boolean.parseBoolean(val.toString());
}
}
if (StringUtils.isNotBlank(attributeTypeRevAttribRefFrom)) {
Map<String, Object> params = new HashMap<>();
params.put(AtlasConstraintDef.CONSTRAINT_PARAM_REF_ATTRIBUTE, attributeTypeRevAttribRefFrom);
ret.addConstraint(new AtlasConstraintDef(CONSTRAINT_TYPE_MAPPED_FROM_REF, params));
}
if (isForeignKeyWithOnDeleteCascade) { // ex: hive_column.table
Map<String, Object> params = new HashMap<>();
params.put(CONSTRAINT_PARAM_ON_DELETE, CONSTRAINT_PARAM_VAL_CASCADE);
ret.addConstraint(new AtlasConstraintDef(CONSTRAINT_TYPE_FOREIGN_KEY, params));
}
}
final String reverseAttributeName = (String) attribInfo.get("reverseAttributeName");
if (StringUtils.isNotBlank(reverseAttributeName)) {
ret.addConstraint(new AtlasConstraintDef(AtlasConstraintDef.CONSTRAINT_TYPE_INVERSE_REF,
new HashMap<String, Object>() {{
put(AtlasConstraintDef.CONSTRAINT_PARAM_ATTRIBUTE, reverseAttributeName);
}}));
}
Map multiplicity = AtlasType.fromJson((String) attribInfo.get("multiplicity"), Map.class);
......
......@@ -139,7 +139,7 @@ public abstract class DeleteHandlerV1 {
}
for (AtlasStructType.AtlasAttribute attributeInfo : entityType.getAllAttributes().values()) {
if (!entityType.isMappedFromRefAttribute(attributeInfo.getName())) {
if (! attributeInfo.isOwnedRef()) {
continue;
}
String edgeLabel = AtlasGraphUtilsV1.getAttributeEdgeLabel(entityType, attributeInfo.getName());
......@@ -284,7 +284,7 @@ public abstract class DeleteHandlerV1 {
for (AtlasStructType.AtlasAttribute attributeInfo : getAttributes(structType)) {
LOG.debug("Deleting attribute {} for {}", attributeInfo.getName(), string(instanceVertex));
boolean isComposite = isEntityType && ((AtlasEntityType)structType).isMappedFromRefAttribute(attributeInfo.getName());
boolean isComposite = isEntityType && attributeInfo.isOwnedRef();
AtlasType attrType = typeRegistry.getType(attributeInfo.getTypeName());
......
......@@ -88,7 +88,9 @@ public class StructVertexMapper implements InstanceGraphMapper<AtlasEdge> {
}
public static boolean shouldManageChildReferences(AtlasStructType type, String attributeName) {
return (type instanceof AtlasEntityType) && ((AtlasEntityType)type).isMappedFromRefAttribute(attributeName);
AtlasStructType.AtlasAttribute attribute = type.getAttribute(attributeName);
return attribute != null ? attribute.isOwnedRef() : false;
}
/**
......
......@@ -63,11 +63,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_ON_DELETE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_REF_ATTRIBUTE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_VAL_CASCADE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_FOREIGN_KEY;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_MAPPED_FROM_REF;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_INVERSE_REF;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_OWNED_REF;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_ATTRIBUTE;
/**
* A driver that sets up sample types and entities using v2 types and entity model for testing purposes.
......@@ -217,8 +215,8 @@ public class QuickStartV2 {
AtlasTypeUtil.createOptionalAttrDef("createTime", "long"));
AtlasEntityDef sdType = AtlasTypeUtil.createClassTypeDef(STORAGE_DESC_TYPE, STORAGE_DESC_TYPE, "1.0", null,
AtlasTypeUtil.createOptionalAttrDefWithConstraint("table", TABLE_TYPE, CONSTRAINT_TYPE_FOREIGN_KEY,
new HashMap<String, Object>() {{ put(CONSTRAINT_PARAM_ON_DELETE, CONSTRAINT_PARAM_VAL_CASCADE); }}),
AtlasTypeUtil.createOptionalAttrDefWithConstraint("table", TABLE_TYPE, CONSTRAINT_TYPE_INVERSE_REF,
new HashMap<String, Object>() {{ put(CONSTRAINT_PARAM_ATTRIBUTE, "sd"); }}),
AtlasTypeUtil.createOptionalAttrDef("location", "string"),
AtlasTypeUtil.createOptionalAttrDef("inputFormat", "string"),
AtlasTypeUtil.createOptionalAttrDef("outputFormat", "string"),
......@@ -228,15 +226,14 @@ public class QuickStartV2 {
AtlasTypeUtil.createOptionalAttrDef("name", "string"),
AtlasTypeUtil.createOptionalAttrDef("dataType", "string"),
AtlasTypeUtil.createOptionalAttrDef("comment", "string"),
AtlasTypeUtil.createOptionalAttrDefWithConstraint("table", TABLE_TYPE, CONSTRAINT_TYPE_FOREIGN_KEY,
new HashMap<String, Object>() {{ put(CONSTRAINT_PARAM_ON_DELETE, CONSTRAINT_PARAM_VAL_CASCADE); }}));
AtlasTypeUtil.createOptionalAttrDefWithConstraint("table", TABLE_TYPE, CONSTRAINT_TYPE_INVERSE_REF,
new HashMap<String, Object>() {{ put(CONSTRAINT_PARAM_ATTRIBUTE, "table"); }}));
colType.setOptions(new HashMap<String, String>() {{ put("schemaAttributes", "[\"name\", \"description\", \"owner\", \"type\", \"comment\", \"position\"]"); }});
AtlasEntityDef tblType = AtlasTypeUtil.createClassTypeDef(TABLE_TYPE, TABLE_TYPE, "1.0", ImmutableSet.of("DataSet"),
AtlasTypeUtil.createRequiredAttrDef("db", DATABASE_TYPE),
AtlasTypeUtil.createRequiredAttrDefWithConstraint("sd", STORAGE_DESC_TYPE, CONSTRAINT_TYPE_MAPPED_FROM_REF,
new HashMap<String, Object>() {{ put(CONSTRAINT_PARAM_REF_ATTRIBUTE, "table"); }}),
AtlasTypeUtil.createRequiredAttrDefWithConstraint("sd", STORAGE_DESC_TYPE, CONSTRAINT_TYPE_OWNED_REF, null),
AtlasTypeUtil.createOptionalAttrDef("owner", "string"),
AtlasTypeUtil.createOptionalAttrDef("createTime", "long"),
AtlasTypeUtil.createOptionalAttrDef("lastAccessTime", "long"),
......@@ -246,7 +243,7 @@ public class QuickStartV2 {
AtlasTypeUtil.createOptionalAttrDef("tableType", "string"),
AtlasTypeUtil.createOptionalAttrDef("temporary", "boolean"),
AtlasTypeUtil.createRequiredListAttrDefWithConstraint("columns", AtlasBaseTypeDef.getArrayTypeName(COLUMN_TYPE),
CONSTRAINT_TYPE_MAPPED_FROM_REF, new HashMap<String, Object>() {{ put(CONSTRAINT_PARAM_REF_ATTRIBUTE, "table"); }}));
CONSTRAINT_TYPE_OWNED_REF, null));
tblType.setOptions(new HashMap<String, String>() {{ put("schemaElementsAttribute", "columns"); }});
......
......@@ -19,21 +19,18 @@
package org.apache.atlas.util;
import static org.apache.atlas.AtlasErrorCode.INVALID_TYPE_DEFINITION;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_ON_DELETE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_VAL_CASCADE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_FOREIGN_KEY;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_MAPPED_FROM_REF;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_OWNED_REF;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_INVERSE_REF;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_ATTRIBUTE;
import static org.apache.atlas.type.AtlasTypeUtil.isArrayType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.model.typedef.AtlasEnumDef;
......@@ -45,7 +42,6 @@ import org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef;
import org.apache.atlas.model.typedef.AtlasTypeDefHeader;
import org.apache.atlas.model.typedef.AtlasTypesDef;
import org.apache.atlas.repository.store.graph.v1.AtlasStructDefStoreV1;
import org.apache.atlas.type.AtlasArrayType;
import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasEnumType;
......@@ -73,6 +69,13 @@ import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import static org.apache.atlas.AtlasErrorCode.INVALID_TYPE_DEFINITION;
import static org.apache.atlas.type.AtlasTypeUtil.isArrayType;
public final class RestUtils {
......@@ -307,85 +310,6 @@ public final class RestUtils {
AttributeDefinition[] attrDefinitions = classType.attributeDefinitions;
for (AttributeDefinition oldAttr : attrDefinitions) {
AtlasAttributeDef newAttr = toAtlasAttributeDef(oldAttr);
// isComposite and reverseAttributeName applicable only for entities/classes.
if (oldAttr.isComposite) {
String attrType = oldAttr.dataTypeName;
attrType = isArrayType(attrType) ? getArrayTypeName(attrType) : attrType;
if (!AtlasTypeUtil.isBuiltInType(attrType)) {
String refAttrName = null;
// 1. Check if attribute datatype is present in payload definition, if present get the typeDefinition,
// check all its attributes and find attribute that matches with classTypeDefName and reverseAttributeName
HierarchicalTypeDefinition<ClassType> refType = findClassType(classTypeDefinitions, attrType);
if (refType != null) {
for (AttributeDefinition refAttr : refType.attributeDefinitions) {
String refAttrDataTypeName = refAttr.dataTypeName;
String refAttrRevAttrName = refAttr.reverseAttributeName;
if (StringUtils.equals(refAttrDataTypeName, classTypeDefName) &&
StringUtils.equals(refAttrRevAttrName, oldAttr.name)) {
refAttrName = refAttr.name;
break;
}
}
}
// 2. Check if attribute present in typeRegistry. If present fetch all attributes associated with the type and
// check revAttrName equals base type attr name AND classTypeDefName equals attribute name
else {
if (registry.isRegisteredType(attrType)) {
AtlasType atlasType = registry.getType(attrType);
if (isEntity(atlasType)) {
AtlasEntityType entityType = (AtlasEntityType) atlasType;
List<AtlasAttributeDef> atlasAttrDefs = entityType.getEntityDef().getAttributeDefs();
for (AtlasAttributeDef attrDef : atlasAttrDefs) {
boolean isForeignKey = entityType.isForeignKeyAttribute(attrDef.getName());
if (isForeignKey) {
AtlasType attribType = entityType.getAttributeType(attrDef.getName());
if (attribType != null) {
if (attribType.getTypeCategory() == TypeCategory.ARRAY) {
attribType = ((AtlasArrayType) attribType).getElementType();
}
if (attribType.getTypeCategory() == TypeCategory.ENTITY) {
String revAttrName = ((AtlasEntityType) attribType).
getMappedFromRefAttribute(entityType.getTypeName(), attrDef.getName());
if (StringUtils.equals(classTypeDefName, attrDef.getTypeName()) &&
StringUtils.equals(oldAttr.name, revAttrName)) {
refAttrName = attrDef.getName();
}
}
}
}
}
}
}
}
if (StringUtils.isNotBlank(refAttrName)) { // ex: hive_table.columns, hive_column.table
Map<String, Object> params = new HashMap<>();
params.put(AtlasConstraintDef.CONSTRAINT_PARAM_REF_ATTRIBUTE, refAttrName);
newAttr.addConstraint(new AtlasConstraintDef(CONSTRAINT_TYPE_MAPPED_FROM_REF, params));
} else { // ex: hive_table.partitionKeys, with no reverseAttribute-reference
newAttr.addConstraint(new AtlasConstraintDef(CONSTRAINT_TYPE_FOREIGN_KEY));
}
}
} else if (StringUtils.isNotEmpty(oldAttr.reverseAttributeName)) {
Map<String, Object> params = new HashMap<>();
params.put(CONSTRAINT_PARAM_ON_DELETE, CONSTRAINT_PARAM_VAL_CASCADE);
newAttr.addConstraint(new AtlasConstraintDef(CONSTRAINT_TYPE_FOREIGN_KEY, params));
}
attrDefs.add(newAttr);
}
......@@ -432,13 +356,23 @@ public final class RestUtils {
return ret.toArray(new EnumValue[ret.size()]);
}
private static AtlasAttributeDef toAtlasAttributeDef(AttributeDefinition attrDefinition) {
private static AtlasAttributeDef toAtlasAttributeDef(final AttributeDefinition attrDefinition) {
AtlasAttributeDef ret = new AtlasAttributeDef();
ret.setName(attrDefinition.name);
ret.setTypeName(attrDefinition.dataTypeName);
ret.setIsIndexable(attrDefinition.isIndexable);
ret.setIsUnique(attrDefinition.isUnique);
if (attrDefinition.isComposite) {
ret.addConstraint(new AtlasConstraintDef(CONSTRAINT_TYPE_OWNED_REF));
}
if (StringUtils.isNotBlank(attrDefinition.reverseAttributeName)) {
ret.addConstraint(new AtlasConstraintDef(CONSTRAINT_TYPE_INVERSE_REF,
new HashMap<String, Object>() {{
put(CONSTRAINT_PARAM_ATTRIBUTE, attrDefinition.reverseAttributeName);
}}));
}
// Multiplicity attribute mapping
Multiplicity multiplicity = attrDefinition.multiplicity;
......
......@@ -136,7 +136,7 @@ public class AtlasStructFormatConverter extends AtlasAbstractFormatConverter {
Object v1Value = null;
AtlasFormatConverter attrConverter = null;
if (attrType.getTypeCategory() == TypeCategory.ENTITY && !attr.legacyIsComposite()) {
if (attrType.getTypeCategory() == TypeCategory.ENTITY && !attr.isOwnedRef()) {
attrConverter = new AtlasObjectIdConverter(converterRegistry, typeRegistry);
v1Value = attrConverter.fromV2ToV1(v2Value, attrType, context);
} else {
......
......@@ -18,9 +18,9 @@
package org.apache.atlas.web.resources;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_ON_DELETE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_VAL_CASCADE;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_FOREIGN_KEY;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_OWNED_REF;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_TYPE_INVERSE_REF;
import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef.CONSTRAINT_PARAM_ATTRIBUTE;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
......@@ -408,11 +408,10 @@ public abstract class BaseResourceIT {
protected void createTypeDefinitionsV2() throws Exception {
AtlasConstraintDef isCompositeSourceConstraint = new AtlasConstraintDef(CONSTRAINT_TYPE_FOREIGN_KEY,
Collections.<String, Object>singletonMap(CONSTRAINT_PARAM_ON_DELETE, CONSTRAINT_PARAM_VAL_CASCADE));
AtlasConstraintDef isCompositeSourceConstraint = new AtlasConstraintDef(CONSTRAINT_TYPE_OWNED_REF);
AtlasConstraintDef isCompositeTargetConstraint = new AtlasConstraintDef(CONSTRAINT_TYPE_FOREIGN_KEY,
Collections.<String, Object>emptyMap());
AtlasConstraintDef isCompositeTargetConstraint = new AtlasConstraintDef(CONSTRAINT_TYPE_INVERSE_REF,
Collections.<String, Object>singletonMap(CONSTRAINT_PARAM_ATTRIBUTE, "randomTable"));
AtlasEntityDef dbClsTypeDef = AtlasTypeUtil.createClassTypeDef(
DATABASE_TYPE_V2,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment