Commit 5900fcb0 by Sarath Subramanian

ATLAS-2119: Implement update and delete operations for RelationshipREST

parent 84f4f103
......@@ -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_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"),
RELATIONSHIP_ALREADY_DELETED(404, "ATLAS-404-00-00F", "Attempting to delete a relationship which is already deleted : {0}"),
// All data conflict errors go here
TYPE_ALREADY_EXISTS(409, "ATLAS-409-00-001", "Given type {0} already exists"),
......
......@@ -24,6 +24,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
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.XmlAccessorType;
......@@ -53,6 +54,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
private AtlasObjectId end1 = null;
private AtlasObjectId end2 = null;
private String label = null;
private PropagateTags propagateTags = PropagateTags.NONE;
private Status status = Status.ACTIVE;
private String createdBy = null;
private String updatedBy = null;
......@@ -84,13 +86,13 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
public AtlasRelationship(String typeName, AtlasObjectId end1, AtlasObjectId end2) {
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) {
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) {
......@@ -107,8 +109,8 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
super(other);
if (other != null) {
init(other.guid, other.end1, other.end2, other.label, other.status, other.createdBy, other.updatedBy,
other.createTime, other.updateTime, other.version);
init(other.guid, other.end1, other.end2, other.label, other.propagateTags, other.status,
other.createdBy, other.updatedBy, other.createTime, other.updateTime, other.version);
}
}
......@@ -180,21 +182,25 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
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() {
return "-" + Long.toString(s_nextId.getAndIncrement());
}
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,
Status status, String createdBy, String updatedBy,
Date createTime, Date updateTime, Long version) {
private void init(String guid, AtlasObjectId end1, AtlasObjectId end2, String label, PropagateTags propagateTags,
Status status, String createdBy, String updatedBy, Date createTime, Date updateTime, Long version) {
setGuid(guid);
setEnd1(end1);
setEnd2(end2);
setLabel(label);
setPropagateTags(propagateTags);
setStatus(status);
setCreatedBy(createdBy);
setUpdatedBy(updatedBy);
......@@ -215,6 +221,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
sb.append(", end1=").append(end1);
sb.append(", end2=").append(end2);
sb.append(", label='").append(label).append('\'');
sb.append(", propagateTags=").append(propagateTags);
sb.append(", status=").append(status);
sb.append(", createdBy='").append(createdBy).append('\'');
sb.append(", updatedBy='").append(updatedBy).append('\'');
......@@ -237,6 +244,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
Objects.equals(end1, that.end1) &&
Objects.equals(end2, that.end2) &&
Objects.equals(label, that.label) &&
propagateTags == that.propagateTags &&
status == that.status &&
Objects.equals(createdBy, that.createdBy) &&
Objects.equals(updatedBy, that.updatedBy) &&
......@@ -247,8 +255,8 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), guid, end1, end2, label, status, createdBy,
updatedBy, createTime, updateTime, version);
return Objects.hash(super.hashCode(), guid, end1, end2, label, propagateTags,
status, createdBy, updatedBy, createTime, updateTime, version);
}
@Override
......
......@@ -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.Referenceable;
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.repository.Constants;
import org.apache.atlas.repository.RepositoryException;
......@@ -722,6 +723,12 @@ public final class GraphHelper {
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
public static String getCreatedByAsString(AtlasElement element){
return element.getProperty(Constants.CREATED_BY_KEY, String.class);
......
......@@ -103,6 +103,10 @@ public class AtlasGraphUtilsV1 {
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) {
return element.getProperty(Constants.ENTITY_TYPE_PROPERTY_KEY, String.class);
}
......
......@@ -40,7 +40,6 @@ import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
import org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -54,14 +53,13 @@ import java.util.List;
import java.util.Set;
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.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.isRelationshipEdge;
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 {
......@@ -94,9 +92,9 @@ public abstract class DeleteHandlerV1 {
for (AtlasVertex instanceVertex : instanceVertices) {
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);
continue;
}
......@@ -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.
* 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 {
while (vertices.size() > 0) {
AtlasVertex vertex = vertices.pop();
AtlasEntity.Status state = AtlasGraphUtilsV1.getState(vertex);
if (state == AtlasEntity.Status.DELETED) {
AtlasEntity.Status state = getState(vertex);
if (state == DELETED) {
//If the reference vertex is marked for deletion, skip it
continue;
}
......@@ -167,7 +182,7 @@ public abstract class DeleteHandlerV1 {
switch (attrType.getTypeCategory()) {
case OBJECT_ID_TYPE:
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();
vertices.push(compositeVertex);
}
......@@ -181,7 +196,7 @@ public abstract class DeleteHandlerV1 {
if (edges != null) {
while (edges.hasNext()) {
edge = edges.next();
if (edge != null && AtlasGraphUtilsV1.getState(edge) == AtlasEntity.Status.ACTIVE) {
if (edge != null && getState(edge) == AtlasEntity.Status.ACTIVE) {
AtlasVertex compositeVertex = edge.getInVertex();
vertices.push(compositeVertex);
}
......@@ -200,7 +215,7 @@ public abstract class DeleteHandlerV1 {
for (String key : keys) {
String mapEdgeLabel = GraphHelper.getQualifiedNameForMapKey(edgeLabel, key);
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();
vertices.push(compositeVertex);
}
......@@ -429,9 +444,9 @@ public abstract class DeleteHandlerV1 {
String outId = GraphHelper.getGuid(outVertex);
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
return;
}
......@@ -564,7 +579,7 @@ public abstract class DeleteHandlerV1 {
LOG.debug("Setting the external references to {} to null(removing edges)", string(instanceVertex));
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) {
//Delete only the active edge references
AtlasAttribute attribute = getAttributeForEdge(edge.getLabel());
......
......@@ -796,6 +796,7 @@ public final class EntityGraphRetriever {
relationship.setEnd2(new AtlasObjectId(GraphHelper.getGuid(end2Vertex), GraphHelper.getTypeName(end2Vertex)));
relationship.setLabel(edge.getLabel());
relationship.setPropagateTags(GraphHelper.getPropagateTags(edge));
return relationship;
}
......
......@@ -115,7 +115,7 @@ public abstract class AtlasRelationshipStoreV1Test {
@BeforeTest
public void init() throws Exception {
entityStore = new AtlasEntityStoreV1(deleteHandler, typeRegistry, mockChangeNotifier, graphMapper);
relationshipStore = new AtlasRelationshipStoreV1(typeRegistry);
relationshipStore = new AtlasRelationshipStoreV1(typeRegistry, deleteHandler);
RequestContextV1.clear();
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