This is an automated email from the ASF dual-hosted git repository.

mosermw pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new cf587f324d NIFI-13949 Implemented NoOpProvenanceRepository in 
nifi-volatile-provenance-repository module
cf587f324d is described below

commit cf587f324db27fbd83933c7d0fbe95a538adf747
Author: HunterG6700 <[email protected]>
AuthorDate: Thu May 15 19:06:59 2025 +0000

    NIFI-13949 Implemented NoOpProvenanceRepository in 
nifi-volatile-provenance-repository module
    
    Signed-off-by: Mike Moser <[email protected]>
    
    Closes #9950
---
 .../src/main/asciidoc/administration-guide.adoc    |   1 +
 nifi-docs/src/main/asciidoc/user-guide.adoc        |  23 ++
 .../nifi/provenance/NoOpProvenanceRepository.java  | 371 +++++++++++++++++++++
 ...org.apache.nifi.provenance.ProvenanceRepository |   1 +
 4 files changed, 396 insertions(+)

diff --git a/nifi-docs/src/main/asciidoc/administration-guide.adoc 
b/nifi-docs/src/main/asciidoc/administration-guide.adoc
index d3c810b989..f8e5a8eb50 100644
--- a/nifi-docs/src/main/asciidoc/administration-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/administration-guide.adoc
@@ -3036,6 +3036,7 @@ The Provenance Repository contains the information 
related to Data Provenance. T
 To store provenance events in memory instead of on disk (in which case all 
events will be lost on restart, and events will be evicted in a 
first-in-first-out order),
 set this property to 
`org.apache.nifi.provenance.VolatileProvenanceRepository`. This leaves a 
configurable number of Provenance Events in the Java heap, so the number
 of events that can be retained is very limited.
+Alternatively, to disable provenance event storage entirely and reduce 
resource usage, set this property to 
`org.apache.nifi.provenance.NoOpProvenanceRepository`.
 
 |`nifi.provenance.repository.rollover.events`| The maximum number of events 
that should be written to a single event file before the file is rolled over. 
The default value is `Integer.MAX_VALUE`
 |====
diff --git a/nifi-docs/src/main/asciidoc/user-guide.adoc 
b/nifi-docs/src/main/asciidoc/user-guide.adoc
index 18e75e8905..0b1c8084ec 100644
--- a/nifi-docs/src/main/asciidoc/user-guide.adoc
+++ b/nifi-docs/src/main/asciidoc/user-guide.adoc
@@ -3011,6 +3011,29 @@ Once these property changes have been made, restart NiFi.
 
 **Note:** Detailed descriptions for each of these properties can be found in 
<<administration-guide.adoc#system_properties,System Properties>>.
 
+[[noOp-provenance]]
+=== NoOp Provenance Repository
+
+The NoOp Provenance Repository does not store any provenance events.
+This is useful when provenance tracking is disabled or minimized, such as 
during testing or in resource-constrained environments.
+When using this implementation, no provenance data is persisted, and all query 
and lineage requests return empty results.
+
+The `NoOp Provenance Repository` implementation:
+
+* Saves no events or indexes.
+* Always returns empty results for queries.
+* Does not perform lineage computations.
+* Is designed for testing or when provenance is not needed.
+
+To configure NiFi to use the `NoOp Provenance Repository`, set in 
`nifi.properties`:
+
+[source,properties]
+----
+nifi.provenance.repository.implementation=org.apache.nifi.provenance.NoOpProvenanceRepository
+----
+
+**Note:** Disabling provenance storage will disable features relying on 
provenance data, such as lineage queries and event searches.
+
 [[experimental_warning]]
 == Experimental Warning
 
diff --git 
a/nifi-framework-bundle/nifi-framework-extensions/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/java/org/apache/nifi/provenance/NoOpProvenanceRepository.java
 
b/nifi-framework-bundle/nifi-framework-extensions/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/java/org/apache/nifi/provenance/NoOpProvenanceRepository.java
new file mode 100644
index 0000000000..b429842c40
--- /dev/null
+++ 
b/nifi-framework-bundle/nifi-framework-extensions/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/java/org/apache/nifi/provenance/NoOpProvenanceRepository.java
@@ -0,0 +1,371 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.provenance;
+
+import org.apache.nifi.authorization.Authorizer;
+import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.events.EventReporter;
+import org.apache.nifi.provenance.lineage.ComputeLineageSubmission;
+import org.apache.nifi.provenance.lineage.LineageComputationType;
+import org.apache.nifi.provenance.search.Query;
+import org.apache.nifi.provenance.search.QueryResult;
+import org.apache.nifi.provenance.search.QuerySubmission;
+import org.apache.nifi.provenance.search.SearchableField;
+import org.apache.nifi.reporting.Severity;
+import org.apache.nifi.util.NiFiProperties;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptySet;
+import static java.util.Collections.singleton;
+
+/**
+ * NoOpProvenanceRepository is an implementation of {@link 
ProvenanceRepository} that does not store events.
+ * This is useful for testing or disabling provenance tracking.
+ * <p>
+ * All query and lineage methods return empty results or no-ops.
+ * The repository logs initialization info via the EventReporter.
+ */
+public class NoOpProvenanceRepository implements ProvenanceRepository {
+
+    /**
+     * Default constructor for service loading only.
+     */
+    public NoOpProvenanceRepository() {
+    }
+
+    /**
+     * Constructs a NoOpProvenanceRepository with provided properties.
+     *
+     * @param ignored NiFi properties, ignored in this implementation.
+     */
+    public NoOpProvenanceRepository(final NiFiProperties ignored) {
+    }
+
+    /**
+     * Initializes the repository but does not actually store events.
+     */
+    @Override
+    public void initialize(EventReporter eventReporter, Authorizer authorizer,
+                           ProvenanceAuthorizableFactory factory, 
IdentifierLookup identifierLookup) throws IOException {
+        eventReporter.reportEvent(Severity.INFO, "Provenance", "Initialized 
NoOpProvenanceRepository - Provenance tracking is disabled");
+    }
+
+    /**
+     * Closes the repository. No-op.
+     */
+    @Override
+    public void close() throws IOException {
+
+    }
+
+    /**
+     * @return a new builder for creating provenance event records
+     */
+    @Override
+    public ProvenanceEventBuilder eventBuilder() {
+        return new StandardProvenanceEventRecord.Builder();
+    }
+
+    /**
+     * Returns null since no events are stored.
+     */
+    @Override
+    public ProvenanceEventRecord getEvent(long id) {
+        return null;
+    }
+
+    /**
+     * @return null since no events are stored.
+     */
+    @Override
+    public ProvenanceEventRecord getEvent(final long id, final NiFiUser user) {
+        return null;
+    }
+
+    /**
+     * @return an empty list since no events are stored
+     */
+    @Override
+    public List<ProvenanceEventRecord> getEvents(long firstRecordId, int 
maxRecords) {
+        return emptyList();
+    }
+
+    /**
+     * @return an empty list since no events are stored
+     */
+    @Override
+    public List<ProvenanceEventRecord> getEvents(long firstRecordId, int 
maxRecords, NiFiUser user) {
+        return emptyList();
+    }
+
+    /**
+     * @return 0 since no events are stored
+     */
+    @Override
+    public Long getMaxEventId() {
+        // No events are stored in this implementation
+        return 0L;
+    }
+
+    /**
+     * No-op. Events are not stored.
+     */
+    @Override
+    public void registerEvent(ProvenanceEventRecord records) {
+
+    }
+
+    /**
+     * No-op. Events are not stored.
+     */
+    @Override
+    public void registerEvents(Iterable<ProvenanceEventRecord> records) {
+
+    }
+
+    @Override
+    public ProvenanceEventRepository getProvenanceEventRepository() {
+        return this;
+    }
+
+    /**
+     * @return a stub query submission that returns an empty result
+     */
+    @Override
+    public QuerySubmission submitQuery(Query query, NiFiUser user) {
+        return new NoOpQuerySubmission(query, user.getIdentity());
+    }
+
+    /**
+     * @return an empty list
+     */
+    @Override
+    public List<ProvenanceEventRecord> getLatestCachedEvents(final String 
componentId, final int eventLimit) {
+        return emptyList();
+    }
+
+    /**
+     * @return a stub query submission with an empty result
+     */
+    @Override
+    public QuerySubmission retrieveQuerySubmission(String queryIdentifier, 
NiFiUser user) {
+        return new NoOpQuerySubmission(queryIdentifier, user.getIdentity());
+    }
+
+    /**
+     * @return a stub lineage computation result with no events
+     */
+    @Override
+    public ComputeLineageSubmission submitLineageComputation(String s, 
NiFiUser user) {
+        return new 
NoOpComputeLineageSubmission(LineageComputationType.FLOWFILE_LINEAGE, null, 
singleton(s), user.getIdentity());
+    }
+
+    /**
+     * @return a stub lineage computation result with an error message
+     */
+    @Override
+    public ComputeLineageSubmission submitLineageComputation(long eventId, 
NiFiUser user) {
+        final NoOpComputeLineageSubmission result = new 
NoOpComputeLineageSubmission(LineageComputationType.FLOWFILE_LINEAGE, eventId, 
emptySet(), user.getIdentity());
+        result.getResult().setError("Could not find event with ID " + eventId);
+        return result;
+    }
+
+    /**
+     * @return a stub lineage submission with no event
+     */
+    @Override
+    public AsyncLineageSubmission retrieveLineageSubmission(final String 
lineageIdentifier, final NiFiUser user) {
+        return new 
NoOpComputeLineageSubmission(LineageComputationType.FLOWFILE_LINEAGE, null, 
emptyList(), user.getIdentity());
+    }
+
+    /**
+     * @return an empty list of searchable fields
+     */
+    @Override
+    public List<SearchableField> getSearchableFields() {
+        return emptyList();
+    }
+
+    /**
+     * @return an empty list of searchable attributes
+     */
+    @Override
+    public List<SearchableField> getSearchableAttributes() {
+        return emptyList();
+    }
+
+    /**
+     * @return a singleton set containing the string "noOp"
+     */
+    @Override
+    public Set<String> getContainerNames() {
+        return singleton("noOp");
+    }
+
+    /**
+     * @return 0 as this implementation does not store data
+     */
+    @Override
+    public long getContainerCapacity(String s) {
+        return 0;
+    }
+
+    /**
+     * @return "noOp" as the file store name
+     */
+    @Override
+    public String getContainerFileStoreName(String containerName) {
+        return "noOp";
+    }
+
+    /**
+     * @return 0 as this implementation does not store data
+     */
+    @Override
+    public long getContainerUsableSpace(String containerName) {
+        return 0;
+    }
+
+    /**
+     * @return a no-op stub lineage submission for expanding parents
+     */
+    @Override
+    public AsyncLineageSubmission submitExpandParents(final long eventId, 
final NiFiUser user) {
+        return new 
NoOpComputeLineageSubmission(LineageComputationType.EXPAND_PARENTS, null, 
emptyList(), user.getIdentity());
+    }
+
+    /**
+     * @return a stub no-op lineage submission for expanding children
+     */
+    @Override
+    public AsyncLineageSubmission submitExpandChildren(final long eventId, 
final NiFiUser user) {
+        return new 
NoOpComputeLineageSubmission(LineageComputationType.EXPAND_CHILDREN, null, 
emptyList(), user.getIdentity());
+    }
+
+    private static class NoOpComputeLineageSubmission extends 
AsyncLineageSubmission {
+
+        public NoOpComputeLineageSubmission(LineageComputationType 
computationType, Long eventId, Collection<String> lineageFlowFileUuids, String 
submitterId) {
+            super(computationType, eventId, lineageFlowFileUuids, 1, 
submitterId);
+        }
+
+        @Override
+        public boolean isCanceled() {
+            return true;
+        }
+
+    }
+
+    private static final QueryResult noOpQueryResult = new QueryResult() {
+        @Override
+        public List<ProvenanceEventRecord> getMatchingEvents() {
+            return emptyList();
+        }
+
+        @Override
+        public long getTotalHitCount() {
+            return 0;
+        }
+
+        @Override
+        public long getQueryTime() {
+            return 0;
+        }
+
+        @Override
+        public Date getExpiration() {
+            return new Date(0);
+        }
+
+        @Override
+        public String getError() {
+            return "";
+        }
+
+        @Override
+        public int getPercentComplete() {
+            return 100;
+        }
+
+        @Override
+        public boolean isFinished() {
+            return true;
+        }
+
+        @Override
+        public boolean awaitCompletion(long time, TimeUnit unit) {
+            return false;
+        }
+    };
+
+    private static class NoOpQuerySubmission implements QuerySubmission {
+        private final Query query;
+        private final String submitterId;
+        private final Date submissionTime = new Date();
+
+        private NoOpQuerySubmission(final Query query, final String id) {
+            this.query = query;
+            this.submitterId = id;
+        }
+
+        private NoOpQuerySubmission(final String queryId, final String id) {
+            this.query = new Query(queryId);
+            this.submitterId = id;
+        }
+
+        @Override
+        public Query getQuery() {
+            return query;
+        }
+
+        @Override
+        public QueryResult getResult() {
+            return noOpQueryResult;
+        }
+
+        @Override
+        public Date getSubmissionTime() {
+            return submissionTime;
+        }
+
+        @Override
+        public String getQueryIdentifier() {
+            return query.getIdentifier();
+        }
+
+        @Override
+        public void cancel() {
+
+        }
+
+        @Override
+        public boolean isCanceled() {
+            return true;
+        }
+
+        @Override
+        public String getSubmitterIdentity() {
+            return submitterId;
+        }
+    }
+}
diff --git 
a/nifi-framework-bundle/nifi-framework-extensions/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/resources/META-INF/services/org.apache.nifi.provenance.ProvenanceRepository
 
b/nifi-framework-bundle/nifi-framework-extensions/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/resources/META-INF/services/org.apache.nifi.provenance.ProvenanceRepository
index 700eb3e6c6..ce0fa4e49c 100644
--- 
a/nifi-framework-bundle/nifi-framework-extensions/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/resources/META-INF/services/org.apache.nifi.provenance.ProvenanceRepository
+++ 
b/nifi-framework-bundle/nifi-framework-extensions/nifi-provenance-repository-bundle/nifi-volatile-provenance-repository/src/main/resources/META-INF/services/org.apache.nifi.provenance.ProvenanceRepository
@@ -12,4 +12,5 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+org.apache.nifi.provenance.NoOpProvenanceRepository
 org.apache.nifi.provenance.VolatileProvenanceRepository
\ No newline at end of file

Reply via email to