diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 66283d8d6e2..aa5b376ec52 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -31,6 +31,7 @@ on: - tagscanarymerge - fixlabels - interceptapis + - mindbodylineage - revert-custom-metadata-changes jobs: diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java index dc3a4f36453..b4b80b45cb8 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java @@ -61,6 +61,7 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; +import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; import org.apache.tinkerpop.gremlin.structure.Direction; @@ -93,6 +94,8 @@ import static org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2.getState; import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.__.id; import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.__.outV; +import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.hasId; +import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.not; public abstract class DeleteHandlerV1 { public static final Logger LOG = LoggerFactory.getLogger(DeleteHandlerV1.class); @@ -1878,7 +1881,7 @@ private void updateAssetHasLineageStatusV2(AtlasVertex assetVertex, AtlasEdge cu AtlasPerfMetrics.MetricRecorder metricRecorder = RequestContext.get().startMetricRecord("updateAssetHasLineageStatusV2"); // Add removed edges to the context - removedEdges.forEach(edge -> RequestContext.get().addToDeletedEdgesIdsForResetHasLineage(edge.getIdForDisplay())); + removedEdges.forEach(edge -> RequestContext.get().addToDeletedEdgesObjectIdsForResetHasLineage(edge.getId())); // Check for active lineage in outgoing edges first boolean hasActiveLineage = hasActiveLineageDirection(assetVertex, currentEdge, Direction.OUT); @@ -1898,15 +1901,19 @@ private void updateAssetHasLineageStatusV2(AtlasVertex assetVertex, AtlasEdge cu /** * Helper method to check for active lineage in a specific direction + * * @param assetVertex The vertex to check * @param currentEdge The current edge to exclude - * @param direction The edge direction to explore + * @param direction The edge direction to explore * @return True if active lineage exists in the specified direction */ private boolean hasActiveLineageDirection(AtlasVertex assetVertex, AtlasEdge currentEdge, Direction direction) { GraphTraversalSource g = ((AtlasJanusGraph) graph).getGraph().traversal(); GraphTraversal traversal; + Set exclude = new HashSet<>(); + exclude.add(currentEdge.getId()); // use the actual TinkerPop id, not "idForDisplay" + exclude.addAll(RequestContext.get().getDeletedEdgesObjectIdsForResetHasLineage()); // Create the appropriate directional traversal if (direction.equals(Direction.OUT)) { traversal = g.V(assetVertex.getId()) @@ -1918,24 +1925,14 @@ private boolean hasActiveLineageDirection(AtlasVertex assetVertex, AtlasEdge cur .has(STATE_PROPERTY_KEY, ACTIVE_STATE_VALUE); } - // Complete the traversal with common operations + + // Filter out current edge using Gremlin + traversal = traversal.hasId(P.without(exclude)); return traversal - .project("id", HAS_LINEAGE) - .by(id()) - .by(outV().values(HAS_LINEAGE)) - .toStream() - .anyMatch(edge -> { - Object edgeId = edge.get("id"); - String edgeIdStr = (edgeId != null) ? edgeId.toString() : ""; - - // Skip if in deleted list or matches current edge - if (RequestContext.get().getDeletedEdgesIdsForResetHasLineage().contains(edgeIdStr) || - currentEdge.getIdForDisplay().equals(edgeIdStr)) { - return false; - } + .outV() // Get the connected vertex + .has(HAS_LINEAGE, true) // Filter vertices with lineage=true + .limit(1) + .hasNext(); // Just check existence, don't materialize using stream() - // Check if this edge has lineage - return Boolean.TRUE.equals(edge.get(HAS_LINEAGE)); - }); } } diff --git a/server-api/src/main/java/org/apache/atlas/RequestContext.java b/server-api/src/main/java/org/apache/atlas/RequestContext.java index 65a197370d7..f79d69abc6f 100644 --- a/server-api/src/main/java/org/apache/atlas/RequestContext.java +++ b/server-api/src/main/java/org/apache/atlas/RequestContext.java @@ -113,6 +113,7 @@ public class RequestContext { private MetricsRegistry metricsRegistry; private boolean skipAuthorizationCheck = false; private Set deletedEdgesIdsForResetHasLineage = new HashSet<>(0); + private Set deletedEdgesObjectIdsForResetHasLineage = new HashSet<>(0); private String requestUri; private boolean delayTagNotifications = false; private boolean skipHasLineageCalculation = false; @@ -183,6 +184,7 @@ public void clearCache() { this.deletedEdgesIds.clear(); this.processGuidIds.clear(); this.deletedEdgesIdsForResetHasLineage.clear(); + this.deletedEdgesObjectIdsForResetHasLineage.clear(); this.requestContextHeaders.clear(); this.relationshipEndToVertexIdMap.clear(); this.relationshipMutationMap.clear(); @@ -509,11 +511,17 @@ public Set getDeletedEdgesIds() { public void addToDeletedEdgesIdsForResetHasLineage(String edgeId) { deletedEdgesIdsForResetHasLineage.add(edgeId); } + public void addToDeletedEdgesObjectIdsForResetHasLineage(Object edgeId) { + deletedEdgesObjectIdsForResetHasLineage.add(edgeId); + } public Set getDeletedEdgesIdsForResetHasLineage() { return deletedEdgesIdsForResetHasLineage; } + public Set getDeletedEdgesObjectIdsForResetHasLineage() { + return deletedEdgesObjectIdsForResetHasLineage; + } public Set getProcessGuidIds() { return processGuidIds; }