Commit acfe9a48 by Madhan Neethiraj

ATLAS-1526: updated AtlasAttribute with helper methods to derive isComposite/reverseAttribute flags

parent 4f4ab9b9
......@@ -231,14 +231,7 @@
"name": "partitionKeys",
"typeName": "array<hive_column>",
"cardinality": "SINGLE",
"constraintDefs": [
{
"type": "foreignKey",
"params": {
"onDelete": "update"
}
}
],
"constraintDefs": [],
"isIndexable": false,
"isOptional": true,
"isUnique": false
......@@ -255,14 +248,7 @@
"name": "columns",
"typeName": "array<hive_column>",
"cardinality": "SINGLE",
"constraintDefs": [
{
"type": "foreignKey",
"params": {
"onDelete": "update"
}
}
],
"constraintDefs": [],
"isIndexable": false,
"isOptional": true,
"isUnique": false
......
......@@ -54,11 +54,7 @@
"name": "nodes",
"typeName": "array<storm_node>",
"cardinality": "LIST",
"constraintDefs": [
{
"type": "foreignKey"
}
],
"constraintDefs": [],
"isIndexable": false,
"isOptional": false,
"isUnique": false
......
......@@ -470,7 +470,6 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
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_PARAM_VAL_UPDATE = "update";
private String type; // foreignKey/mappedFromRef/valueInRange
private Map<String, Object> params; // onDelete=cascade/refAttribute=attr2/min=0,max=23
......
......@@ -20,7 +20,6 @@ package org.apache.atlas.type;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasObjectId;
import org.apache.atlas.model.typedef.AtlasEntityDef;
......@@ -134,7 +133,7 @@ public class AtlasEntityType extends AtlasStructType {
for (Map.Entry<String, AtlasAttribute> e : mappedFromRefAttributes.entrySet()) {
AtlasAttribute attribute = e.getValue();
if(StringUtils.equals(attribute.getStructType().getTypeName(), typeName) && StringUtils.equals(attribute.getName(), attribName)) {
if(StringUtils.equals(attribute.getDefinedInType().getTypeName(), typeName) && StringUtils.equals(attribute.getName(), attribName)) {
ret = e.getKey();
break;
......@@ -358,11 +357,11 @@ public class AtlasEntityType extends AtlasStructType {
AtlasType attribType = attribute.getAttributeType();
if (attribType.getTypeCategory() == TypeCategory.ARRAY) {
if (attribType instanceof AtlasArrayType) {
attribType = ((AtlasArrayType)attribType).getElementType();
}
if (attribType.getTypeCategory() != TypeCategory.ENTITY) {
if (!(attribType instanceof AtlasEntityType)) {
throw new AtlasBaseException(AtlasErrorCode.CONSTRAINT_NOT_SATISFIED, getTypeName(),
attribDef.getName(), CONSTRAINT_TYPE_MAPPED_FROM_REF,
attribDef.getTypeName());
......@@ -427,11 +426,23 @@ public class AtlasEntityType extends AtlasStructType {
public String toTypeName() { return fromAttribute.getTypeName(); }
public AtlasStructType fromType() { return fromAttribute.getStructType(); }
public AtlasStructType fromType() { return fromAttribute.getDefinedInType(); }
public AtlasAttribute fromAttribute() { return fromAttribute; }
public AtlasEntityType toType() { return (AtlasEntityType)fromAttribute.getAttributeType(); }
public AtlasEntityType toType() {
AtlasType attrType = fromAttribute.getAttributeType();
if (attrType instanceof AtlasArrayType) {
attrType = ((AtlasArrayType)attrType).getElementType();
}
if (attrType instanceof AtlasEntityType) {
return (AtlasEntityType)attrType;
}
return null;
}
public AtlasConstraintDef getConstraint() { return refConstraint; }
......@@ -439,10 +450,6 @@ public class AtlasEntityType extends AtlasStructType {
return StringUtils.equals(getOnDeleteAction(), CONSTRAINT_PARAM_VAL_CASCADE);
}
public boolean isOnDeleteUpdate() {
return StringUtils.equals(getOnDeleteAction(), CONSTRAINT_PARAM_VAL_UPDATE);
}
private String getOnDeleteAction() {
Map<String, Object> params = refConstraint.getParams();
......
......@@ -19,12 +19,12 @@ package org.apache.atlas.type;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasStruct;
import org.apache.atlas.model.typedef.AtlasStructDef;
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.type.AtlasEntityType.ForeignKeyReference;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
......@@ -38,7 +38,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* class that implements behaviour of a struct-type.
*/
......@@ -109,11 +108,6 @@ public class AtlasStructType extends AtlasType {
AtlasConstraintDef.CONSTRAINT_PARAM_VAL_CASCADE);
}
public boolean isForeignKeyOnDeleteActionUpdate(String attributeName) {
return StringUtils.equals(getForeignKeyOnDeleteAction(attributeName),
AtlasConstraintDef.CONSTRAINT_PARAM_VAL_UPDATE);
}
@Override
public void resolveReferences(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
Map<String, AtlasAttribute> a = new HashMap<>();
......@@ -153,10 +147,14 @@ public class AtlasStructType extends AtlasType {
AtlasAttribute attribute = getAttribute(attributeName);
AtlasConstraintDef constraint = e.getValue();
AtlasType attributeType = attribute.getAttributeType();
AtlasType attrType = attribute.getAttributeType();
if (attrType instanceof AtlasArrayType) {
attrType = ((AtlasArrayType)attrType).getElementType();
}
if (attributeType instanceof AtlasEntityType) {
((AtlasEntityType)attributeType).addForeignKeyReference(attribute, constraint);
if (attrType instanceof AtlasEntityType) {
((AtlasEntityType)attrType).addForeignKeyReference(attribute, constraint);
}
}
}
......@@ -406,21 +404,21 @@ public class AtlasStructType extends AtlasType {
continue;
}
if (this.getTypeCategory() != TypeCategory.ENTITY) {
if (!(this instanceof AtlasEntityType)) {
throw new AtlasBaseException(AtlasErrorCode.UNSUPPORTED_CONSTRAINT,
AtlasConstraintDef.CONSTRAINT_TYPE_FOREIGN_KEY, getTypeName(), attribute.getName());
}
AtlasType attribType = attribute.getAttributeType();
AtlasType attrType = attribute.getAttributeType();
if (attribType.getTypeCategory() == TypeCategory.ARRAY) {
attribType = ((AtlasArrayType) attribType).getElementType();
if (attrType instanceof AtlasArrayType) {
attrType = ((AtlasArrayType) attrType).getElementType();
}
if (attribType.getTypeCategory() != TypeCategory.ENTITY) {
if (!(attrType instanceof AtlasEntityType)) {
throw new AtlasBaseException(AtlasErrorCode.CONSTRAINT_NOT_SATISFIED,
getTypeName(), attribute.getName(), AtlasConstraintDef.CONSTRAINT_TYPE_FOREIGN_KEY,
attribType.getTypeName());
attrType.getTypeName());
}
if (ret == null) {
......@@ -446,21 +444,21 @@ public class AtlasStructType extends AtlasType {
public static class AtlasAttribute {
private final AtlasStructType structType;
private final AtlasStructType definedInType;
private final AtlasType attributeType;
private final AtlasAttributeDef attributeDef;
private final String qualifiedName;
public AtlasAttribute(AtlasStructType structType, AtlasAttributeDef attrDef, AtlasType attributeType) {
this.structType = structType;
public AtlasAttribute(AtlasStructType definedInType, AtlasAttributeDef attrDef, AtlasType attributeType) {
this.definedInType = definedInType;
this.attributeDef = attrDef;
this.attributeType = attributeType;
this.qualifiedName = getQualifiedAttributeName(structType.getStructDef(), attributeDef.getName());
this.qualifiedName = getQualifiedAttributeName(definedInType.getStructDef(), attributeDef.getName());
}
public AtlasStructType getStructType() { return structType; }
public AtlasStructType getDefinedInType() { return definedInType; }
public AtlasStructDef getStructDef() { return structType.getStructDef(); }
public AtlasStructDef getDefinedInDef() { return definedInType.getStructDef(); }
public AtlasType getAttributeType() {
return attributeType;
......@@ -480,20 +478,73 @@ public class AtlasStructType extends AtlasType {
return qualifiedName;
}
public boolean isForeignKeyWithOnDeleteCascade() {
return definedInType.isForeignKeyOnDeleteActionCascade(getName());
}
/*
* "isContainedAttribute" can not be computed and cached in the constructor - as structType is not fully
* true - if attribute-type has foreign-key(onDelete=cascade) reference to this type
* false - in all cases
*
* "legacyIsComposite" can not be computed and cached in the constructor - as definedInType is not fully
* populated at the time AtlasAttribute object is constructed.
*/
public boolean isContainedAttribute() {
if ( structType.isForeignKeyOnDeleteActionUpdate(attributeDef.getName()) ) {
return true;
public boolean legacyIsComposite() {
boolean ret = false;
if (definedInType instanceof AtlasEntityType) {
AtlasEntityType entityType = (AtlasEntityType) definedInType;
AtlasType attrType = attributeType;
if (attrType instanceof AtlasArrayType) {
attrType = ((AtlasArrayType)attrType).getElementType();
}
if ( structType instanceof AtlasEntityType) {
return ((AtlasEntityType) structType).isMappedFromRefAttribute(attributeDef.getName());
if (attrType instanceof AtlasEntityType) {
for (ForeignKeyReference fkRef : entityType.getForeignKeyReferences()) {
if (fkRef.isOnDeleteCascade() && StringUtils.equals(fkRef.fromTypeName(), attrType.getTypeName())) {
ret = true;
break;
}
}
}
}
return false;
if (LOG.isDebugEnabled()) {
LOG.debug("*** {}.{}: isComposite={} ***", definedInType.getTypeName(), getName(), ret);
}
return ret;
}
/*
* return the name of the attribute in attribute-type that has mappedFromRef constraint on this attribute
*
* "legacyReverseAttribute" can not be computed and cached in the constructor - as definedInType is not fully
* populated at the time AtlasAttribute object is constructed.
*/
public String legacyReverseAttribute() {
String ret = null;
if (definedInType instanceof AtlasEntityType) {
AtlasType attrType = attributeType;
if (attrType instanceof AtlasArrayType) {
attrType = ((AtlasArrayType)attrType).getElementType();
}
if (attrType instanceof AtlasEntityType) {
AtlasEntityType attribEntityType = (AtlasEntityType) attrType;
ret = attribEntityType.getMappedFromRefAttribute(definedInType.getTypeName(), getName());
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("*** {}.{}: reverseAttribute={} ***", definedInType.getTypeName(), getName(), ret);
}
return ret;
}
public static String getQualifiedAttributeName(AtlasStructDef structDef, String attrName) {
......
......@@ -154,7 +154,6 @@ public class TestAtlasEntityType {
assertEquals(fkRef.fromAttributeName(), ATTR_TABLE);
assertEquals(fkRef.toTypeName(), TYPE_TABLE);
assertTrue(fkRef.isOnDeleteCascade());
assertFalse(fkRef.isOnDeleteUpdate());
assertEquals(typeTable.getForeignKeyAttributes().size(), 0);
assertEquals(typeTable.getMappedFromRefAttributes().size(), 1);
......
......@@ -160,11 +160,11 @@ public class GraphMutationContext {
}
public AtlasStructType getParentType() {
return attribute.getStructType();
return attribute.getDefinedInType();
}
public AtlasStructDef getStructDef() {
return attribute.getStructDef();
return attribute.getDefinedInDef();
}
public AtlasAttributeDef getAttributeDef() {
......
......@@ -93,6 +93,10 @@ public class TypesUtil {
return new StructTypeDefinition(name, description, attrDefs);
}
public static StructTypeDefinition createStructTypeDef(String name, String description, String version, AttributeDefinition... attrDefs) {
return new StructTypeDefinition(name, description, version, attrDefs);
}
public static HierarchicalTypeDefinition<ClassType> createClassTypeDef(String name,
ImmutableSet<String> superTypes, AttributeDefinition... attrDefs) {
return createClassTypeDef(name, null, superTypes, attrDefs);
......
......@@ -136,7 +136,7 @@ public class AtlasStructFormatConverter extends AtlasAbstractFormatConverter {
Object v1Value = null;
AtlasFormatConverter attrConverter = null;
if (attrType.getTypeCategory() == TypeCategory.ENTITY && !attr.isContainedAttribute()) {
if (attrType.getTypeCategory() == TypeCategory.ENTITY && !attr.legacyIsComposite()) {
attrConverter = new AtlasObjectIdConverter(converterRegistry, typeRegistry);
v1Value = attrConverter.fromV2ToV1(v2Value, attrType, context);
} else {
......
......@@ -21,17 +21,10 @@ package org.apache.atlas.web.resources;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.core.ResourceContext;
import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasException;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.atlas.model.typedef.AtlasEnumDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasTypesDef;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.typesystem.TypesDef;
import org.apache.atlas.typesystem.exception.TypeExistsException;
import org.apache.atlas.typesystem.json.TypesSerialization;
import org.apache.atlas.util.RestUtils;
import org.apache.atlas.utils.AtlasPerfTracer;
......@@ -231,38 +224,12 @@ public class TypesResource {
perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "TypesResource.getDefinition(" + typeName + ")");
}
TypesREST typesRest = resourceContext.getResource(TypesREST.class);
JSONObject response = new JSONObject();
try {
TypeCategory typeCategory = typeRegistry.getType(typeName).getTypeCategory();
TypesDef typesDef = null;
if (typeCategory != null) {
switch (typeCategory) {
case ENUM:
AtlasEnumDef enumDef = typesRest.getEnumDefByName(typeName);
typesDef = RestUtils.toTypesDef(enumDef);
break;
case STRUCT:
AtlasStructDef structDef = typesRest.getStructDefByName(typeName);
typesDef = RestUtils.toTypesDef(structDef, typeRegistry);
break;
case ENTITY:
AtlasEntityDef entityDef = typesRest.getEntityDefByName(typeName);
typesDef = RestUtils.toTypesDef(entityDef, typeRegistry);
break;
case CLASSIFICATION:
AtlasClassificationDef classificationDef = typesRest.getClassificationDefByName(typeName);
typesDef = RestUtils.toTypesDef(classificationDef, typeRegistry);
break;
default:
typesDef = new TypesDef();
break;
}
}
TypesDef typesDef = RestUtils.toTypesDef(typeRegistry.getType(typeName), typeRegistry);;
String typeDefinition = TypesSerialization.toJson(typesDef);
final String typeDefinition = TypesSerialization.toJson(typesDef);
response.put(AtlasClient.TYPENAME, typeName);
response.put(AtlasClient.DEFINITION, new JSONObject(typeDefinition));
response.put(AtlasClient.REQUEST_ID, Servlets.getRequestId());
......
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