Commit f59284ad by Sarath Subramanian

ATLAS-2040: Relationship with many-to-many cardinality gives incorrect relationship attribute value

parent 1b7e41f1
...@@ -31,6 +31,7 @@ import org.slf4j.Logger; ...@@ -31,6 +31,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection; import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.BOTH;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.IN; import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.IN;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.OUT; import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.OUT;
...@@ -118,24 +119,33 @@ public class AtlasRelationshipType extends AtlasStructType { ...@@ -118,24 +119,33 @@ public class AtlasRelationshipType extends AtlasStructType {
} }
private void addRelationshipEdgeDirection() { private void addRelationshipEdgeDirection() {
AtlasRelationshipEndDef endDef1 = relationshipDef.getEndDef1(); AtlasRelationshipEndDef endDef1 = relationshipDef.getEndDef1();
AtlasRelationshipEndDef endDef2 = relationshipDef.getEndDef2(); AtlasRelationshipEndDef endDef2 = relationshipDef.getEndDef2();
AtlasAttribute end1Attribute = end1Type.getRelationshipAttribute(endDef1.getName());
AtlasAttribute end2Attribute = end2Type.getRelationshipAttribute(endDef2.getName());
//default relationship edge direction is end1 (out) -> end2 (in) if (StringUtils.equals(endDef1.getType(), endDef2.getType()) &&
AtlasRelationshipEdgeDirection end1Direction = OUT; StringUtils.equals(endDef1.getName(), endDef2.getName())) {
AtlasRelationshipEdgeDirection end2Direction = IN;
if (endDef1.getIsLegacyAttribute() && endDef2.getIsLegacyAttribute()) { AtlasAttribute endAttribute = end1Type.getRelationshipAttribute(endDef1.getName());
end2Direction = OUT;
} else if (!endDef1.getIsLegacyAttribute() && endDef2.getIsLegacyAttribute()) {
end1Direction = IN;
end2Direction = OUT;
}
end1Attribute.setRelationshipEdgeDirection(end1Direction); endAttribute.setRelationshipEdgeDirection(BOTH);
end2Attribute.setRelationshipEdgeDirection(end2Direction); } else {
AtlasAttribute end1Attribute = end1Type.getRelationshipAttribute(endDef1.getName());
AtlasAttribute end2Attribute = end2Type.getRelationshipAttribute(endDef2.getName());
//default relationship edge direction is end1 (out) -> end2 (in)
AtlasRelationshipEdgeDirection end1Direction = OUT;
AtlasRelationshipEdgeDirection end2Direction = IN;
if (endDef1.getIsLegacyAttribute() && endDef2.getIsLegacyAttribute()) {
end2Direction = OUT;
} else if (!endDef1.getIsLegacyAttribute() && endDef2.getIsLegacyAttribute()) {
end1Direction = IN;
end2Direction = OUT;
}
end1Attribute.setRelationshipEdgeDirection(end1Direction);
end2Attribute.setRelationshipEdgeDirection(end2Direction);
}
} }
@Override @Override
...@@ -200,7 +210,6 @@ public class AtlasRelationshipType extends AtlasStructType { ...@@ -200,7 +210,6 @@ public class AtlasRelationshipType extends AtlasStructType {
AtlasRelationshipEndDef endDef2 = relationshipDef.getEndDef2(); AtlasRelationshipEndDef endDef2 = relationshipDef.getEndDef2();
RelationshipCategory relationshipCategory = relationshipDef.getRelationshipCategory(); RelationshipCategory relationshipCategory = relationshipDef.getRelationshipCategory();
String name = relationshipDef.getName(); String name = relationshipDef.getName();
boolean isContainer1 = endDef1.getIsContainer(); boolean isContainer1 = endDef1.getIsContainer();
boolean isContainer2 = endDef2.getIsContainer(); boolean isContainer2 = endDef2.getIsContainer();
......
...@@ -794,6 +794,6 @@ public class AtlasStructType extends AtlasType { ...@@ -794,6 +794,6 @@ public class AtlasStructType extends AtlasType {
private static final char DOUBLE_QUOTE_CHAR = '"'; private static final char DOUBLE_QUOTE_CHAR = '"';
private static final char SPACE_CHAR = ' '; private static final char SPACE_CHAR = ' ';
public enum AtlasRelationshipEdgeDirection { IN, OUT } public enum AtlasRelationshipEdgeDirection { IN, OUT, BOTH }
} }
} }
...@@ -42,7 +42,6 @@ import org.apache.atlas.repository.graphdb.AtlasVertex; ...@@ -42,7 +42,6 @@ import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1; import org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1;
import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasRelationshipType; import org.apache.atlas.type.AtlasRelationshipType;
import org.apache.atlas.type.AtlasStructType;
import org.apache.atlas.type.AtlasType; import org.apache.atlas.type.AtlasType;
import org.apache.atlas.typesystem.IReferenceableInstance; import org.apache.atlas.typesystem.IReferenceableInstance;
import org.apache.atlas.typesystem.ITypedInstance; import org.apache.atlas.typesystem.ITypedInstance;
...@@ -86,6 +85,10 @@ import java.util.Set; ...@@ -86,6 +85,10 @@ import java.util.Set;
import java.util.Stack; import java.util.Stack;
import java.util.UUID; import java.util.UUID;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.BOTH;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.IN;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.OUT;
/** /**
* Utility class for graph operations. * Utility class for graph operations.
*/ */
...@@ -308,7 +311,7 @@ public final class GraphHelper { ...@@ -308,7 +311,7 @@ public final class GraphHelper {
//In some cases of parallel APIs, the edge is added, but get edge by label doesn't return the edge. ATLAS-1104 //In some cases of parallel APIs, the edge is added, but get edge by label doesn't return the edge. ATLAS-1104
//So traversing all the edges //So traversing all the edges
public Iterator<AtlasEdge> getAdjacentEdgesByLabel(AtlasVertex instanceVertex, AtlasEdgeDirection direction, final String edgeLabel) { public static Iterator<AtlasEdge> getAdjacentEdgesByLabel(AtlasVertex instanceVertex, AtlasEdgeDirection direction, final String edgeLabel) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Finding edges for {} with label {}", string(instanceVertex), edgeLabel); LOG.debug("Finding edges for {} with label {}", string(instanceVertex), edgeLabel);
} }
...@@ -348,11 +351,11 @@ public final class GraphHelper { ...@@ -348,11 +351,11 @@ public final class GraphHelper {
return null; return null;
} }
public Iterator<AtlasEdge> getIncomingEdgesByLabel(AtlasVertex instanceVertex, String edgeLabel) { public static Iterator<AtlasEdge> getIncomingEdgesByLabel(AtlasVertex instanceVertex, String edgeLabel) {
return getAdjacentEdgesByLabel(instanceVertex, AtlasEdgeDirection.IN, edgeLabel); return getAdjacentEdgesByLabel(instanceVertex, AtlasEdgeDirection.IN, edgeLabel);
} }
public Iterator<AtlasEdge> getOutGoingEdgesByLabel(AtlasVertex instanceVertex, String edgeLabel) { public static Iterator<AtlasEdge> getOutGoingEdgesByLabel(AtlasVertex instanceVertex, String edgeLabel) {
return getAdjacentEdgesByLabel(instanceVertex, AtlasEdgeDirection.OUT, edgeLabel); return getAdjacentEdgesByLabel(instanceVertex, AtlasEdgeDirection.OUT, edgeLabel);
} }
...@@ -361,20 +364,24 @@ public final class GraphHelper { ...@@ -361,20 +364,24 @@ public final class GraphHelper {
switch (edgeDirection) { switch (edgeDirection) {
case IN: case IN:
ret = getEdgeForLabel(vertex, edgeLabel, AtlasEdgeDirection.IN); ret = getEdgeForLabel(vertex, edgeLabel, AtlasEdgeDirection.IN);
break; break;
case OUT: case OUT:
ret = getEdgeForLabel(vertex, edgeLabel, AtlasEdgeDirection.OUT);
break;
case BOTH:
default: default:
ret = getEdgeForLabel(vertex, edgeLabel, AtlasEdgeDirection.OUT); ret = getEdgeForLabel(vertex, edgeLabel, AtlasEdgeDirection.BOTH);
break; break;
} }
return ret; return ret;
} }
public Iterator<AtlasEdge> getEdgesForLabel(AtlasVertex vertex, String edgeLabel, AtlasRelationshipEdgeDirection edgeDirection) { public static Iterator<AtlasEdge> getEdgesForLabel(AtlasVertex vertex, String edgeLabel, AtlasRelationshipEdgeDirection edgeDirection) {
Iterator<AtlasEdge> ret; Iterator<AtlasEdge> ret = null;
switch (edgeDirection) { switch (edgeDirection) {
case IN: case IN:
...@@ -382,8 +389,11 @@ public final class GraphHelper { ...@@ -382,8 +389,11 @@ public final class GraphHelper {
break; break;
case OUT: case OUT:
default: ret = getOutGoingEdgesByLabel(vertex, edgeLabel);
ret = getOutGoingEdgesByLabel(vertex, edgeLabel); break;
case BOTH:
ret = getAdjacentEdgesByLabel(vertex, AtlasEdgeDirection.BOTH, edgeLabel);
break; break;
} }
...@@ -1341,32 +1351,38 @@ public final class GraphHelper { ...@@ -1341,32 +1351,38 @@ public final class GraphHelper {
return StringUtils.isNotEmpty(edge.getLabel()) ? edgeLabel.startsWith("r:") : false; return StringUtils.isNotEmpty(edge.getLabel()) ? edgeLabel.startsWith("r:") : false;
} }
public static AtlasObjectId getReferenceObjectId(AtlasEdge edge, AtlasRelationshipEdgeDirection relationshipDirection) { public static AtlasObjectId getReferenceObjectId(AtlasEdge edge, AtlasRelationshipEdgeDirection relationshipDirection,
AtlasVertex parentVertex) {
AtlasObjectId ret = null; AtlasObjectId ret = null;
if (relationshipDirection == AtlasRelationshipEdgeDirection.OUT) { if (relationshipDirection == OUT) {
ret = new AtlasObjectId(getGuid(edge.getInVertex()), getTypeName(edge.getInVertex())); ret = getAtlasObjectIdForInVertex(edge);
} else if (relationshipDirection == IN) {
ret = getAtlasObjectIdForOutVertex(edge);
} else if (relationshipDirection == AtlasRelationshipEdgeDirection.IN) { } else if (relationshipDirection == BOTH){
ret = new AtlasObjectId(getGuid(edge.getOutVertex()), getTypeName(edge.getOutVertex())); // since relationship direction is BOTH, edge direction can be inward or outward
// compare with parent entity vertex and pick the right reference vertex
if (verticesEquals(parentVertex, edge.getOutVertex())) {
ret = getAtlasObjectIdForInVertex(edge);
} else {
ret = getAtlasObjectIdForOutVertex(edge);
}
} }
return ret; return ret;
} }
public static AtlasObjectId getCurrentObjectId(AtlasEdge edge, AtlasRelationshipEdgeDirection relationshipDirection) { public static AtlasObjectId getAtlasObjectIdForOutVertex(AtlasEdge edge) {
String typeName = null; return new AtlasObjectId(getGuid(edge.getOutVertex()), getTypeName(edge.getOutVertex()));
String guid = null; }
if (relationshipDirection == AtlasRelationshipEdgeDirection.OUT) {
typeName = GraphHelper.getTypeName(edge.getOutVertex());
guid = GraphHelper.getGuid(edge.getOutVertex());
} else if (relationshipDirection == AtlasRelationshipEdgeDirection.IN) { public static AtlasObjectId getAtlasObjectIdForInVertex(AtlasEdge edge) {
typeName = GraphHelper.getTypeName(edge.getInVertex()); return new AtlasObjectId(getGuid(edge.getInVertex()), getTypeName(edge.getInVertex()));
guid = GraphHelper.getGuid(edge.getInVertex()); }
}
return new AtlasObjectId(guid, typeName); private static boolean verticesEquals(AtlasVertex vertexA, AtlasVertex vertexB) {
return StringUtils.equals(getGuid(vertexB), getGuid(vertexA));
} }
} }
\ No newline at end of file
...@@ -40,6 +40,7 @@ import org.apache.atlas.type.AtlasStructType.AtlasAttribute; ...@@ -40,6 +40,7 @@ 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,9 +55,13 @@ import java.util.Set; ...@@ -54,9 +55,13 @@ import java.util.Set;
import java.util.Stack; import java.util.Stack;
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;
public abstract class DeleteHandlerV1 { public abstract class DeleteHandlerV1 {
...@@ -219,14 +224,14 @@ public abstract class DeleteHandlerV1 { ...@@ -219,14 +224,14 @@ public abstract class DeleteHandlerV1 {
* @throws AtlasException * @throws AtlasException
*/ */
public boolean deleteEdgeReference(AtlasEdge edge, TypeCategory typeCategory, boolean isOwned, public boolean deleteEdgeReference(AtlasEdge edge, TypeCategory typeCategory, boolean isOwned,
boolean forceDeleteStructTrait) throws AtlasBaseException { boolean forceDeleteStructTrait, AtlasVertex vertex) throws AtlasBaseException {
// default edge direction is outward // default edge direction is outward
return deleteEdgeReference(edge, typeCategory, isOwned, forceDeleteStructTrait, AtlasRelationshipEdgeDirection.OUT); return deleteEdgeReference(edge, typeCategory, isOwned, forceDeleteStructTrait, AtlasRelationshipEdgeDirection.OUT, vertex);
} }
public boolean deleteEdgeReference(AtlasEdge edge, TypeCategory typeCategory, boolean isOwned, boolean forceDeleteStructTrait, public boolean deleteEdgeReference(AtlasEdge edge, TypeCategory typeCategory, boolean isOwned, boolean forceDeleteStructTrait,
AtlasRelationshipEdgeDirection relationshipDirection) throws AtlasBaseException { AtlasRelationshipEdgeDirection relationshipDirection, AtlasVertex entityVertex) throws AtlasBaseException {
LOG.debug("Deleting {}", string(edge)); LOG.debug("Deleting {}", string(edge));
boolean forceDelete = boolean forceDelete =
(typeCategory == TypeCategory.STRUCT || typeCategory == TypeCategory.CLASSIFICATION) && forceDeleteStructTrait; (typeCategory == TypeCategory.STRUCT || typeCategory == TypeCategory.CLASSIFICATION) && forceDeleteStructTrait;
...@@ -250,7 +255,7 @@ public abstract class DeleteHandlerV1 { ...@@ -250,7 +255,7 @@ public abstract class DeleteHandlerV1 {
if (isRelationshipEdge(edge)) { if (isRelationshipEdge(edge)) {
deleteEdge(edge, false); deleteEdge(edge, false);
AtlasObjectId deletedReferenceObjectId = getReferenceObjectId(edge, relationshipDirection); AtlasObjectId deletedReferenceObjectId = getReferenceObjectId(edge, relationshipDirection, entityVertex);
RequestContextV1.get().recordEntityUpdate(deletedReferenceObjectId); RequestContextV1.get().recordEntityUpdate(deletedReferenceObjectId);
} else { } else {
//legacy case - not a relationship edge //legacy case - not a relationship edge
...@@ -344,7 +349,7 @@ public abstract class DeleteHandlerV1 { ...@@ -344,7 +349,7 @@ public abstract class DeleteHandlerV1 {
if (edges != null) { if (edges != null) {
while (edges.hasNext()) { while (edges.hasNext()) {
AtlasEdge edge = edges.next(); AtlasEdge edge = edges.next();
deleteEdgeReference(edge, elemType.getTypeCategory(), isOwned, false); deleteEdgeReference(edge, elemType.getTypeCategory(), isOwned, false, instanceVertex);
} }
} }
} }
...@@ -377,7 +382,7 @@ public abstract class DeleteHandlerV1 { ...@@ -377,7 +382,7 @@ public abstract class DeleteHandlerV1 {
boolean isOwned) throws AtlasBaseException { boolean isOwned) throws AtlasBaseException {
AtlasEdge edge = graphHelper.getEdgeForLabel(outVertex, edgeLabel); AtlasEdge edge = graphHelper.getEdgeForLabel(outVertex, edgeLabel);
if (edge != null) { if (edge != null) {
deleteEdgeReference(edge, typeCategory, isOwned, false); deleteEdgeReference(edge, typeCategory, isOwned, false, outVertex);
} }
} }
......
...@@ -72,6 +72,9 @@ import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_STRING; ...@@ -72,6 +72,9 @@ import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_STRING;
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.store.graph.v1.AtlasGraphUtilsV1.getIdFromVertex; import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.getIdFromVertex;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection; import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.BOTH;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.IN;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection.OUT;
public final class EntityGraphRetriever { public final class EntityGraphRetriever {
...@@ -683,10 +686,12 @@ public final class EntityGraphRetriever { ...@@ -683,10 +686,12 @@ public final class EntityGraphRetriever {
List<AtlasRelatedObjectId> ret = new ArrayList<>(); List<AtlasRelatedObjectId> ret = new ArrayList<>();
Iterator<AtlasEdge> edges = null; Iterator<AtlasEdge> edges = null;
if (attribute.getRelationshipEdgeDirection() == AtlasRelationshipEdgeDirection.IN) { if (attribute.getRelationshipEdgeDirection() == IN) {
edges = graphHelper.getIncomingEdgesByLabel(entityVertex, attribute.getRelationshipEdgeLabel()); edges = graphHelper.getIncomingEdgesByLabel(entityVertex, attribute.getRelationshipEdgeLabel());
} else if (attribute.getRelationshipEdgeDirection() == AtlasRelationshipEdgeDirection.OUT) { } else if (attribute.getRelationshipEdgeDirection() == OUT) {
edges = graphHelper.getOutGoingEdgesByLabel(entityVertex, attribute.getRelationshipEdgeLabel()); edges = graphHelper.getOutGoingEdgesByLabel(entityVertex, attribute.getRelationshipEdgeLabel());
} else if (attribute.getRelationshipEdgeDirection() == BOTH) {
edges = graphHelper.getAdjacentEdgesByLabel(entityVertex, AtlasEdgeDirection.BOTH, attribute.getRelationshipEdgeLabel());
} }
if (edges != null) { if (edges != null) {
......
...@@ -20,9 +20,15 @@ package org.apache.atlas.repository.store.graph.v1; ...@@ -20,9 +20,15 @@ package org.apache.atlas.repository.store.graph.v1;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.apache.atlas.TestModules; import org.apache.atlas.TestModules;
import org.apache.atlas.model.instance.AtlasEntity; import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasObjectId;
import org.testng.annotations.Guice; import org.testng.annotations.Guice;
import java.util.List;
import static org.apache.atlas.type.AtlasTypeUtil.getAtlasObjectId; import static org.apache.atlas.type.AtlasTypeUtil.getAtlasObjectId;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
/** /**
* Inverse reference update test with {@link HardDeleteHandlerV1} * Inverse reference update test with {@link HardDeleteHandlerV1}
...@@ -51,4 +57,56 @@ public class AtlasRelationshipStoreHardDeleteV1Test extends AtlasRelationshipSto ...@@ -51,4 +57,56 @@ public class AtlasRelationshipStoreHardDeleteV1Test extends AtlasRelationshipSto
protected void verifyRelationshipAttributeUpdate_NonComposite_OneToOne(AtlasEntity a1, AtlasEntity b) { protected void verifyRelationshipAttributeUpdate_NonComposite_OneToOne(AtlasEntity a1, AtlasEntity b) {
verifyRelationshipAttributeValue(a1, "b", null); verifyRelationshipAttributeValue(a1, "b", null);
} }
}
@Override
protected void verifyRelationshipAttributeUpdate_ManyToMany_Friends(AtlasEntity max, AtlasEntity julius, AtlasEntity mike, AtlasEntity john) throws Exception {
AtlasObjectId johnId = employeeNameIdMap.get("John");
AtlasObjectId mikeId = employeeNameIdMap.get("Mike");
AtlasObjectId juliusId = employeeNameIdMap.get("Julius");
AtlasObjectId maxId = employeeNameIdMap.get("Max");
List<AtlasObjectId> maxFriendsIds = toAtlasObjectIds(max.getRelationshipAttribute("friends"));
assertNotNull(maxFriendsIds);
assertEquals(maxFriendsIds.size(), 2);
assertObjectIdsContains(maxFriendsIds, johnId);
assertObjectIdsContains(maxFriendsIds, juliusId);
// Julius's updated friends: [Max]
List<AtlasObjectId> juliusFriendsIds = toAtlasObjectIds(julius.getRelationshipAttribute("friends"));
assertNotNull(juliusFriendsIds);
assertEquals(juliusFriendsIds.size(), 1);
assertObjectIdsContains(juliusFriendsIds, maxId);
// Mike's updated friends: [John]
List<AtlasObjectId> mikeFriendsIds = toAtlasObjectIds(mike.getRelationshipAttribute("friends"));
assertNotNull(mikeFriendsIds);
assertEquals(mikeFriendsIds.size(), 1);
assertObjectIdsContains(mikeFriendsIds, johnId);
// John's updated friends: [Max, Mike]
List<AtlasObjectId> johnFriendsIds = toAtlasObjectIds(john.getRelationshipAttribute("friends"));
assertNotNull(johnFriendsIds);
assertEquals(johnFriendsIds.size(), 2);
assertObjectIdsContains(johnFriendsIds, maxId);
assertObjectIdsContains(johnFriendsIds, mikeId);
}
protected void verifyRelationshipAttributeUpdate_OneToOne_Sibling(AtlasEntity julius, AtlasEntity jane, AtlasEntity mike) throws Exception {
AtlasObjectId juliusId = employeeNameIdMap.get("Julius");
AtlasObjectId mikeId = employeeNameIdMap.get("Mike");
// Julius sibling updated to Mike
AtlasObjectId juliusSiblingId = toAtlasObjectId(julius.getRelationshipAttribute("sibling"));
assertNotNull(juliusSiblingId);
assertObjectIdEquals(juliusSiblingId, mikeId);
// Mike's sibling is Julius
AtlasObjectId mikeSiblingId = toAtlasObjectId(mike.getRelationshipAttribute("sibling"));
assertNotNull(mikeSiblingId);
assertObjectIdEquals(mikeSiblingId, juliusId);
// Julius removed from Jane's sibling (hard delete)
AtlasObjectId janeSiblingId = toAtlasObjectId(jane.getRelationshipAttribute("sibling"));
assertNull(janeSiblingId);
}
}
\ No newline at end of file
...@@ -20,9 +20,14 @@ package org.apache.atlas.repository.store.graph.v1; ...@@ -20,9 +20,14 @@ package org.apache.atlas.repository.store.graph.v1;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.apache.atlas.TestModules; import org.apache.atlas.TestModules;
import org.apache.atlas.model.instance.AtlasEntity; import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasObjectId;
import org.testng.annotations.Guice; import org.testng.annotations.Guice;
import java.util.List;
import static org.apache.atlas.type.AtlasTypeUtil.getAtlasObjectId; import static org.apache.atlas.type.AtlasTypeUtil.getAtlasObjectId;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
/** /**
...@@ -52,4 +57,60 @@ public class AtlasRelationshipStoreSoftDeleteV1Test extends AtlasRelationshipSto ...@@ -52,4 +57,60 @@ public class AtlasRelationshipStoreSoftDeleteV1Test extends AtlasRelationshipSto
protected void verifyRelationshipAttributeUpdate_NonComposite_OneToOne(AtlasEntity a1, AtlasEntity b) { protected void verifyRelationshipAttributeUpdate_NonComposite_OneToOne(AtlasEntity a1, AtlasEntity b) {
verifyRelationshipAttributeValue(a1, "b", b.getGuid()); verifyRelationshipAttributeValue(a1, "b", b.getGuid());
} }
}
@Override
protected void verifyRelationshipAttributeUpdate_ManyToMany_Friends(AtlasEntity max, AtlasEntity julius, AtlasEntity mike, AtlasEntity john) throws Exception {
AtlasObjectId johnId = employeeNameIdMap.get("John");
AtlasObjectId mikeId = employeeNameIdMap.get("Mike");
AtlasObjectId juliusId = employeeNameIdMap.get("Julius");
AtlasObjectId maxId = employeeNameIdMap.get("Max");
// Max's updated friends: [Julius, John, Mike(soft deleted)]
List<AtlasObjectId> maxFriendsIds = toAtlasObjectIds(max.getRelationshipAttribute("friends"));
assertNotNull(maxFriendsIds);
assertEquals(maxFriendsIds.size(), 3);
assertObjectIdsContains(maxFriendsIds, johnId);
assertObjectIdsContains(maxFriendsIds, juliusId);
assertObjectIdsContains(maxFriendsIds, mikeId);
// Julius's updated friends: [Max]
List<AtlasObjectId> juliusFriendsIds = toAtlasObjectIds(julius.getRelationshipAttribute("friends"));
assertNotNull(juliusFriendsIds);
assertEquals(juliusFriendsIds.size(), 1);
assertObjectIdsContains(juliusFriendsIds, maxId);
// Mike's updated friends: [John, Max(soft deleted)]
List<AtlasObjectId> mikeFriendsIds = toAtlasObjectIds(mike.getRelationshipAttribute("friends"));
assertNotNull(mikeFriendsIds);
assertEquals(mikeFriendsIds.size(), 2);
assertObjectIdsContains(mikeFriendsIds, johnId);
assertObjectIdsContains(mikeFriendsIds, maxId);
// John's updated friends: [Max, Mike]
List<AtlasObjectId> johnFriendsIds = toAtlasObjectIds(john.getRelationshipAttribute("friends"));
assertNotNull(johnFriendsIds);
assertEquals(johnFriendsIds.size(), 2);
assertObjectIdsContains(johnFriendsIds, maxId);
assertObjectIdsContains(johnFriendsIds, mikeId);
}
protected void verifyRelationshipAttributeUpdate_OneToOne_Sibling(AtlasEntity julius, AtlasEntity jane, AtlasEntity mike) throws Exception {
AtlasObjectId juliusId = employeeNameIdMap.get("Julius");
AtlasObjectId mikeId = employeeNameIdMap.get("Mike");
// Julius sibling updated to Mike
AtlasObjectId juliusSiblingId = toAtlasObjectId(julius.getRelationshipAttribute("sibling"));
assertNotNull(juliusSiblingId);
assertObjectIdEquals(juliusSiblingId, mikeId);
// Mike's sibling is Julius
AtlasObjectId mikeSiblingId = toAtlasObjectId(mike.getRelationshipAttribute("sibling"));
assertNotNull(mikeSiblingId);
assertObjectIdEquals(mikeSiblingId, juliusId);
// Jane's sibling is still Julius (soft delete)
AtlasObjectId janeSiblingId = toAtlasObjectId(jane.getRelationshipAttribute("sibling"));
assertNotNull(janeSiblingId);
assertObjectIdEquals(janeSiblingId, juliusId);
}
}
\ No newline at end of file
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