Commit 5900fcb0 by Sarath Subramanian

ATLAS-2119: Implement update and delete operations for RelationshipREST

parent 84f4f103
...@@ -119,6 +119,7 @@ public enum AtlasErrorCode { ...@@ -119,6 +119,7 @@ public enum AtlasErrorCode {
RELATIONSHIP_GUID_NOT_FOUND(404, "ATLAS-404-00-00C", "Given relationship guid {0} is invalid/not found"), RELATIONSHIP_GUID_NOT_FOUND(404, "ATLAS-404-00-00C", "Given relationship guid {0} is invalid/not found"),
RELATIONSHIP_CRUD_INVALID_PARAMS(404, "ATLAS-404-00-00D", "Invalid relationship creation/updation parameters passed : {0}"), RELATIONSHIP_CRUD_INVALID_PARAMS(404, "ATLAS-404-00-00D", "Invalid relationship creation/updation parameters passed : {0}"),
RELATIONSHIPDEF_END_TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-00E", "RelationshipDef {0} endDef typename {0} cannot be found"), RELATIONSHIPDEF_END_TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-00E", "RelationshipDef {0} endDef typename {0} cannot be found"),
RELATIONSHIP_ALREADY_DELETED(404, "ATLAS-404-00-00F", "Attempting to delete a relationship which is already deleted : {0}"),
// All data conflict errors go here // All data conflict errors go here
TYPE_ALREADY_EXISTS(409, "ATLAS-409-00-001", "Given type {0} already exists"), TYPE_ALREADY_EXISTS(409, "ATLAS-409-00-001", "Given type {0} already exists"),
......
...@@ -24,6 +24,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; ...@@ -24,6 +24,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.apache.atlas.model.typedef.AtlasRelationshipDef; import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessorType;
...@@ -49,16 +50,17 @@ import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ ...@@ -49,16 +50,17 @@ import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_
public class AtlasRelationship extends AtlasStruct implements Serializable { public class AtlasRelationship extends AtlasStruct implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private String guid = null; private String guid = null;
private AtlasObjectId end1 = null; private AtlasObjectId end1 = null;
private AtlasObjectId end2 = null; private AtlasObjectId end2 = null;
private String label = null; private String label = null;
private Status status = Status.ACTIVE; private PropagateTags propagateTags = PropagateTags.NONE;
private String createdBy = null; private Status status = Status.ACTIVE;
private String updatedBy = null; private String createdBy = null;
private Date createTime = null; private String updatedBy = null;
private Date updateTime = null; private Date createTime = null;
private Long version = 0L; private Date updateTime = null;
private Long version = 0L;
public enum Status { ACTIVE, DELETED } public enum Status { ACTIVE, DELETED }
...@@ -84,13 +86,13 @@ public class AtlasRelationship extends AtlasStruct implements Serializable { ...@@ -84,13 +86,13 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
public AtlasRelationship(String typeName, AtlasObjectId end1, AtlasObjectId end2) { public AtlasRelationship(String typeName, AtlasObjectId end1, AtlasObjectId end2) {
super(typeName); super(typeName);
init(nextInternalId(), end1, end2, null, null, null, null, null, null, 0L); init(nextInternalId(), end1, end2, null, null, null, null, null, null, null, 0L);
} }
public AtlasRelationship(String typeName, AtlasObjectId end1, AtlasObjectId end2, Map<String, Object> attributes) { public AtlasRelationship(String typeName, AtlasObjectId end1, AtlasObjectId end2, Map<String, Object> attributes) {
super(typeName, attributes); super(typeName, attributes);
init(nextInternalId(), end1, end2, null, null, null, null, null, null, 0L); init(nextInternalId(), end1, end2, null, null, null, null, null, null, null, 0L);
} }
public AtlasRelationship(String typeName, String attrName, Object attrValue) { public AtlasRelationship(String typeName, String attrName, Object attrValue) {
...@@ -107,8 +109,8 @@ public class AtlasRelationship extends AtlasStruct implements Serializable { ...@@ -107,8 +109,8 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
super(other); super(other);
if (other != null) { if (other != null) {
init(other.guid, other.end1, other.end2, other.label, other.status, other.createdBy, other.updatedBy, init(other.guid, other.end1, other.end2, other.label, other.propagateTags, other.status,
other.createTime, other.updateTime, other.version); other.createdBy, other.updatedBy, other.createTime, other.updateTime, other.version);
} }
} }
...@@ -180,21 +182,25 @@ public class AtlasRelationship extends AtlasStruct implements Serializable { ...@@ -180,21 +182,25 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
public void setLabel(String label) { this.label = label; } public void setLabel(String label) { this.label = label; }
public PropagateTags getPropagateTags() { return propagateTags; }
public void setPropagateTags(PropagateTags propagateTags) { this.propagateTags = propagateTags; }
private static String nextInternalId() { private static String nextInternalId() {
return "-" + Long.toString(s_nextId.getAndIncrement()); return "-" + Long.toString(s_nextId.getAndIncrement());
} }
private void init() { private void init() {
init(nextInternalId(), null, null, null, null, null, null, null, null, 0L); init(nextInternalId(), null, null, null, null, null, null, null, null, null, 0L);
} }
private void init(String guid, AtlasObjectId end1, AtlasObjectId end2, String label, private void init(String guid, AtlasObjectId end1, AtlasObjectId end2, String label, PropagateTags propagateTags,
Status status, String createdBy, String updatedBy, Status status, String createdBy, String updatedBy, Date createTime, Date updateTime, Long version) {
Date createTime, Date updateTime, Long version) {
setGuid(guid); setGuid(guid);
setEnd1(end1); setEnd1(end1);
setEnd2(end2); setEnd2(end2);
setLabel(label); setLabel(label);
setPropagateTags(propagateTags);
setStatus(status); setStatus(status);
setCreatedBy(createdBy); setCreatedBy(createdBy);
setUpdatedBy(updatedBy); setUpdatedBy(updatedBy);
...@@ -215,6 +221,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable { ...@@ -215,6 +221,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
sb.append(", end1=").append(end1); sb.append(", end1=").append(end1);
sb.append(", end2=").append(end2); sb.append(", end2=").append(end2);
sb.append(", label='").append(label).append('\''); sb.append(", label='").append(label).append('\'');
sb.append(", propagateTags=").append(propagateTags);
sb.append(", status=").append(status); sb.append(", status=").append(status);
sb.append(", createdBy='").append(createdBy).append('\''); sb.append(", createdBy='").append(createdBy).append('\'');
sb.append(", updatedBy='").append(updatedBy).append('\''); sb.append(", updatedBy='").append(updatedBy).append('\'');
...@@ -233,22 +240,23 @@ public class AtlasRelationship extends AtlasStruct implements Serializable { ...@@ -233,22 +240,23 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
if (!super.equals(o)) { return false; } if (!super.equals(o)) { return false; }
AtlasRelationship that = (AtlasRelationship) o; AtlasRelationship that = (AtlasRelationship) o;
return Objects.equals(guid, that.guid) && return Objects.equals(guid, that.guid) &&
Objects.equals(end1, that.end1) && Objects.equals(end1, that.end1) &&
Objects.equals(end2, that.end2) && Objects.equals(end2, that.end2) &&
Objects.equals(label, that.label) && Objects.equals(label, that.label) &&
status == that.status && propagateTags == that.propagateTags &&
Objects.equals(createdBy, that.createdBy) && status == that.status &&
Objects.equals(updatedBy, that.updatedBy) && Objects.equals(createdBy, that.createdBy) &&
Objects.equals(createTime, that.createTime) && Objects.equals(updatedBy, that.updatedBy) &&
Objects.equals(updateTime, that.updateTime) && Objects.equals(createTime, that.createTime) &&
Objects.equals(version, that.version); Objects.equals(updateTime, that.updateTime) &&
Objects.equals(version, that.version);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(super.hashCode(), guid, end1, end2, label, status, createdBy, return Objects.hash(super.hashCode(), guid, end1, end2, label, propagateTags,
updatedBy, createTime, updateTime, version); status, createdBy, updatedBy, createTime, updateTime, version);
} }
@Override @Override
......
...@@ -33,6 +33,7 @@ import org.apache.atlas.model.typedef.AtlasRelationshipDef; ...@@ -33,6 +33,7 @@ import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.v1.model.instance.Id; import org.apache.atlas.v1.model.instance.Id;
import org.apache.atlas.v1.model.instance.Referenceable; import org.apache.atlas.v1.model.instance.Referenceable;
import org.apache.atlas.type.AtlasStructType.AtlasAttribute; import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
import org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection; import org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection;
import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.RepositoryException; import org.apache.atlas.repository.RepositoryException;
...@@ -722,6 +723,12 @@ public final class GraphHelper { ...@@ -722,6 +723,12 @@ public final class GraphHelper {
return (getState(element) == Id.EntityState.DELETED) ? AtlasRelationship.Status.DELETED : AtlasRelationship.Status.ACTIVE; return (getState(element) == Id.EntityState.DELETED) ? AtlasRelationship.Status.DELETED : AtlasRelationship.Status.ACTIVE;
} }
public static PropagateTags getPropagateTags(AtlasElement element) {
String propagateTags = element.getProperty(Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, String.class);
return (propagateTags == null) ? null : PropagateTags.valueOf(propagateTags);
}
//Added conditions in fetching system attributes to handle test failures in GremlinTest where these properties are not set //Added conditions in fetching system attributes to handle test failures in GremlinTest where these properties are not set
public static String getCreatedByAsString(AtlasElement element){ public static String getCreatedByAsString(AtlasElement element){
return element.getProperty(Constants.CREATED_BY_KEY, String.class); return element.getProperty(Constants.CREATED_BY_KEY, String.class);
......
...@@ -103,6 +103,10 @@ public class AtlasGraphUtilsV1 { ...@@ -103,6 +103,10 @@ public class AtlasGraphUtilsV1 {
return vertex.getProperty(Constants.GUID_PROPERTY_KEY, String.class); return vertex.getProperty(Constants.GUID_PROPERTY_KEY, String.class);
} }
public static String getIdFromEdge(AtlasEdge edge) {
return edge.getProperty(Constants.GUID_PROPERTY_KEY, String.class);
}
public static String getTypeName(AtlasElement element) { public static String getTypeName(AtlasElement element) {
return element.getProperty(Constants.ENTITY_TYPE_PROPERTY_KEY, String.class); return element.getProperty(Constants.ENTITY_TYPE_PROPERTY_KEY, String.class);
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
package org.apache.atlas.repository.store.graph.v1; package org.apache.atlas.repository.store.graph.v1;
import com.google.common.collect.ImmutableSet;
import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.annotation.GraphTransaction; import org.apache.atlas.annotation.GraphTransaction;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
...@@ -24,6 +25,7 @@ import org.apache.atlas.model.TypeCategory; ...@@ -24,6 +25,7 @@ import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.instance.AtlasObjectId; import org.apache.atlas.model.instance.AtlasObjectId;
import org.apache.atlas.model.instance.AtlasRelationship; import org.apache.atlas.model.instance.AtlasRelationship;
import org.apache.atlas.model.typedef.AtlasRelationshipDef; import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
import org.apache.atlas.model.typedef.AtlasRelationshipEndDef; import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.RepositoryException; import org.apache.atlas.repository.RepositoryException;
...@@ -44,6 +46,7 @@ import org.springframework.stereotype.Component; ...@@ -44,6 +46,7 @@ import org.springframework.stereotype.Component;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
...@@ -52,7 +55,11 @@ import java.util.Objects; ...@@ -52,7 +55,11 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import static org.apache.atlas.model.instance.AtlasEntity.Status.DELETED;
import static org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags.ONE_TO_TWO;
import static org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags.TWO_TO_ONE;
import static org.apache.atlas.repository.graphdb.AtlasEdgeDirection.BOTH; import static org.apache.atlas.repository.graphdb.AtlasEdgeDirection.BOTH;
import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.getState;
import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.getTypeName; import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.getTypeName;
@Component @Component
...@@ -62,12 +69,14 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { ...@@ -62,12 +69,14 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore {
private final AtlasTypeRegistry typeRegistry; private final AtlasTypeRegistry typeRegistry;
private final EntityGraphRetriever entityRetriever; private final EntityGraphRetriever entityRetriever;
private final DeleteHandlerV1 deleteHandler;
private final GraphHelper graphHelper = GraphHelper.getInstance(); private final GraphHelper graphHelper = GraphHelper.getInstance();
@Inject @Inject
public AtlasRelationshipStoreV1(AtlasTypeRegistry typeRegistry) { public AtlasRelationshipStoreV1(AtlasTypeRegistry typeRegistry, DeleteHandlerV1 deleteHandler) {
this.typeRegistry = typeRegistry; this.typeRegistry = typeRegistry;
this.entityRetriever = new EntityGraphRetriever(typeRegistry); this.entityRetriever = new EntityGraphRetriever(typeRegistry);
this.deleteHandler = deleteHandler;
} }
@Override @Override
...@@ -97,9 +106,16 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { ...@@ -97,9 +106,16 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore {
LOG.debug("==> update({})", relationship); LOG.debug("==> update({})", relationship);
} }
AtlasRelationship ret = null; String guid = relationship.getGuid();
if (StringUtils.isEmpty(guid)) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_GUID_NOT_FOUND, guid);
}
validateRelationship(relationship);
AtlasRelationship ret = updateRelationship(relationship);
// TODO: update(relationship) implementation
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("<== update({}): {}", relationship, ret); LOG.debug("<== update({}): {}", relationship, ret);
...@@ -135,7 +151,21 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { ...@@ -135,7 +151,21 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore {
LOG.debug("==> deleteById({})", guid); LOG.debug("==> deleteById({})", guid);
} }
// TODO: deleteById(guid) implementation if (StringUtils.isEmpty(guid)) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_CRUD_INVALID_PARAMS, " empty/null guid");
}
AtlasEdge edge = graphHelper.getEdgeForGUID(guid);
if (edge == null) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_GUID_NOT_FOUND, guid);
}
if (getState(edge) == DELETED) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_ALREADY_DELETED, guid);
}
deleteHandler.deleteRelationships(Collections.singleton(edge));
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("<== deleteById({}): {}", guid); LOG.debug("<== deleteById({}): {}", guid);
...@@ -206,6 +236,33 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { ...@@ -206,6 +236,33 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore {
return ret; return ret;
} }
private AtlasRelationship updateRelationship(AtlasRelationship relationship) throws AtlasBaseException {
AtlasEdge relationshipEdge = graphHelper.getEdgeForGUID(relationship.getGuid());
if (relationshipEdge == null) {
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_GUID_NOT_FOUND, relationship.getGuid());
}
AtlasRelationshipType relationType = typeRegistry.getRelationshipTypeByName(relationship.getTypeName());
AtlasGraphUtilsV1.setProperty(relationshipEdge, Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, relationship.getPropagateTags().name());
if (MapUtils.isNotEmpty(relationType.getAllAttributes())) {
for (AtlasAttribute attr : relationType.getAllAttributes().values()) {
String attrName = attr.getName();
String attrVertexProperty = attr.getVertexPropertyName();
if (relationship.hasAttribute(attrName)) {
Object attrValue = relationship.getAttribute(attrName);
AtlasGraphUtilsV1.setProperty(relationshipEdge, attrVertexProperty, attrValue);
}
}
}
return entityRetriever.mapEdgeToAtlasRelationship(relationshipEdge);
}
private void validateRelationship(AtlasRelationship relationship) throws AtlasBaseException { private void validateRelationship(AtlasRelationship relationship) throws AtlasBaseException {
if (relationship == null) { if (relationship == null) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "AtlasRelationship is null"); throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "AtlasRelationship is null");
...@@ -252,38 +309,44 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { ...@@ -252,38 +309,44 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("validateEnds entry relationship:" + relationship); LOG.debug("validateEnds entry relationship:" + relationship);
} }
List<AtlasObjectId> ends = new ArrayList<>(); List<AtlasObjectId> ends = new ArrayList<>();
List<AtlasRelationshipEndDef> endDefs = new ArrayList<>(); List<AtlasRelationshipEndDef> endDefs = new ArrayList<>();
String relationshipTypeName = relationship.getTypeName(); String relationshipTypeName = relationship.getTypeName();
AtlasRelationshipDef relationshipDef = typeRegistry.getRelationshipDefByName(relationshipTypeName); AtlasRelationshipDef relationshipDef = typeRegistry.getRelationshipDefByName(relationshipTypeName);
ends.add(relationship.getEnd1()); ends.add(relationship.getEnd1());
ends.add(relationship.getEnd2()); ends.add(relationship.getEnd2());
endDefs.add(relationshipDef.getEndDef1()); endDefs.add(relationshipDef.getEndDef1());
endDefs.add(relationshipDef.getEndDef2()); endDefs.add(relationshipDef.getEndDef2());
for (int i = 0; i < ends.size(); i++) { for (int i = 0; i < ends.size(); i++) {
AtlasObjectId end = ends.get(i); AtlasObjectId end = ends.get(i);
String guid = end.getGuid(); String guid = end.getGuid();
String typeName = end.getTypeName(); String typeName = end.getTypeName();
Map<String, Object> uniqueAttributes = end.getUniqueAttributes(); Map<String, Object> uniqueAttributes = end.getUniqueAttributes();
AtlasVertex endVertex = AtlasGraphUtilsV1.findByGuid(guid); AtlasVertex endVertex = AtlasGraphUtilsV1.findByGuid(guid);
if (!AtlasTypeUtil.isValidGuid(guid) || endVertex == null) { if (!AtlasTypeUtil.isValidGuid(guid) || endVertex == null) {
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid); throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
} else if (MapUtils.isNotEmpty(uniqueAttributes)) { } else if (MapUtils.isNotEmpty(uniqueAttributes)) {
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName); AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName);
if (AtlasGraphUtilsV1.findByUniqueAttributes(entityType, uniqueAttributes) == null) { if (AtlasGraphUtilsV1.findByUniqueAttributes(entityType, uniqueAttributes) == null) {
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND, typeName, uniqueAttributes.toString()); throw new AtlasBaseException(AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND, typeName, uniqueAttributes.toString());
} }
} else { } else {
// check whether the guid is the correct type // check whether the guid is the correct type
String vertexTypeName = endVertex.getProperty(Constants.TYPE_NAME_PROPERTY_KEY, String.class); String vertexTypeName = endVertex.getProperty(Constants.TYPE_NAME_PROPERTY_KEY, String.class);
if (!Objects.equals(vertexTypeName, typeName)) { if (!Objects.equals(vertexTypeName, typeName)) {
String attrName = endDefs.get(i).getName(); String attrName = endDefs.get(i).getName();
throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_INVALID_ENDTYPE, attrName, guid, vertexTypeName, typeName); throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_INVALID_ENDTYPE, attrName, guid, vertexTypeName, typeName);
} }
} }
} }
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("validateEnds exit successfully validated relationship:" + relationship); LOG.debug("validateEnds exit successfully validated relationship:" + relationship);
} }
...@@ -350,11 +413,10 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { ...@@ -350,11 +413,10 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore {
return ret; return ret;
} }
private AtlasEdge createRelationshipEdge(AtlasVertex fromVertex, AtlasVertex toVertex, AtlasRelationship relationship) private AtlasEdge createRelationshipEdge(AtlasVertex fromVertex, AtlasVertex toVertex, AtlasRelationship relationship) throws RepositoryException {
throws RepositoryException { String relationshipLabel = getRelationshipEdgeLabel(fromVertex, toVertex, relationship);
PropagateTags tagPropagation = getRelationshipTagPropagation(fromVertex, toVertex, relationship);
String relationshipLabel = getRelationshipEdgeLabel(fromVertex, toVertex, relationship); AtlasEdge ret = graphHelper.getOrCreateEdge(fromVertex, toVertex, relationshipLabel);
AtlasEdge ret = graphHelper.getOrCreateEdge(fromVertex, toVertex, relationshipLabel);
// map additional properties to relationship edge // map additional properties to relationship edge
if (ret != null) { if (ret != null) {
...@@ -363,6 +425,29 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { ...@@ -363,6 +425,29 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore {
AtlasGraphUtilsV1.setProperty(ret, Constants.ENTITY_TYPE_PROPERTY_KEY, relationship.getTypeName()); AtlasGraphUtilsV1.setProperty(ret, Constants.ENTITY_TYPE_PROPERTY_KEY, relationship.getTypeName());
AtlasGraphUtilsV1.setProperty(ret, Constants.GUID_PROPERTY_KEY, guid); AtlasGraphUtilsV1.setProperty(ret, Constants.GUID_PROPERTY_KEY, guid);
AtlasGraphUtilsV1.setProperty(ret, Constants.VERSION_PROPERTY_KEY, getRelationshipVersion(relationship)); AtlasGraphUtilsV1.setProperty(ret, Constants.VERSION_PROPERTY_KEY, getRelationshipVersion(relationship));
AtlasGraphUtilsV1.setProperty(ret, Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, tagPropagation.name());
}
return ret;
}
private PropagateTags getRelationshipTagPropagation(AtlasVertex fromVertex, AtlasVertex toVertex, AtlasRelationship relationship) {
AtlasRelationshipType relationshipType = typeRegistry.getRelationshipTypeByName(relationship.getTypeName());
AtlasRelationshipEndDef endDef1 = relationshipType.getRelationshipDef().getEndDef1();
AtlasRelationshipEndDef endDef2 = relationshipType.getRelationshipDef().getEndDef2();
Set<String> fromVertexTypes = getTypeAndAllSuperTypes(getTypeName(fromVertex));
Set<String> toVertexTypes = getTypeAndAllSuperTypes(getTypeName(toVertex));
PropagateTags ret = relationshipType.getRelationshipDef().getPropagateTags();
// relationshipDef is defined as end1 (hive_db) and end2 (hive_table) and tagPropagation = ONE_TO_TWO
// relationship edge exists from [hive_table --> hive_db]
// swap the tagPropagation property for such cases.
if (fromVertexTypes.contains(endDef2.getType()) && toVertexTypes.contains(endDef1.getType())) {
if (ret == ONE_TO_TWO) {
ret = TWO_TO_ONE;
} else if (ret == TWO_TO_ONE) {
ret = ONE_TO_TWO;
}
} }
return ret; return ret;
......
...@@ -40,7 +40,6 @@ import org.apache.atlas.type.AtlasStructType.AtlasAttribute; ...@@ -40,7 +40,6 @@ import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
import org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection; import org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection;
import org.apache.atlas.type.AtlasType; import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -54,14 +53,13 @@ import java.util.List; ...@@ -54,14 +53,13 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.Stack; import java.util.Stack;
import static org.apache.atlas.model.instance.AtlasEntity.Status.DELETED;
import static org.apache.atlas.repository.graph.GraphHelper.EDGE_LABEL_PREFIX; import static org.apache.atlas.repository.graph.GraphHelper.EDGE_LABEL_PREFIX;
import static org.apache.atlas.repository.graph.GraphHelper.getAtlasObjectIdForInVertex;
import static org.apache.atlas.repository.graph.GraphHelper.getAtlasObjectIdForOutVertex;
import static org.apache.atlas.repository.graph.GraphHelper.getGuid;
import static org.apache.atlas.repository.graph.GraphHelper.getReferenceObjectId; import static org.apache.atlas.repository.graph.GraphHelper.getReferenceObjectId;
import static org.apache.atlas.repository.graph.GraphHelper.isRelationshipEdge; import static org.apache.atlas.repository.graph.GraphHelper.isRelationshipEdge;
import static org.apache.atlas.repository.graph.GraphHelper.string; import static org.apache.atlas.repository.graph.GraphHelper.string;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.BOTH; import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.getIdFromEdge;
import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.getState;
public abstract class DeleteHandlerV1 { public abstract class DeleteHandlerV1 {
...@@ -94,9 +92,9 @@ public abstract class DeleteHandlerV1 { ...@@ -94,9 +92,9 @@ public abstract class DeleteHandlerV1 {
for (AtlasVertex instanceVertex : instanceVertices) { for (AtlasVertex instanceVertex : instanceVertices) {
String guid = AtlasGraphUtilsV1.getIdFromVertex(instanceVertex); String guid = AtlasGraphUtilsV1.getIdFromVertex(instanceVertex);
AtlasEntity.Status state = AtlasGraphUtilsV1.getState(instanceVertex); AtlasEntity.Status state = getState(instanceVertex);
if (state == AtlasEntity.Status.DELETED) { if (state == DELETED) {
LOG.debug("Skipping deletion of {} as it is already deleted", guid); LOG.debug("Skipping deletion of {} as it is already deleted", guid);
continue; continue;
} }
...@@ -128,6 +126,23 @@ public abstract class DeleteHandlerV1 { ...@@ -128,6 +126,23 @@ public abstract class DeleteHandlerV1 {
} }
/** /**
* Deletes the specified relationship edges.
*
* @param edges
* @throws AtlasBaseException
*/
public void deleteRelationships(Collection<AtlasEdge> edges) throws AtlasBaseException {
for (AtlasEdge edge : edges) {
if (getState(edge) == DELETED) {
LOG.debug("Skipping deletion of {} as it is already deleted", getIdFromEdge(edge));
continue;
}
deleteEdge(edge, false);
}
}
/**
* Get the GUIDs and vertices for all composite entities owned/contained by the specified root entity AtlasVertex. * Get the GUIDs and vertices for all composite entities owned/contained by the specified root entity AtlasVertex.
* The graph is traversed from the root entity through to the leaf nodes of the containment graph. * The graph is traversed from the root entity through to the leaf nodes of the containment graph.
* *
...@@ -142,8 +157,8 @@ public abstract class DeleteHandlerV1 { ...@@ -142,8 +157,8 @@ public abstract class DeleteHandlerV1 {
while (vertices.size() > 0) { while (vertices.size() > 0) {
AtlasVertex vertex = vertices.pop(); AtlasVertex vertex = vertices.pop();
AtlasEntity.Status state = AtlasGraphUtilsV1.getState(vertex); AtlasEntity.Status state = getState(vertex);
if (state == AtlasEntity.Status.DELETED) { if (state == DELETED) {
//If the reference vertex is marked for deletion, skip it //If the reference vertex is marked for deletion, skip it
continue; continue;
} }
...@@ -167,7 +182,7 @@ public abstract class DeleteHandlerV1 { ...@@ -167,7 +182,7 @@ public abstract class DeleteHandlerV1 {
switch (attrType.getTypeCategory()) { switch (attrType.getTypeCategory()) {
case OBJECT_ID_TYPE: case OBJECT_ID_TYPE:
AtlasEdge edge = graphHelper.getEdgeForLabel(vertex, edgeLabel); AtlasEdge edge = graphHelper.getEdgeForLabel(vertex, edgeLabel);
if (edge != null && AtlasGraphUtilsV1.getState(edge) == AtlasEntity.Status.ACTIVE) { if (edge != null && getState(edge) == AtlasEntity.Status.ACTIVE) {
AtlasVertex compositeVertex = edge.getInVertex(); AtlasVertex compositeVertex = edge.getInVertex();
vertices.push(compositeVertex); vertices.push(compositeVertex);
} }
...@@ -181,7 +196,7 @@ public abstract class DeleteHandlerV1 { ...@@ -181,7 +196,7 @@ public abstract class DeleteHandlerV1 {
if (edges != null) { if (edges != null) {
while (edges.hasNext()) { while (edges.hasNext()) {
edge = edges.next(); edge = edges.next();
if (edge != null && AtlasGraphUtilsV1.getState(edge) == AtlasEntity.Status.ACTIVE) { if (edge != null && getState(edge) == AtlasEntity.Status.ACTIVE) {
AtlasVertex compositeVertex = edge.getInVertex(); AtlasVertex compositeVertex = edge.getInVertex();
vertices.push(compositeVertex); vertices.push(compositeVertex);
} }
...@@ -200,7 +215,7 @@ public abstract class DeleteHandlerV1 { ...@@ -200,7 +215,7 @@ public abstract class DeleteHandlerV1 {
for (String key : keys) { for (String key : keys) {
String mapEdgeLabel = GraphHelper.getQualifiedNameForMapKey(edgeLabel, key); String mapEdgeLabel = GraphHelper.getQualifiedNameForMapKey(edgeLabel, key);
edge = graphHelper.getEdgeForLabel(vertex, mapEdgeLabel); edge = graphHelper.getEdgeForLabel(vertex, mapEdgeLabel);
if (edge != null && AtlasGraphUtilsV1.getState(edge) == AtlasEntity.Status.ACTIVE) { if (edge != null && getState(edge) == AtlasEntity.Status.ACTIVE) {
AtlasVertex compositeVertex = edge.getInVertex(); AtlasVertex compositeVertex = edge.getInVertex();
vertices.push(compositeVertex); vertices.push(compositeVertex);
} }
...@@ -429,9 +444,9 @@ public abstract class DeleteHandlerV1 { ...@@ -429,9 +444,9 @@ public abstract class DeleteHandlerV1 {
String outId = GraphHelper.getGuid(outVertex); String outId = GraphHelper.getGuid(outVertex);
AtlasObjectId objId = new AtlasObjectId(outId, typeName); AtlasObjectId objId = new AtlasObjectId(outId, typeName);
AtlasEntity.Status state = AtlasGraphUtilsV1.getState(outVertex); AtlasEntity.Status state = getState(outVertex);
if (state == AtlasEntity.Status.DELETED || (outId != null && RequestContextV1.get().isDeletedEntity(objId))) { if (state == DELETED || (outId != null && RequestContextV1.get().isDeletedEntity(objId))) {
//If the reference vertex is marked for deletion, skip updating the reference //If the reference vertex is marked for deletion, skip updating the reference
return; return;
} }
...@@ -564,7 +579,7 @@ public abstract class DeleteHandlerV1 { ...@@ -564,7 +579,7 @@ public abstract class DeleteHandlerV1 {
LOG.debug("Setting the external references to {} to null(removing edges)", string(instanceVertex)); LOG.debug("Setting the external references to {} to null(removing edges)", string(instanceVertex));
for (AtlasEdge edge : (Iterable<AtlasEdge>) instanceVertex.getEdges(AtlasEdgeDirection.IN)) { for (AtlasEdge edge : (Iterable<AtlasEdge>) instanceVertex.getEdges(AtlasEdgeDirection.IN)) {
AtlasEntity.Status edgeState = AtlasGraphUtilsV1.getState(edge); AtlasEntity.Status edgeState = getState(edge);
if (edgeState == AtlasEntity.Status.ACTIVE) { if (edgeState == AtlasEntity.Status.ACTIVE) {
//Delete only the active edge references //Delete only the active edge references
AtlasAttribute attribute = getAttributeForEdge(edge.getLabel()); AtlasAttribute attribute = getAttributeForEdge(edge.getLabel());
......
...@@ -796,6 +796,7 @@ public final class EntityGraphRetriever { ...@@ -796,6 +796,7 @@ public final class EntityGraphRetriever {
relationship.setEnd2(new AtlasObjectId(GraphHelper.getGuid(end2Vertex), GraphHelper.getTypeName(end2Vertex))); relationship.setEnd2(new AtlasObjectId(GraphHelper.getGuid(end2Vertex), GraphHelper.getTypeName(end2Vertex)));
relationship.setLabel(edge.getLabel()); relationship.setLabel(edge.getLabel());
relationship.setPropagateTags(GraphHelper.getPropagateTags(edge));
return relationship; return relationship;
} }
......
...@@ -115,7 +115,7 @@ public abstract class AtlasRelationshipStoreV1Test { ...@@ -115,7 +115,7 @@ public abstract class AtlasRelationshipStoreV1Test {
@BeforeTest @BeforeTest
public void init() throws Exception { public void init() throws Exception {
entityStore = new AtlasEntityStoreV1(deleteHandler, typeRegistry, mockChangeNotifier, graphMapper); entityStore = new AtlasEntityStoreV1(deleteHandler, typeRegistry, mockChangeNotifier, graphMapper);
relationshipStore = new AtlasRelationshipStoreV1(typeRegistry); relationshipStore = new AtlasRelationshipStoreV1(typeRegistry, deleteHandler);
RequestContextV1.clear(); RequestContextV1.clear();
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER); RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
......
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