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