This is an automated email from the ASF dual-hosted git repository.
exceptionfactory 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 51a07427d9 NIFI-14478 Fixed Modification Tracking for Pasted Versioned
Process Groups (#9894)
51a07427d9 is described below
commit 51a07427d99a69568605920f06ac7f9d3e229da8
Author: Michael Moser <[email protected]>
AuthorDate: Sat Sep 6 21:18:51 2025 -0400
NIFI-14478 Fixed Modification Tracking for Pasted Versioned Process Groups
(#9894)
- Removed ability for a version controlled Process Group to be compared
against anything but the version from the Flow Registry
Signed-off-by: David Handermann <[email protected]>
---
.../StandardVersionedComponentSynchronizer.java | 2 +-
.../apache/nifi/groups/StandardProcessGroup.java | 1 -
.../nifi/groups/FlowSynchronizationOptions.java | 22 ------------------
.../flow/StandardStatelessGroupNodeFactory.java | 1 -
.../serialization/VersionedFlowSynchronizer.java | 1 -
.../apache/nifi/tests/system/pg/CopyPasteIT.java | 27 ++++++++++++++++++++++
6 files changed, 28 insertions(+), 26 deletions(-)
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java
index 7623bdd504..b79ee4d6e8 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/flow/synchronization/StandardVersionedComponentSynchronizer.java
@@ -517,7 +517,7 @@ public class StandardVersionedComponentSynchronizer
implements VersionedComponen
.storageLocation(storageLocation)
.flowName(flowId)
.version(version)
-
.flowSnapshot(syncOptions.isUpdateGroupVersionControlSnapshot() ? proposed :
null)
+ .flowSnapshot(null)
.status(new StandardVersionedFlowStatus(flowState,
flowState.getDescription()))
.build();
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
index cc1928a070..54436ada0d 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-components/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
@@ -3846,7 +3846,6 @@ public final class StandardProcessGroup implements
ProcessGroup {
.ignoreLocalModifications(!verifyNotDirty)
.updateDescendantVersionedFlows(updateDescendantVersionedFlows)
.updateGroupSettings(updateSettings)
- .updateGroupVersionControlSnapshot(true)
.updateRpgUrls(false)
.propertyDecryptor(value -> null)
.build();
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/FlowSynchronizationOptions.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/FlowSynchronizationOptions.java
index f609a8b88b..b857f07f05 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/FlowSynchronizationOptions.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/FlowSynchronizationOptions.java
@@ -30,7 +30,6 @@ public class FlowSynchronizationOptions {
private final boolean ignoreLocalModifications;
private final boolean updateSettings;
private final boolean updateDescendantVersionedFlows;
- private final boolean updateGroupVersionControlSnapshot;
private final boolean updateRpgUrls;
private final Duration componentStopTimeout;
private final ComponentStopTimeoutAction timeoutAction;
@@ -45,7 +44,6 @@ public class FlowSynchronizationOptions {
this.ignoreLocalModifications = builder.ignoreLocalModifications;
this.updateSettings = builder.updateSettings;
this.updateDescendantVersionedFlows =
builder.updateDescendantVersionedFlows;
- this.updateGroupVersionControlSnapshot =
builder.updateGroupVersionControlSnapshot;
this.updateRpgUrls = builder.updateRpgUrls;
this.componentStopTimeout = builder.componentStopTimeout;
this.timeoutAction = builder.timeoutAction;
@@ -77,10 +75,6 @@ public class FlowSynchronizationOptions {
return updateDescendantVersionedFlows;
}
- public boolean isUpdateGroupVersionControlSnapshot() {
- return updateGroupVersionControlSnapshot;
- }
-
public boolean isUpdateRpgUrls() {
return updateRpgUrls;
}
@@ -112,7 +106,6 @@ public class FlowSynchronizationOptions {
private boolean ignoreLocalModifications = false;
private boolean updateSettings = true;
private boolean updateDescendantVersionedFlows = true;
- private boolean updateGroupVersionControlSnapshot = true;
private boolean updateRpgUrls = false;
private ScheduledStateChangeListener scheduledStateChangeListener;
private PropertyDecryptor propertyDecryptor = value -> value;
@@ -183,20 +176,6 @@ public class FlowSynchronizationOptions {
return this;
}
- /**
- * When a Process Group is version controlled, it tracks whether or
not there are any local modifications by comparing the current dataflow
- * to a snapshot of what the Versioned Flow looks like. If this value
is set to <code>true</code>, when the Process Group is synchronized
- * with a VersionedProcessGroup, that VersionedProcessGroup will
become the snapshot of what the Versioned Flow looks like. If
<code>false</code>,
- * the snapshot is not updated.
- *
- * @param updateGroupVersionControlSnapshot <code>true</code> to
update the snapshot, <code>false</code> otherwise
- * @return the builder
- */
- public Builder updateGroupVersionControlSnapshot(final boolean
updateGroupVersionControlSnapshot) {
- this.updateGroupVersionControlSnapshot =
updateGroupVersionControlSnapshot;
- return this;
- }
-
/**
* Specifies whether or not the URLs / "Target URIs" of a Remote
Process Group that exists in both the proposed flow and the current flow
* should be updated to match that of the proposed flow
@@ -285,7 +264,6 @@ public class FlowSynchronizationOptions {
builder.ignoreLocalModifications =
options.isIgnoreLocalModifications();
builder.updateSettings = options.isUpdateSettings();
builder.updateDescendantVersionedFlows =
options.isUpdateDescendantVersionedFlows();
- builder.updateGroupVersionControlSnapshot =
options.isUpdateGroupVersionControlSnapshot();
builder.updateRpgUrls = options.isUpdateRpgUrls();
builder.propertyDecryptor = options.getPropertyDecryptor();
builder.componentStopTimeout = options.getComponentStopTimeout();
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/flow/StandardStatelessGroupNodeFactory.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/flow/StandardStatelessGroupNodeFactory.java
index 41568ed9a2..879023445a 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/flow/StandardStatelessGroupNodeFactory.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/flow/StandardStatelessGroupNodeFactory.java
@@ -293,7 +293,6 @@ public class StandardStatelessGroupNodeFactory implements
StatelessGroupNodeFact
.topLevelGroupId(group.getIdentifier())
.updateDescendantVersionedFlows(true)
.updateGroupSettings(true)
- .updateGroupVersionControlSnapshot(false)
.updateRpgUrls(true)
.ignoreLocalModifications(true)
.build();
diff --git
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
index 68b2713048..61a586edd8 100644
---
a/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
+++
b/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/VersionedFlowSynchronizer.java
@@ -445,7 +445,6 @@ public class VersionedFlowSynchronizer implements
FlowSynchronizer {
.ignoreLocalModifications(true)
.updateGroupSettings(true)
.updateDescendantVersionedFlows(true)
- .updateGroupVersionControlSnapshot(false)
.updateRpgUrls(true)
.propertyDecryptor(encryptor::decrypt)
.build();
diff --git
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/pg/CopyPasteIT.java
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/pg/CopyPasteIT.java
index c86b4f619c..f66c800695 100644
---
a/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/pg/CopyPasteIT.java
+++
b/nifi-system-tests/nifi-system-test-suite/src/test/java/org/apache/nifi/tests/system/pg/CopyPasteIT.java
@@ -402,4 +402,31 @@ public class CopyPasteIT extends NiFiSystemIT {
assertNotEquals(terminate1.getComponent().getId(),
terminate2.getComponent().getId());
assertEquals(terminate1.getComponent().getVersionedComponentId(),
terminate2.getComponent().getVersionedComponentId());
}
+
+ @Test
+ public void testCopyPasteVersionControlledProcessGroupWithLocalChanges()
throws NiFiClientException, IOException, InterruptedException {
+ // Create a top-level PG and version it with nothing in it.
+ final FlowRegistryClientEntity clientEntity = registerClient();
+ final ProcessGroupEntity topLevel1 =
getClientUtil().createProcessGroup("Top Level 1", "root");
+
+ // Create a lower level PG and add a Processor. Commit as Version 1
of the PG.
+ final ProcessGroupEntity innerGroup =
getClientUtil().createProcessGroup("Inner 1", topLevel1.getId());
+ ProcessorEntity terminate1 =
getClientUtil().createProcessor("TerminateFlowFile", innerGroup.getId());
+ VersionControlInformationEntity vciEntity =
getClientUtil().startVersionControl(innerGroup, clientEntity,
TEST_FLOWS_BUCKET, FIRST_FLOW_ID);
+ assertEquals("1",
vciEntity.getVersionControlInformation().getVersion());
+
+ // Modify the processor and wait for the group to show it has local
changes
+ getClientUtil().updateProcessorSchedulingPeriod(terminate1, "2 mins");
+ waitFor(() ->
VersionControlInformationDTO.LOCALLY_MODIFIED.equals(getClientUtil().getVersionControlState(innerGroup.getId())));
+
+ // Copy the versioned and modified process group and paste it to a new
PG.
+ final ProcessGroupEntity topLevel2 =
getClientUtil().createProcessGroup("Top Level 2", "root");
+ final CopyRequestEntity copyRequestEntity = new CopyRequestEntity();
+ copyRequestEntity.setProcessGroups(Set.of(innerGroup.getId()));
+ final FlowDTO flowDto =
getClientUtil().copyAndPaste(topLevel1.getId(), copyRequestEntity,
topLevel2.getRevision(), topLevel2.getId());
+
+ // The new PG should also show as being locally modified from Version
1 of the PG
+ final String pastedGroupId =
flowDto.getProcessGroups().iterator().next().getId();
+ waitFor(() ->
VersionControlInformationDTO.LOCALLY_MODIFIED.equals(getClientUtil().getVersionControlState(pastedGroupId)));
+ }
}