From 39caff73274aeaf0fc611c9bb2e192c956467601 Mon Sep 17 00:00:00 2001 From: Koji Kawamura Date: Fri, 23 Mar 2018 15:57:17 +0900 Subject: [PATCH] NIFI-4993: Fixed unauthorized lineage computation Before this fix, if provenance lineage is qualied by a user who does not have 'view the data' plivilege for a component which emits provenance events those create new FlowFile, then lineage computation stops at such component, instead of connecting other available events with the created FlowFile lineage node. Expected edges are not created because PlaceholderProvenanceEvent returns 'UNKNOWN' event type, edge population logics relying on that type do not work. This commit modifies PlaceholderProvenanceEvent so that it can return original event type if necessary, as well as children and parent event uuids. --- .../provenance/PlaceholderProvenanceEvent.java | 14 ++++++++++++-- .../nifi/provenance/StandardLineageResult.java | 6 ++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/PlaceholderProvenanceEvent.java b/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/PlaceholderProvenanceEvent.java index 5644355b2285..8d10b9935cbe 100644 --- a/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/PlaceholderProvenanceEvent.java +++ b/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/PlaceholderProvenanceEvent.java @@ -30,12 +30,18 @@ public class PlaceholderProvenanceEvent implements ProvenanceEventRecord { private final long eventId; private final long eventTime; private final String flowFileUuid; + private final ProvenanceEventType eventType; + private final List childUuids; + private final List parentUuids; public PlaceholderProvenanceEvent(final ProvenanceEventRecord original) { this.componentId = original.getComponentId(); this.eventId = original.getEventId(); this.eventTime = original.getEventTime(); this.flowFileUuid = original.getFlowFileUuid(); + this.eventType = original.getEventType(); + this.childUuids = original.getChildUuids(); + this.parentUuids = original.getParentUuids(); } @Override @@ -120,12 +126,12 @@ public String getFlowFileUuid() { @Override public List getParentUuids() { - return null; + return parentUuids; } @Override public List getChildUuids() { - return null; + return childUuids; } @Override @@ -197,4 +203,8 @@ public Long getPreviousContentClaimOffset() { public String getBestEventIdentifier() { return Long.toString(getEventId()); } + + ProvenanceEventType getOriginalEventType() { + return this.eventType; + } } diff --git a/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/StandardLineageResult.java b/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/StandardLineageResult.java index 2b7b34a864be..7726a34b0008 100644 --- a/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/StandardLineageResult.java +++ b/nifi-commons/nifi-data-provenance-utils/src/main/java/org/apache/nifi/provenance/StandardLineageResult.java @@ -247,6 +247,8 @@ public int compare(final ProvenanceEventRecord o1, final ProvenanceEventRecord o // Create an edge that connects this node to the previous node for the same FlowFile UUID. final LineageNode lastNode = lastEventMap.get(record.getFlowFileUuid()); + final ProvenanceEventType eventType = record instanceof PlaceholderProvenanceEvent + ? ((PlaceholderProvenanceEvent) record).getOriginalEventType() : record.getEventType(); if (lastNode != null) { // We calculate the Edge UUID based on whether or not this event is a SPAWN. // If this event is a SPAWN, then we want to use the previous node's UUID because a @@ -255,7 +257,7 @@ public int compare(final ProvenanceEventRecord o1, final ProvenanceEventRecord o // the UUID of this record is appropriate, so we just use it. final String edgeUuid; - switch (record.getEventType()) { + switch (eventType) { case JOIN: case CLONE: case REPLAY: @@ -271,7 +273,7 @@ public int compare(final ProvenanceEventRecord o1, final ProvenanceEventRecord o lastEventMap.put(record.getFlowFileUuid(), lineageNode); - switch (record.getEventType()) { + switch (eventType) { case FORK: case JOIN: case REPLAY: